drivers: rtc-pm8058: Fix automatic wakeup of APPS due to RTC alarm.
Alarm interrupt causes automatic wakeup even when the phone is in powerdown state. CRs-Fixed: 286086 Signed-off-by: Ashay Jaiswal <ashayj@codeaurora.org>
This commit is contained in:
committed by
Bryan Huntsman
parent
ba345d5b68
commit
4d1ab557f0
@@ -21,6 +21,7 @@
|
|||||||
#include <linux/input/pmic8058-keypad.h>
|
#include <linux/input/pmic8058-keypad.h>
|
||||||
#include <linux/pmic8058-batt-alarm.h>
|
#include <linux/pmic8058-batt-alarm.h>
|
||||||
#include <linux/pmic8058-pwrkey.h>
|
#include <linux/pmic8058-pwrkey.h>
|
||||||
|
#include <linux/rtc/rtc-pm8058.h>
|
||||||
#include <linux/pmic8058-vibrator.h>
|
#include <linux/pmic8058-vibrator.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
#include <linux/pmic8058-othc.h>
|
#include <linux/pmic8058-othc.h>
|
||||||
@@ -5772,6 +5773,10 @@ static struct resource resources_rtc[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct pm8058_rtc_platform_data pm8058_rtc_pdata = {
|
||||||
|
.rtc_alarm_powerup = false,
|
||||||
|
};
|
||||||
|
|
||||||
static struct pmic8058_led pmic8058_flash_leds[] = {
|
static struct pmic8058_led pmic8058_flash_leds[] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.name = "camera:flash0",
|
.name = "camera:flash0",
|
||||||
@@ -5925,6 +5930,7 @@ static struct mfd_cell pm8058_subdevs[] = {
|
|||||||
.id = -1,
|
.id = -1,
|
||||||
.num_resources = ARRAY_SIZE(resources_rtc),
|
.num_resources = ARRAY_SIZE(resources_rtc),
|
||||||
.resources = resources_rtc,
|
.resources = resources_rtc,
|
||||||
|
.platform_data = &pm8058_rtc_pdata,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "pm8058-tm",
|
.name = "pm8058-tm",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#define PM8058_RTC_CTRL 0x1E8
|
#define PM8058_RTC_CTRL 0x1E8
|
||||||
#define PM8058_RTC_ENABLE BIT(7)
|
#define PM8058_RTC_ENABLE BIT(7)
|
||||||
#define PM8058_RTC_ALARM_ENABLE BIT(1)
|
#define PM8058_RTC_ALARM_ENABLE BIT(1)
|
||||||
|
#define PM8058_RTC_ABORT_ENABLE BIT(0)
|
||||||
#define PM8058_RTC_ALARM_CTRL 0x1E9
|
#define PM8058_RTC_ALARM_CTRL 0x1E9
|
||||||
#define PM8058_RTC_ALARM_CLEAR BIT(0)
|
#define PM8058_RTC_ALARM_CLEAR BIT(0)
|
||||||
#define PM8058_RTC_TEST 0x1F6
|
#define PM8058_RTC_TEST 0x1F6
|
||||||
@@ -423,36 +424,36 @@ static int __devinit pm8058_rtc_probe(struct platform_device *pdev)
|
|||||||
goto fail_rtc_enable;
|
goto fail_rtc_enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(reg & PM8058_RTC_ENABLE)) {
|
/* Enable RTC, ABORT enable and disable alarm */
|
||||||
/* Enable RTC, clear alarm register */
|
reg |= ((PM8058_RTC_ENABLE | PM8058_RTC_ABORT_ENABLE) &
|
||||||
reg |= PM8058_RTC_ENABLE;
|
~PM8058_RTC_ALARM_ENABLE);
|
||||||
reg &= ~PM8058_RTC_ALARM_ENABLE;
|
|
||||||
rc = pm8058_write(pm_chip, PM8058_RTC_CTRL, ®, 1);
|
|
||||||
if (rc < 0) {
|
|
||||||
pr_err("%s: PM8058 write failed\n", __func__);
|
|
||||||
goto fail_rtc_enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear RTC alarm register */
|
rc = pm8058_write(pm_chip, PM8058_RTC_CTRL, ®, 1);
|
||||||
rc = pm8058_read(rtc_dd->pm_chip, PM8058_RTC_ALARM_CTRL,
|
if (rc < 0) {
|
||||||
®_alarm, 1);
|
pr_err("%s: PM8058 write failed\n", __func__);
|
||||||
if (rc < 0) {
|
goto fail_rtc_enable;
|
||||||
pr_err("%s: PM8058 read failed\n", __func__);
|
|
||||||
goto fail_rtc_enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_alarm &= ~PM8058_RTC_ALARM_CLEAR;
|
|
||||||
rc = pm8058_write(rtc_dd->pm_chip, PM8058_RTC_ALARM_CTRL,
|
|
||||||
®_alarm, 1);
|
|
||||||
if (rc < 0) {
|
|
||||||
pr_err("%s: PM8058 write failed\n", __func__);
|
|
||||||
goto fail_rtc_enable;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear RTC alarm control register */
|
||||||
|
rc = pm8058_read(rtc_dd->pm_chip, PM8058_RTC_ALARM_CTRL,
|
||||||
|
®_alarm, 1);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("%s: PM8058 read failed\n", __func__);
|
||||||
|
goto fail_rtc_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_alarm &= ~PM8058_RTC_ALARM_CLEAR;
|
||||||
|
rc = pm8058_write(rtc_dd->pm_chip, PM8058_RTC_ALARM_CTRL,
|
||||||
|
®_alarm, 1);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("%s: PM8058 write failed\n", __func__);
|
||||||
|
goto fail_rtc_enable;
|
||||||
|
}
|
||||||
|
|
||||||
rtc_dd->rtc_ctrl_reg = reg;
|
rtc_dd->rtc_ctrl_reg = reg;
|
||||||
|
|
||||||
#ifdef CONFIG_RTC_PM8058_WRITE_ENABLE
|
#ifdef CONFIG_RTC_PM8058_WRITE_ENABLE
|
||||||
pm8058_rtc0_ops.set_time = pm8058_rtc0_set_time,
|
pm8058_rtc0_ops.set_time = pm8058_rtc0_set_time;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Register the RTC device */
|
/* Register the RTC device */
|
||||||
@@ -533,9 +534,48 @@ static int __devexit pm8058_rtc_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pm8058_rtc_shutdown(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
u8 reg;
|
||||||
|
int rc, i;
|
||||||
|
bool rtc_alarm_powerup = false;
|
||||||
|
struct pm8058_rtc *rtc_dd = platform_get_drvdata(pdev);
|
||||||
|
struct pm8058_rtc_platform_data *pdata = pdev->dev.platform_data;
|
||||||
|
|
||||||
|
if (pdata != NULL)
|
||||||
|
rtc_alarm_powerup = pdata->rtc_alarm_powerup;
|
||||||
|
|
||||||
|
if (!rtc_alarm_powerup) {
|
||||||
|
|
||||||
|
dev_dbg(&pdev->dev, "Disabling alarm interrupts\n");
|
||||||
|
|
||||||
|
/* Disable RTC alarms */
|
||||||
|
reg = rtc_dd->rtc_ctrl_reg;
|
||||||
|
reg &= ~PM8058_RTC_ALARM_ENABLE;
|
||||||
|
rc = pm8058_write(rtc_dd->pm_chip, PM8058_RTC_CTRL, ®, 1);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("%s: PM8058 write failed\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear Alarm register */
|
||||||
|
reg = 0x0;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
rc = pm8058_write(rtc_dd->pm_chip,
|
||||||
|
PM8058_RTC_ALARM_BASE + i, ®, 1);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("%s: PM8058 write failed\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct platform_driver pm8058_rtc_driver = {
|
static struct platform_driver pm8058_rtc_driver = {
|
||||||
.probe = pm8058_rtc_probe,
|
.probe = pm8058_rtc_probe,
|
||||||
.remove = __devexit_p(pm8058_rtc_remove),
|
.remove = __devexit_p(pm8058_rtc_remove),
|
||||||
|
.shutdown = pm8058_rtc_shutdown,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "pm8058-rtc",
|
.name = "pm8058-rtc",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
|
/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
#ifndef __RTC_PM8058_H__
|
#ifndef __RTC_PM8058_H__
|
||||||
#define __RTC_PM8058_H__
|
#define __RTC_PM8058_H__
|
||||||
|
|
||||||
struct pm8058_rtc_pdata {
|
struct pm8058_rtc_platform_data {
|
||||||
bool rtc_write_enable;
|
bool rtc_alarm_powerup;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __RTC_PM8058_H__ */
|
#endif /* __RTC_PM8058_H__ */
|
||||||
|
|||||||
Reference in New Issue
Block a user