RTC: Add driver for DS1685 family of real time clocks
PATCH RESEND 1/2 RTC: Add driver for DS1685 family of real time clocks
From: Joshua Kinard <[email protected]>
This adds a driver for the Dallas/Maxim DS1685-family of RTC chips. It supports the DS1685/DS1687, DS1688/DS1691, DS1689/DS1693, DS17285/DS17287, DS17485/DS17487, and DS17885/DS17887 RTC chips. These chips are commonly found in SGI O2 and SGI Octane systems. It was originally derived from a driver patch submitted by Matthias Fuchs many years ago for use in EPPC-405-UC modules, which also used these RTCs. In addition to the time-keeping functions, this RTC also handles the shutdown mechanism of the O2 and Octane and acts as a partial NVRAM for the boot PROMS in these systems.
Verified on both an SGI O2 and an SGI Octane.
--- MAINTAINERS | 6 drivers/rtc/Kconfig | 90 + drivers/rtc/Makefile | 1 drivers/rtc/rtc-ds1685.c | 2252 +++++++++++++++++++++++++++++++++++ include/linux/rtc/ds1685.h | 375 +++++ 5 files changed, 2724 insertions(+) create mode 100644 drivers/rtc/rtc-ds1685.c create mode 100644 include/linux/rtc/ds1685.h
The checkpatch errors regarding "Macros with complex values should be enclosed in parenthesis" should be fine. That macro construct I copied from elsewhere in the kernel, and I don't think wrapping them in parenthesis helps at all. Please let me know of any problems, thanks!
linux-rtc-ds1685.patch
MAINTAINERS +6 -0
@@ -2915,6 +2915,12 @@ S: Supported F: drivers/input/touchscreen/cyttsp* F: include/linux/input/cyttsp.h +DALLAS/MAXIM DS1685-FAMILY REAL TIME CLOCK +M: Joshua Kinard <[email protected]> +S: Maintained +F: drivers/rtc/rtc-ds1685.c +F: include/linux/rtc/ds1685.h + DAMA SLAVE for AX.25 M: Joerg Reuter <[email protected]> W: http://yaina.de/jreuter/
drivers/rtc/Kconfig +90 -0
96 lines not on this page · raw message
drivers/rtc/Makefile +1 -0
@@ -52,6 +52,7 @@ obj-$(CONFIG_RTC_DRV_DS1390) += rtc-ds1390.o obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o +obj-$(CONFIG_RTC_DRV_DS1685_FAMILY) += rtc-ds1685.o obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o
drivers/rtc/rtc-ds1685.c new file +2252 -0
2,252 lines not on this page · raw message
include/linux/rtc/ds1685.h new file +375 -0
375 lines not on this page · raw message
Quoted 18 lines · On Fri, 12 Dec 2014 17:13:38 -0500 Joshua Kinard <[email protected]> wrote:
From: Joshua Kinard <[email protected]>
This adds a driver for the Dallas/Maxim DS1685-family of RTC chips. It supports the DS1685/DS1687, DS1688/DS1691, DS1689/DS1693, DS17285/DS17287, DS17485/DS17487, and DS17885/DS17887 RTC chips. These chips are commonly found in SGI O2 and SGI Octane systems. It was originally derived from a driver patch submitted by Matthias Fuchs many years ago for use in EPPC-405-UC modules, which also used these RTCs. In addition to the time-keeping functions, this RTC also handles the shutdown mechanism of the O2 and Octane and acts as a partial NVRAM for the boot PROMS in these systems.
Verified on both an SGI O2 and an SGI Octane.
...
drivers/rtc/rtc-ds1685.c new file +3
-0+static int +ds1685_rtc_probe (struct platform_device *pdev) +{
drivers/rtc/rtc-ds1685.c line 1837
Quoted 10 lines
drivers/rtc/rtc-ds1685.c new file +10
-0+struct rtc_device *rtc_dev; +struct resource *res; +struct ds1685_priv *rtc; +struct ds1685_rtc_platform_data *pdata; +u8 ctrla, ctrlb, hours; +unsigned char am_pm; +int ret =0 ; + +/* Get the platform data. */ + pdata = (struct ds1685_rtc_platform_data *) pdev->dev.platform_data;
That cast isn't needed.
Quoted 37 lines
drivers/rtc/rtc-ds1685.c new file +37
-0+if (!pdata) +return -ENODEV ; + +/* Allocate memory for the rtc device. */ + rtc =devm_kzalloc (&pdev->dev,sizeof (*rtc),GFP_KERNEL ); +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) { +/* 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->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;
drivers/rtc/rtc-ds1685.c line 1884
Quoted 10 lines
drivers/rtc/rtc-ds1685.c new file +10
-0+ +/* 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;
I'm trying to understand how this works and I'm not getting very far. Perhaps it is the intention that some code(?) is to allocate and populate a ds1685_rtc_platform_data and use platform_device_add_data() on it, but no such code exists.
Or something. What's going on here?
Quoted 34 lines
drivers/rtc/rtc-ds1685.c new file +31
-0+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; + +/* Platform wake_alarm function, if defined. */ +if (pdata->plat_wake_alarm) + rtc->wake_alarm = pdata->plat_wake_alarm; + +/* Platform post_ram_clear function, if defined. */ +if (pdata->plat_post_ram_clear) + rtc->post_ram_clear = pdata->plat_post_ram_clear; + +/* Init the spinlock, workqueue, & set the driver data. */ +spin_lock_init (&rtc->lock); +INIT_WORK (&rtc->work, ds1685_rtc_work_queue); +platform_set_drvdata (pdev, rtc);
Quoted 5 lines · On Mon, 9 Feb 2015 16:18:44 -0800 Andrew Morton <[email protected]>…
drivers/rtc/rtc-ds1685.c line 1884
Quoted 3 lines
drivers/rtc/rtc-ds1685.c new file +3
-0+/* Platform read function, else default if mmio setup */ +if (pdata->plat_read) + rtc->read = pdata->plat_read;I'm trying to understand how this works and I'm not getting very far.
oop, never mind, it's there in patch 2/2.
Quoted 17 lines · Andrew Morton
Quoted 15 lines · On Fri, 12 Dec 2014 17:13:38 -0500 Joshua Kinard <[email protected]> wrote:
From: Joshua Kinard <[email protected]>
This adds a driver for the Dallas/Maxim DS1685-family of RTC chips. It supports the DS1685/DS1687, DS1688/DS1691, DS1689/DS1693, DS17285/DS17287, DS17485/DS17487, and DS17885/DS17887 RTC chips. These chips are commonly found in SGI O2 and SGI Octane systems. It was originally derived from a driver patch submitted by Matthias Fuchs many years ago for use in EPPC-405-UC modules, which also used these RTCs. In addition to the time-keeping functions, this RTC also handles the shutdown mechanism of the O2 and Octane and acts as a partial NVRAM for the boot PROMS in these systems.
Verified on both an SGI O2 and an SGI Octane.
...
Quoted 15 lines
drivers/rtc/rtc-ds1685.c line 1837
Quoted 13 lines
drivers/rtc/rtc-ds1685.c new file +13
-0+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; +unsigned char am_pm; +int ret =0 ; + +/* Get the platform data. */ + pdata = (struct ds1685_rtc_platform_data *) pdev->dev.platform_data;That cast isn't needed.
Huh, I thought GCC complained about that once, but it doesn't now (gcc-4.7.4).
Would you like me to remove it and re-send the patch, even though it looks
like you've added it to -mm?
Quoted 53 lines
Quoted 37 lines
drivers/rtc/rtc-ds1685.c new file +37
-0+if (!pdata) +return -ENODEV ; + +/* Allocate memory for the rtc device. */ + rtc =devm_kzalloc (&pdev->dev,sizeof (*rtc),GFP_KERNEL ); +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) { +/* 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->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;drivers/rtc/rtc-ds1685.c line 1884
Quoted 10 lines
drivers/rtc/rtc-ds1685.c new file +10
-0+ +/* 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;I'm trying to understand how this works and I'm not getting very far. Perhaps it is the intention that some code(?) is to allocate and populate a
ds1685_rtc_platform_dataand useplatform_device_add_data()on it, but no such code exists.
Quoted 1 line
Or something. What's going on here?
Yeah, as you saw in the second patch, this is a mechanism to keep arch or machine-specific code out of a general driver. SGI O2's use MMIO to read/set the RTC (which are the default methods in this patch), but SGI Octane's, whose code is not in-tree yet, use this same RTC (DS1687-5) via PIO access because the RTC is tucked behind the IOC3 PCI Metadevice's "ByteBus" (write an address port, read a data port). Thus, two different methods are needed by each machine to talk to the same RTC driver, so this looked like the best approach, after I looked at a few other drivers.
Quoted 23 lines
Quoted 23 lines
drivers/rtc/rtc-ds1685.c new file +23
-0+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; + +/* Platform wake_alarm function, if defined. */ +if (pdata->plat_wake_alarm) + rtc->wake_alarm = pdata->plat_wake_alarm; +
Quoted 8 lines
drivers/rtc/rtc-ds1685.c line 1915
Quoted 8 lines
drivers/rtc/rtc-ds1685.c new file +8
-0+/* Platform post_ram_clear function, if defined. */ +if (pdata->plat_post_ram_clear) + rtc->post_ram_clear = pdata->plat_post_ram_clear; + +/* Init the spinlock, workqueue, & set the driver data. */ +spin_lock_init (&rtc->lock); +INIT_WORK (&rtc->work, ds1685_rtc_work_queue); +platform_set_drvdata (pdev, rtc);
--J