diff options
author | Thomas Bogendoerfer <tbogendoerfer@suse.de> | 2019-10-14 23:46:21 +0200 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2019-10-16 10:39:00 +0200 |
commit | 299b610117a4145dfe15963f0ea037ab319ce531 (patch) | |
tree | 1fb468c08bd358b879ca13210da5ebcf60d43bac /drivers/rtc | |
parent | rtc: ds1685: use devm_platform_ioremap_resource helper (diff) | |
download | linux-299b610117a4145dfe15963f0ea037ab319ce531.tar.xz linux-299b610117a4145dfe15963f0ea037ab319ce531.zip |
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 <tbogendoerfer@suse.de>
Acked-by: Joshua Kinard <kumba@gentoo.org>
Reviewed-by: Joshua Kinard <kumba@gentoo.org>
Link: https://lore.kernel.org/r/20191014214621.25257-1-tbogendoerfer@suse.de
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-ds1685.c | 78 |
1 files changed, 52 insertions, 26 deletions
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; |