aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Demeter <michael.demeter@intel.com>2012-01-26 12:40:27 -0500
committerMatthew Garrett <mjg@redhat.com>2012-03-20 12:02:26 -0400
commit7714567c87f43862d3d7049ed2907567be3e50c3 (patch)
tree10124759f2e8515333ed65eae316912352c274a7 /drivers
parentf39eaa674bc3747c94abadbc46b6d389953e64b8 (diff)
intel_mid_powerbtn: use MSIC read/write instead of ipc_scu
In the 2.6.36 kernel we did not have the MSIC driver. Changed all ipc_scu_reads/writes to use the MSIC driver and defines. Added a fix from the 2.6.36 kernel where the SCU FW could send a power button interrupt to the IA32 FW and the kernel was not running yet. This resulted in the interrupt not getting cleared and the power button was ignored. this fix just clears the interrupt on start-up. Signed-off-by: Michael Demeter <michael.demeter@intel.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Revert style-only changes. Remove unused variable. Fix comment style.] Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/intel_mid_powerbtn.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c
index ff3de343b64c..0a3594c7e912 100644
--- a/drivers/platform/x86/intel_mid_powerbtn.c
+++ b/drivers/platform/x86/intel_mid_powerbtn.c
@@ -23,21 +23,27 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/input.h> 25#include <linux/input.h>
26 26#include <linux/mfd/intel_msic.h>
27#include <asm/intel_scu_ipc.h>
28 27
29#define DRIVER_NAME "msic_power_btn" 28#define DRIVER_NAME "msic_power_btn"
30 29
31#define MSIC_PB_STATUS 0x3f
32#define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ 30#define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */
33 31
32/*
33 * MSIC document ti_datasheet defines the 1st bit reg 0x21 is used to mask
34 * power button interrupt
35 */
36#define MSIC_PWRBTNM (1 << 0)
37
34static irqreturn_t mfld_pb_isr(int irq, void *dev_id) 38static irqreturn_t mfld_pb_isr(int irq, void *dev_id)
35{ 39{
36 struct input_dev *input = dev_id; 40 struct input_dev *input = dev_id;
37 int ret; 41 int ret;
38 u8 pbstat; 42 u8 pbstat;
39 43
40 ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); 44 ret = intel_msic_reg_read(INTEL_MSIC_PBSTATUS, &pbstat);
45 dev_dbg(input->dev.parent, "PB_INT status= %d\n", pbstat);
46
41 if (ret < 0) { 47 if (ret < 0) {
42 dev_err(input->dev.parent, "Read error %d while reading" 48 dev_err(input->dev.parent, "Read error %d while reading"
43 " MSIC_PB_STATUS\n", ret); 49 " MSIC_PB_STATUS\n", ret);
@@ -88,6 +94,24 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev)
88 } 94 }
89 95
90 platform_set_drvdata(pdev, input); 96 platform_set_drvdata(pdev, input);
97
98 /*
99 * SCU firmware might send power button interrupts to IA core before
100 * kernel boots and doesn't get EOI from IA core. The first bit of
101 * MSIC reg 0x21 is kept masked, and SCU firmware doesn't send new
102 * power interrupt to Android kernel. Unmask the bit when probing
103 * power button in kernel.
104 * There is a very narrow race between irq handler and power button
105 * initialization. The race happens rarely. So we needn't worry
106 * about it.
107 */
108 error = intel_msic_reg_update(INTEL_MSIC_IRQLVL1MSK, 0, MSIC_PWRBTNM);
109 if (error) {
110 dev_err(&pdev->dev, "Unable to clear power button interrupt, "
111 "error: %d\n", error);
112 goto err_free_irq;
113 }
114
91 return 0; 115 return 0;
92 116
93err_free_irq: 117err_free_irq: