Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Michael Demeter and committed by
Matthew Garrett
7714567c f39eaa67

+28 -4
+28 -4
drivers/platform/x86/intel_mid_powerbtn.c
··· 23 23 #include <linux/slab.h> 24 24 #include <linux/platform_device.h> 25 25 #include <linux/input.h> 26 - 27 - #include <asm/intel_scu_ipc.h> 26 + #include <linux/mfd/intel_msic.h> 28 27 29 28 #define DRIVER_NAME "msic_power_btn" 30 29 31 - #define MSIC_PB_STATUS 0x3f 32 30 #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ 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) 33 37 34 38 static irqreturn_t mfld_pb_isr(int irq, void *dev_id) 35 39 { ··· 41 37 int ret; 42 38 u8 pbstat; 43 39 44 - ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); 40 + ret = intel_msic_reg_read(INTEL_MSIC_PBSTATUS, &pbstat); 41 + dev_dbg(input->dev.parent, "PB_INT status= %d\n", pbstat); 42 + 45 43 if (ret < 0) { 46 44 dev_err(input->dev.parent, "Read error %d while reading" 47 45 " MSIC_PB_STATUS\n", ret); ··· 94 88 } 95 89 96 90 platform_set_drvdata(pdev, input); 91 + 92 + /* 93 + * SCU firmware might send power button interrupts to IA core before 94 + * kernel boots and doesn't get EOI from IA core. The first bit of 95 + * MSIC reg 0x21 is kept masked, and SCU firmware doesn't send new 96 + * power interrupt to Android kernel. Unmask the bit when probing 97 + * power button in kernel. 98 + * There is a very narrow race between irq handler and power button 99 + * initialization. The race happens rarely. So we needn't worry 100 + * about it. 101 + */ 102 + error = intel_msic_reg_update(INTEL_MSIC_IRQLVL1MSK, 0, MSIC_PWRBTNM); 103 + if (error) { 104 + dev_err(&pdev->dev, "Unable to clear power button interrupt, " 105 + "error: %d\n", error); 106 + goto err_free_irq; 107 + } 108 + 97 109 return 0; 98 110 99 111 err_free_irq: