From f00eaa38eb0c7185ffff51c5288d00af9032e354 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 7 Oct 2019 15:47:15 +0200 Subject: rtc: add a timestamp for year 0 A few RTCs handle dates from year 0 to year 9999. Add a timestamp even if years before 1970 will probably never be used. Link: https://lore.kernel.org/r/20191007134724.15505-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- include/linux/rtc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/rtc.h b/include/linux/rtc.h index df666cf29ef1..2680f9b2b119 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -160,6 +160,7 @@ struct rtc_device { #define to_rtc_device(d) container_of(d, struct rtc_device, dev) /* useful timestamps */ +#define RTC_TIMESTAMP_BEGIN_0000 -62167219200ULL /* 0000-01-01 00:00:00 */ #define RTC_TIMESTAMP_BEGIN_1900 -2208988800LL /* 1900-01-01 00:00:00 */ #define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */ #define RTC_TIMESTAMP_END_2063 2966371199LL /* 2063-12-31 23:59:59 */ -- cgit v1.2.3 From 9e420d7f125f51ab1eda37497b08c4fad9efe4a8 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Fri, 11 Oct 2019 17:05:43 +0200 Subject: rts: ds1685: remove not needed fields from private struct A few of the fields in struct ds1685_priv aren't needed at all, so we can remove it. Signed-off-by: Thomas Bogendoerfer Acked-by: Joshua Kinard Link: https://lore.kernel.org/r/20191011150546.9186-1-tbogendoerfer@suse.de Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1685.c | 3 --- include/linux/rtc/ds1685.h | 3 --- 2 files changed, 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 184e4a3e2bef..51f568473de8 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -1086,12 +1086,10 @@ ds1685_rtc_probe(struct platform_device *pdev) * Set the base address for the rtc, and ioremap its * registers. */ - rtc->baseaddr = res->start; rtc->regs = devm_ioremap(&pdev->dev, res->start, rtc->size); if (!rtc->regs) return -ENOMEM; } - rtc->alloc_io_resources = pdata->alloc_io_resources; /* Get the register step size. */ if (pdata->regstep > 0) @@ -1271,7 +1269,6 @@ ds1685_rtc_probe(struct platform_device *pdev) /* See if the platform doesn't support UIE. */ if (pdata->uie_unsupported) rtc_dev->uie_unsupported = 1; - rtc->uie_unsupported = pdata->uie_unsupported; rtc->dev = rtc_dev; diff --git a/include/linux/rtc/ds1685.h b/include/linux/rtc/ds1685.h index 43aec568ba7c..b9671d00d964 100644 --- a/include/linux/rtc/ds1685.h +++ b/include/linux/rtc/ds1685.h @@ -43,13 +43,10 @@ struct ds1685_priv { struct rtc_device *dev; void __iomem *regs; u32 regstep; - resource_size_t baseaddr; size_t size; int irq_num; bool bcd_mode; bool no_irq; - bool uie_unsupported; - bool alloc_io_resources; u8 (*read)(struct ds1685_priv *, int); void (*write)(struct ds1685_priv *, int, u8); void (*prepare_poweroff)(void); -- cgit v1.2.3 From af818031f4637b0e8d106fcc9023f1c22c44e13a Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Fri, 11 Oct 2019 17:05:44 +0200 Subject: rtc: ds1685: use devm_platform_ioremap_resource helper Simplify ioremapping of registers by using devm_platform_ioremap_resource. Signed-off-by: Thomas Bogendoerfer Acked-by: Joshua Kinard Link: https://lore.kernel.org/r/20191011150546.9186-2-tbogendoerfer@suse.de Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1685.c | 23 +++-------------------- include/linux/rtc/ds1685.h | 1 - 2 files changed, 3 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 51f568473de8..349a8d1caca1 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -1040,7 +1040,6 @@ static int ds1685_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc_dev; - struct resource *res; struct ds1685_priv *rtc; struct ds1685_rtc_platform_data *pdata; u8 ctrla, ctrlb, hours; @@ -1070,25 +1069,9 @@ ds1685_rtc_probe(struct platform_device *pdev) * that sits behind the IOC3 PCI metadevice. */ if (pdata->alloc_io_resources) { - /* Get the platform resources. */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENXIO; - rtc->size = resource_size(res); - - /* Request a memory region. */ - /* XXX: mmio-only for now. */ - if (!devm_request_mem_region(&pdev->dev, res->start, rtc->size, - pdev->name)) - return -EBUSY; - - /* - * Set the base address for the rtc, and ioremap its - * registers. - */ - rtc->regs = devm_ioremap(&pdev->dev, res->start, rtc->size); - if (!rtc->regs) - return -ENOMEM; + rtc->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(rtc->regs)) + return PTR_ERR(rtc->regs); } /* Get the register step size. */ diff --git a/include/linux/rtc/ds1685.h b/include/linux/rtc/ds1685.h index b9671d00d964..101c7adc05a2 100644 --- a/include/linux/rtc/ds1685.h +++ b/include/linux/rtc/ds1685.h @@ -43,7 +43,6 @@ struct ds1685_priv { struct rtc_device *dev; void __iomem *regs; u32 regstep; - size_t size; int irq_num; bool bcd_mode; bool no_irq; -- cgit v1.2.3 From 299b610117a4145dfe15963f0ea037ab319ce531 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Mon, 14 Oct 2019 23:46:21 +0200 Subject: rtc: ds1685: add indirect access method and remove plat_read/plat_write SGI Octane (IP30) doesn't have RTC register directly mapped into CPU address space, but accesses RTC registers with an address and data register. This is now supported by additional access functions, which are selected by a new field in platform data. Removed plat_read/plat_write since there is no user and their usage could introduce lifetime issue, when functions are placed in different modules. Signed-off-by: Thomas Bogendoerfer Acked-by: Joshua Kinard Reviewed-by: Joshua Kinard Link: https://lore.kernel.org/r/20191014214621.25257-1-tbogendoerfer@suse.de Signed-off-by: Alexandre Belloni --- arch/mips/sgi-ip32/ip32-platform.c | 2 +- drivers/rtc/rtc-ds1685.c | 78 +++++++++++++++++++++++++------------- include/linux/rtc/ds1685.h | 8 ++-- 3 files changed, 58 insertions(+), 30 deletions(-) (limited to 'include/linux') diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c index 5a2a82148d8d..c3909bd8dd1a 100644 --- a/arch/mips/sgi-ip32/ip32-platform.c +++ b/arch/mips/sgi-ip32/ip32-platform.c @@ -115,7 +115,7 @@ ip32_rtc_platform_data[] = { .bcd_mode = true, .no_irq = false, .uie_unsupported = false, - .alloc_io_resources = true, + .access_type = ds1685_reg_direct, .plat_prepare_poweroff = ip32_prepare_poweroff, }, }; diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 349a8d1caca1..98d06b3ee913 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -31,7 +31,10 @@ /* ----------------------------------------------------------------------- */ -/* Standard read/write functions if platform does not provide overrides */ +/* + * Standard read/write + * all registers are mapped in CPU address space + */ /** * ds1685_read - read a value from an rtc register. @@ -59,6 +62,35 @@ ds1685_write(struct ds1685_priv *rtc, int reg, u8 value) } /* ----------------------------------------------------------------------- */ +/* + * Indirect read/write functions + * access happens via address and data register mapped in CPU address space + */ + +/** + * ds1685_indirect_read - read a value from an rtc register. + * @rtc: pointer to the ds1685 rtc structure. + * @reg: the register address to read. + */ +static u8 +ds1685_indirect_read(struct ds1685_priv *rtc, int reg) +{ + writeb(reg, rtc->regs); + return readb(rtc->data); +} + +/** + * ds1685_indirect_write - write a value to an rtc register. + * @rtc: pointer to the ds1685 rtc structure. + * @reg: the register address to write. + * @value: value to write to the register. + */ +static void +ds1685_indirect_write(struct ds1685_priv *rtc, int reg, u8 value) +{ + writeb(reg, rtc->regs); + writeb(value, rtc->data); +} /* ----------------------------------------------------------------------- */ /* Inlined functions */ @@ -1062,42 +1094,36 @@ ds1685_rtc_probe(struct platform_device *pdev) if (!rtc) return -ENOMEM; - /* - * Allocate/setup any IORESOURCE_MEM resources, if required. Not all - * platforms put the RTC in an easy-access place. Like the SGI Octane, - * which attaches the RTC to a "ByteBus", hooked to a SuperIO chip - * that sits behind the IOC3 PCI metadevice. - */ - if (pdata->alloc_io_resources) { + /* Setup resources and access functions */ + switch (pdata->access_type) { + case ds1685_reg_direct: + rtc->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(rtc->regs)) + return PTR_ERR(rtc->regs); + rtc->read = ds1685_read; + rtc->write = ds1685_write; + break; + case ds1685_reg_indirect: rtc->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rtc->regs)) return PTR_ERR(rtc->regs); + rtc->data = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(rtc->data)) + return PTR_ERR(rtc->data); + rtc->read = ds1685_indirect_read; + rtc->write = ds1685_indirect_write; + break; } + if (!rtc->read || !rtc->write) + return -ENXIO; + /* Get the register step size. */ if (pdata->regstep > 0) rtc->regstep = pdata->regstep; else rtc->regstep = 1; - /* Platform read function, else default if mmio setup */ - if (pdata->plat_read) - rtc->read = pdata->plat_read; - else - if (pdata->alloc_io_resources) - rtc->read = ds1685_read; - else - return -ENXIO; - - /* Platform write function, else default if mmio setup */ - if (pdata->plat_write) - rtc->write = pdata->plat_write; - else - if (pdata->alloc_io_resources) - rtc->write = ds1685_write; - else - return -ENXIO; - /* Platform pre-shutdown function, if defined. */ if (pdata->plat_prepare_poweroff) rtc->prepare_poweroff = pdata->plat_prepare_poweroff; diff --git a/include/linux/rtc/ds1685.h b/include/linux/rtc/ds1685.h index 101c7adc05a2..67ee9d20cc5a 100644 --- a/include/linux/rtc/ds1685.h +++ b/include/linux/rtc/ds1685.h @@ -42,6 +42,7 @@ struct ds1685_priv { struct rtc_device *dev; void __iomem *regs; + void __iomem *data; u32 regstep; int irq_num; bool bcd_mode; @@ -70,12 +71,13 @@ struct ds1685_rtc_platform_data { const bool bcd_mode; const bool no_irq; const bool uie_unsupported; - const bool alloc_io_resources; - u8 (*plat_read)(struct ds1685_priv *, int); - void (*plat_write)(struct ds1685_priv *, int, u8); void (*plat_prepare_poweroff)(void); void (*plat_wake_alarm)(void); void (*plat_post_ram_clear)(void); + enum { + ds1685_reg_direct, + ds1685_reg_indirect + } access_type; }; -- cgit v1.2.3 From 8d6ac1cec7251a74c2d2f21e72b842c000206811 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 16 Oct 2019 22:16:22 +0200 Subject: rtc: add timestamp for end of 2199 Some RTCs handle date up to 2199. Link: https://lore.kernel.org/r/20191016201626.31309-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- include/linux/rtc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 2680f9b2b119..e86a9f307b82 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -165,6 +165,7 @@ struct rtc_device { #define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */ #define RTC_TIMESTAMP_END_2063 2966371199LL /* 2063-12-31 23:59:59 */ #define RTC_TIMESTAMP_END_2099 4102444799LL /* 2099-12-31 23:59:59 */ +#define RTC_TIMESTAMP_END_2199 7258118399LL /* 2199-12-31 23:59:59 */ #define RTC_TIMESTAMP_END_9999 253402300799LL /* 9999-12-31 23:59:59 */ extern struct rtc_device *devm_rtc_device_register(struct device *dev, -- cgit v1.2.3 From ae4866884338259318be94fa8f88015cced07000 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 19 Oct 2019 22:50:34 +0200 Subject: rtc: introduce lock helpers Introduce rtc_lock and rtc_unlock to shorten the code when locking and unlocking ops_lock from drivers. Link: https://lore.kernel.org/r/20191019205034.6382-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- include/linux/rtc.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/rtc.h b/include/linux/rtc.h index e86a9f307b82..4e9d3c71addb 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -159,6 +159,9 @@ struct rtc_device { }; #define to_rtc_device(d) container_of(d, struct rtc_device, dev) +#define rtc_lock(d) mutex_lock(&d->ops_lock) +#define rtc_unlock(d) mutex_unlock(&d->ops_lock) + /* useful timestamps */ #define RTC_TIMESTAMP_BEGIN_0000 -62167219200ULL /* 0000-01-01 00:00:00 */ #define RTC_TIMESTAMP_BEGIN_1900 -2208988800LL /* 1900-01-01 00:00:00 */ -- cgit v1.2.3