rtc: max77620: add support to disable time prints in suspend/resume
Laxman Dewangan [Tue, 10 Nov 2015 09:01:25 +0000 (14:01 +0530)]
Add support to disable time prints in suspend/resume
to speedup the suspend/resume execution.

MAX77620 takes 16ms to read the timer register which impact
the suspend/resume KPIs.

The print can be disabled by adding property
maxim,disable-time-print-suspend-resume

Also it can be enabled/disabled by the sysfs interface
time_display_suspend at
/sys/devices/platform/7000d000.i2c/i2c-4/4-003c/max77620-rtc.1

To see the current state
cat time_display_suspend
To disable
echo 0 > time_display_suspend
To enable
echo 1 > time_display_suspend

bug 200148303

Change-Id: Icf08810e85ae9e8abed37cde4d251bfda6b51ac5
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/831225
GVS: Gerrit_Virtual_Submit

Documentation/devicetree/bindings/mfd/max77620.txt
drivers/rtc/rtc-max77620.c

index cd9bcd9..77addc0 100644 (file)
@@ -61,6 +61,16 @@ Optinal properties:
        -maxim,enable-global-lpm: Enable global LPM when the external control goes from
                        HIGH to LOW.
 
+RTC:
+====
+Device support RTC. The driver displaysthe alarm time in suspend and current
+time in resume. The option is provided through DT to avoid this prints.
+Optional properties:
+       - maxim,disable-time-print-suspend-resume: Disable time display
+               in suspend and resume in RTC driver. This will reduce the
+               suspend/resume delay as RTC register read is 16ms delay by
+               HW.
+
 Pinmux and GPIO:
 ===============
 Device has 8 GPIO pins which can be configured as GPIO as well as the special IO
index 7ee9136..4ebfbef 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/rtc.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/mfd/max77620.h>
 
 #define MAX77620_RTC60S_MASK           (1 << 0)
@@ -74,6 +76,7 @@ struct max77620_rtc {
        struct mutex io_lock;
        int irq;
        u8 irq_mask;
+       bool disable_time_display_in_suspend;
 };
 
 static inline struct device *_to_parent(struct max77620_rtc *rtc)
@@ -492,9 +495,50 @@ static int max77620_rtc_preinit(struct max77620_rtc *rtc)
        return 0;
 }
 
+
+static ssize_t max77620_rtc_set_time_display_suspend(struct device *dev,
+               struct device_attribute *attr,
+                const char *buf, size_t count)
+{
+       struct max77620_rtc *rtc = dev_get_drvdata(dev);
+
+       if (sysfs_streq(buf, "enabled\n") || sysfs_streq(buf, "1"))
+               rtc->disable_time_display_in_suspend = false;
+       else if (sysfs_streq(buf, "disabled\n") || sysfs_streq(buf, "0"))
+               rtc->disable_time_display_in_suspend = true;
+       else
+               dev_err(dev, "Configuring invalid mode\n");
+       return count;
+}
+
+static ssize_t max77620_rtc_show_time_display_suspend(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct max77620_rtc *rtc = dev_get_drvdata(dev);
+
+       if (rtc->disable_time_display_in_suspend)
+               return sprintf(buf, "disabled\n");
+       return sprintf(buf, "enabled\n");
+}
+
+static DEVICE_ATTR(time_display_suspend, 0444,
+               max77620_rtc_show_time_display_suspend,
+               max77620_rtc_set_time_display_suspend);
+
+static struct attribute *max77620_rtc_attributes[] = {
+       &dev_attr_time_display_suspend.attr,
+       NULL,
+};
+
+static const struct attribute_group max77620_rtc_attr_group = {
+       .attrs  = max77620_rtc_attributes,
+};
+
 static int max77620_rtc_probe(struct platform_device *pdev)
 {
        static struct max77620_rtc *rtc;
+       struct device_node *np = pdev->dev.parent->of_node;
+
        int ret = 0;
 
        rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
@@ -507,6 +551,15 @@ static int max77620_rtc_probe(struct platform_device *pdev)
        rtc->dev = &pdev->dev;
        mutex_init(&rtc->io_lock);
 
+       rtc->disable_time_display_in_suspend = of_property_read_bool(np,
+                               "maxim,disable-time-print-suspend-resume");
+
+       ret = sysfs_create_group(&pdev->dev.kobj, &max77620_rtc_attr_group);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "probe: Failed to create sysfs\n");
+               return ret;
+       }
+
        ret = max77620_rtc_preinit(rtc);
        if (ret) {
                dev_err(&pdev->dev, "probe: Failed to rtc preinit\n");
@@ -562,6 +615,9 @@ static int max77620_rtc_suspend(struct device *dev)
                struct rtc_wkalrm alm;
 
                enable_irq_wake(max77620_rtc->irq);
+               if (max77620_rtc->disable_time_display_in_suspend)
+                       return 0;
+
                ret = max77620_rtc_read_alarm(dev, &alm);
                if (!ret)
                        dev_info(dev, "%s() alrm %d time %d %d %d %d %d %d\n",
@@ -583,6 +639,10 @@ static int max77620_rtc_resume(struct device *dev)
                int ret;
 
                disable_irq_wake(max77620_rtc->irq);
+
+               if (max77620_rtc->disable_time_display_in_suspend)
+                       return 0;
+
                ret = max77620_rtc_read_time(dev, &tm);
                if (!ret)
                        dev_info(dev, "%s() %d %d %d %d %d %d\n",