diff options
Diffstat (limited to 'drivers/rtc')
66 files changed, 1754 insertions, 936 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 83b4b89b9d5a..9d4290617cee 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -945,11 +945,11 @@ config RTC_DRV_DA9055  	  will be called rtc-da9055  config RTC_DRV_DA9063 -	tristate "Dialog Semiconductor DA9063 RTC" -	depends on MFD_DA9063 +	tristate "Dialog Semiconductor DA9063/DA9062 RTC" +	depends on MFD_DA9063 || MFD_DA9062  	help  	  If you say yes here you will get support for the RTC subsystem -	  of the Dialog Semiconductor DA9063. +	  for the Dialog Semiconductor PMIC chips DA9063 and DA9062.  	  This driver can also be built as a module. If so, the module  	  will be called "rtc-da9063". @@ -1116,6 +1116,13 @@ config RTC_DRV_OPAL  	  This driver can also be built as a module. If so, the module  	  will be called rtc-opal. +config RTC_DRV_ZYNQMP +	tristate "Xilinx Zynq Ultrascale+ MPSoC RTC" +	depends on OF +	help +	  If you say yes here you get support for the RTC controller found on +	  Xilinx Zynq Ultrascale+ MPSoC. +  comment "on-CPU RTC drivers"  config RTC_DRV_DAVINCI @@ -1306,11 +1313,13 @@ config RTC_DRV_GENERIC  	  just say Y.  config RTC_DRV_PXA -	tristate "PXA27x/PXA3xx" -	depends on ARCH_PXA -	help -	 If you say Y here you will get access to the real time clock -	 built into your PXA27x or PXA3xx CPU. +       tristate "PXA27x/PXA3xx" +       depends on ARCH_PXA +       select RTC_DRV_SA1100 +       help +         If you say Y here you will get access to the real time clock +         built into your PXA27x or PXA3xx CPU. This RTC is actually 2 RTCs +         consisting of an SA1100 compatible RTC and the extended PXA RTC.  	 This RTC driver uses PXA RTC registers available since pxa27x  	 series (RDxR, RYxR) instead of legacy RCNR, RTAR. @@ -1456,6 +1465,18 @@ config RTC_DRV_JZ4740  	  This driver can also be buillt as a module. If so, the module  	  will be called rtc-jz4740. +config RTC_DRV_LPC24XX +	tristate "NXP RTC for LPC178x/18xx/408x/43xx" +	depends on ARCH_LPC18XX || COMPILE_TEST +	depends on OF && HAS_IOMEM +	help +	  This enables support for the NXP RTC found which can be found on +	  NXP LPC178x/18xx/408x/43xx devices. + +	  If you have one of the devices above enable this driver to use +	  the hardware RTC. This driver can also be buillt as a module. If +	  so, the module will be called rtc-lpc24xx. +  config RTC_DRV_LPC32XX  	depends on ARCH_LPC32XX  	tristate "NXP LPC32XX RTC" @@ -1523,6 +1544,7 @@ config RTC_DRV_MXC  config RTC_DRV_SNVS  	tristate "Freescale SNVS RTC support" +	select REGMAP_MMIO  	depends on HAS_IOMEM  	depends on OF  	help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 1b09a62fcf4b..e491eb524434 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -74,6 +74,7 @@ obj-$(CONFIG_RTC_DRV_ISL12057)	+= rtc-isl12057.o  obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o  obj-$(CONFIG_RTC_DRV_JZ4740)	+= rtc-jz4740.o  obj-$(CONFIG_RTC_DRV_LP8788)	+= rtc-lp8788.o +obj-$(CONFIG_RTC_DRV_LPC24XX)	+= rtc-lpc24xx.o  obj-$(CONFIG_RTC_DRV_LPC32XX)	+= rtc-lpc32xx.o  obj-$(CONFIG_RTC_DRV_LOONGSON1)	+= rtc-ls1x.o  obj-$(CONFIG_RTC_DRV_M41T80)	+= rtc-m41t80.o @@ -158,3 +159,4 @@ obj-$(CONFIG_RTC_DRV_WM831X)	+= rtc-wm831x.o  obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o  obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o  obj-$(CONFIG_RTC_DRV_XGENE)	+= rtc-xgene.o +obj-$(CONFIG_RTC_DRV_ZYNQMP)	+= rtc-zynqmp.o diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index ea2a315df6b7..de86578bcd6d 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -202,6 +202,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,  	rtc->max_user_freq = 64;  	rtc->dev.parent = dev;  	rtc->dev.class = rtc_class; +	rtc->dev.groups = rtc_get_dev_attribute_groups();  	rtc->dev.release = rtc_device_release;  	mutex_init(&rtc->ops_lock); @@ -234,12 +235,12 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,  	err = device_register(&rtc->dev);  	if (err) { +		/* This will free both memory and the ID */  		put_device(&rtc->dev); -		goto exit_kfree; +		goto exit;  	}  	rtc_dev_add_device(rtc); -	rtc_sysfs_add_device(rtc);  	rtc_proc_add_device(rtc);  	dev_info(dev, "rtc core: registered %s as %s\n", @@ -247,9 +248,6 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,  	return rtc; -exit_kfree: -	kfree(rtc); -  exit_ida:  	ida_simple_remove(&rtc_ida, id); @@ -268,19 +266,17 @@ EXPORT_SYMBOL_GPL(rtc_device_register);   */  void rtc_device_unregister(struct rtc_device *rtc)  { -	if (get_device(&rtc->dev) != NULL) { -		mutex_lock(&rtc->ops_lock); -		/* remove innards of this RTC, then disable it, before -		 * letting any rtc_class_open() users access it again -		 */ -		rtc_sysfs_del_device(rtc); -		rtc_dev_del_device(rtc); -		rtc_proc_del_device(rtc); -		device_unregister(&rtc->dev); -		rtc->ops = NULL; -		mutex_unlock(&rtc->ops_lock); -		put_device(&rtc->dev); -	} +	mutex_lock(&rtc->ops_lock); +	/* +	 * Remove innards of this RTC, then disable it, before +	 * letting any rtc_class_open() users access it again +	 */ +	rtc_dev_del_device(rtc); +	rtc_proc_del_device(rtc); +	device_del(&rtc->dev); +	rtc->ops = NULL; +	mutex_unlock(&rtc->ops_lock); +	put_device(&rtc->dev);  }  EXPORT_SYMBOL_GPL(rtc_device_unregister); @@ -363,7 +359,6 @@ static int __init rtc_init(void)  	}  	rtc_class->pm = RTC_CLASS_DEV_PM_OPS;  	rtc_dev_init(); -	rtc_sysfs_init(rtc_class);  	return 0;  } diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 11b639067312..5836751b8203 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -564,7 +564,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)  void rtc_update_irq(struct rtc_device *rtc,  		unsigned long num, unsigned long events)  { -	if (unlikely(IS_ERR_OR_NULL(rtc))) +	if (IS_ERR_OR_NULL(rtc))  		return;  	pm_stay_awake(rtc->dev.parent); diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c index 7df0579d9852..466bf7f9a285 100644 --- a/drivers/rtc/rtc-88pm80x.c +++ b/drivers/rtc/rtc-88pm80x.c @@ -251,17 +251,26 @@ static SIMPLE_DEV_PM_OPS(pm80x_rtc_pm_ops, pm80x_rtc_suspend, pm80x_rtc_resume);  static int pm80x_rtc_probe(struct platform_device *pdev)  {  	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent); -	struct pm80x_platform_data *pm80x_pdata = -				dev_get_platdata(pdev->dev.parent); -	struct pm80x_rtc_pdata *pdata = NULL; +	struct pm80x_rtc_pdata *pdata = dev_get_platdata(&pdev->dev);  	struct pm80x_rtc_info *info; +	struct device_node *node = pdev->dev.of_node;  	struct rtc_time tm;  	unsigned long ticks = 0;  	int ret; -	pdata = dev_get_platdata(&pdev->dev); -	if (pdata == NULL) -		dev_warn(&pdev->dev, "No platform data!\n"); +	if (!pdata && !node) { +		dev_err(&pdev->dev, +			"pm80x-rtc requires platform data or of_node\n"); +		return -EINVAL; +	} + +	if (!pdata) { +		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); +		if (!pdata) { +			dev_err(&pdev->dev, "failed to allocate memory\n"); +			return -ENOMEM; +		} +	}  	info =  	    devm_kzalloc(&pdev->dev, sizeof(struct pm80x_rtc_info), GFP_KERNEL); @@ -327,11 +336,8 @@ static int pm80x_rtc_probe(struct platform_device *pdev)  	regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_RTC1_USE_XO,  			   PM800_RTC1_USE_XO); -	if (pm80x_pdata) { -		pdata = pm80x_pdata->rtc; -		if (pdata) -			info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup; -	} +	/* remember whether this power up is caused by PMIC RTC or not */ +	info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup;  	device_init_wakeup(&pdev->dev, 1); diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index b5cbc1bf5a3e..a319bf1e49de 100644 --- a/drivers/rtc/rtc-ab-b5ze-s3.c +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -1009,6 +1009,7 @@ static const struct of_device_id abb5zes3_dt_match[] = {  	{ .compatible = "abracon,abb5zes3" },  	{ },  }; +MODULE_DEVICE_TABLE(of, abb5zes3_dt_match);  #endif  static const struct i2c_device_id abb5zes3_id[] = { @@ -1020,7 +1021,6 @@ MODULE_DEVICE_TABLE(i2c, abb5zes3_id);  static struct i2c_driver abb5zes3_driver = {  	.driver = {  		.name = DRV_NAME, -		.owner = THIS_MODULE,  		.pm = &abb5zes3_rtc_pm_ops,  		.of_match_table = of_match_ptr(abb5zes3_dt_match),  	}, diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 133d2e2e1a25..51407c4c7bd2 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -445,7 +445,9 @@ static const struct rtc_class_ops ab8540_rtc_ops = {  static const struct platform_device_id ab85xx_rtc_ids[] = {  	{ "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, },  	{ "ab8540-rtc", (kernel_ulong_t)&ab8540_rtc_ops, }, +	{ /* sentinel */ }  }; +MODULE_DEVICE_TABLE(platform, ab85xx_rtc_ids);  static int ab8500_rtc_probe(struct platform_device *pdev)  { diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index 4337c3bc6ace..afea84c7a155 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -28,7 +28,7 @@  #define ABX8XX_REG_WD		0x07  #define ABX8XX_REG_CTRL1	0x10 -#define ABX8XX_CTRL_WRITE	BIT(1) +#define ABX8XX_CTRL_WRITE	BIT(0)  #define ABX8XX_CTRL_12_24	BIT(6)  #define ABX8XX_REG_CFG_KEY	0x1f diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c index 4b62d1a875e4..9a3f2a6f512e 100644 --- a/drivers/rtc/rtc-armada38x.c +++ b/drivers/rtc/rtc-armada38x.c @@ -40,13 +40,6 @@ struct armada38x_rtc {  	void __iomem	    *regs;  	void __iomem	    *regs_soc;  	spinlock_t	    lock; -	/* -	 * While setting the time, the RTC TIME register should not be -	 * accessed. Setting the RTC time involves sleeping during -	 * 100ms, so a mutex instead of a spinlock is used to protect -	 * it -	 */ -	struct mutex	    mutex_time;  	int		    irq;  }; @@ -64,9 +57,9 @@ static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)  static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)  {  	struct armada38x_rtc *rtc = dev_get_drvdata(dev); -	unsigned long time, time_check; +	unsigned long time, time_check, flags; -	mutex_lock(&rtc->mutex_time); +	spin_lock_irqsave(&rtc->lock, flags);  	time = readl(rtc->regs + RTC_TIME);  	/*  	 * WA for failing time set attempts. As stated in HW ERRATA if @@ -77,7 +70,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)  	if ((time_check - time) > 1)  		time_check = readl(rtc->regs + RTC_TIME); -	mutex_unlock(&rtc->mutex_time); +	spin_unlock_irqrestore(&rtc->lock, flags);  	rtc_time_to_tm(time_check, tm); @@ -95,16 +88,16 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)  	if (ret)  		goto out;  	/* -	 * Setting the RTC time not always succeeds. According to the -	 * errata we need to first write on the status register and -	 * then wait for 100ms before writing to the time register to be -	 * sure that the data will be taken into account. +	 * According to errata FE-3124064, Write to RTC TIME register +	 * may fail. As a workaround, after writing to RTC TIME +	 * register, issue a dummy write of 0x0 twice to RTC Status +	 * register.  	 */ -	mutex_lock(&rtc->mutex_time); -	rtc_delayed_write(0, rtc, RTC_STATUS); -	msleep(100); +	spin_lock_irqsave(&rtc->lock, flags);  	rtc_delayed_write(time, rtc, RTC_TIME); -	mutex_unlock(&rtc->mutex_time); +	rtc_delayed_write(0, rtc, RTC_STATUS); +	rtc_delayed_write(0, rtc, RTC_STATUS); +	spin_unlock_irqrestore(&rtc->lock, flags);  out:  	return ret; @@ -229,7 +222,6 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)  		return -ENOMEM;  	spin_lock_init(&rtc->lock); -	mutex_init(&rtc->mutex_time);  	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");  	rtc->regs = devm_ioremap_resource(&pdev->dev, res); @@ -303,6 +295,7 @@ static const struct of_device_id armada38x_rtc_of_match_table[] = {  	{ .compatible = "marvell,armada-380-rtc", },  	{}  }; +MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);  #endif  static struct platform_driver armada38x_rtc_driver = { diff --git a/drivers/rtc/rtc-as3722.c b/drivers/rtc/rtc-as3722.c index 9f38eda69154..56cc5821118b 100644 --- a/drivers/rtc/rtc-as3722.c +++ b/drivers/rtc/rtc-as3722.c @@ -45,7 +45,7 @@ static void as3722_time_to_reg(u8 *rbuff, struct rtc_time *tm)  	rbuff[1] = bin2bcd(tm->tm_min);  	rbuff[2] = bin2bcd(tm->tm_hour);  	rbuff[3] = bin2bcd(tm->tm_mday); -	rbuff[4] = bin2bcd(tm->tm_mon); +	rbuff[4] = bin2bcd(tm->tm_mon + 1);  	rbuff[5] = bin2bcd(tm->tm_year - (AS3722_RTC_START_YEAR - 1900));  } @@ -55,7 +55,7 @@ static void as3722_reg_to_time(u8 *rbuff, struct rtc_time *tm)  	tm->tm_min = bcd2bin(rbuff[1] & 0x7F);  	tm->tm_hour = bcd2bin(rbuff[2] & 0x3F);  	tm->tm_mday = bcd2bin(rbuff[3] & 0x3F); -	tm->tm_mon = bcd2bin(rbuff[4] & 0x1F); +	tm->tm_mon = bcd2bin(rbuff[4] & 0x1F) - 1;  	tm->tm_year = (AS3722_RTC_START_YEAR - 1900) + bcd2bin(rbuff[5] & 0x7F);  	return;  } diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 35efd3f75b18..cb62e214b52a 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -18,20 +18,21 @@   *   */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/time.h> -#include <linux/rtc.h>  #include <linux/bcd.h> +#include <linux/clk.h> +#include <linux/completion.h>  #include <linux/interrupt.h> -#include <linux/spinlock.h>  #include <linux/ioctl.h> -#include <linux/completion.h>  #include <linux/io.h> -#include <linux/of.h> +#include <linux/kernel.h> +#include <linux/module.h>  #include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> +#include <linux/spinlock.h>  #include <linux/suspend.h> +#include <linux/time.h>  #include <linux/uaccess.h>  #include "rtc-at91rm9200.h" @@ -59,6 +60,7 @@ static bool suspended;  static DEFINE_SPINLOCK(suspended_lock);  static unsigned long cached_events;  static u32 at91_rtc_imr; +static struct clk *sclk;  static void at91_rtc_write_ier(u32 mask)  { @@ -407,6 +409,16 @@ static int __init at91_rtc_probe(struct platform_device *pdev)  		return -ENOMEM;  	} +	sclk = devm_clk_get(&pdev->dev, NULL); +	if (IS_ERR(sclk)) +		return PTR_ERR(sclk); + +	ret = clk_prepare_enable(sclk); +	if (ret) { +		dev_err(&pdev->dev, "Could not enable slow clock\n"); +		return ret; +	} +  	at91_rtc_write(AT91_RTC_CR, 0);  	at91_rtc_write(AT91_RTC_MR, 0);		/* 24 hour mode */ @@ -420,7 +432,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)  			       "at91_rtc", pdev);  	if (ret) {  		dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); -		return ret; +		goto err_clk;  	}  	/* cpu init code should really have flagged this device as @@ -431,8 +443,10 @@ static int __init at91_rtc_probe(struct platform_device *pdev)  	rtc = devm_rtc_device_register(&pdev->dev, pdev->name,  				&at91_rtc_ops, THIS_MODULE); -	if (IS_ERR(rtc)) -		return PTR_ERR(rtc); +	if (IS_ERR(rtc)) { +		ret = PTR_ERR(rtc); +		goto err_clk; +	}  	platform_set_drvdata(pdev, rtc);  	/* enable SECEV interrupt in order to initialize at91_rtc_upd_rdy @@ -442,6 +456,11 @@ static int __init at91_rtc_probe(struct platform_device *pdev)  	dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n");  	return 0; + +err_clk: +	clk_disable_unprepare(sclk); + +	return ret;  }  /* @@ -454,6 +473,8 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)  					AT91_RTC_SECEV | AT91_RTC_TIMEV |  					AT91_RTC_CALEV); +	clk_disable_unprepare(sclk); +  	return 0;  } diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 5ccaee32df72..7206e2fa4383 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -11,20 +11,20 @@   * 2 of the License, or (at your option) any later version.   */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/time.h> -#include <linux/rtc.h> +#include <linux/clk.h>  #include <linux/interrupt.h>  #include <linux/ioctl.h> -#include <linux/slab.h> -#include <linux/platform_data/atmel.h>  #include <linux/io.h> +#include <linux/kernel.h>  #include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h>  #include <linux/regmap.h> +#include <linux/rtc.h> +#include <linux/slab.h>  #include <linux/suspend.h> -#include <linux/clk.h> +#include <linux/time.h>  /*   * This driver uses two configurable hardware resources that live in the @@ -425,18 +425,19 @@ static int at91_rtc_probe(struct platform_device *pdev)  	if (IS_ERR(rtc->sclk))  		return PTR_ERR(rtc->sclk); -	sclk_rate = clk_get_rate(rtc->sclk); -	if (!sclk_rate || sclk_rate > AT91_RTT_RTPRES) { -		dev_err(&pdev->dev, "Invalid slow clock rate\n"); -		return -EINVAL; -	} -  	ret = clk_prepare_enable(rtc->sclk);  	if (ret) {  		dev_err(&pdev->dev, "Could not enable slow clock\n");  		return ret;  	} +	sclk_rate = clk_get_rate(rtc->sclk); +	if (!sclk_rate || sclk_rate > AT91_RTT_RTPRES) { +		dev_err(&pdev->dev, "Invalid slow clock rate\n"); +		ret = -EINVAL; +		goto err_clk; +	} +  	mr = rtt_readl(rtc, MR);  	/* unless RTT is counting at 1 Hz, re-initialize it */ @@ -451,8 +452,10 @@ static int at91_rtc_probe(struct platform_device *pdev)  	rtc->rtcdev = devm_rtc_device_register(&pdev->dev, pdev->name,  					&at91_rtc_ops, THIS_MODULE); -	if (IS_ERR(rtc->rtcdev)) -		return PTR_ERR(rtc->rtcdev); +	if (IS_ERR(rtc->rtcdev)) { +		ret = PTR_ERR(rtc->rtcdev); +		goto err_clk; +	}  	/* register irq handler after we know what name we'll use */  	ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt, @@ -460,7 +463,7 @@ static int at91_rtc_probe(struct platform_device *pdev)  			       dev_name(&rtc->rtcdev->dev), rtc);  	if (ret) {  		dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); -		return ret; +		goto err_clk;  	}  	/* NOTE:  sam9260 rev A silicon has a ROM bug which resets the @@ -474,6 +477,11 @@ static int at91_rtc_probe(struct platform_device *pdev)  				dev_name(&rtc->rtcdev->dev));  	return 0; + +err_clk: +	clk_disable_unprepare(rtc->sclk); + +	return ret;  }  /* @@ -487,8 +495,7 @@ static int at91_rtc_remove(struct platform_device *pdev)  	/* disable all interrupts */  	rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); -	if (!IS_ERR(rtc->sclk)) -		clk_disable_unprepare(rtc->sclk); +	clk_disable_unprepare(rtc->sclk);  	return 0;  } diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 3d44b11721ea..535a5f9338d0 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -361,7 +361,7 @@ static int bfin_rtc_probe(struct platform_device *pdev)  	/* Register our RTC with the RTC framework */  	rtc->rtc_dev = devm_rtc_device_register(dev, pdev->name, &bfin_rtc_ops,  						THIS_MODULE); -	if (unlikely(IS_ERR(rtc->rtc_dev))) +	if (IS_ERR(rtc->rtc_dev))  		return PTR_ERR(rtc->rtc_dev);  	/* Grab the IRQ and init the hardware */ diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 92679df6d6e2..0299988b4f13 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -212,7 +212,7 @@ static int bq32k_probe(struct i2c_client *client,  	if (error)  		return error; -	if (client && client->dev.of_node) +	if (client->dev.of_node)  		trickle_charger_of_init(dev, client->dev.of_node);  	rtc = devm_rtc_device_register(&client->dev, bq32k_driver.driver.name, @@ -234,7 +234,6 @@ MODULE_DEVICE_TABLE(i2c, bq32k_id);  static struct i2c_driver bq32k_driver = {  	.driver = {  		.name	= "bq32k", -		.owner	= THIS_MODULE,  	},  	.probe		= bq32k_probe,  	.id_table	= bq32k_id, diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index a82556a0757a..8f7034ba7d9e 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -41,7 +41,6 @@  #include <linux/pm.h>  #include <linux/of.h>  #include <linux/of_platform.h> -#include <linux/dmi.h>  /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */  #include <asm-generic/rtc.h> @@ -51,6 +50,7 @@ struct cmos_rtc {  	struct device		*dev;  	int			irq;  	struct resource		*iomem; +	time64_t		alarm_expires;  	void			(*wake_on)(struct device *);  	void			(*wake_off)(struct device *); @@ -377,53 +377,11 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)  	spin_unlock_irq(&rtc_lock); -	return 0; -} - -/* - * Do not disable RTC alarm on shutdown - workaround for b0rked BIOSes. - */ -static bool alarm_disable_quirk; +	cmos->alarm_expires = rtc_tm_to_time64(&t->time); -static int __init set_alarm_disable_quirk(const struct dmi_system_id *id) -{ -	alarm_disable_quirk = true; -	pr_info("BIOS has alarm-disable quirk - RTC alarms disabled\n");  	return 0;  } -static const struct dmi_system_id rtc_quirks[] __initconst = { -	/* https://bugzilla.novell.com/show_bug.cgi?id=805740 */ -	{ -		.callback = set_alarm_disable_quirk, -		.ident    = "IBM Truman", -		.matches  = { -			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), -			DMI_MATCH(DMI_PRODUCT_NAME, "4852570"), -		}, -	}, -	/* https://bugzilla.novell.com/show_bug.cgi?id=812592 */ -	{ -		.callback = set_alarm_disable_quirk, -		.ident    = "Gigabyte GA-990XA-UD3", -		.matches  = { -			DMI_MATCH(DMI_SYS_VENDOR, -					"Gigabyte Technology Co., Ltd."), -			DMI_MATCH(DMI_PRODUCT_NAME, "GA-990XA-UD3"), -		}, -	}, -	/* http://permalink.gmane.org/gmane.linux.kernel/1604474 */ -	{ -		.callback = set_alarm_disable_quirk, -		.ident    = "Toshiba Satellite L300", -		.matches  = { -			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), -			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), -		}, -	}, -	{} -}; -  static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)  {  	struct cmos_rtc	*cmos = dev_get_drvdata(dev); @@ -432,9 +390,6 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)  	if (!is_valid_irq(cmos->irq))  		return -EINVAL; -	if (alarm_disable_quirk) -		return 0; -  	spin_lock_irqsave(&rtc_lock, flags);  	if (enabled) @@ -512,13 +467,6 @@ cmos_nvram_read(struct file *filp, struct kobject *kobj,  {  	int	retval; -	if (unlikely(off >= attr->size)) -		return 0; -	if (unlikely(off < 0)) -		return -EINVAL; -	if ((off + count) > attr->size) -		count = attr->size - off; -  	off += NVRAM_OFFSET;  	spin_lock_irq(&rtc_lock);  	for (retval = 0; count; count--, off++, retval++) { @@ -543,12 +491,6 @@ cmos_nvram_write(struct file *filp, struct kobject *kobj,  	int		retval;  	cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); -	if (unlikely(off >= attr->size)) -		return -EFBIG; -	if (unlikely(off < 0)) -		return -EINVAL; -	if ((off + count) > attr->size) -		count = attr->size - off;  	/* NOTE:  on at least PCs and Ataris, the boot firmware uses a  	 * checksum on part of the NVRAM data.  That's currently ignored @@ -860,6 +802,51 @@ static void __exit cmos_do_remove(struct device *dev)  	cmos->dev = NULL;  } +static int cmos_aie_poweroff(struct device *dev) +{ +	struct cmos_rtc	*cmos = dev_get_drvdata(dev); +	struct rtc_time now; +	time64_t t_now; +	int retval = 0; +	unsigned char rtc_control; + +	if (!cmos->alarm_expires) +		return -EINVAL; + +	spin_lock_irq(&rtc_lock); +	rtc_control = CMOS_READ(RTC_CONTROL); +	spin_unlock_irq(&rtc_lock); + +	/* We only care about the situation where AIE is disabled. */ +	if (rtc_control & RTC_AIE) +		return -EBUSY; + +	cmos_read_time(dev, &now); +	t_now = rtc_tm_to_time64(&now); + +	/* +	 * When enabling "RTC wake-up" in BIOS setup, the machine reboots +	 * automatically right after shutdown on some buggy boxes. +	 * This automatic rebooting issue won't happen when the alarm +	 * time is larger than now+1 seconds. +	 * +	 * If the alarm time is equal to now+1 seconds, the issue can be +	 * prevented by cancelling the alarm. +	 */ +	if (cmos->alarm_expires == t_now + 1) { +		struct rtc_wkalrm alarm; + +		/* Cancel the AIE timer by configuring the past time. */ +		rtc_time64_to_tm(t_now - 1, &alarm.time); +		alarm.enabled = 0; +		retval = cmos_set_alarm(dev, &alarm); +	} else if (cmos->alarm_expires > t_now + 1) { +		retval = -EBUSY; +	} + +	return retval; +} +  #ifdef CONFIG_PM  static int cmos_suspend(struct device *dev) @@ -1094,8 +1081,12 @@ static void cmos_pnp_shutdown(struct pnp_dev *pnp)  	struct device *dev = &pnp->dev;  	struct cmos_rtc	*cmos = dev_get_drvdata(dev); -	if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(dev)) -		return; +	if (system_state == SYSTEM_POWER_OFF) { +		int retval = cmos_poweroff(dev); + +		if (cmos_aie_poweroff(dev) < 0 && !retval) +			return; +	}  	cmos_do_shutdown(cmos->irq);  } @@ -1200,8 +1191,12 @@ static void cmos_platform_shutdown(struct platform_device *pdev)  	struct device *dev = &pdev->dev;  	struct cmos_rtc	*cmos = dev_get_drvdata(dev); -	if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(dev)) -		return; +	if (system_state == SYSTEM_POWER_OFF) { +		int retval = cmos_poweroff(dev); + +		if (cmos_aie_poweroff(dev) < 0 && !retval) +			return; +	}  	cmos_do_shutdown(cmos->irq);  } @@ -1243,8 +1238,6 @@ static int __init cmos_init(void)  			platform_driver_registered = true;  	} -	dmi_check_system(rtc_quirks); -  	if (retval == 0)  		return 0; diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 56343b2fbc68..101b7a240e0f 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c @@ -263,6 +263,7 @@ static const struct of_device_id coh901331_dt_match[] = {  	{ .compatible = "stericsson,coh901331" },  	{},  }; +MODULE_DEVICE_TABLE(of, coh901331_dt_match);  static struct platform_driver coh901331_driver = {  	.driver = { diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h index 5f9df7430a22..a098aea197fc 100644 --- a/drivers/rtc/rtc-core.h +++ b/drivers/rtc/rtc-core.h @@ -48,23 +48,10 @@ static inline void rtc_proc_del_device(struct rtc_device *rtc)  #endif  #ifdef CONFIG_RTC_INTF_SYSFS - -extern void __init rtc_sysfs_init(struct class *); -extern void rtc_sysfs_add_device(struct rtc_device *rtc); -extern void rtc_sysfs_del_device(struct rtc_device *rtc); - +const struct attribute_group **rtc_get_dev_attribute_groups(void);  #else - -static inline void rtc_sysfs_init(struct class *rtc) -{ -} - -static inline void rtc_sysfs_add_device(struct rtc_device *rtc) +static inline const struct attribute_group **rtc_get_dev_attribute_groups(void)  { +	return NULL;  } - -static inline void rtc_sysfs_del_device(struct rtc_device *rtc) -{ -} -  #endif diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index 7ffc5707f8b9..00a8f7f4f87c 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c @@ -12,15 +12,18 @@   * Library General Public License for more details.   */ +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/interrupt.h>  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/init.h> +#include <linux/of.h>  #include <linux/platform_device.h> -#include <linux/interrupt.h> +#include <linux/regmap.h>  #include <linux/rtc.h>  #include <linux/slab.h> -#include <linux/delay.h> -#include <linux/regmap.h> + +#include <linux/mfd/da9062/registers.h>  #include <linux/mfd/da9063/registers.h>  #include <linux/mfd/da9063/core.h> @@ -29,99 +32,231 @@  #define YEARS_FROM_DA9063(year)		((year) + 100)  #define MONTHS_FROM_DA9063(month)	((month) - 1) -#define RTC_ALARM_DATA_LEN (DA9063_AD_REG_ALARM_Y - DA9063_AD_REG_ALARM_MI + 1) - -#define RTC_DATA_LEN	(DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1) -#define RTC_SEC		0 -#define RTC_MIN		1 -#define RTC_HOUR	2 -#define RTC_DAY		3 -#define RTC_MONTH	4 -#define RTC_YEAR	5 - -struct da9063_rtc { -	struct rtc_device	*rtc_dev; -	struct da9063		*hw; -	struct rtc_time		alarm_time; -	bool			rtc_sync; -	int			alarm_year; -	int			alarm_start; -	int			alarm_len; -	int			data_start; +enum { +	RTC_SEC	= 0, +	RTC_MIN	= 1, +	RTC_HOUR = 2, +	RTC_DAY	= 3, +	RTC_MONTH = 4, +	RTC_YEAR = 5, +	RTC_DATA_LEN +}; + +struct da9063_compatible_rtc_regmap { +	/* REGS */ +	int rtc_enable_reg; +	int rtc_enable_32k_crystal_reg; +	int rtc_alarm_secs_reg; +	int rtc_alarm_year_reg; +	int rtc_count_secs_reg; +	int rtc_count_year_reg; +	int rtc_event_reg; +	/* MASKS */ +	int rtc_enable_mask; +	int rtc_crystal_mask; +	int rtc_event_alarm_mask; +	int rtc_alarm_on_mask; +	int rtc_alarm_status_mask; +	int rtc_tick_on_mask; +	int rtc_ready_to_read_mask; +	int rtc_count_sec_mask; +	int rtc_count_min_mask; +	int rtc_count_hour_mask; +	int rtc_count_day_mask; +	int rtc_count_month_mask; +	int rtc_count_year_mask; +	/* ALARM CONFIG */ +	int rtc_data_start; +	int rtc_alarm_len; +}; + +struct da9063_compatible_rtc { +	struct rtc_device *rtc_dev; +	struct rtc_time alarm_time; +	struct regmap *regmap; +	const struct da9063_compatible_rtc_regmap *config; +	bool rtc_sync; +}; + +static const struct da9063_compatible_rtc_regmap da9063_ad_regs = { +	/* REGS */ +	.rtc_enable_reg             = DA9063_REG_CONTROL_E, +	.rtc_alarm_secs_reg         = DA9063_AD_REG_ALARM_MI, +	.rtc_alarm_year_reg         = DA9063_AD_REG_ALARM_Y, +	.rtc_count_secs_reg         = DA9063_REG_COUNT_S, +	.rtc_count_year_reg         = DA9063_REG_COUNT_Y, +	.rtc_event_reg              = DA9063_REG_EVENT_A, +	/* MASKS */ +	.rtc_enable_mask            = DA9063_RTC_EN, +	.rtc_crystal_mask           = DA9063_CRYSTAL, +	.rtc_enable_32k_crystal_reg = DA9063_REG_EN_32K, +	.rtc_event_alarm_mask       = DA9063_E_ALARM, +	.rtc_alarm_on_mask          = DA9063_ALARM_ON, +	.rtc_alarm_status_mask      = DA9063_ALARM_STATUS_ALARM | +				      DA9063_ALARM_STATUS_TICK, +	.rtc_tick_on_mask           = DA9063_TICK_ON, +	.rtc_ready_to_read_mask     = DA9063_RTC_READ, +	.rtc_count_sec_mask         = DA9063_COUNT_SEC_MASK, +	.rtc_count_min_mask         = DA9063_COUNT_MIN_MASK, +	.rtc_count_hour_mask        = DA9063_COUNT_HOUR_MASK, +	.rtc_count_day_mask         = DA9063_COUNT_DAY_MASK, +	.rtc_count_month_mask       = DA9063_COUNT_MONTH_MASK, +	.rtc_count_year_mask        = DA9063_COUNT_YEAR_MASK, +	/* ALARM CONFIG */ +	.rtc_data_start             = RTC_MIN, +	.rtc_alarm_len              = RTC_DATA_LEN - 1, +}; + +static const struct da9063_compatible_rtc_regmap da9063_bb_regs = { +	/* REGS */ +	.rtc_enable_reg             = DA9063_REG_CONTROL_E, +	.rtc_alarm_secs_reg         = DA9063_BB_REG_ALARM_S, +	.rtc_alarm_year_reg         = DA9063_BB_REG_ALARM_Y, +	.rtc_count_secs_reg         = DA9063_REG_COUNT_S, +	.rtc_count_year_reg         = DA9063_REG_COUNT_Y, +	.rtc_event_reg              = DA9063_REG_EVENT_A, +	/* MASKS */ +	.rtc_enable_mask            = DA9063_RTC_EN, +	.rtc_crystal_mask           = DA9063_CRYSTAL, +	.rtc_enable_32k_crystal_reg = DA9063_REG_EN_32K, +	.rtc_event_alarm_mask       = DA9063_E_ALARM, +	.rtc_alarm_on_mask          = DA9063_ALARM_ON, +	.rtc_alarm_status_mask      = DA9063_ALARM_STATUS_ALARM | +				      DA9063_ALARM_STATUS_TICK, +	.rtc_tick_on_mask           = DA9063_TICK_ON, +	.rtc_ready_to_read_mask     = DA9063_RTC_READ, +	.rtc_count_sec_mask         = DA9063_COUNT_SEC_MASK, +	.rtc_count_min_mask         = DA9063_COUNT_MIN_MASK, +	.rtc_count_hour_mask        = DA9063_COUNT_HOUR_MASK, +	.rtc_count_day_mask         = DA9063_COUNT_DAY_MASK, +	.rtc_count_month_mask       = DA9063_COUNT_MONTH_MASK, +	.rtc_count_year_mask        = DA9063_COUNT_YEAR_MASK, +	/* ALARM CONFIG */ +	.rtc_data_start             = RTC_SEC, +	.rtc_alarm_len              = RTC_DATA_LEN, +}; + +static const struct da9063_compatible_rtc_regmap da9062_aa_regs = { +	/* REGS */ +	.rtc_enable_reg             = DA9062AA_CONTROL_E, +	.rtc_alarm_secs_reg         = DA9062AA_ALARM_S, +	.rtc_alarm_year_reg         = DA9062AA_ALARM_Y, +	.rtc_count_secs_reg         = DA9062AA_COUNT_S, +	.rtc_count_year_reg         = DA9062AA_COUNT_Y, +	.rtc_event_reg              = DA9062AA_EVENT_A, +	/* MASKS */ +	.rtc_enable_mask            = DA9062AA_RTC_EN_MASK, +	.rtc_crystal_mask           = DA9062AA_CRYSTAL_MASK, +	.rtc_enable_32k_crystal_reg = DA9062AA_EN_32K, +	.rtc_event_alarm_mask       = DA9062AA_M_ALARM_MASK, +	.rtc_alarm_on_mask          = DA9062AA_ALARM_ON_MASK, +	.rtc_alarm_status_mask      = (0x02 << 6), +	.rtc_tick_on_mask           = DA9062AA_TICK_ON_MASK, +	.rtc_ready_to_read_mask     = DA9062AA_RTC_READ_MASK, +	.rtc_count_sec_mask         = DA9062AA_COUNT_SEC_MASK, +	.rtc_count_min_mask         = DA9062AA_COUNT_MIN_MASK, +	.rtc_count_hour_mask        = DA9062AA_COUNT_HOUR_MASK, +	.rtc_count_day_mask         = DA9062AA_COUNT_DAY_MASK, +	.rtc_count_month_mask       = DA9062AA_COUNT_MONTH_MASK, +	.rtc_count_year_mask        = DA9062AA_COUNT_YEAR_MASK, +	/* ALARM CONFIG */ +	.rtc_data_start             = RTC_SEC, +	.rtc_alarm_len              = RTC_DATA_LEN, +}; + +static const struct of_device_id da9063_compatible_reg_id_table[] = { +	{ .compatible = "dlg,da9063-rtc", .data = &da9063_bb_regs }, +	{ .compatible = "dlg,da9062-rtc", .data = &da9062_aa_regs }, +	{ },  }; +MODULE_DEVICE_TABLE(of, da9063_compatible_reg_id_table); -static void da9063_data_to_tm(u8 *data, struct rtc_time *tm) +static void da9063_data_to_tm(u8 *data, struct rtc_time *tm, +			      struct da9063_compatible_rtc *rtc)  { -	tm->tm_sec  = data[RTC_SEC]  & DA9063_COUNT_SEC_MASK; -	tm->tm_min  = data[RTC_MIN]  & DA9063_COUNT_MIN_MASK; -	tm->tm_hour = data[RTC_HOUR] & DA9063_COUNT_HOUR_MASK; -	tm->tm_mday = data[RTC_DAY]  & DA9063_COUNT_DAY_MASK; +	const struct da9063_compatible_rtc_regmap *config = rtc->config; + +	tm->tm_sec  = data[RTC_SEC]  & config->rtc_count_sec_mask; +	tm->tm_min  = data[RTC_MIN]  & config->rtc_count_min_mask; +	tm->tm_hour = data[RTC_HOUR] & config->rtc_count_hour_mask; +	tm->tm_mday = data[RTC_DAY]  & config->rtc_count_day_mask;  	tm->tm_mon  = MONTHS_FROM_DA9063(data[RTC_MONTH] & -					 DA9063_COUNT_MONTH_MASK); +					 config->rtc_count_month_mask);  	tm->tm_year = YEARS_FROM_DA9063(data[RTC_YEAR] & -					DA9063_COUNT_YEAR_MASK); +					config->rtc_count_year_mask);  } -static void da9063_tm_to_data(struct rtc_time *tm, u8 *data) +static void da9063_tm_to_data(struct rtc_time *tm, u8 *data, +			      struct da9063_compatible_rtc *rtc)  { -	data[RTC_SEC] &= ~DA9063_COUNT_SEC_MASK; -	data[RTC_SEC] |= tm->tm_sec & DA9063_COUNT_SEC_MASK; +	const struct da9063_compatible_rtc_regmap *config = rtc->config; + +	data[RTC_SEC] &= ~config->rtc_count_sec_mask; +	data[RTC_SEC] |= tm->tm_sec & config->rtc_count_sec_mask; -	data[RTC_MIN] &= ~DA9063_COUNT_MIN_MASK; -	data[RTC_MIN] |= tm->tm_min & DA9063_COUNT_MIN_MASK; +	data[RTC_MIN] &= ~config->rtc_count_min_mask; +	data[RTC_MIN] |= tm->tm_min & config->rtc_count_min_mask; -	data[RTC_HOUR] &= ~DA9063_COUNT_HOUR_MASK; -	data[RTC_HOUR] |= tm->tm_hour & DA9063_COUNT_HOUR_MASK; +	data[RTC_HOUR] &= ~config->rtc_count_hour_mask; +	data[RTC_HOUR] |= tm->tm_hour & config->rtc_count_hour_mask; -	data[RTC_DAY] &= ~DA9063_COUNT_DAY_MASK; -	data[RTC_DAY] |= tm->tm_mday & DA9063_COUNT_DAY_MASK; +	data[RTC_DAY] &= ~config->rtc_count_day_mask; +	data[RTC_DAY] |= tm->tm_mday & config->rtc_count_day_mask; -	data[RTC_MONTH] &= ~DA9063_COUNT_MONTH_MASK; +	data[RTC_MONTH] &= ~config->rtc_count_month_mask;  	data[RTC_MONTH] |= MONTHS_TO_DA9063(tm->tm_mon) & -				DA9063_COUNT_MONTH_MASK; +				config->rtc_count_month_mask; -	data[RTC_YEAR] &= ~DA9063_COUNT_YEAR_MASK; +	data[RTC_YEAR] &= ~config->rtc_count_year_mask;  	data[RTC_YEAR] |= YEARS_TO_DA9063(tm->tm_year) & -				DA9063_COUNT_YEAR_MASK; +				config->rtc_count_year_mask;  }  static int da9063_rtc_stop_alarm(struct device *dev)  { -	struct da9063_rtc *rtc = dev_get_drvdata(dev); +	struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); +	const struct da9063_compatible_rtc_regmap *config = rtc->config; -	return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, -				  DA9063_ALARM_ON, 0); +	return regmap_update_bits(rtc->regmap, +				  config->rtc_alarm_year_reg, +				  config->rtc_alarm_on_mask, +				  0);  }  static int da9063_rtc_start_alarm(struct device *dev)  { -	struct da9063_rtc *rtc = dev_get_drvdata(dev); +	struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); +	const struct da9063_compatible_rtc_regmap *config = rtc->config; -	return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, -				  DA9063_ALARM_ON, DA9063_ALARM_ON); +	return regmap_update_bits(rtc->regmap, +				  config->rtc_alarm_year_reg, +				  config->rtc_alarm_on_mask, +				  config->rtc_alarm_on_mask);  }  static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm)  { -	struct da9063_rtc *rtc = dev_get_drvdata(dev); +	struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); +	const struct da9063_compatible_rtc_regmap *config = rtc->config;  	unsigned long tm_secs;  	unsigned long al_secs;  	u8 data[RTC_DATA_LEN];  	int ret; -	ret = regmap_bulk_read(rtc->hw->regmap, DA9063_REG_COUNT_S, +	ret = regmap_bulk_read(rtc->regmap, +			       config->rtc_count_secs_reg,  			       data, RTC_DATA_LEN);  	if (ret < 0) {  		dev_err(dev, "Failed to read RTC time data: %d\n", ret);  		return ret;  	} -	if (!(data[RTC_SEC] & DA9063_RTC_READ)) { +	if (!(data[RTC_SEC] & config->rtc_ready_to_read_mask)) {  		dev_dbg(dev, "RTC not yet ready to be read by the host\n");  		return -EINVAL;  	} -	da9063_data_to_tm(data, tm); +	da9063_data_to_tm(data, tm, rtc);  	rtc_tm_to_time(tm, &tm_secs);  	rtc_tm_to_time(&rtc->alarm_time, &al_secs); @@ -137,12 +272,14 @@ static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm)  static int da9063_rtc_set_time(struct device *dev, struct rtc_time *tm)  { -	struct da9063_rtc *rtc = dev_get_drvdata(dev); +	struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); +	const struct da9063_compatible_rtc_regmap *config = rtc->config;  	u8 data[RTC_DATA_LEN];  	int ret; -	da9063_tm_to_data(tm, data); -	ret = regmap_bulk_write(rtc->hw->regmap, DA9063_REG_COUNT_S, +	da9063_tm_to_data(tm, data, rtc); +	ret = regmap_bulk_write(rtc->regmap, +				config->rtc_count_secs_reg,  				data, RTC_DATA_LEN);  	if (ret < 0)  		dev_err(dev, "Failed to set RTC time data: %d\n", ret); @@ -152,26 +289,31 @@ static int da9063_rtc_set_time(struct device *dev, struct rtc_time *tm)  static int da9063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)  { -	struct da9063_rtc *rtc = dev_get_drvdata(dev); +	struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); +	const struct da9063_compatible_rtc_regmap *config = rtc->config;  	u8 data[RTC_DATA_LEN];  	int ret;  	unsigned int val;  	data[RTC_SEC] = 0; -	ret = regmap_bulk_read(rtc->hw->regmap, rtc->alarm_start, -			       &data[rtc->data_start], rtc->alarm_len); +	ret = regmap_bulk_read(rtc->regmap, +			       config->rtc_alarm_secs_reg, +			       &data[config->rtc_data_start], +			       config->rtc_alarm_len);  	if (ret < 0)  		return ret; -	da9063_data_to_tm(data, &alrm->time); +	da9063_data_to_tm(data, &alrm->time, rtc); -	alrm->enabled = !!(data[RTC_YEAR] & DA9063_ALARM_ON); +	alrm->enabled = !!(data[RTC_YEAR] & config->rtc_alarm_on_mask); -	ret = regmap_read(rtc->hw->regmap, DA9063_REG_EVENT_A, &val); +	ret = regmap_read(rtc->regmap, +			  config->rtc_event_reg, +			  &val);  	if (ret < 0)  		return ret; -	if (val & (DA9063_E_ALARM)) +	if (val & config->rtc_event_alarm_mask)  		alrm->pending = 1;  	else  		alrm->pending = 0; @@ -181,11 +323,12 @@ static int da9063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)  static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)  { -	struct da9063_rtc *rtc = dev_get_drvdata(dev); +	struct da9063_compatible_rtc *rtc = dev_get_drvdata(dev); +	const struct da9063_compatible_rtc_regmap *config = rtc->config;  	u8 data[RTC_DATA_LEN];  	int ret; -	da9063_tm_to_data(&alrm->time, data); +	da9063_tm_to_data(&alrm->time, data, rtc);  	ret = da9063_rtc_stop_alarm(dev);  	if (ret < 0) { @@ -193,14 +336,16 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)  		return ret;  	} -	ret = regmap_bulk_write(rtc->hw->regmap, rtc->alarm_start, -			       &data[rtc->data_start], rtc->alarm_len); +	ret = regmap_bulk_write(rtc->regmap, +				config->rtc_alarm_secs_reg, +				&data[config->rtc_data_start], +				config->rtc_alarm_len);  	if (ret < 0) {  		dev_err(dev, "Failed to write alarm: %d\n", ret);  		return ret;  	} -	da9063_data_to_tm(data, &rtc->alarm_time); +	da9063_data_to_tm(data, &rtc->alarm_time, rtc);  	if (alrm->enabled) {  		ret = da9063_rtc_start_alarm(dev); @@ -213,7 +358,8 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)  	return ret;  } -static int da9063_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +static int da9063_rtc_alarm_irq_enable(struct device *dev, +				       unsigned int enabled)  {  	if (enabled)  		return da9063_rtc_start_alarm(dev); @@ -223,10 +369,13 @@ static int da9063_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)  static irqreturn_t da9063_alarm_event(int irq, void *data)  { -	struct da9063_rtc *rtc = data; +	struct da9063_compatible_rtc *rtc = data; +	const struct da9063_compatible_rtc_regmap *config = rtc->config; -	regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, -			   DA9063_ALARM_ON, 0); +	regmap_update_bits(rtc->regmap, +			   config->rtc_alarm_year_reg, +			   config->rtc_alarm_on_mask, +			   0);  	rtc->rtc_sync = true;  	rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); @@ -244,72 +393,92 @@ static const struct rtc_class_ops da9063_rtc_ops = {  static int da9063_rtc_probe(struct platform_device *pdev)  { -	struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); -	struct da9063_rtc *rtc; +	struct da9063_compatible_rtc *rtc; +	const struct da9063_compatible_rtc_regmap *config; +	const struct of_device_id *match;  	int irq_alarm;  	u8 data[RTC_DATA_LEN];  	int ret; -	ret = regmap_update_bits(da9063->regmap, DA9063_REG_CONTROL_E, -				 DA9063_RTC_EN, DA9063_RTC_EN); -	if (ret < 0) { -		dev_err(&pdev->dev, "Failed to enable RTC\n"); -		goto err; -	} +	if (!pdev->dev.of_node) +		return -ENXIO; -	ret = regmap_update_bits(da9063->regmap, DA9063_REG_EN_32K, -				 DA9063_CRYSTAL, DA9063_CRYSTAL); -	if (ret < 0) { -		dev_err(&pdev->dev, "Failed to run 32kHz oscillator\n"); -		goto err; -	} +	match = of_match_node(da9063_compatible_reg_id_table, +			      pdev->dev.of_node);  	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);  	if (!rtc)  		return -ENOMEM; -	if (da9063->variant_code == PMIC_DA9063_AD) { -		rtc->alarm_year = DA9063_AD_REG_ALARM_Y; -		rtc->alarm_start = DA9063_AD_REG_ALARM_MI; -		rtc->alarm_len = RTC_ALARM_DATA_LEN; -		rtc->data_start = RTC_MIN; -	} else { -		rtc->alarm_year = DA9063_BB_REG_ALARM_Y; -		rtc->alarm_start = DA9063_BB_REG_ALARM_S; -		rtc->alarm_len = RTC_DATA_LEN; -		rtc->data_start = RTC_SEC; +	rtc->config = match->data; +	if (of_device_is_compatible(pdev->dev.of_node, "dlg,da9063-rtc")) { +		struct da9063 *chip = dev_get_drvdata(pdev->dev.parent); + +		if (chip->variant_code == PMIC_DA9063_AD) +			rtc->config = &da9063_ad_regs;  	} -	ret = regmap_update_bits(da9063->regmap, rtc->alarm_start, -			DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM, -			0); +	rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL); +	if (!rtc->regmap) { +		dev_warn(&pdev->dev, "Parent regmap unavailable.\n"); +		return -ENXIO; +	} + +	config = rtc->config; +	ret = regmap_update_bits(rtc->regmap, +				 config->rtc_enable_reg, +				 config->rtc_enable_mask, +				 config->rtc_enable_mask); +	if (ret < 0) { +		dev_err(&pdev->dev, "Failed to enable RTC\n"); +		return ret; +	} + +	ret = regmap_update_bits(rtc->regmap, +				 config->rtc_enable_32k_crystal_reg, +				 config->rtc_crystal_mask, +				 config->rtc_crystal_mask); +	if (ret < 0) { +		dev_err(&pdev->dev, "Failed to run 32kHz oscillator\n"); +		return ret; +	} + +	ret = regmap_update_bits(rtc->regmap, +				 config->rtc_alarm_secs_reg, +				 config->rtc_alarm_status_mask, +				 0);  	if (ret < 0) {  		dev_err(&pdev->dev, "Failed to access RTC alarm register\n"); -		goto err; +		return ret;  	} -	ret = regmap_update_bits(da9063->regmap, rtc->alarm_start, +	ret = regmap_update_bits(rtc->regmap, +				 config->rtc_alarm_secs_reg,  				 DA9063_ALARM_STATUS_ALARM,  				 DA9063_ALARM_STATUS_ALARM);  	if (ret < 0) {  		dev_err(&pdev->dev, "Failed to access RTC alarm register\n"); -		goto err; +		return ret;  	} -	ret = regmap_update_bits(da9063->regmap, rtc->alarm_year, -				 DA9063_TICK_ON, 0); +	ret = regmap_update_bits(rtc->regmap, +				 config->rtc_alarm_year_reg, +				 config->rtc_tick_on_mask, +				 0);  	if (ret < 0) {  		dev_err(&pdev->dev, "Failed to disable TICKs\n"); -		goto err; +		return ret;  	}  	data[RTC_SEC] = 0; -	ret = regmap_bulk_read(da9063->regmap, rtc->alarm_start, -			       &data[rtc->data_start], rtc->alarm_len); +	ret = regmap_bulk_read(rtc->regmap, +			       config->rtc_alarm_secs_reg, +			       &data[config->rtc_data_start], +			       config->rtc_alarm_len);  	if (ret < 0) {  		dev_err(&pdev->dev, "Failed to read initial alarm data: %d\n",  			ret); -		goto err; +		return ret;  	}  	platform_set_drvdata(pdev, rtc); @@ -322,18 +491,16 @@ static int da9063_rtc_probe(struct platform_device *pdev)  	if (ret) {  		dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n",  			irq_alarm, ret); -		goto err; +		return ret;  	} -	rtc->hw = da9063;  	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC,  					   &da9063_rtc_ops, THIS_MODULE);  	if (IS_ERR(rtc->rtc_dev))  		return PTR_ERR(rtc->rtc_dev); -	da9063_data_to_tm(data, &rtc->alarm_time); +	da9063_data_to_tm(data, &rtc->alarm_time, rtc);  	rtc->rtc_sync = false; -err:  	return ret;  } @@ -341,6 +508,7 @@ static struct platform_driver da9063_rtc_driver = {  	.probe		= da9063_rtc_probe,  	.driver		= {  		.name	= DA9063_DRVNAME_RTC, +		.of_match_table = da9063_compatible_reg_id_table,  	},  }; diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 799c34bcb26f..a6d9434addf6 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -477,6 +477,7 @@ void rtc_dev_prepare(struct rtc_device *rtc)  	cdev_init(&rtc->char_dev, &rtc_dev_fops);  	rtc->char_dev.owner = rtc->owner; +	rtc->char_dev.kobj.parent = &rtc->dev.kobj;  }  void rtc_dev_add_device(struct rtc_device *rtc) diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 12b07158a366..baa5d047f9c8 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -538,15 +538,6 @@ ds1305_nvram_read(struct file *filp, struct kobject *kobj,  	spi = container_of(kobj, struct spi_device, dev.kobj); -	if (unlikely(off >= DS1305_NVRAM_LEN)) -		return 0; -	if (count >= DS1305_NVRAM_LEN) -		count = DS1305_NVRAM_LEN; -	if ((off + count) > DS1305_NVRAM_LEN) -		count = DS1305_NVRAM_LEN - off; -	if (unlikely(!count)) -		return count; -  	addr = DS1305_NVRAM + off;  	msg_init(&m, x, &addr, count, NULL, buf); @@ -569,15 +560,6 @@ ds1305_nvram_write(struct file *filp, struct kobject *kobj,  	spi = container_of(kobj, struct spi_device, dev.kobj); -	if (unlikely(off >= DS1305_NVRAM_LEN)) -		return -EFBIG; -	if (count >= DS1305_NVRAM_LEN) -		count = DS1305_NVRAM_LEN; -	if ((off + count) > DS1305_NVRAM_LEN) -		count = DS1305_NVRAM_LEN - off; -	if (unlikely(!count)) -		return count; -  	addr = (DS1305_WRITE | DS1305_NVRAM) + off;  	msg_init(&m, x, &addr, count, buf, NULL); diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 6e76de1856fc..a705e6490808 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -11,14 +11,17 @@   * published by the Free Software Foundation.   */ -#include <linux/module.h> +#include <linux/bcd.h> +#include <linux/i2c.h>  #include <linux/init.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/of_irq.h> +#include <linux/pm_wakeirq.h> +#include <linux/rtc/ds1307.h> +#include <linux/rtc.h>  #include <linux/slab.h> -#include <linux/i2c.h>  #include <linux/string.h> -#include <linux/rtc.h> -#include <linux/bcd.h> -#include <linux/rtc/ds1307.h>  /*   * We can't determine type by probing, but if we expect pre-Linux code @@ -114,7 +117,7 @@ struct ds1307 {  #define HAS_ALARM	1		/* bit 1 == irq claimed */  	struct i2c_client	*client;  	struct rtc_device	*rtc; -	struct work_struct	work; +	int			wakeirq;  	s32 (*read_block_data)(const struct i2c_client *client, u8 command,  			       u8 length, u8 *values);  	s32 (*write_block_data)(const struct i2c_client *client, u8 command, @@ -311,27 +314,17 @@ static s32 ds1307_native_smbus_read_block_data(const struct i2c_client *client,  /*----------------------------------------------------------------------*/  /* - * The IRQ logic includes a "real" handler running in IRQ context just - * long enough to schedule this workqueue entry.   We need a task context - * to talk to the RTC, since I2C I/O calls require that; and disable the - * IRQ until we clear its status on the chip, so that this handler can - * work with any type of triggering (not just falling edge). - *   * The ds1337 and ds1339 both have two alarms, but we only use the first   * one (with a "seconds" field).  For ds1337 we expect nINTA is our alarm   * signal; ds1339 chips have only one alarm signal.   */ -static void ds1307_work(struct work_struct *work) +static irqreturn_t ds1307_irq(int irq, void *dev_id)  { -	struct ds1307		*ds1307; -	struct i2c_client	*client; -	struct mutex		*lock; +	struct i2c_client	*client = dev_id; +	struct ds1307		*ds1307 = i2c_get_clientdata(client); +	struct mutex		*lock = &ds1307->rtc->ops_lock;  	int			stat, control; -	ds1307 = container_of(work, struct ds1307, work); -	client = ds1307->client; -	lock = &ds1307->rtc->ops_lock; -  	mutex_lock(lock);  	stat = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);  	if (stat < 0) @@ -352,18 +345,8 @@ static void ds1307_work(struct work_struct *work)  	}  out: -	if (test_bit(HAS_ALARM, &ds1307->flags)) -		enable_irq(client->irq);  	mutex_unlock(lock); -} -static irqreturn_t ds1307_irq(int irq, void *dev_id) -{ -	struct i2c_client	*client = dev_id; -	struct ds1307		*ds1307 = i2c_get_clientdata(client); - -	disable_irq_nosync(irq); -	schedule_work(&ds1307->work);  	return IRQ_HANDLED;  } @@ -634,13 +617,14 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {  					 MCP794XX_BIT_ALMX_C1 | \  					 MCP794XX_BIT_ALMX_C2) -static void mcp794xx_work(struct work_struct *work) +static irqreturn_t mcp794xx_irq(int irq, void *dev_id)  { -	struct ds1307 *ds1307 = container_of(work, struct ds1307, work); -	struct i2c_client *client = ds1307->client; +	struct i2c_client       *client = dev_id; +	struct ds1307           *ds1307 = i2c_get_clientdata(client); +	struct mutex            *lock = &ds1307->rtc->ops_lock;  	int reg, ret; -	mutex_lock(&ds1307->rtc->ops_lock); +	mutex_lock(lock);  	/* Check and clear alarm 0 interrupt flag. */  	reg = i2c_smbus_read_byte_data(client, MCP794XX_REG_ALARM0_CTRL); @@ -665,9 +649,9 @@ static void mcp794xx_work(struct work_struct *work)  	rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF);  out: -	if (test_bit(HAS_ALARM, &ds1307->flags)) -		enable_irq(client->irq); -	mutex_unlock(&ds1307->rtc->ops_lock); +	mutex_unlock(lock); + +	return IRQ_HANDLED;  }  static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t) @@ -798,13 +782,6 @@ ds1307_nvram_read(struct file *filp, struct kobject *kobj,  	client = kobj_to_i2c_client(kobj);  	ds1307 = i2c_get_clientdata(client); -	if (unlikely(off >= ds1307->nvram->size)) -		return 0; -	if ((off + count) > ds1307->nvram->size) -		count = ds1307->nvram->size - off; -	if (unlikely(!count)) -		return count; -  	result = ds1307->read_block_data(client, ds1307->nvram_offset + off,  								count, buf);  	if (result < 0) @@ -824,13 +801,6 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj,  	client = kobj_to_i2c_client(kobj);  	ds1307 = i2c_get_clientdata(client); -	if (unlikely(off >= ds1307->nvram->size)) -		return -EFBIG; -	if ((off + count) > ds1307->nvram->size) -		count = ds1307->nvram->size - off; -	if (unlikely(!count)) -		return count; -  	result = ds1307->write_block_data(client, ds1307->nvram_offset + off,  								count, buf);  	if (result < 0) { @@ -896,6 +866,8 @@ static int ds1307_probe(struct i2c_client *client,  	bool			want_irq = false;  	unsigned char		*buf;  	struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); +	irq_handler_t	irq_handler = ds1307_irq; +  	static const int	bbsqi_bitpos[] = {  		[ds_1337] = 0,  		[ds_1339] = DS1339_BIT_BBSQI, @@ -962,8 +934,6 @@ static int ds1307_probe(struct i2c_client *client,  		 * running on Vbackup (BBSQI/BBSQW)  		 */  		if (ds1307->client->irq > 0 && chip->alarm) { -			INIT_WORK(&ds1307->work, ds1307_work); -  			ds1307->regs[0] |= DS1337_BIT_INTCN  					| bbsqi_bitpos[ds1307->type];  			ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); @@ -1053,7 +1023,7 @@ static int ds1307_probe(struct i2c_client *client,  	case mcp794xx:  		rtc_ops = &mcp794xx_rtc_ops;  		if (ds1307->client->irq > 0 && chip->alarm) { -			INIT_WORK(&ds1307->work, mcp794xx_work); +			irq_handler = mcp794xx_irq;  			want_irq = true;  		}  		break; @@ -1176,18 +1146,43 @@ read_rtc:  	}  	if (want_irq) { -		err = request_irq(client->irq, ds1307_irq, IRQF_SHARED, -			  ds1307->rtc->name, client); +		struct device_node *node = client->dev.of_node; + +		err = devm_request_threaded_irq(&client->dev, +						client->irq, NULL, irq_handler, +						IRQF_SHARED | IRQF_ONESHOT, +						ds1307->rtc->name, client);  		if (err) {  			client->irq = 0;  			dev_err(&client->dev, "unable to request IRQ!\n"); -		} else { +			goto no_irq; +		} + +		set_bit(HAS_ALARM, &ds1307->flags); +		dev_dbg(&client->dev, "got IRQ %d\n", client->irq); + +		/* Currently supported by OF code only! */ +		if (!node) +			goto no_irq; + +		err = of_irq_get(node, 1); +		if (err <= 0) { +			if (err == -EPROBE_DEFER) +				goto exit; +			goto no_irq; +		} +		ds1307->wakeirq = err; -			set_bit(HAS_ALARM, &ds1307->flags); -			dev_dbg(&client->dev, "got IRQ %d\n", client->irq); +		err = dev_pm_set_dedicated_wake_irq(&client->dev, +						    ds1307->wakeirq); +		if (err) { +			dev_err(&client->dev, "unable to setup wakeIRQ %d!\n", +				err); +			goto exit;  		}  	} +no_irq:  	if (chip->nvram_size) {  		ds1307->nvram = devm_kzalloc(&client->dev, @@ -1231,10 +1226,8 @@ static int ds1307_remove(struct i2c_client *client)  {  	struct ds1307 *ds1307 = i2c_get_clientdata(client); -	if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) { -		free_irq(client->irq, client); -		cancel_work_sync(&ds1307->work); -	} +	if (ds1307->wakeirq) +		dev_pm_clear_wake_irq(&client->dev);  	if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))  		sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram); @@ -1245,7 +1238,6 @@ static int ds1307_remove(struct i2c_client *client)  static struct i2c_driver ds1307_driver = {  	.driver = {  		.name	= "rtc-ds1307", -		.owner	= THIS_MODULE,  	},  	.probe		= ds1307_probe,  	.remove		= ds1307_remove, diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index ae9f997223b1..79a06dd3c185 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c @@ -162,12 +162,6 @@ static ssize_t ds1343_nvram_write(struct file *filp, struct kobject *kobj,  	struct device *dev = kobj_to_dev(kobj);  	struct ds1343_priv *priv = dev_get_drvdata(dev); -	if (unlikely(!count)) -		return count; - -	if ((count + off) > DS1343_NVRAM_LEN) -		count = DS1343_NVRAM_LEN - off; -  	address = DS1343_NVRAM + off;  	ret = regmap_bulk_write(priv->map, address, buf, count); @@ -187,12 +181,6 @@ static ssize_t ds1343_nvram_read(struct file *filp, struct kobject *kobj,  	struct device *dev = kobj_to_dev(kobj);  	struct ds1343_priv *priv = dev_get_drvdata(dev); -	if (unlikely(!count)) -		return count; - -	if ((count + off) > DS1343_NVRAM_LEN) -		count = DS1343_NVRAM_LEN - off; -  	address = DS1343_NVRAM + off;  	ret = regmap_bulk_read(priv->map, address, buf, count); diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 167783fa7ac1..3b3049c8c9e0 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -664,11 +664,8 @@ static int ds1374_remove(struct i2c_client *client)  {  	struct ds1374 *ds1374 = i2c_get_clientdata(client);  #ifdef CONFIG_RTC_DRV_DS1374_WDT -	int res; - -	res = misc_deregister(&ds1374_miscdev); -	if (!res) -		ds1374_miscdev.parent = NULL; +	misc_deregister(&ds1374_miscdev); +	ds1374_miscdev.parent = NULL;  	unregister_reboot_notifier(&ds1374_wdt_notifier);  #endif @@ -689,7 +686,7 @@ static int ds1374_suspend(struct device *dev)  {  	struct i2c_client *client = to_i2c_client(dev); -	if (client->irq >= 0 && device_may_wakeup(&client->dev)) +	if (client->irq > 0 && device_may_wakeup(&client->dev))  		enable_irq_wake(client->irq);  	return 0;  } @@ -698,7 +695,7 @@ static int ds1374_resume(struct device *dev)  {  	struct i2c_client *client = to_i2c_client(dev); -	if (client->irq >= 0 && device_may_wakeup(&client->dev)) +	if (client->irq > 0 && device_may_wakeup(&client->dev))  		disable_irq_wake(client->irq);  	return 0;  } @@ -709,7 +706,6 @@ static SIMPLE_DEV_PM_OPS(ds1374_pm, ds1374_suspend, ds1374_resume);  static struct i2c_driver ds1374_driver = {  	.driver = {  		.name = "rtc-ds1374", -		.owner = THIS_MODULE,  		.pm = &ds1374_pm,  	},  	.probe = ds1374_probe, diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 7415c2b4d6e8..da3d04ce83bd 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -64,7 +64,7 @@ enum ds1511reg {  #define DS1511_KIE	0x04  #define DS1511_WDE	0x02  #define DS1511_WDS	0x01 -#define DS1511_RAM_MAX	0xff +#define DS1511_RAM_MAX	0x100  #define RTC_CMD		DS1511_CONTROL_B  #define RTC_CMD1	DS1511_CONTROL_A @@ -159,7 +159,7 @@ ds1511_wdog_set(unsigned long deciseconds)  	/*  	 * set wdog enable and wdog 'steering' bit to issue a reset  	 */ -	rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD); +	rtc_write(rtc_read(RTC_CMD) | DS1511_WDE | DS1511_WDS, RTC_CMD);  }  void @@ -407,26 +407,10 @@ ds1511_nvram_read(struct file *filp, struct kobject *kobj,  {  	ssize_t count; -	/* -	 * if count is more than one, turn on "burst" mode -	 * turn it off when you're done -	 */ -	if (size > 1) -		rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); - -	if (pos > DS1511_RAM_MAX) -		pos = DS1511_RAM_MAX; - -	if (size + pos > DS1511_RAM_MAX + 1) -		size = DS1511_RAM_MAX - pos + 1; -  	rtc_write(pos, DS1511_RAMADDR_LSB); -	for (count = 0; size > 0; count++, size--) +	for (count = 0; count < size; count++)  		*buf++ = rtc_read(DS1511_RAMDATA); -	if (count > 1) -		rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); -  	return count;  } @@ -437,26 +421,10 @@ ds1511_nvram_write(struct file *filp, struct kobject *kobj,  {  	ssize_t count; -	/* -	 * if count is more than one, turn on "burst" mode -	 * turn it off when you're done -	 */ -	if (size > 1) -		rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); - -	if (pos > DS1511_RAM_MAX) -		pos = DS1511_RAM_MAX; - -	if (size + pos > DS1511_RAM_MAX + 1) -		size = DS1511_RAM_MAX - pos + 1; -  	rtc_write(pos, DS1511_RAMADDR_LSB); -	for (count = 0; size > 0; count++, size--) +	for (count = 0; count < size; count++)  		rtc_write(*buf++, DS1511_RAMDATA); -	if (count > 1) -		rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); -  	return count;  } @@ -490,7 +458,7 @@ static int ds1511_rtc_probe(struct platform_device *pdev)  	/*  	 * turn on the clock and the crystal, etc.  	 */ -	rtc_write(0, RTC_CMD); +	rtc_write(DS1511_BME, RTC_CMD);  	rtc_write(0, RTC_CMD1);  	/*  	 * clear the wdog counter diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index a24e091bcb41..38422ab4ec5a 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -245,7 +245,7 @@ static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj,  	void __iomem *ioaddr = pdata->ioaddr;  	ssize_t count; -	for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) +	for (count = 0; count < size; count++)  		*buf++ = readb(ioaddr + pos++);  	return count;  } @@ -260,7 +260,7 @@ static ssize_t ds1553_nvram_write(struct file *filp, struct kobject *kobj,  	void __iomem *ioaddr = pdata->ioaddr;  	ssize_t count; -	for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) +	for (count = 0; count < size; count++)  		writeb(*buf++, ioaddr + pos++);  	return count;  } diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 818a3635a8c8..05a51ef52703 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -2145,27 +2145,7 @@ static struct platform_driver ds1685_rtc_driver = {  	.probe		= ds1685_rtc_probe,  	.remove		= ds1685_rtc_remove,  }; - -/** - * ds1685_rtc_init - rtc module init. - */ -static int __init -ds1685_rtc_init(void) -{ -	return platform_driver_register(&ds1685_rtc_driver); -} - -/** - * ds1685_rtc_exit - rtc module exit. - */ -static void __exit -ds1685_rtc_exit(void) -{ -	platform_driver_unregister(&ds1685_rtc_driver); -} - -module_init(ds1685_rtc_init); -module_exit(ds1685_rtc_exit); +module_platform_driver(ds1685_rtc_driver);  /* ----------------------------------------------------------------------- */ diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 0f8d8ace1515..c5168b3bcf1a 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -134,7 +134,7 @@ static ssize_t ds1742_nvram_read(struct file *filp, struct kobject *kobj,  	void __iomem *ioaddr = pdata->ioaddr_nvram;  	ssize_t count; -	for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--) +	for (count = 0; count < size; count++)  		*buf++ = readb(ioaddr + pos++);  	return count;  } @@ -149,7 +149,7 @@ static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj,  	void __iomem *ioaddr = pdata->ioaddr_nvram;  	ssize_t count; -	for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--) +	for (count = 0; count < size; count++)  		writeb(*buf++, ioaddr + pos++);  	return count;  } diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 7e48e532214f..4e99ace66f74 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -443,7 +443,7 @@ static int ds3232_remove(struct i2c_client *client)  {  	struct ds3232 *ds3232 = i2c_get_clientdata(client); -	if (client->irq >= 0) { +	if (client->irq > 0) {  		mutex_lock(&ds3232->mutex);  		ds3232->exiting = 1;  		mutex_unlock(&ds3232->mutex); @@ -463,7 +463,10 @@ static int ds3232_suspend(struct device *dev)  	if (device_can_wakeup(dev)) {  		ds3232->suspended = true; -		irq_set_irq_wake(client->irq, 1); +		if (irq_set_irq_wake(client->irq, 1)) { +			dev_warn_once(dev, "Cannot set wakeup source\n"); +			ds3232->suspended = false; +		}  	}  	return 0; @@ -500,7 +503,6 @@ MODULE_DEVICE_TABLE(i2c, ds3232_id);  static struct i2c_driver ds3232_driver = {  	.driver = {  		.name = "rtc-ds3232", -		.owner = THIS_MODULE,  		.pm	= &ds3232_pm_ops,  	},  	.probe = ds3232_probe, diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index 83c3b3029fa7..576eadbba296 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -523,7 +523,6 @@ exit_free:  static struct i2c_driver fm3130_driver = {  	.driver = {  		.name	= "rtc-fm3130", -		.owner	= THIS_MODULE,  	},  	.probe		= fm3130_probe,  	.id_table	= fm3130_id, diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c index 35f4486738fc..e84184647d15 100644 --- a/drivers/rtc/rtc-gemini.c +++ b/drivers/rtc/rtc-gemini.c @@ -148,10 +148,7 @@ static int gemini_rtc_probe(struct platform_device *pdev)  	rtc->rtc_dev = rtc_device_register(pdev->name, dev,  					   &gemini_rtc_ops, THIS_MODULE); -	if (likely(IS_ERR(rtc->rtc_dev))) -		return PTR_ERR(rtc->rtc_dev); - -	return 0; +	return PTR_ERR_OR_ZERO(rtc->rtc_dev);  }  static int gemini_rtc_remove(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index e9da7959d3fe..097325d96db5 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -599,7 +599,6 @@ MODULE_DEVICE_TABLE(of, hym8563_dt_idtable);  static struct i2c_driver hym8563_driver = {  	.driver		= {  		.name	= "rtc-hym8563", -		.owner	= THIS_MODULE,  		.pm	= &hym8563_pm_ops,  		.of_match_table	= hym8563_dt_idtable,  	}, diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index f9b082784b90..839d1fd63cd7 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -151,12 +151,7 @@ static int isl12022_get_datetime(struct i2c_client *client, struct rtc_time *tm)  		tm->tm_sec, tm->tm_min, tm->tm_hour,  		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); -	/* The clock can give out invalid datetime, but we cannot return -	 * -EINVAL otherwise hwclock will refuse to set the time on bootup. */ -	if (rtc_valid_tm(tm) < 0) -		dev_err(&client->dev, "retrieved date and time is invalid.\n"); - -	return 0; +	return rtc_valid_tm(tm);  }  static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm) @@ -279,6 +274,7 @@ static const struct of_device_id isl12022_dt_match[] = {  	{ .compatible = "isil,isl12022" },  	{ },  }; +MODULE_DEVICE_TABLE(of, isl12022_dt_match);  #endif  static const struct i2c_device_id isl12022_id[] = { diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c index da818d3337ce..a0462e5430c7 100644 --- a/drivers/rtc/rtc-isl12057.c +++ b/drivers/rtc/rtc-isl12057.c @@ -648,6 +648,7 @@ static const struct of_device_id isl12057_dt_match[] = {  	{ .compatible = "isil,isl12057" },  	{ },  }; +MODULE_DEVICE_TABLE(of, isl12057_dt_match);  #endif  static const struct i2c_device_id isl12057_id[] = { @@ -659,7 +660,6 @@ MODULE_DEVICE_TABLE(i2c, isl12057_id);  static struct i2c_driver isl12057_driver = {  	.driver = {  		.name = DRV_NAME, -		.owner = THIS_MODULE,  		.pm = &isl12057_rtc_pm_ops,  		.of_match_table = of_match_ptr(isl12057_dt_match),  	}, diff --git a/drivers/rtc/rtc-lpc24xx.c b/drivers/rtc/rtc-lpc24xx.c new file mode 100644 index 000000000000..59d99596fdeb --- /dev/null +++ b/drivers/rtc/rtc-lpc24xx.c @@ -0,0 +1,310 @@ +/* + * RTC driver for NXP LPC178x/18xx/43xx Real-Time Clock (RTC) + * + * Copyright (C) 2011 NXP Semiconductors + * Copyright (C) 2015 Joachim Eastwood <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> + +/* LPC24xx RTC register offsets and bits */ +#define LPC24XX_ILR		0x00 +#define  LPC24XX_RTCCIF		BIT(0) +#define  LPC24XX_RTCALF		BIT(1) +#define LPC24XX_CTC		0x04 +#define LPC24XX_CCR		0x08 +#define  LPC24XX_CLKEN		BIT(0) +#define  LPC178X_CCALEN		BIT(4) +#define LPC24XX_CIIR		0x0c +#define LPC24XX_AMR		0x10 +#define  LPC24XX_ALARM_DISABLE	0xff +#define LPC24XX_CTIME0		0x14 +#define LPC24XX_CTIME1		0x18 +#define LPC24XX_CTIME2		0x1c +#define LPC24XX_SEC		0x20 +#define LPC24XX_MIN		0x24 +#define LPC24XX_HOUR		0x28 +#define LPC24XX_DOM		0x2c +#define LPC24XX_DOW		0x30 +#define LPC24XX_DOY		0x34 +#define LPC24XX_MONTH		0x38 +#define LPC24XX_YEAR		0x3c +#define LPC24XX_ALSEC		0x60 +#define LPC24XX_ALMIN		0x64 +#define LPC24XX_ALHOUR		0x68 +#define LPC24XX_ALDOM		0x6c +#define LPC24XX_ALDOW		0x70 +#define LPC24XX_ALDOY		0x74 +#define LPC24XX_ALMON		0x78 +#define LPC24XX_ALYEAR		0x7c + +/* Macros to read fields in consolidated time (CT) registers */ +#define CT0_SECS(x)		(((x) >> 0)  & 0x3f) +#define CT0_MINS(x)		(((x) >> 8)  & 0x3f) +#define CT0_HOURS(x)		(((x) >> 16) & 0x1f) +#define CT0_DOW(x)		(((x) >> 24) & 0x07) +#define CT1_DOM(x)		(((x) >> 0)  & 0x1f) +#define CT1_MONTH(x)		(((x) >> 8)  & 0x0f) +#define CT1_YEAR(x)		(((x) >> 16) & 0xfff) +#define CT2_DOY(x)		(((x) >> 0)  & 0xfff) + +#define rtc_readl(dev, reg)		readl((dev)->rtc_base + (reg)) +#define rtc_writel(dev, reg, val)	writel((val), (dev)->rtc_base + (reg)) + +struct lpc24xx_rtc { +	void __iomem *rtc_base; +	struct rtc_device *rtc; +	struct clk *clk_rtc; +	struct clk *clk_reg; +}; + +static int lpc24xx_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ +	struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); + +	/* Disable RTC during update */ +	rtc_writel(rtc, LPC24XX_CCR, LPC178X_CCALEN); + +	rtc_writel(rtc, LPC24XX_SEC,	tm->tm_sec); +	rtc_writel(rtc, LPC24XX_MIN,	tm->tm_min); +	rtc_writel(rtc, LPC24XX_HOUR,	tm->tm_hour); +	rtc_writel(rtc, LPC24XX_DOW,	tm->tm_wday); +	rtc_writel(rtc, LPC24XX_DOM,	tm->tm_mday); +	rtc_writel(rtc, LPC24XX_DOY,	tm->tm_yday); +	rtc_writel(rtc, LPC24XX_MONTH,	tm->tm_mon); +	rtc_writel(rtc, LPC24XX_YEAR,	tm->tm_year); + +	rtc_writel(rtc, LPC24XX_CCR, LPC24XX_CLKEN | LPC178X_CCALEN); + +	return 0; +} + +static int lpc24xx_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ +	struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); +	u32 ct0, ct1, ct2; + +	ct0 = rtc_readl(rtc, LPC24XX_CTIME0); +	ct1 = rtc_readl(rtc, LPC24XX_CTIME1); +	ct2 = rtc_readl(rtc, LPC24XX_CTIME2); + +	tm->tm_sec  = CT0_SECS(ct0); +	tm->tm_min  = CT0_MINS(ct0); +	tm->tm_hour = CT0_HOURS(ct0); +	tm->tm_wday = CT0_DOW(ct0); +	tm->tm_mon  = CT1_MONTH(ct1); +	tm->tm_mday = CT1_DOM(ct1); +	tm->tm_year = CT1_YEAR(ct1); +	tm->tm_yday = CT2_DOY(ct2); + +	return rtc_valid_tm(tm); +} + +static int lpc24xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) +{ +	struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); +	struct rtc_time *tm = &wkalrm->time; + +	tm->tm_sec  = rtc_readl(rtc, LPC24XX_ALSEC); +	tm->tm_min  = rtc_readl(rtc, LPC24XX_ALMIN); +	tm->tm_hour = rtc_readl(rtc, LPC24XX_ALHOUR); +	tm->tm_mday = rtc_readl(rtc, LPC24XX_ALDOM); +	tm->tm_wday = rtc_readl(rtc, LPC24XX_ALDOW); +	tm->tm_yday = rtc_readl(rtc, LPC24XX_ALDOY); +	tm->tm_mon  = rtc_readl(rtc, LPC24XX_ALMON); +	tm->tm_year = rtc_readl(rtc, LPC24XX_ALYEAR); + +	wkalrm->enabled = rtc_readl(rtc, LPC24XX_AMR) == 0; +	wkalrm->pending = !!(rtc_readl(rtc, LPC24XX_ILR) & LPC24XX_RTCCIF); + +	return rtc_valid_tm(&wkalrm->time); +} + +static int lpc24xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) +{ +	struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); +	struct rtc_time *tm = &wkalrm->time; + +	/* Disable alarm irq during update */ +	rtc_writel(rtc, LPC24XX_AMR, LPC24XX_ALARM_DISABLE); + +	rtc_writel(rtc, LPC24XX_ALSEC,  tm->tm_sec); +	rtc_writel(rtc, LPC24XX_ALMIN,  tm->tm_min); +	rtc_writel(rtc, LPC24XX_ALHOUR, tm->tm_hour); +	rtc_writel(rtc, LPC24XX_ALDOM,  tm->tm_mday); +	rtc_writel(rtc, LPC24XX_ALDOW,  tm->tm_wday); +	rtc_writel(rtc, LPC24XX_ALDOY,  tm->tm_yday); +	rtc_writel(rtc, LPC24XX_ALMON,  tm->tm_mon); +	rtc_writel(rtc, LPC24XX_ALYEAR, tm->tm_year); + +	if (wkalrm->enabled) +		rtc_writel(rtc, LPC24XX_AMR, 0); + +	return 0; +} + +static int lpc24xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) +{ +	struct lpc24xx_rtc *rtc = dev_get_drvdata(dev); + +	if (enable) +		rtc_writel(rtc, LPC24XX_AMR, 0); +	else +		rtc_writel(rtc, LPC24XX_AMR, LPC24XX_ALARM_DISABLE); + +	return 0; +} + +static irqreturn_t lpc24xx_rtc_interrupt(int irq, void *data) +{ +	unsigned long events = RTC_IRQF; +	struct lpc24xx_rtc *rtc = data; +	u32 rtc_iir; + +	/* Check interrupt cause */ +	rtc_iir = rtc_readl(rtc, LPC24XX_ILR); +	if (rtc_iir & LPC24XX_RTCALF) { +		events |= RTC_AF; +		rtc_writel(rtc, LPC24XX_AMR, LPC24XX_ALARM_DISABLE); +	} + +	/* Clear interrupt status and report event */ +	rtc_writel(rtc, LPC24XX_ILR, rtc_iir); +	rtc_update_irq(rtc->rtc, 1, events); + +	return IRQ_HANDLED; +} + +static const struct rtc_class_ops lpc24xx_rtc_ops = { +	.read_time		= lpc24xx_rtc_read_time, +	.set_time		= lpc24xx_rtc_set_time, +	.read_alarm		= lpc24xx_rtc_read_alarm, +	.set_alarm		= lpc24xx_rtc_set_alarm, +	.alarm_irq_enable	= lpc24xx_rtc_alarm_irq_enable, +}; + +static int lpc24xx_rtc_probe(struct platform_device *pdev) +{ +	struct lpc24xx_rtc *rtc; +	struct resource *res; +	int irq, ret; + +	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); +	if (!rtc) +		return -ENOMEM; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	rtc->rtc_base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(rtc->rtc_base)) +		return PTR_ERR(rtc->rtc_base); + +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_warn(&pdev->dev, "can't get interrupt resource\n"); +		return irq; +	} + +	rtc->clk_rtc = devm_clk_get(&pdev->dev, "rtc"); +	if (IS_ERR(rtc->clk_rtc)) { +		dev_err(&pdev->dev, "error getting rtc clock\n"); +		return PTR_ERR(rtc->clk_rtc); +	} + +	rtc->clk_reg = devm_clk_get(&pdev->dev, "reg"); +	if (IS_ERR(rtc->clk_reg)) { +		dev_err(&pdev->dev, "error getting reg clock\n"); +		return PTR_ERR(rtc->clk_reg); +	} + +	ret = clk_prepare_enable(rtc->clk_rtc); +	if (ret) { +		dev_err(&pdev->dev, "unable to enable rtc clock\n"); +		return ret; +	} + +	ret = clk_prepare_enable(rtc->clk_reg); +	if (ret) { +		dev_err(&pdev->dev, "unable to enable reg clock\n"); +		goto disable_rtc_clk; +	} + +	platform_set_drvdata(pdev, rtc); + +	/* Clear any pending interrupts */ +	rtc_writel(rtc, LPC24XX_ILR, LPC24XX_RTCCIF | LPC24XX_RTCALF); + +	/* Enable RTC count */ +	rtc_writel(rtc, LPC24XX_CCR, LPC24XX_CLKEN | LPC178X_CCALEN); + +	ret = devm_request_irq(&pdev->dev, irq, lpc24xx_rtc_interrupt, 0, +			       pdev->name, rtc); +	if (ret < 0) { +		dev_warn(&pdev->dev, "can't request interrupt\n"); +		goto disable_clks; +	} + +	rtc->rtc = devm_rtc_device_register(&pdev->dev, "lpc24xx-rtc", +					    &lpc24xx_rtc_ops, THIS_MODULE); +	if (IS_ERR(rtc->rtc)) { +		dev_err(&pdev->dev, "can't register rtc device\n"); +		ret = PTR_ERR(rtc->rtc); +		goto disable_clks; +	} + +	return 0; + +disable_clks: +	clk_disable_unprepare(rtc->clk_reg); +disable_rtc_clk: +	clk_disable_unprepare(rtc->clk_rtc); +	return ret; +} + +static int lpc24xx_rtc_remove(struct platform_device *pdev) +{ +	struct lpc24xx_rtc *rtc = platform_get_drvdata(pdev); + +	/* Ensure all interrupt sources are masked */ +	rtc_writel(rtc, LPC24XX_AMR, LPC24XX_ALARM_DISABLE); +	rtc_writel(rtc, LPC24XX_CIIR, 0); + +	rtc_writel(rtc, LPC24XX_CCR, LPC178X_CCALEN); + +	clk_disable_unprepare(rtc->clk_rtc); +	clk_disable_unprepare(rtc->clk_reg); + +	return 0; +} + +static const struct of_device_id lpc24xx_rtc_match[] = { +	{ .compatible = "nxp,lpc1788-rtc" }, +	{ } +}; +MODULE_DEVICE_TABLE(of, lpc24xx_rtc_match); + +static struct platform_driver lpc24xx_rtc_driver = { +	.probe	= lpc24xx_rtc_probe, +	.remove	= lpc24xx_rtc_remove, +	.driver	= { +		.name = "lpc24xx-rtc", +		.of_match_table	= lpc24xx_rtc_match, +	}, +}; +module_platform_driver(lpc24xx_rtc_driver); + +MODULE_AUTHOR("Kevin Wells <[email protected]>"); +MODULE_DESCRIPTION("RTC driver for the LPC178x/18xx/408x/43xx SoCs"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 90abb5bd589c..d99a705bec07 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -345,11 +345,12 @@ static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj,  	ssize_t cnt = 0;  	unsigned long flags; -	for (; size > 0 && pos < pdata->offset; cnt++, size--) { -		spin_lock_irqsave(&m48t59->lock, flags); +	spin_lock_irqsave(&m48t59->lock, flags); + +	for (; cnt < size; cnt++)  		*buf++ = M48T59_READ(cnt); -		spin_unlock_irqrestore(&m48t59->lock, flags); -	} + +	spin_unlock_irqrestore(&m48t59->lock, flags);  	return cnt;  } @@ -365,11 +366,12 @@ static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj,  	ssize_t cnt = 0;  	unsigned long flags; -	for (; size > 0 && pos < pdata->offset; cnt++, size--) { -		spin_lock_irqsave(&m48t59->lock, flags); +	spin_lock_irqsave(&m48t59->lock, flags); + +	for (; cnt < size; cnt++)  		M48T59_WRITE(*buf++, cnt); -		spin_unlock_irqrestore(&m48t59->lock, flags); -	} + +	spin_unlock_irqrestore(&m48t59->lock, flags);  	return cnt;  } diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c index 9e02bcda0c09..db984d4bf952 100644 --- a/drivers/rtc/rtc-max8997.c +++ b/drivers/rtc/rtc-max8997.c @@ -521,6 +521,7 @@ static const struct platform_device_id rtc_id[] = {  	{ "max8997-rtc", 0 },  	{},  }; +MODULE_DEVICE_TABLE(platform, rtc_id);  static struct platform_driver max8997_rtc_driver = {  	.driver		= { diff --git a/drivers/rtc/rtc-moxart.c b/drivers/rtc/rtc-moxart.c index 73759c9a4527..07b30a373a92 100644 --- a/drivers/rtc/rtc-moxart.c +++ b/drivers/rtc/rtc-moxart.c @@ -312,6 +312,7 @@ static const struct of_device_id moxart_rtc_match[] = {  	{ .compatible = "moxa,moxart-rtc" },  	{ },  }; +MODULE_DEVICE_TABLE(of, moxart_rtc_match);  static struct platform_driver moxart_rtc_driver = {  	.probe	= moxart_rtc_probe, diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 1767e18d5bd4..4ca4daa0b8f3 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -406,6 +406,7 @@ static const struct of_device_id mpc5121_rtc_match[] = {  	{ .compatible = "fsl,mpc5200-rtc", },  	{},  }; +MODULE_DEVICE_TABLE(of, mpc5121_rtc_match);  #endif  static struct platform_driver mpc5121_rtc_driver = { diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c index c0090b698ff3..06a5c52b292f 100644 --- a/drivers/rtc/rtc-mt6397.c +++ b/drivers/rtc/rtc-mt6397.c @@ -343,6 +343,8 @@ static int mtk_rtc_probe(struct platform_device *pdev)  		goto out_dispose_irq;  	} +	device_init_wakeup(&pdev->dev, 1); +  	rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev,  					   &mtk_rtc_ops, THIS_MODULE);  	if (IS_ERR(rtc->rtc_dev)) { @@ -351,8 +353,6 @@ static int mtk_rtc_probe(struct platform_device *pdev)  		goto out_free_irq;  	} -	device_init_wakeup(&pdev->dev, 1); -  	return 0;  out_free_irq: @@ -373,15 +373,42 @@ static int mtk_rtc_remove(struct platform_device *pdev)  	return 0;  } +#ifdef CONFIG_PM_SLEEP +static int mt6397_rtc_suspend(struct device *dev) +{ +	struct mt6397_rtc *rtc = dev_get_drvdata(dev); + +	if (device_may_wakeup(dev)) +		enable_irq_wake(rtc->irq); + +	return 0; +} + +static int mt6397_rtc_resume(struct device *dev) +{ +	struct mt6397_rtc *rtc = dev_get_drvdata(dev); + +	if (device_may_wakeup(dev)) +		disable_irq_wake(rtc->irq); + +	return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend, +			mt6397_rtc_resume); +  static const struct of_device_id mt6397_rtc_of_match[] = {  	{ .compatible = "mediatek,mt6397-rtc", },  	{ }  }; +MODULE_DEVICE_TABLE(of, mt6397_rtc_of_match);  static struct platform_driver mtk_rtc_driver = {  	.driver = {  		.name = "mt6397-rtc",  		.of_match_table = mt6397_rtc_of_match, +		.pm = &mt6397_pm_ops,  	},  	.probe	= mtk_rtc_probe,  	.remove = mtk_rtc_remove, diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 7f50d2ef7f6e..79bb28617d45 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -324,6 +324,7 @@ static const struct of_device_id rtc_mv_of_match_table[] = {  	{ .compatible = "marvell,orion-rtc", },  	{}  }; +MODULE_DEVICE_TABLE(of, rtc_mv_of_match_table);  #endif  static struct platform_driver mv_rtc_driver = { diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 5fc292c2dfdf..7bd89d90048f 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -16,6 +16,8 @@  #include <linux/interrupt.h>  #include <linux/platform_device.h>  #include <linux/clk.h> +#include <linux/of.h> +#include <linux/of_device.h>  #define RTC_INPUT_CLK_32768HZ	(0x00 << 5)  #define RTC_INPUT_CLK_32000HZ	(0x01 << 5) @@ -79,7 +81,8 @@ struct rtc_plat_data {  	struct rtc_device *rtc;  	void __iomem *ioaddr;  	int irq; -	struct clk *clk; +	struct clk *clk_ref; +	struct clk *clk_ipg;  	struct rtc_time g_rtc_alarm;  	enum imx_rtc_type devtype;  }; @@ -97,6 +100,15 @@ static const struct platform_device_id imx_rtc_devtype[] = {  };  MODULE_DEVICE_TABLE(platform, imx_rtc_devtype); +#ifdef CONFIG_OF +static const struct of_device_id imx_rtc_dt_ids[] = { +	{ .compatible = "fsl,imx1-rtc", .data = (const void *)IMX1_RTC }, +	{ .compatible = "fsl,imx21-rtc", .data = (const void *)IMX21_RTC }, +	{} +}; +MODULE_DEVICE_TABLE(of, imx_rtc_dt_ids); +#endif +  static inline int is_imx1_rtc(struct rtc_plat_data *data)  {  	return data->devtype == IMX1_RTC; @@ -361,29 +373,45 @@ static int mxc_rtc_probe(struct platform_device *pdev)  	u32 reg;  	unsigned long rate;  	int ret; +	const struct of_device_id *of_id;  	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);  	if (!pdata)  		return -ENOMEM; -	pdata->devtype = pdev->id_entry->driver_data; +	of_id = of_match_device(imx_rtc_dt_ids, &pdev->dev); +	if (of_id) +		pdata->devtype = (enum imx_rtc_type)of_id->data; +	else +		pdata->devtype = pdev->id_entry->driver_data;  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res);  	if (IS_ERR(pdata->ioaddr))  		return PTR_ERR(pdata->ioaddr); -	pdata->clk = devm_clk_get(&pdev->dev, NULL); -	if (IS_ERR(pdata->clk)) { -		dev_err(&pdev->dev, "unable to get clock!\n"); -		return PTR_ERR(pdata->clk); +	pdata->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); +	if (IS_ERR(pdata->clk_ipg)) { +		dev_err(&pdev->dev, "unable to get ipg clock!\n"); +		return PTR_ERR(pdata->clk_ipg);  	} -	ret = clk_prepare_enable(pdata->clk); +	ret = clk_prepare_enable(pdata->clk_ipg);  	if (ret)  		return ret; -	rate = clk_get_rate(pdata->clk); +	pdata->clk_ref = devm_clk_get(&pdev->dev, "ref"); +	if (IS_ERR(pdata->clk_ref)) { +		dev_err(&pdev->dev, "unable to get ref clock!\n"); +		ret = PTR_ERR(pdata->clk_ref); +		goto exit_put_clk_ipg; +	} + +	ret = clk_prepare_enable(pdata->clk_ref); +	if (ret) +		goto exit_put_clk_ipg; + +	rate = clk_get_rate(pdata->clk_ref);  	if (rate == 32768)  		reg = RTC_INPUT_CLK_32768HZ; @@ -394,7 +422,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)  	else {  		dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate);  		ret = -EINVAL; -		goto exit_put_clk; +		goto exit_put_clk_ref;  	}  	reg |= RTC_ENABLE_BIT; @@ -402,7 +430,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)  	if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) {  		dev_err(&pdev->dev, "hardware module can't be enabled!\n");  		ret = -EIO; -		goto exit_put_clk; +		goto exit_put_clk_ref;  	}  	platform_set_drvdata(pdev, pdata); @@ -424,15 +452,17 @@ static int mxc_rtc_probe(struct platform_device *pdev)  				  THIS_MODULE);  	if (IS_ERR(rtc)) {  		ret = PTR_ERR(rtc); -		goto exit_put_clk; +		goto exit_put_clk_ref;  	}  	pdata->rtc = rtc;  	return 0; -exit_put_clk: -	clk_disable_unprepare(pdata->clk); +exit_put_clk_ref: +	clk_disable_unprepare(pdata->clk_ref); +exit_put_clk_ipg: +	clk_disable_unprepare(pdata->clk_ipg);  	return ret;  } @@ -441,7 +471,8 @@ static int mxc_rtc_remove(struct platform_device *pdev)  {  	struct rtc_plat_data *pdata = platform_get_drvdata(pdev); -	clk_disable_unprepare(pdata->clk); +	clk_disable_unprepare(pdata->clk_ref); +	clk_disable_unprepare(pdata->clk_ipg);  	return 0;  } @@ -473,6 +504,7 @@ static SIMPLE_DEV_PM_OPS(mxc_rtc_pm_ops, mxc_rtc_suspend, mxc_rtc_resume);  static struct platform_driver mxc_rtc_driver = {  	.driver = {  		   .name	= "mxc_rtc", +		   .of_match_table = of_match_ptr(imx_rtc_dt_ids),  		   .pm		= &mxc_rtc_pm_ops,  	},  	.id_table = imx_rtc_devtype, diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 8b6355ffaff9..ec2e9c5fb993 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -25,6 +25,7 @@  #include <linux/of_device.h>  #include <linux/pm_runtime.h>  #include <linux/io.h> +#include <linux/clk.h>  /*   * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock @@ -107,6 +108,7 @@  /* OMAP_RTC_OSC_REG bit fields: */  #define OMAP_RTC_OSC_32KCLK_EN		BIT(6) +#define OMAP_RTC_OSC_SEL_32KCLK_SRC	BIT(3)  /* OMAP_RTC_IRQWAKEEN bit fields: */  #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN	BIT(1) @@ -132,10 +134,12 @@ struct omap_rtc_device_type {  struct omap_rtc {  	struct rtc_device *rtc;  	void __iomem *base; +	struct clk *clk;  	int irq_alarm;  	int irq_timer;  	u8 interrupts_reg;  	bool is_pmic_controller; +	bool has_ext_clk;  	const struct omap_rtc_device_type *type;  }; @@ -553,6 +557,15 @@ static int omap_rtc_probe(struct platform_device *pdev)  	if (rtc->irq_alarm <= 0)  		return -ENOENT; +	rtc->clk = devm_clk_get(&pdev->dev, "ext-clk"); +	if (!IS_ERR(rtc->clk)) +		rtc->has_ext_clk = true; +	else +		rtc->clk = devm_clk_get(&pdev->dev, "int-clk"); + +	if (!IS_ERR(rtc->clk)) +		clk_prepare_enable(rtc->clk); +  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	rtc->base = devm_ioremap_resource(&pdev->dev, res);  	if (IS_ERR(rtc->base)) @@ -627,6 +640,16 @@ static int omap_rtc_probe(struct platform_device *pdev)  	if (reg != new_ctrl)  		rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); +	/* +	 * If we have the external clock then switch to it so we can keep +	 * ticking across suspend. +	 */ +	if (rtc->has_ext_clk) { +		reg = rtc_read(rtc, OMAP_RTC_OSC_REG); +		rtc_write(rtc, OMAP_RTC_OSC_REG, +			  reg | OMAP_RTC_OSC_SEL_32KCLK_SRC); +	} +  	rtc->type->lock(rtc);  	device_init_wakeup(&pdev->dev, true); @@ -672,6 +695,7 @@ err:  static int __exit omap_rtc_remove(struct platform_device *pdev)  {  	struct omap_rtc *rtc = platform_get_drvdata(pdev); +	u8 reg;  	if (pm_power_off == omap_rtc_power_off &&  			omap_rtc_power_off_rtc == rtc) { @@ -681,10 +705,19 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)  	device_init_wakeup(&pdev->dev, 0); +	if (!IS_ERR(rtc->clk)) +		clk_disable_unprepare(rtc->clk); +  	rtc->type->unlock(rtc);  	/* leave rtc running, but disable irqs */  	rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); +	if (rtc->has_ext_clk) { +		reg = rtc_read(rtc, OMAP_RTC_OSC_REG); +		reg &= ~OMAP_RTC_OSC_SEL_32KCLK_SRC; +		rtc_write(rtc, OMAP_RTC_OSC_REG, reg); +	} +  	rtc->type->lock(rtc);  	/* Disable the clock/module */ diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c index 7061dcae2b09..6fbf9e617151 100644 --- a/drivers/rtc/rtc-opal.c +++ b/drivers/rtc/rtc-opal.c @@ -190,11 +190,9 @@ exit:  	return rc;  } -static const struct rtc_class_ops opal_rtc_ops = { +static struct rtc_class_ops opal_rtc_ops = {  	.read_time	= opal_get_rtc_time,  	.set_time	= opal_set_rtc_time, -	.read_alarm	= opal_get_tpo_time, -	.set_alarm	= opal_set_tpo_time,  };  static int opal_rtc_probe(struct platform_device *pdev) @@ -202,8 +200,11 @@ static int opal_rtc_probe(struct platform_device *pdev)  	struct rtc_device *rtc;  	if (pdev->dev.of_node && of_get_property(pdev->dev.of_node, "has-tpo", -						 NULL)) +						 NULL)) {  		device_set_wakeup_capable(&pdev->dev, true); +		opal_rtc_ops.read_alarm	= opal_get_tpo_time; +		opal_rtc_ops.set_alarm = opal_set_tpo_time; +	}  	rtc = devm_rtc_device_register(&pdev->dev, DRVNAME, &opal_rtc_ops,  				       THIS_MODULE); @@ -236,7 +237,6 @@ static struct platform_driver opal_rtc_driver = {  	.id_table	= opal_rtc_driver_ids,  	.driver		= {  		.name		= DRVNAME, -		.owner		= THIS_MODULE,  		.of_match_table	= opal_rtc_match,  	},  }; diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 8a7556cbcb7f..1c47650fe624 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -165,13 +165,7 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)  			tm->tm_sec, tm->tm_min, tm->tm_hour,  			tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); -	/* the clock can give out invalid datetime, but we cannot return -	 * -EINVAL otherwise hwclock will refuse to set the time on bootup. -	 */ -	if (rtc_valid_tm(tm) < 0) -		dev_err(dev, "retrieved date/time is not valid.\n"); - -	return 0; +	return rtc_valid_tm(tm);  }  static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 9bd842e97749..4b11d31f7174 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -33,11 +33,14 @@  #define PCF2127_REG_MO          (0x08)  #define PCF2127_REG_YR          (0x09) +#define PCF2127_OSF             BIT(7)  /* Oscillator Fail flag */ +  static struct i2c_driver pcf2127_driver;  struct pcf2127 {  	struct rtc_device *rtc;  	int voltage_low; /* indicates if a low_voltage was detected */ +	int oscillator_failed; /* OSF was detected and date is unreliable */  };  /* @@ -59,7 +62,18 @@ static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm)  	if (buf[PCF2127_REG_CTRL3] & 0x04) {  		pcf2127->voltage_low = 1;  		dev_info(&client->dev, -			"low voltage detected, date/time is not reliable.\n"); +			"low voltage detected, check/replace RTC battery.\n"); +	} + +	if (buf[PCF2127_REG_SC] & PCF2127_OSF) { +		/* +		 * no need clear the flag here, +		 * it will be cleared once the new date is saved +		 */ +		pcf2127->oscillator_failed = 1; +		dev_warn(&client->dev, +			 "oscillator stop detected, date/time is not reliable\n"); +		return -EINVAL;  	}  	dev_dbg(&client->dev, @@ -88,17 +102,12 @@ static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm)  		tm->tm_sec, tm->tm_min, tm->tm_hour,  		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); -	/* the clock can give out invalid datetime, but we cannot return -	 * -EINVAL otherwise hwclock will refuse to set the time on bootup. -	 */ -	if (rtc_valid_tm(tm) < 0) -		dev_err(&client->dev, "retrieved date/time is not valid.\n"); - -	return 0; +	return rtc_valid_tm(tm);  }  static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm)  { +	struct pcf2127 *pcf2127 = i2c_get_clientdata(client);  	unsigned char buf[8];  	int i = 0, err; @@ -112,7 +121,7 @@ static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm)  	buf[i++] = PCF2127_REG_SC;  	/* hours, minutes and seconds */ -	buf[i++] = bin2bcd(tm->tm_sec); +	buf[i++] = bin2bcd(tm->tm_sec);	/* this will also clear OSF flag */  	buf[i++] = bin2bcd(tm->tm_min);  	buf[i++] = bin2bcd(tm->tm_hour);  	buf[i++] = bin2bcd(tm->tm_mday); @@ -132,6 +141,9 @@ static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm)  		return -EIO;  	} +	/* clear OSF flag in client data */ +	pcf2127->oscillator_failed = 0; +  	return 0;  } @@ -144,7 +156,9 @@ static int pcf2127_rtc_ioctl(struct device *dev,  	switch (cmd) {  	case RTC_VL_READ:  		if (pcf2127->voltage_low) -			dev_info(dev, "low voltage detected, date/time is not reliable.\n"); +			dev_info(dev, "low voltage detected, check/replace battery\n"); +		if (pcf2127->oscillator_failed) +			dev_info(dev, "oscillator stop detected, date/time is not reliable\n");  		if (copy_to_user((void __user *)arg, &pcf2127->voltage_low,  					sizeof(int))) @@ -217,7 +231,6 @@ MODULE_DEVICE_TABLE(of, pcf2127_of_match);  static struct i2c_driver pcf2127_driver = {  	.driver		= {  		.name	= "rtc-pcf2127", -		.owner	= THIS_MODULE,  		.of_match_table = of_match_ptr(pcf2127_of_match),  	},  	.probe		= pcf2127_probe, diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index 6a12bf62c504..b6d73dd881f2 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -189,7 +189,6 @@ MODULE_DEVICE_TABLE(of, pcf85063_of_match);  static struct i2c_driver pcf85063_driver = {  	.driver		= {  		.name	= "rtc-pcf85063", -		.owner	= THIS_MODULE,  		.of_match_table = of_match_ptr(pcf85063_of_match),  	},  	.probe		= pcf85063_probe, diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index 4cdb64be061b..e7ebcc0b7e59 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c @@ -334,7 +334,6 @@ MODULE_DEVICE_TABLE(of, pcf8523_of_match);  static struct i2c_driver pcf8523_driver = {  	.driver = {  		.name = DRIVER_NAME, -		.owner = THIS_MODULE,  		.of_match_table = of_match_ptr(pcf8523_of_match),  	},  	.probe = pcf8523_probe, diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 8bba022be946..e569243db57e 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -483,7 +483,6 @@ MODULE_DEVICE_TABLE(of, pcf8563_of_match);  static struct i2c_driver pcf8563_driver = {  	.driver		= {  		.name	= "rtc-pcf8563", -		.owner	= THIS_MODULE,  		.of_match_table = of_match_ptr(pcf8563_of_match),  	},  	.probe		= pcf8563_probe, diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 5911a6dca291..7ca9e8871d77 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c @@ -309,7 +309,6 @@ MODULE_DEVICE_TABLE(i2c, pcf8583_id);  static struct i2c_driver pcf8583_driver = {  	.driver = {  		.name	= "pcf8583", -		.owner	= THIS_MODULE,  	},  	.probe		= pcf8583_probe,  	.id_table	= pcf8583_id, diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 99181fff88fd..41dcb7ddb906 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -476,6 +476,6 @@ static struct amba_driver pl031_driver = {  module_amba_driver(pl031_driver); -MODULE_AUTHOR("Deepak Saxena <[email protected]"); +MODULE_AUTHOR("Deepak Saxena <[email protected]>");  MODULE_DESCRIPTION("ARM AMBA PL031 RTC Driver");  MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index 4561f375327d..fe4985b54608 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -32,6 +32,8 @@  #include <mach/hardware.h> +#include "rtc-sa1100.h" +  #define RTC_DEF_DIVIDER		(32768 - 1)  #define RTC_DEF_TRIM		0  #define MAXFREQ_PERIODIC	1000 @@ -86,10 +88,9 @@  	__raw_writel((value), (pxa_rtc)->base + (reg))  struct pxa_rtc { +	struct sa1100_rtc sa1100_rtc;  	struct resource	*ress;  	void __iomem		*base; -	int			irq_1Hz; -	int			irq_Alrm;  	struct rtc_device	*rtc;  	spinlock_t		lock;		/* Protects this structure */  }; @@ -184,25 +185,25 @@ static int pxa_rtc_open(struct device *dev)  	struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev);  	int ret; -	ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, 0, +	ret = request_irq(pxa_rtc->sa1100_rtc.irq_1hz, pxa_rtc_irq, 0,  			  "rtc 1Hz", dev);  	if (ret < 0) { -		dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz, -			ret); +		dev_err(dev, "can't get irq %i, err %d\n", +			pxa_rtc->sa1100_rtc.irq_1hz, ret);  		goto err_irq_1Hz;  	} -	ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, 0, +	ret = request_irq(pxa_rtc->sa1100_rtc.irq_alarm, pxa_rtc_irq, 0,  			  "rtc Alrm", dev);  	if (ret < 0) { -		dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm, -			ret); +		dev_err(dev, "can't get irq %i, err %d\n", +			pxa_rtc->sa1100_rtc.irq_alarm, ret);  		goto err_irq_Alrm;  	}  	return 0;  err_irq_Alrm: -	free_irq(pxa_rtc->irq_1Hz, dev); +	free_irq(pxa_rtc->sa1100_rtc.irq_1hz, dev);  err_irq_1Hz:  	return ret;  } @@ -215,8 +216,8 @@ static void pxa_rtc_release(struct device *dev)  	rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_RDALE1 | RTSR_HZE);  	spin_unlock_irq(&pxa_rtc->lock); -	free_irq(pxa_rtc->irq_Alrm, dev); -	free_irq(pxa_rtc->irq_1Hz, dev); +	free_irq(pxa_rtc->sa1100_rtc.irq_1hz, dev); +	free_irq(pxa_rtc->sa1100_rtc.irq_alarm, dev);  }  static int pxa_alarm_irq_enable(struct device *dev, unsigned int enabled) @@ -320,12 +321,13 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev;  	struct pxa_rtc *pxa_rtc; +	struct sa1100_rtc *sa1100_rtc;  	int ret; -	u32 rttr;  	pxa_rtc = devm_kzalloc(dev, sizeof(*pxa_rtc), GFP_KERNEL);  	if (!pxa_rtc)  		return -ENOMEM; +	sa1100_rtc = &pxa_rtc->sa1100_rtc;  	spin_lock_init(&pxa_rtc->lock);  	platform_set_drvdata(pdev, pxa_rtc); @@ -336,13 +338,13 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)  		return -ENXIO;  	} -	pxa_rtc->irq_1Hz = platform_get_irq(pdev, 0); -	if (pxa_rtc->irq_1Hz < 0) { +	sa1100_rtc->irq_1hz = platform_get_irq(pdev, 0); +	if (sa1100_rtc->irq_1hz < 0) {  		dev_err(dev, "No 1Hz IRQ resource defined\n");  		return -ENXIO;  	} -	pxa_rtc->irq_Alrm = platform_get_irq(pdev, 1); -	if (pxa_rtc->irq_Alrm < 0) { +	sa1100_rtc->irq_alarm = platform_get_irq(pdev, 1); +	if (sa1100_rtc->irq_alarm < 0) {  		dev_err(dev, "No alarm IRQ resource defined\n");  		return -ENXIO;  	} @@ -354,15 +356,14 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)  		return -ENOMEM;  	} -	/* -	 * If the clock divider is uninitialized then reset it to the -	 * default value to get the 1Hz clock. -	 */ -	if (rtc_readl(pxa_rtc, RTTR) == 0) { -		rttr = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); -		rtc_writel(pxa_rtc, RTTR, rttr); -		dev_warn(dev, "warning: initializing default clock" -			 " divider/trim value\n"); +	sa1100_rtc->rcnr = pxa_rtc->base + 0x0; +	sa1100_rtc->rtsr = pxa_rtc->base + 0x8; +	sa1100_rtc->rtar = pxa_rtc->base + 0x4; +	sa1100_rtc->rttr = pxa_rtc->base + 0xc; +	ret = sa1100_rtc_init(pdev, sa1100_rtc); +	if (!ret) { +		dev_err(dev, "Unable to init SA1100 RTC sub-device\n"); +		return ret;  	}  	rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_RDALE1 | RTSR_HZE); @@ -402,7 +403,7 @@ static int pxa_rtc_suspend(struct device *dev)  	struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev);  	if (device_may_wakeup(dev)) -		enable_irq_wake(pxa_rtc->irq_Alrm); +		enable_irq_wake(pxa_rtc->sa1100_rtc.irq_alarm);  	return 0;  } @@ -411,7 +412,7 @@ static int pxa_rtc_resume(struct device *dev)  	struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev);  	if (device_may_wakeup(dev)) -		disable_irq_wake(pxa_rtc->irq_Alrm); +		disable_irq_wake(pxa_rtc->sa1100_rtc.irq_alarm);  	return 0;  }  #endif diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c index b548551f385c..026035373ae6 100644 --- a/drivers/rtc/rtc-rp5c01.c +++ b/drivers/rtc/rtc-rp5c01.c @@ -170,7 +170,7 @@ static ssize_t rp5c01_nvram_read(struct file *filp, struct kobject *kobj,  	spin_lock_irq(&priv->lock); -	for (count = 0; size > 0 && pos < RP5C01_MODE; count++, size--) { +	for (count = 0; count < size; count++) {  		u8 data;  		rp5c01_write(priv, @@ -200,7 +200,7 @@ static ssize_t rp5c01_nvram_write(struct file *filp, struct kobject *kobj,  	spin_lock_irq(&priv->lock); -	for (count = 0; size > 0 && pos < RP5C01_MODE; count++, size--) { +	for (count = 0; count < size; count++) {  		u8 data = *buf++;  		rp5c01_write(priv, diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index e6298e02b400..24c3d69ce1b9 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -18,13 +18,11 @@   * modify it under the terms of the GNU General Public License   * version 2 as published by the Free Software Foundation.   */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h>  #include <linux/bcd.h> +#include <linux/bitops.h>  #include <linux/i2c.h> -#include <linux/list.h> +#include <linux/kernel.h> +#include <linux/module.h>  #include <linux/rtc.h>  /* Register definitions */ @@ -48,17 +46,17 @@  #define RX8025_BIT_CTRL1_CT	(7 << 0)  /* 1 Hz periodic level irq */  #define RX8025_BIT_CTRL1_CT_1HZ	4 -#define RX8025_BIT_CTRL1_TEST	(1 << 3) -#define RX8025_BIT_CTRL1_1224	(1 << 5) -#define RX8025_BIT_CTRL1_DALE	(1 << 6) -#define RX8025_BIT_CTRL1_WALE	(1 << 7) - -#define RX8025_BIT_CTRL2_DAFG	(1 << 0) -#define RX8025_BIT_CTRL2_WAFG	(1 << 1) -#define RX8025_BIT_CTRL2_CTFG	(1 << 2) -#define RX8025_BIT_CTRL2_PON	(1 << 4) -#define RX8025_BIT_CTRL2_XST	(1 << 5) -#define RX8025_BIT_CTRL2_VDET	(1 << 6) +#define RX8025_BIT_CTRL1_TEST	BIT(3) +#define RX8025_BIT_CTRL1_1224	BIT(5) +#define RX8025_BIT_CTRL1_DALE	BIT(6) +#define RX8025_BIT_CTRL1_WALE	BIT(7) + +#define RX8025_BIT_CTRL2_DAFG	BIT(0) +#define RX8025_BIT_CTRL2_WAFG	BIT(1) +#define RX8025_BIT_CTRL2_CTFG	BIT(2) +#define RX8025_BIT_CTRL2_PON	BIT(4) +#define RX8025_BIT_CTRL2_XST	BIT(5) +#define RX8025_BIT_CTRL2_VDET	BIT(6)  /* Clock precision adjustment */  #define RX8025_ADJ_RESOLUTION	3050 /* in ppb */ @@ -74,84 +72,84 @@ MODULE_DEVICE_TABLE(i2c, rx8025_id);  struct rx8025_data {  	struct i2c_client *client;  	struct rtc_device *rtc; -	struct work_struct work;  	u8 ctrl1; -	unsigned exiting:1;  }; -static int rx8025_read_reg(struct i2c_client *client, int number, u8 *value) +static s32 rx8025_read_reg(const struct i2c_client *client, u8 number)  { -	int ret = i2c_smbus_read_byte_data(client, (number << 4) | 0x08); - -	if (ret < 0) { -		dev_err(&client->dev, "Unable to read register #%d\n", number); -		return ret; -	} - -	*value = ret; -	return 0; +	return i2c_smbus_read_byte_data(client, number << 4);  } -static int rx8025_read_regs(struct i2c_client *client, -			    int number, u8 length, u8 *values) +static int rx8025_read_regs(const struct i2c_client *client, +			    u8 number, u8 length, u8 *values)  { -	int ret = i2c_smbus_read_i2c_block_data(client, (number << 4) | 0x08, -						length, values); - -	if (ret != length) { -		dev_err(&client->dev, "Unable to read registers #%d..#%d\n", -			number, number + length - 1); +	int ret = i2c_smbus_read_i2c_block_data(client, number << 4, length, +						values); +	if (ret != length)  		return ret < 0 ? ret : -EIO; -	}  	return 0;  } -static int rx8025_write_reg(struct i2c_client *client, int number, u8 value) +static s32 rx8025_write_reg(const struct i2c_client *client, u8 number, +			    u8 value)  { -	int ret = i2c_smbus_write_byte_data(client, number << 4, value); - -	if (ret) -		dev_err(&client->dev, "Unable to write register #%d\n", -			number); +	return i2c_smbus_write_byte_data(client, number << 4, value); +} -	return ret; +static s32 rx8025_write_regs(const struct i2c_client *client, +			     u8 number, u8 length, const u8 *values) +{ +	return i2c_smbus_write_i2c_block_data(client, number << 4, +					      length, values);  } -static int rx8025_write_regs(struct i2c_client *client, -			     int number, u8 length, u8 *values) +static int rx8025_check_validity(struct device *dev)  { -	int ret = i2c_smbus_write_i2c_block_data(client, (number << 4) | 0x08, -						 length, values); +	struct rx8025_data *rx8025 = dev_get_drvdata(dev); +	int ctrl2; + +	ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2); +	if (ctrl2 < 0) +		return ctrl2; + +	if (ctrl2 & RX8025_BIT_CTRL2_VDET) +		dev_warn(dev, "power voltage drop detected\n"); + +	if (ctrl2 & RX8025_BIT_CTRL2_PON) { +		dev_warn(dev, "power-on reset detected, date is invalid\n"); +		return -EINVAL; +	} -	if (ret) -		dev_err(&client->dev, "Unable to write registers #%d..#%d\n", -			number, number + length - 1); +	if (!(ctrl2 & RX8025_BIT_CTRL2_XST)) { +		dev_warn(dev, "crystal stopped, date is invalid\n"); +		return -EINVAL; +	} -	return ret; +	return 0;  } -static irqreturn_t rx8025_irq(int irq, void *dev_id) +static int rx8025_reset_validity(struct i2c_client *client)  { -	struct i2c_client *client = dev_id; -	struct rx8025_data *rx8025 = i2c_get_clientdata(client); +	int ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2); -	disable_irq_nosync(irq); -	schedule_work(&rx8025->work); -	return IRQ_HANDLED; +	if (ctrl2 < 0) +		return ctrl2; + +	ctrl2 &= ~(RX8025_BIT_CTRL2_PON | RX8025_BIT_CTRL2_VDET); + +	return rx8025_write_reg(client, RX8025_REG_CTRL2, +				ctrl2 | RX8025_BIT_CTRL2_XST);  } -static void rx8025_work(struct work_struct *work) +static irqreturn_t rx8025_handle_irq(int irq, void *dev_id)  { -	struct rx8025_data *rx8025 = container_of(work, struct rx8025_data, -						  work); -	struct i2c_client *client = rx8025->client; -	struct mutex *lock = &rx8025->rtc->ops_lock; -	u8 status; - -	mutex_lock(lock); +	struct i2c_client *client = dev_id; +	struct rx8025_data *rx8025 = i2c_get_clientdata(client); +	int status; -	if (rx8025_read_reg(client, RX8025_REG_CTRL2, &status)) +	status = rx8025_read_reg(client, RX8025_REG_CTRL2); +	if (status < 0)  		goto out;  	if (!(status & RX8025_BIT_CTRL2_XST)) @@ -161,9 +159,7 @@ static void rx8025_work(struct work_struct *work)  	if (status & RX8025_BIT_CTRL2_CTFG) {  		/* periodic */  		status &= ~RX8025_BIT_CTRL2_CTFG; -		local_irq_disable();  		rtc_update_irq(rx8025->rtc, 1, RTC_PF | RTC_IRQF); -		local_irq_enable();  	}  	if (status & RX8025_BIT_CTRL2_DAFG) { @@ -172,20 +168,11 @@ static void rx8025_work(struct work_struct *work)  		if (rx8025_write_reg(client, RX8025_REG_CTRL1,  				     rx8025->ctrl1 & ~RX8025_BIT_CTRL1_DALE))  			goto out; -		local_irq_disable();  		rtc_update_irq(rx8025->rtc, 1, RTC_AF | RTC_IRQF); -		local_irq_enable();  	} -	/* acknowledge IRQ */ -	rx8025_write_reg(client, RX8025_REG_CTRL2, -			 status | RX8025_BIT_CTRL2_XST); -  out: -	if (!rx8025->exiting) -		enable_irq(client->irq); - -	mutex_unlock(lock); +	return IRQ_HANDLED;  }  static int rx8025_get_time(struct device *dev, struct rtc_time *dt) @@ -194,6 +181,10 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)  	u8 date[7];  	int err; +	err = rx8025_check_validity(dev); +	if (err) +		return err; +  	err = rx8025_read_regs(rx8025->client, RX8025_REG_SEC, 7, date);  	if (err)  		return err; @@ -213,10 +204,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)  	dt->tm_mday = bcd2bin(date[RX8025_REG_MDAY] & 0x3f);  	dt->tm_mon = bcd2bin(date[RX8025_REG_MONTH] & 0x1f) - 1; -	dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]); - -	if (dt->tm_year < 70) -		dt->tm_year += 100; +	dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]) + 100;  	dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,  		dt->tm_sec, dt->tm_min, dt->tm_hour, @@ -229,12 +217,10 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)  {  	struct rx8025_data *rx8025 = dev_get_drvdata(dev);  	u8 date[7]; +	int ret; -	/* -	 * BUG: The HW assumes every year that is a multiple of 4 to be a leap -	 * year.  Next time this is wrong is 2100, which will not be a leap -	 * year. -	 */ +	if ((dt->tm_year < 100) || (dt->tm_year > 199)) +		return -EINVAL;  	/*  	 * Here the read-only bits are written as "0".  I'm not sure if that @@ -251,17 +237,21 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)  	date[RX8025_REG_WDAY] = bin2bcd(dt->tm_wday);  	date[RX8025_REG_MDAY] = bin2bcd(dt->tm_mday);  	date[RX8025_REG_MONTH] = bin2bcd(dt->tm_mon + 1); -	date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year % 100); +	date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year - 100);  	dev_dbg(dev,  		"%s: write 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",  		__func__,  		date[0], date[1], date[2], date[3], date[4], date[5], date[6]); -	return rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date); +	ret = rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date); +	if (ret < 0) +		return ret; + +	return rx8025_reset_validity(rx8025->client);  } -static int rx8025_init_client(struct i2c_client *client, int *need_reset) +static int rx8025_init_client(struct i2c_client *client)  {  	struct rx8025_data *rx8025 = i2c_get_clientdata(client);  	u8 ctrl[2], ctrl2; @@ -275,38 +265,18 @@ static int rx8025_init_client(struct i2c_client *client, int *need_reset)  	/* Keep test bit zero ! */  	rx8025->ctrl1 = ctrl[0] & ~RX8025_BIT_CTRL1_TEST; -	if (ctrl[1] & RX8025_BIT_CTRL2_PON) { -		dev_warn(&client->dev, "power-on reset was detected, " -			 "you may have to readjust the clock\n"); -		*need_reset = 1; -	} - -	if (ctrl[1] & RX8025_BIT_CTRL2_VDET) { -		dev_warn(&client->dev, "a power voltage drop was detected, " -			 "you may have to readjust the clock\n"); -		*need_reset = 1; -	} - -	if (!(ctrl[1] & RX8025_BIT_CTRL2_XST)) { -		dev_warn(&client->dev, "Oscillation stop was detected," -			 "you may have to readjust the clock\n"); -		*need_reset = 1; -	} -  	if (ctrl[1] & (RX8025_BIT_CTRL2_DAFG | RX8025_BIT_CTRL2_WAFG)) {  		dev_warn(&client->dev, "Alarm was detected\n");  		need_clear = 1;  	} -	if (!(ctrl[1] & RX8025_BIT_CTRL2_CTFG)) +	if (ctrl[1] & RX8025_BIT_CTRL2_CTFG)  		need_clear = 1; -	if (*need_reset || need_clear) { -		ctrl2 = ctrl[0]; -		ctrl2 &= ~(RX8025_BIT_CTRL2_PON | RX8025_BIT_CTRL2_VDET | -			   RX8025_BIT_CTRL2_CTFG | RX8025_BIT_CTRL2_WAFG | +	if (need_clear) { +		ctrl2 = ctrl[1]; +		ctrl2 &= ~(RX8025_BIT_CTRL2_CTFG | RX8025_BIT_CTRL2_WAFG |  			   RX8025_BIT_CTRL2_DAFG); -		ctrl2 |= RX8025_BIT_CTRL2_XST;  		err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2);  	} @@ -319,8 +289,8 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)  {  	struct rx8025_data *rx8025 = dev_get_drvdata(dev);  	struct i2c_client *client = rx8025->client; -	u8 ctrl2, ald[2]; -	int err; +	u8 ald[2]; +	int ctrl2, err;  	if (client->irq <= 0)  		return -EINVAL; @@ -329,9 +299,9 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)  	if (err)  		return err; -	err = rx8025_read_reg(client, RX8025_REG_CTRL2, &ctrl2); -	if (err) -		return err; +	ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2); +	if (ctrl2 < 0) +		return ctrl2;  	dev_dbg(dev, "%s: read alarm 0x%02x 0x%02x ctrl2 %02x\n",  		__func__, ald[0], ald[1], ctrl2); @@ -452,12 +422,11 @@ static struct rtc_class_ops rx8025_rtc_ops = {  static int rx8025_get_clock_adjust(struct device *dev, int *adj)  {  	struct i2c_client *client = to_i2c_client(dev); -	u8 digoff; -	int err; +	int digoff; -	err = rx8025_read_reg(client, RX8025_REG_DIGOFF, &digoff); -	if (err) -		return err; +	digoff = rx8025_read_reg(client, RX8025_REG_DIGOFF); +	if (digoff < 0) +		return digoff;  	*adj = digoff >= 64 ? digoff - 128 : digoff;  	if (*adj > 0) @@ -539,88 +508,53 @@ static int rx8025_probe(struct i2c_client *client,  {  	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);  	struct rx8025_data *rx8025; -	int err, need_reset = 0; +	int err = 0;  	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA  				     | I2C_FUNC_SMBUS_I2C_BLOCK)) {  		dev_err(&adapter->dev,  			"doesn't support required functionality\n"); -		err = -EIO; -		goto errout; +		return -EIO;  	}  	rx8025 = devm_kzalloc(&client->dev, sizeof(*rx8025), GFP_KERNEL);  	if (!rx8025) { -		err = -ENOMEM; -		goto errout; +		return -ENOMEM;  	}  	rx8025->client = client;  	i2c_set_clientdata(client, rx8025); -	INIT_WORK(&rx8025->work, rx8025_work); -	err = rx8025_init_client(client, &need_reset); +	err = rx8025_init_client(client);  	if (err) -		goto errout; - -	if (need_reset) { -		struct rtc_time tm; -		dev_info(&client->dev, -			 "bad conditions detected, resetting date\n"); -		rtc_time_to_tm(0, &tm);	/* 1970/1/1 */ -		rx8025_set_time(&client->dev, &tm); -	} +		return err;  	rx8025->rtc = devm_rtc_device_register(&client->dev, client->name,  					  &rx8025_rtc_ops, THIS_MODULE);  	if (IS_ERR(rx8025->rtc)) { -		err = PTR_ERR(rx8025->rtc);  		dev_err(&client->dev, "unable to register the class device\n"); -		goto errout; +		return PTR_ERR(rx8025->rtc);  	}  	if (client->irq > 0) {  		dev_info(&client->dev, "IRQ %d supplied\n", client->irq); -		err = request_irq(client->irq, rx8025_irq, -				  0, "rx8025", client); +		err = devm_request_threaded_irq(&client->dev, client->irq, NULL, +						rx8025_handle_irq, 0, "rx8025", +						client);  		if (err) { -			dev_err(&client->dev, "unable to request IRQ\n"); -			goto errout; +			dev_err(&client->dev, "unable to request IRQ, alarms disabled\n"); +			client->irq = 0;  		}  	} -	rx8025->rtc->irq_freq = 1;  	rx8025->rtc->max_user_freq = 1;  	err = rx8025_sysfs_register(&client->dev); -	if (err) -		goto errout_irq; - -	return 0; - -errout_irq: -	if (client->irq > 0) -		free_irq(client->irq, client); - -errout: -	dev_err(&adapter->dev, "probing for rx8025 failed\n");  	return err;  }  static int rx8025_remove(struct i2c_client *client)  { -	struct rx8025_data *rx8025 = i2c_get_clientdata(client); -	struct mutex *lock = &rx8025->rtc->ops_lock; - -	if (client->irq > 0) { -		mutex_lock(lock); -		rx8025->exiting = 1; -		mutex_unlock(lock); - -		free_irq(client->irq, client); -		cancel_work_sync(&rx8025->work); -	} -  	rx8025_sysfs_unregister(&client->dev);  	return 0;  } @@ -628,7 +562,6 @@ static int rx8025_remove(struct i2c_client *client)  static struct i2c_driver rx8025_driver = {  	.driver = {  		.name = "rtc-rx8025", -		.owner = THIS_MODULE,  	},  	.probe		= rx8025_probe,  	.remove		= rx8025_remove, diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index de8d9c427782..161e25d016c3 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c @@ -315,7 +315,6 @@ MODULE_DEVICE_TABLE(i2c, rx8581_id);  static struct i2c_driver rx8581_driver = {  	.driver		= {  		.name	= "rtc-rx8581", -		.owner	= THIS_MODULE,  	},  	.probe		= rx8581_probe,  	.id_table	= rx8581_id, diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index a0f832362199..7cc8f73a3fe8 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -39,6 +39,7 @@ struct s3c_rtc {  	void __iomem *base;  	struct clk *rtc_clk;  	struct clk *rtc_src_clk; +	bool clk_disabled;  	struct s3c_rtc_data *data; @@ -71,9 +72,12 @@ static void s3c_rtc_enable_clk(struct s3c_rtc *info)  	unsigned long irq_flags;  	spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); -	clk_enable(info->rtc_clk); -	if (info->data->needs_src_clk) -		clk_enable(info->rtc_src_clk); +	if (info->clk_disabled) { +		clk_enable(info->rtc_clk); +		if (info->data->needs_src_clk) +			clk_enable(info->rtc_src_clk); +		info->clk_disabled = false; +	}  	spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags);  } @@ -82,9 +86,12 @@ static void s3c_rtc_disable_clk(struct s3c_rtc *info)  	unsigned long irq_flags;  	spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); -	if (info->data->needs_src_clk) -		clk_disable(info->rtc_src_clk); -	clk_disable(info->rtc_clk); +	if (!info->clk_disabled) { +		if (info->data->needs_src_clk) +			clk_disable(info->rtc_src_clk); +		clk_disable(info->rtc_clk); +		info->clk_disabled = true; +	}  	spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags);  } @@ -128,6 +135,11 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)  	s3c_rtc_disable_clk(info); +	if (enabled) +		s3c_rtc_enable_clk(info); +	else +		s3c_rtc_disable_clk(info); +  	return 0;  } @@ -410,8 +422,9 @@ static int s3c_rtc_remove(struct platform_device *pdev)  	s3c_rtc_setaie(info->dev, 0); +	if (info->data->needs_src_clk) +		clk_unprepare(info->rtc_src_clk);  	clk_unprepare(info->rtc_clk); -	info->rtc_clk = NULL;  	return 0;  } @@ -482,6 +495,7 @@ static int s3c_rtc_probe(struct platform_device *pdev)  		if (IS_ERR(info->rtc_src_clk)) {  			dev_err(&pdev->dev,  				"failed to find rtc source clock\n"); +			clk_disable_unprepare(info->rtc_clk);  			return PTR_ERR(info->rtc_src_clk);  		}  		clk_prepare_enable(info->rtc_src_clk); diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 8c70d785ba73..f2504b4eef34 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -635,6 +635,16 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)  	case S2MPS13X:  		data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);  		ret = regmap_write(info->regmap, info->regs->ctrl, data[0]); +		if (ret < 0) +			break; + +		/* +		 * Should set WUDR & (RUDR or AUDR) bits to high after writing +		 * RTC_CTRL register like writing Alarm registers. We can't find +		 * the description from datasheet but vendor code does that +		 * really. +		 */ +		ret = s5m8767_rtc_set_alarm_reg(info);  		break;  	default: @@ -797,6 +807,7 @@ static const struct platform_device_id s5m_rtc_id[] = {  	{ "s2mps14-rtc",	S2MPS14X },  	{ },  }; +MODULE_DEVICE_TABLE(platform, s5m_rtc_id);  static struct platform_driver s5m_rtc_driver = {  	.driver		= { diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index b6e1ca08c2c0..c2187bf6c7e4 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -35,24 +35,17 @@  #include <linux/bitops.h>  #include <linux/io.h> -#include <mach/hardware.h> -#include <mach/irqs.h> +#define RTSR_HZE		BIT(3)	/* HZ interrupt enable */ +#define RTSR_ALE		BIT(2)	/* RTC alarm interrupt enable */ +#define RTSR_HZ			BIT(1)	/* HZ rising-edge detected */ +#define RTSR_AL			BIT(0)	/* RTC alarm detected */ -#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) -#include <mach/regs-rtc.h> -#endif +#include "rtc-sa1100.h"  #define RTC_DEF_DIVIDER		(32768 - 1)  #define RTC_DEF_TRIM		0  #define RTC_FREQ		1024 -struct sa1100_rtc { -	spinlock_t		lock; -	int			irq_1hz; -	int			irq_alarm; -	struct rtc_device	*rtc; -	struct clk		*clk; -};  static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)  { @@ -63,16 +56,16 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)  	spin_lock(&info->lock); -	rtsr = RTSR; +	rtsr = readl_relaxed(info->rtsr);  	/* clear interrupt sources */ -	RTSR = 0; +	writel_relaxed(0, info->rtsr);  	/* Fix for a nasty initialization problem the in SA11xx RTSR register.  	 * See also the comments in sa1100_rtc_probe(). */  	if (rtsr & (RTSR_ALE | RTSR_HZE)) {  		/* This is the original code, before there was the if test  		 * above. This code does not clear interrupts that were not  		 * enabled. */ -		RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); +		writel_relaxed((RTSR_AL | RTSR_HZ) & (rtsr >> 2), info->rtsr);  	} else {  		/* For some reason, it is possible to enter this routine  		 * without interruptions enabled, it has been tested with @@ -81,13 +74,13 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)  		 * This situation leads to an infinite "loop" of interrupt  		 * routine calling and as a result the processor seems to  		 * lock on its first call to open(). */ -		RTSR = RTSR_AL | RTSR_HZ; +		writel_relaxed(RTSR_AL | RTSR_HZ, info->rtsr);  	}  	/* clear alarm interrupt if it has occurred */  	if (rtsr & RTSR_AL)  		rtsr &= ~RTSR_ALE; -	RTSR = rtsr & (RTSR_ALE | RTSR_HZE); +	writel_relaxed(rtsr & (RTSR_ALE | RTSR_HZE), info->rtsr);  	/* update irq data & counter */  	if (rtsr & RTSR_AL) @@ -135,7 +128,7 @@ static void sa1100_rtc_release(struct device *dev)  	struct sa1100_rtc *info = dev_get_drvdata(dev);  	spin_lock_irq(&info->lock); -	RTSR = 0; +	writel_relaxed(0, info->rtsr);  	spin_unlock_irq(&info->lock);  	free_irq(info->irq_alarm, dev); @@ -144,39 +137,46 @@ static void sa1100_rtc_release(struct device *dev)  static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)  { +	u32 rtsr;  	struct sa1100_rtc *info = dev_get_drvdata(dev);  	spin_lock_irq(&info->lock); +	rtsr = readl_relaxed(info->rtsr);  	if (enabled) -		RTSR |= RTSR_ALE; +		rtsr |= RTSR_ALE;  	else -		RTSR &= ~RTSR_ALE; +		rtsr &= ~RTSR_ALE; +	writel_relaxed(rtsr, info->rtsr);  	spin_unlock_irq(&info->lock);  	return 0;  }  static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm)  { -	rtc_time_to_tm(RCNR, tm); +	struct sa1100_rtc *info = dev_get_drvdata(dev); + +	rtc_time_to_tm(readl_relaxed(info->rcnr), tm);  	return 0;  }  static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm)  { +	struct sa1100_rtc *info = dev_get_drvdata(dev);  	unsigned long time;  	int ret;  	ret = rtc_tm_to_time(tm, &time);  	if (ret == 0) -		RCNR = time; +		writel_relaxed(time, info->rcnr);  	return ret;  }  static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)  {  	u32	rtsr; +	struct sa1100_rtc *info = dev_get_drvdata(dev); -	rtsr = RTSR; +	rtsr = readl_relaxed(info->rtsr);  	alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0;  	alrm->pending = (rtsr & RTSR_AL) ? 1 : 0;  	return 0; @@ -192,12 +192,13 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)  	ret = rtc_tm_to_time(&alrm->time, &time);  	if (ret != 0)  		goto out; -	RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); -	RTAR = time; +	writel_relaxed(readl_relaxed(info->rtsr) & +		(RTSR_HZE | RTSR_ALE | RTSR_AL), info->rtsr); +	writel_relaxed(time, info->rtar);  	if (alrm->enabled) -		RTSR |= RTSR_ALE; +		writel_relaxed(readl_relaxed(info->rtsr) | RTSR_ALE, info->rtsr);  	else -		RTSR &= ~RTSR_ALE; +		writel_relaxed(readl_relaxed(info->rtsr) & ~RTSR_ALE, info->rtsr);  out:  	spin_unlock_irq(&info->lock); @@ -206,8 +207,10 @@ out:  static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)  { -	seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); -	seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); +	struct sa1100_rtc *info = dev_get_drvdata(dev); + +	seq_printf(seq, "trim/divider\t\t: 0x%08x\n", readl_relaxed(info->rttr)); +	seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", readl_relaxed(info->rtsr));  	return 0;  } @@ -223,29 +226,18 @@ static const struct rtc_class_ops sa1100_rtc_ops = {  	.alarm_irq_enable = sa1100_rtc_alarm_irq_enable,  }; -static int sa1100_rtc_probe(struct platform_device *pdev) +int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info)  {  	struct rtc_device *rtc; -	struct sa1100_rtc *info; -	int irq_1hz, irq_alarm, ret = 0; +	int ret; -	irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz"); -	irq_alarm = platform_get_irq_byname(pdev, "rtc alarm"); -	if (irq_1hz < 0 || irq_alarm < 0) -		return -ENODEV; +	spin_lock_init(&info->lock); -	info = devm_kzalloc(&pdev->dev, sizeof(struct sa1100_rtc), GFP_KERNEL); -	if (!info) -		return -ENOMEM;  	info->clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(info->clk)) {  		dev_err(&pdev->dev, "failed to find rtc clock source\n");  		return PTR_ERR(info->clk);  	} -	info->irq_1hz = irq_1hz; -	info->irq_alarm = irq_alarm; -	spin_lock_init(&info->lock); -	platform_set_drvdata(pdev, info);  	ret = clk_prepare_enable(info->clk);  	if (ret) @@ -257,22 +249,19 @@ static int sa1100_rtc_probe(struct platform_device *pdev)  	 * If the clock divider is uninitialized then reset it to the  	 * default value to get the 1Hz clock.  	 */ -	if (RTTR == 0) { -		RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); +	if (readl_relaxed(info->rttr) == 0) { +		writel_relaxed(RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16), info->rttr);  		dev_warn(&pdev->dev, "warning: "  			"initializing default clock divider/trim value\n");  		/* The current RTC value probably doesn't make sense either */ -		RCNR = 0; +		writel_relaxed(0, info->rcnr);  	} -	device_init_wakeup(&pdev->dev, 1); -  	rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &sa1100_rtc_ops,  					THIS_MODULE); -  	if (IS_ERR(rtc)) { -		ret = PTR_ERR(rtc); -		goto err_dev; +		clk_disable_unprepare(info->clk); +		return PTR_ERR(rtc);  	}  	info->rtc = rtc; @@ -298,12 +287,52 @@ static int sa1100_rtc_probe(struct platform_device *pdev)  	 *  	 * Notice that clearing bit 1 and 0 is accomplished by writting ONES to  	 * the corresponding bits in RTSR. */ -	RTSR = RTSR_AL | RTSR_HZ; +	writel_relaxed(RTSR_AL | RTSR_HZ, info->rtsr);  	return 0; -err_dev: -	clk_disable_unprepare(info->clk); -	return ret; +} +EXPORT_SYMBOL_GPL(sa1100_rtc_init); + +static int sa1100_rtc_probe(struct platform_device *pdev) +{ +	struct sa1100_rtc *info; +	struct resource *iores; +	void __iomem *base; +	int irq_1hz, irq_alarm; + +	irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz"); +	irq_alarm = platform_get_irq_byname(pdev, "rtc alarm"); +	if (irq_1hz < 0 || irq_alarm < 0) +		return -ENODEV; + +	info = devm_kzalloc(&pdev->dev, sizeof(struct sa1100_rtc), GFP_KERNEL); +	if (!info) +		return -ENOMEM; +	info->irq_1hz = irq_1hz; +	info->irq_alarm = irq_alarm; + +	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	base = devm_ioremap_resource(&pdev->dev, iores); +	if (IS_ERR(base)) +		return PTR_ERR(base); + +	if (IS_ENABLED(CONFIG_ARCH_SA1100) || +	    of_device_is_compatible(pdev->dev.of_node, "mrvl,sa1100-rtc")) { +		info->rcnr = base + 0x04; +		info->rtsr = base + 0x10; +		info->rtar = base + 0x00; +		info->rttr = base + 0x08; +	} else { +		info->rcnr = base + 0x0; +		info->rtsr = base + 0x8; +		info->rtar = base + 0x4; +		info->rttr = base + 0xc; +	} + +	platform_set_drvdata(pdev, info); +	device_init_wakeup(&pdev->dev, 1); + +	return sa1100_rtc_init(pdev, info);  }  static int sa1100_rtc_remove(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-sa1100.h b/drivers/rtc/rtc-sa1100.h new file mode 100644 index 000000000000..2c79c0c57822 --- /dev/null +++ b/drivers/rtc/rtc-sa1100.h @@ -0,0 +1,23 @@ +#ifndef __RTC_SA1100_H__ +#define __RTC_SA1100_H__ + +#include <linux/kernel.h> + +struct clk; +struct platform_device; + +struct sa1100_rtc { +	spinlock_t		lock; +	void __iomem		*rcnr; +	void __iomem		*rtar; +	void __iomem		*rtsr; +	void __iomem		*rttr; +	int			irq_1hz; +	int			irq_alarm; +	struct rtc_device	*rtc; +	struct clk		*clk; +}; + +int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info); + +#endif diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index edc3b43282d4..7367f617145c 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -13,6 +13,7 @@  #include <linux/slab.h>  #include <linux/io.h>  #include <linux/of.h> +#include <linux/regmap.h>  #include <linux/rtc/sirfsoc_rtciobrg.h> @@ -48,12 +49,27 @@ struct sirfsoc_rtc_drv {  	/* Overflow for every 8 years extra time */  	u32			overflow_rtc;  	spinlock_t		lock; +	struct regmap *regmap;  #ifdef CONFIG_PM  	u32		saved_counter;  	u32		saved_overflow_rtc;  #endif  }; +static u32 sirfsoc_rtc_readl(struct sirfsoc_rtc_drv *rtcdrv, u32 offset) +{ +	u32 val; + +	regmap_read(rtcdrv->regmap, rtcdrv->rtc_base + offset, &val); +	return val; +} + +static void sirfsoc_rtc_writel(struct sirfsoc_rtc_drv *rtcdrv, +			       u32 offset, u32 val) +{ +	regmap_write(rtcdrv->regmap, rtcdrv->rtc_base + offset, val); +} +  static int sirfsoc_rtc_read_alarm(struct device *dev,  		struct rtc_wkalrm *alrm)  { @@ -64,9 +80,9 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,  	spin_lock_irq(&rtcdrv->lock); -	rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); +	rtc_count = sirfsoc_rtc_readl(rtcdrv, RTC_CN); -	rtc_alarm = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_ALARM0); +	rtc_alarm = sirfsoc_rtc_readl(rtcdrv, RTC_ALARM0);  	memset(alrm, 0, sizeof(struct rtc_wkalrm));  	/* @@ -82,8 +98,7 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,  		rtc_time_to_tm(rtcdrv->overflow_rtc  				<< (BITS_PER_LONG - RTC_SHIFT)  				| rtc_alarm >> RTC_SHIFT, &(alrm->time)); -	if (sirfsoc_rtc_iobrg_readl( -			rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E) +	if (sirfsoc_rtc_readl(rtcdrv, RTC_STATUS) & SIRFSOC_RTC_AL0E)  		alrm->enabled = 1;  	spin_unlock_irq(&rtcdrv->lock); @@ -103,8 +118,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,  		spin_lock_irq(&rtcdrv->lock); -		rtc_status_reg = sirfsoc_rtc_iobrg_readl( -				rtcdrv->rtc_base + RTC_STATUS); +		rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);  		if (rtc_status_reg & SIRFSOC_RTC_AL0E) {  			/*  			 * An ongoing alarm in progress - ingore it and not @@ -113,8 +127,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,  			dev_info(dev, "An old alarm was set, will be replaced by a new one\n");  		} -		sirfsoc_rtc_iobrg_writel( -			rtc_alarm << RTC_SHIFT, rtcdrv->rtc_base + RTC_ALARM0); +		sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, rtc_alarm << RTC_SHIFT);  		rtc_status_reg &= ~0x07; /* mask out the lower status bits */  		/*  		 * This bit RTC_AL sets it as a wake-up source for Sleep Mode @@ -123,8 +136,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,  		rtc_status_reg |= SIRFSOC_RTC_AL0;  		/* enable the RTC alarm interrupt */  		rtc_status_reg |= SIRFSOC_RTC_AL0E; -		sirfsoc_rtc_iobrg_writel( -			rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); +		sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);  		spin_unlock_irq(&rtcdrv->lock);  	} else { @@ -135,8 +147,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,  		 */  		spin_lock_irq(&rtcdrv->lock); -		rtc_status_reg = sirfsoc_rtc_iobrg_readl( -				rtcdrv->rtc_base + RTC_STATUS); +		rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);  		if (rtc_status_reg & SIRFSOC_RTC_AL0E) {  			/* clear the RTC status register's alarm bit */  			rtc_status_reg &= ~0x07; @@ -145,8 +156,8 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,  			/* Clear the Alarm enable bit */  			rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); -			sirfsoc_rtc_iobrg_writel(rtc_status_reg, -					rtcdrv->rtc_base + RTC_STATUS); +			sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, +					   rtc_status_reg);  		}  		spin_unlock_irq(&rtcdrv->lock); @@ -167,9 +178,9 @@ static int sirfsoc_rtc_read_time(struct device *dev,  	 * fail, read several times to make sure get stable value.  	 */  	do { -		tmp_rtc = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); +		tmp_rtc = sirfsoc_rtc_readl(rtcdrv, RTC_CN);  		cpu_relax(); -	} while (tmp_rtc != sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN)); +	} while (tmp_rtc != sirfsoc_rtc_readl(rtcdrv, RTC_CN));  	rtc_time_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT) |  					tmp_rtc >> RTC_SHIFT, tm); @@ -187,10 +198,8 @@ static int sirfsoc_rtc_set_time(struct device *dev,  	rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT); -	sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc, -			rtcdrv->rtc_base + RTC_SW_VALUE); -	sirfsoc_rtc_iobrg_writel( -			rtc_time << RTC_SHIFT, rtcdrv->rtc_base + RTC_CN); +	sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc); +	sirfsoc_rtc_writel(rtcdrv, RTC_CN, rtc_time << RTC_SHIFT);  	return 0;  } @@ -222,14 +231,13 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,  	spin_lock_irq(&rtcdrv->lock); -	rtc_status_reg = sirfsoc_rtc_iobrg_readl( -				rtcdrv->rtc_base + RTC_STATUS); +	rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);  	if (enabled)  		rtc_status_reg |= SIRFSOC_RTC_AL0E;  	else  		rtc_status_reg &= ~SIRFSOC_RTC_AL0E; -	sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); +	sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);  	spin_unlock_irq(&rtcdrv->lock); @@ -254,7 +262,7 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)  	spin_lock(&rtcdrv->lock); -	rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS); +	rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);  	/* this bit will be set ONLY if an alarm was active  	 * and it expired NOW  	 * So this is being used as an ASSERT @@ -270,7 +278,8 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)  		/* Clear the Alarm enable bit */  		rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);  	} -	sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); + +	sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);  	spin_unlock(&rtcdrv->lock); @@ -287,6 +296,13 @@ static const struct of_device_id sirfsoc_rtc_of_match[] = {  	{ .compatible = "sirf,prima2-sysrtc"},  	{},  }; + +const struct regmap_config sysrtc_regmap_config = { +	.reg_bits = 32, +	.val_bits = 32, +	.fast_io = true, +}; +  MODULE_DEVICE_TABLE(of, sirfsoc_rtc_of_match);  static int sirfsoc_rtc_probe(struct platform_device *pdev) @@ -314,27 +330,35 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev)  	/* Register rtc alarm as a wakeup source */  	device_init_wakeup(&pdev->dev, 1); +	rtcdrv->regmap = devm_regmap_init_iobg(&pdev->dev, +			&sysrtc_regmap_config); +	if (IS_ERR(rtcdrv->regmap)) { +		err = PTR_ERR(rtcdrv->regmap); +		dev_err(&pdev->dev, "Failed to allocate register map: %d\n", +			err); +		return err; +	} +  	/*  	 * Set SYS_RTC counter in RTC_HZ HZ Units  	 * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1  	 * If 16HZ, therefore RTC_DIV = 1023;  	 */  	rtc_div = ((32768 / RTC_HZ) / 2) - 1; -	sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV); +	sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div);  	/* 0x3 -> RTC_CLK */ -	sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK, -			rtcdrv->rtc_base + RTC_CLOCK_SWITCH); +	sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK);  	/* reset SYS RTC ALARM0 */ -	sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0); +	sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0);  	/* reset SYS RTC ALARM1 */ -	sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1); +	sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0);  	/* Restore RTC Overflow From Register After Command Reboot */  	rtcdrv->overflow_rtc = -		sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE); +		sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE);  	rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,  			&sirfsoc_rtc_ops, THIS_MODULE); @@ -372,10 +396,10 @@ static int sirfsoc_rtc_suspend(struct device *dev)  {  	struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev);  	rtcdrv->overflow_rtc = -		sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE); +		sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE);  	rtcdrv->saved_counter = -		sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); +		sirfsoc_rtc_readl(rtcdrv, RTC_CN);  	rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc;  	if (device_may_wakeup(dev) && !enable_irq_wake(rtcdrv->irq))  		rtcdrv->irq_wake = 1; @@ -392,12 +416,10 @@ static int sirfsoc_rtc_resume(struct device *dev)  	 * if resume from snapshot and the rtc power is lost,  	 * restroe the rtc settings  	 */ -	if (SIRFSOC_RTC_CLK != sirfsoc_rtc_iobrg_readl( -			rtcdrv->rtc_base + RTC_CLOCK_SWITCH)) { +	if (SIRFSOC_RTC_CLK != sirfsoc_rtc_readl(rtcdrv, RTC_CLOCK_SWITCH)) {  		u32 rtc_div;  		/* 0x3 -> RTC_CLK */ -		sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK, -			rtcdrv->rtc_base + RTC_CLOCK_SWITCH); +		sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK);  		/*  		 * Set SYS_RTC counter in RTC_HZ HZ Units  		 * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1 @@ -405,13 +427,13 @@ static int sirfsoc_rtc_resume(struct device *dev)  		 */  		rtc_div = ((32768 / RTC_HZ) / 2) - 1; -		sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV); +		sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div);  		/* reset SYS RTC ALARM0 */ -		sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0); +		sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0);  		/* reset SYS RTC ALARM1 */ -		sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1); +		sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0);  	}  	rtcdrv->overflow_rtc = rtcdrv->saved_overflow_rtc; @@ -419,15 +441,14 @@ static int sirfsoc_rtc_resume(struct device *dev)  	 * if current counter is small than previous,  	 * it means overflow in sleep  	 */ -	tmp = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); +	tmp = sirfsoc_rtc_readl(rtcdrv, RTC_CN);  	if (tmp <= rtcdrv->saved_counter)  		rtcdrv->overflow_rtc++;  	/*  	 *PWRC Value Be Changed When Suspend, Restore Overflow  	 * In Memory To Register  	 */ -	sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc, -			rtcdrv->rtc_base + RTC_SW_VALUE); +	sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc);  	if (device_may_wakeup(dev) && rtcdrv->irq_wake) {  		disable_irq_wake(rtcdrv->irq); diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index d87a85cefb66..950c5d0b6dca 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -18,6 +18,10 @@  #include <linux/platform_device.h>  #include <linux/rtc.h>  #include <linux/clk.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> + +#define SNVS_LPREGISTER_OFFSET	0x34  /* These register offsets are relative to LP (Low Power) range */  #define SNVS_LPCR		0x04 @@ -37,31 +41,36 @@  struct snvs_rtc_data {  	struct rtc_device *rtc; -	void __iomem *ioaddr; +	struct regmap *regmap; +	int offset;  	int irq; -	spinlock_t lock;  	struct clk *clk;  }; -static u32 rtc_read_lp_counter(void __iomem *ioaddr) +static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)  {  	u64 read1, read2; +	u32 val;  	do { -		read1 = readl(ioaddr + SNVS_LPSRTCMR); +		regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val); +		read1 = val;  		read1 <<= 32; -		read1 |= readl(ioaddr + SNVS_LPSRTCLR); +		regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val); +		read1 |= val; -		read2 = readl(ioaddr + SNVS_LPSRTCMR); +		regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val); +		read2 = val;  		read2 <<= 32; -		read2 |= readl(ioaddr + SNVS_LPSRTCLR); +		regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val); +		read2 |= val;  	} while (read1 != read2);  	/* Convert 47-bit counter to 32-bit raw second count */  	return (u32) (read1 >> CNTR_TO_SECS_SH);  } -static void rtc_write_sync_lp(void __iomem *ioaddr) +static void rtc_write_sync_lp(struct snvs_rtc_data *data)  {  	u32 count1, count2, count3;  	int i; @@ -69,15 +78,15 @@ static void rtc_write_sync_lp(void __iomem *ioaddr)  	/* Wait for 3 CKIL cycles */  	for (i = 0; i < 3; i++) {  		do { -			count1 = readl(ioaddr + SNVS_LPSRTCLR); -			count2 = readl(ioaddr + SNVS_LPSRTCLR); +			regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); +			regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2);  		} while (count1 != count2);  		/* Now wait until counter value changes */  		do {  			do { -				count2 = readl(ioaddr + SNVS_LPSRTCLR); -				count3 = readl(ioaddr + SNVS_LPSRTCLR); +				regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2); +				regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count3);  			} while (count2 != count3);  		} while (count3 == count1);  	} @@ -85,23 +94,14 @@ static void rtc_write_sync_lp(void __iomem *ioaddr)  static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)  { -	unsigned long flags;  	int timeout = 1000;  	u32 lpcr; -	spin_lock_irqsave(&data->lock, flags); - -	lpcr = readl(data->ioaddr + SNVS_LPCR); -	if (enable) -		lpcr |= SNVS_LPCR_SRTC_ENV; -	else -		lpcr &= ~SNVS_LPCR_SRTC_ENV; -	writel(lpcr, data->ioaddr + SNVS_LPCR); - -	spin_unlock_irqrestore(&data->lock, flags); +	regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_SRTC_ENV, +			   enable ? SNVS_LPCR_SRTC_ENV : 0);  	while (--timeout) { -		lpcr = readl(data->ioaddr + SNVS_LPCR); +		regmap_read(data->regmap, data->offset + SNVS_LPCR, &lpcr);  		if (enable) {  			if (lpcr & SNVS_LPCR_SRTC_ENV) @@ -121,7 +121,7 @@ static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)  static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)  {  	struct snvs_rtc_data *data = dev_get_drvdata(dev); -	unsigned long time = rtc_read_lp_counter(data->ioaddr); +	unsigned long time = rtc_read_lp_counter(data);  	rtc_time_to_tm(time, tm); @@ -139,8 +139,8 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)  	snvs_rtc_enable(data, false);  	/* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */ -	writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR); -	writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR); +	regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH); +	regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH));  	/* Enable RTC again */  	snvs_rtc_enable(data, true); @@ -153,10 +153,10 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)  	struct snvs_rtc_data *data = dev_get_drvdata(dev);  	u32 lptar, lpsr; -	lptar = readl(data->ioaddr + SNVS_LPTAR); +	regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar);  	rtc_time_to_tm(lptar, &alrm->time); -	lpsr = readl(data->ioaddr + SNVS_LPSR); +	regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);  	alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;  	return 0; @@ -165,21 +165,12 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)  static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)  {  	struct snvs_rtc_data *data = dev_get_drvdata(dev); -	u32 lpcr; -	unsigned long flags; - -	spin_lock_irqsave(&data->lock, flags); -	lpcr = readl(data->ioaddr + SNVS_LPCR); -	if (enable) -		lpcr |= (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN); -	else -		lpcr &= ~(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN); -	writel(lpcr, data->ioaddr + SNVS_LPCR); +	regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, +			   (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN), +			   enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0); -	spin_unlock_irqrestore(&data->lock, flags); - -	rtc_write_sync_lp(data->ioaddr); +	rtc_write_sync_lp(data);  	return 0;  } @@ -189,24 +180,14 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)  	struct snvs_rtc_data *data = dev_get_drvdata(dev);  	struct rtc_time *alrm_tm = &alrm->time;  	unsigned long time; -	unsigned long flags; -	u32 lpcr;  	rtc_tm_to_time(alrm_tm, &time); -	spin_lock_irqsave(&data->lock, flags); - -	/* Have to clear LPTA_EN before programming new alarm time in LPTAR */ -	lpcr = readl(data->ioaddr + SNVS_LPCR); -	lpcr &= ~SNVS_LPCR_LPTA_EN; -	writel(lpcr, data->ioaddr + SNVS_LPCR); - -	spin_unlock_irqrestore(&data->lock, flags); - -	writel(time, data->ioaddr + SNVS_LPTAR); +	regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0); +	regmap_write(data->regmap, data->offset + SNVS_LPTAR, time);  	/* Clear alarm interrupt status bit */ -	writel(SNVS_LPSR_LPTA, data->ioaddr + SNVS_LPSR); +	regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA);  	return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);  } @@ -226,7 +207,7 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)  	u32 lpsr;  	u32 events = 0; -	lpsr = readl(data->ioaddr + SNVS_LPSR); +	regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);  	if (lpsr & SNVS_LPSR_LPTA) {  		events |= (RTC_AF | RTC_IRQF); @@ -238,25 +219,48 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)  	}  	/* clear interrupt status */ -	writel(lpsr, data->ioaddr + SNVS_LPSR); +	regmap_write(data->regmap, data->offset + SNVS_LPSR, lpsr);  	return events ? IRQ_HANDLED : IRQ_NONE;  } +static const struct regmap_config snvs_rtc_config = { +	.reg_bits = 32, +	.val_bits = 32, +	.reg_stride = 4, +}; +  static int snvs_rtc_probe(struct platform_device *pdev)  {  	struct snvs_rtc_data *data;  	struct resource *res;  	int ret; +	void __iomem *mmio;  	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);  	if (!data)  		return -ENOMEM; -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	data->ioaddr = devm_ioremap_resource(&pdev->dev, res); -	if (IS_ERR(data->ioaddr)) -		return PTR_ERR(data->ioaddr); +	data->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap"); + +	if (IS_ERR(data->regmap)) { +		dev_warn(&pdev->dev, "snvs rtc: you use old dts file, please update it\n"); +		res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + +		mmio = devm_ioremap_resource(&pdev->dev, res); +		if (IS_ERR(mmio)) +			return PTR_ERR(mmio); + +		data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config); +	} else { +		data->offset = SNVS_LPREGISTER_OFFSET; +		of_property_read_u32(pdev->dev.of_node, "offset", &data->offset); +	} + +	if (!data->regmap) { +		dev_err(&pdev->dev, "Can't find snvs syscon\n"); +		return -ENODEV; +	}  	data->irq = platform_get_irq(pdev, 0);  	if (data->irq < 0) @@ -276,13 +280,11 @@ static int snvs_rtc_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, data); -	spin_lock_init(&data->lock); -  	/* Initialize glitch detect */ -	writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR); +	regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT);  	/* Clear interrupt status */ -	writel(0xffffffff, data->ioaddr + SNVS_LPSR); +	regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff);  	/* Enable RTC */  	snvs_rtc_enable(data, true); diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c index 3f9d0acb81c7..74c0a336ceea 100644 --- a/drivers/rtc/rtc-st-lpc.c +++ b/drivers/rtc/rtc-st-lpc.c @@ -208,7 +208,7 @@ static int st_rtc_probe(struct platform_device *pdev)  		return -EINVAL;  	} -	/* LPC can either run in RTC or WDT mode */ +	/* LPC can either run as a Clocksource or in RTC or WDT mode */  	if (mode != ST_LPC_MODE_RTC)  		return -ENODEV; diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 0e93b714ee41..ba6a83b5b5c9 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -254,7 +254,7 @@ static ssize_t stk17ta8_nvram_read(struct file *filp, struct kobject *kobj,  	void __iomem *ioaddr = pdata->ioaddr;  	ssize_t count; -	for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) +	for (count = 0; count < size; count++)  		*buf++ = readb(ioaddr + pos++);  	return count;  } @@ -269,7 +269,7 @@ static ssize_t stk17ta8_nvram_write(struct file *filp, struct kobject *kobj,  	void __iomem *ioaddr = pdata->ioaddr;  	ssize_t count; -	for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) +	for (count = 0; count < size; count++)  		writeb(*buf++, ioaddr + pos++);  	return count;  } diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index babd43bf3ddc..7273855ed02e 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c @@ -122,20 +122,8 @@ hctosys_show(struct device *dev, struct device_attribute *attr, char *buf)  }  static DEVICE_ATTR_RO(hctosys); -static struct attribute *rtc_attrs[] = { -	&dev_attr_name.attr, -	&dev_attr_date.attr, -	&dev_attr_time.attr, -	&dev_attr_since_epoch.attr, -	&dev_attr_max_user_freq.attr, -	&dev_attr_hctosys.attr, -	NULL, -}; -ATTRIBUTE_GROUPS(rtc); -  static ssize_t -rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, -		char *buf) +wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf)  {  	ssize_t retval;  	unsigned long alarm; @@ -159,7 +147,7 @@ rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr,  }  static ssize_t -rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr, +wakealarm_store(struct device *dev, struct device_attribute *attr,  		const char *buf, size_t n)  {  	ssize_t retval; @@ -221,45 +209,57 @@ rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr,  	retval = rtc_set_alarm(rtc, &alm);  	return (retval < 0) ? retval : n;  } -static DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR, -		rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm); +static DEVICE_ATTR_RW(wakealarm); +static struct attribute *rtc_attrs[] = { +	&dev_attr_name.attr, +	&dev_attr_date.attr, +	&dev_attr_time.attr, +	&dev_attr_since_epoch.attr, +	&dev_attr_max_user_freq.attr, +	&dev_attr_hctosys.attr, +	&dev_attr_wakealarm.attr, +	NULL, +};  /* The reason to trigger an alarm with no process watching it (via sysfs)   * is its side effect:  waking from a system state like suspend-to-RAM or   * suspend-to-disk.  So: no attribute unless that side effect is possible.   * (Userspace may disable that mechanism later.)   */ -static inline int rtc_does_wakealarm(struct rtc_device *rtc) +static bool rtc_does_wakealarm(struct rtc_device *rtc)  {  	if (!device_can_wakeup(rtc->dev.parent)) -		return 0; +		return false; +  	return rtc->ops->set_alarm != NULL;  } - -void rtc_sysfs_add_device(struct rtc_device *rtc) +static umode_t rtc_attr_is_visible(struct kobject *kobj, +				   struct attribute *attr, int n)  { -	int err; +	struct device *dev = container_of(kobj, struct device, kobj); +	struct rtc_device *rtc = to_rtc_device(dev); +	umode_t mode = attr->mode; -	/* not all RTCs support both alarms and wakeup */ -	if (!rtc_does_wakealarm(rtc)) -		return; +	if (attr == &dev_attr_wakealarm.attr) +		if (!rtc_does_wakealarm(rtc)) +			mode = 0; -	err = device_create_file(&rtc->dev, &dev_attr_wakealarm); -	if (err) -		dev_err(rtc->dev.parent, -			"failed to create alarm attribute, %d\n", err); +	return mode;  } -void rtc_sysfs_del_device(struct rtc_device *rtc) -{ -	/* REVISIT did we add it successfully? */ -	if (rtc_does_wakealarm(rtc)) -		device_remove_file(&rtc->dev, &dev_attr_wakealarm); -} +static struct attribute_group rtc_attr_group = { +	.is_visible	= rtc_attr_is_visible, +	.attrs		= rtc_attrs, +}; + +static const struct attribute_group *rtc_attr_groups[] = { +	&rtc_attr_group, +	NULL +}; -void __init rtc_sysfs_init(struct class *rtc_class) +const struct attribute_group **rtc_get_dev_attribute_groups(void)  { -	rtc_class->dev_groups = rtc_groups; +	return rtc_attr_groups;  } diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index cb7f94ede516..560d9a5e0225 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -199,8 +199,7 @@ static ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj,  	ssize_t count;  	spin_lock_irq(&pdata->lock); -	for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; -	     count++, size--) { +	for (count = 0; count < size; count++) {  		__raw_writel(pos++, &rtcreg->adr);  		*buf++ = __raw_readl(&rtcreg->dat);  	} @@ -218,8 +217,7 @@ static ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj,  	ssize_t count;  	spin_lock_irq(&pdata->lock); -	for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; -	     count++, size--) { +	for (count = 0; count < size; count++) {  		__raw_writel(pos++, &rtcreg->adr);  		__raw_writel(*buf++, &rtcreg->dat);  	} diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index a58b6d17e6f0..27e896995e9b 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c @@ -271,6 +271,7 @@ static const struct of_device_id wmt_dt_ids[] = {  	{ .compatible = "via,vt8500-rtc", },  	{}  }; +MODULE_DEVICE_TABLE(of, wmt_dt_ids);  static struct platform_driver vt8500_rtc_driver = {  	.probe		= vt8500_rtc_probe, diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c new file mode 100644 index 000000000000..8b28762f06df --- /dev/null +++ b/drivers/rtc/rtc-zynqmp.c @@ -0,0 +1,279 @@ +/* + * Xilinx Zynq Ultrascale+ MPSoC Real Time Clock Driver + * + * Copyright (C) 2015 Xilinx, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> + +/* RTC Registers */ +#define RTC_SET_TM_WR		0x00 +#define RTC_SET_TM_RD		0x04 +#define RTC_CALIB_WR		0x08 +#define RTC_CALIB_RD		0x0C +#define RTC_CUR_TM		0x10 +#define RTC_CUR_TICK		0x14 +#define RTC_ALRM		0x18 +#define RTC_INT_STS		0x20 +#define RTC_INT_MASK		0x24 +#define RTC_INT_EN		0x28 +#define RTC_INT_DIS		0x2C +#define RTC_CTRL		0x40 + +#define RTC_FR_EN		BIT(20) +#define RTC_FR_DATSHIFT		16 +#define RTC_TICK_MASK		0xFFFF +#define RTC_INT_SEC		BIT(0) +#define RTC_INT_ALRM		BIT(1) +#define RTC_OSC_EN		BIT(24) + +#define RTC_CALIB_DEF		0x198233 +#define RTC_CALIB_MASK		0x1FFFFF +#define RTC_SEC_MAX_VAL		0xFFFFFFFF + +struct xlnx_rtc_dev { +	struct rtc_device	*rtc; +	void __iomem		*reg_base; +	int			alarm_irq; +	int			sec_irq; +}; + +static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); +	unsigned long new_time; + +	new_time = rtc_tm_to_time64(tm); + +	if (new_time > RTC_SEC_MAX_VAL) +		return -EINVAL; + +	writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR); + +	return 0; +} + +static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); + +	rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm); + +	return rtc_valid_tm(tm); +} + +static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); + +	rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time); +	alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM; + +	return 0; +} + +static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled) +{ +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); + +	if (enabled) +		writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN); +	else +		writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS); + +	return 0; +} + +static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); +	unsigned long alarm_time; + +	alarm_time = rtc_tm_to_time64(&alrm->time); + +	if (alarm_time > RTC_SEC_MAX_VAL) +		return -EINVAL; + +	writel((u32)alarm_time, (xrtcdev->reg_base + RTC_ALRM)); + +	xlnx_rtc_alarm_irq_enable(dev, alrm->enabled); + +	return 0; +} + +static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval) +{ +	/* +	 * Based on crystal freq of 33.330 KHz +	 * set the seconds counter and enable, set fractions counter +	 * to default value suggested as per design spec +	 * to correct RTC delay in frequency over period of time. +	 */ +	calibval &= RTC_CALIB_MASK; +	writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); +} + +static const struct rtc_class_ops xlnx_rtc_ops = { +	.set_time	  = xlnx_rtc_set_time, +	.read_time	  = xlnx_rtc_read_time, +	.read_alarm	  = xlnx_rtc_read_alarm, +	.set_alarm	  = xlnx_rtc_set_alarm, +	.alarm_irq_enable = xlnx_rtc_alarm_irq_enable, +}; + +static irqreturn_t xlnx_rtc_interrupt(int irq, void *id) +{ +	struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *)id; +	unsigned int status; + +	status = readl(xrtcdev->reg_base + RTC_INT_STS); +	/* Check if interrupt asserted */ +	if (!(status & (RTC_INT_SEC | RTC_INT_ALRM))) +		return IRQ_NONE; + +	/* Clear interrupt */ +	writel(status, xrtcdev->reg_base + RTC_INT_STS); + +	if (status & RTC_INT_SEC) +		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF); +	if (status & RTC_INT_ALRM) +		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF); + +	return IRQ_HANDLED; +} + +static int xlnx_rtc_probe(struct platform_device *pdev) +{ +	struct xlnx_rtc_dev *xrtcdev; +	struct resource *res; +	int ret; +	unsigned int calibvalue; + +	xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL); +	if (!xrtcdev) +		return -ENOMEM; + +	platform_set_drvdata(pdev, xrtcdev); + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + +	xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(xrtcdev->reg_base)) +		return PTR_ERR(xrtcdev->reg_base); + +	xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm"); +	if (xrtcdev->alarm_irq < 0) { +		dev_err(&pdev->dev, "no irq resource\n"); +		return xrtcdev->alarm_irq; +	} +	ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq, +			       xlnx_rtc_interrupt, 0, +			       dev_name(&pdev->dev), xrtcdev); +	if (ret) { +		dev_err(&pdev->dev, "request irq failed\n"); +		return ret; +	} + +	xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec"); +	if (xrtcdev->sec_irq < 0) { +		dev_err(&pdev->dev, "no irq resource\n"); +		return xrtcdev->sec_irq; +	} +	ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq, +			       xlnx_rtc_interrupt, 0, +			       dev_name(&pdev->dev), xrtcdev); +	if (ret) { +		dev_err(&pdev->dev, "request irq failed\n"); +		return ret; +	} + +	ret = of_property_read_u32(pdev->dev.of_node, "calibration", +				   &calibvalue); +	if (ret) +		calibvalue = RTC_CALIB_DEF; + +	xlnx_init_rtc(xrtcdev, calibvalue); + +	device_init_wakeup(&pdev->dev, 1); + +	xrtcdev->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, +					 &xlnx_rtc_ops, THIS_MODULE); +	return PTR_ERR_OR_ZERO(xrtcdev->rtc); +} + +static int xlnx_rtc_remove(struct platform_device *pdev) +{ +	xlnx_rtc_alarm_irq_enable(&pdev->dev, 0); +	device_init_wakeup(&pdev->dev, 0); + +	return 0; +} + +static int __maybe_unused xlnx_rtc_suspend(struct device *dev) +{ +	struct platform_device *pdev = to_platform_device(dev); +	struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev); + +	if (device_may_wakeup(&pdev->dev)) +		enable_irq_wake(xrtcdev->alarm_irq); +	else +		xlnx_rtc_alarm_irq_enable(dev, 0); + +	return 0; +} + +static int __maybe_unused xlnx_rtc_resume(struct device *dev) +{ +	struct platform_device *pdev = to_platform_device(dev); +	struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev); + +	if (device_may_wakeup(&pdev->dev)) +		disable_irq_wake(xrtcdev->alarm_irq); +	else +		xlnx_rtc_alarm_irq_enable(dev, 1); + +	return 0; +} + +static SIMPLE_DEV_PM_OPS(xlnx_rtc_pm_ops, xlnx_rtc_suspend, xlnx_rtc_resume); + +static const struct of_device_id xlnx_rtc_of_match[] = { +	{.compatible = "xlnx,zynqmp-rtc" }, +	{ } +}; +MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match); + +static struct platform_driver xlnx_rtc_driver = { +	.probe		= xlnx_rtc_probe, +	.remove		= xlnx_rtc_remove, +	.driver		= { +		.name	= KBUILD_MODNAME, +		.pm	= &xlnx_rtc_pm_ops, +		.of_match_table	= xlnx_rtc_of_match, +	}, +}; + +module_platform_driver(xlnx_rtc_driver); + +MODULE_DESCRIPTION("Xilinx Zynq MPSoC RTC driver"); +MODULE_AUTHOR("Xilinx Inc."); +MODULE_LICENSE("GPL v2");  |