Skip to content

Commit 54c5848

Browse files
jwrdegoedezhang-rui
authored andcommitted
Thermal: Intel SoC DTS: Translate IO-APIC GSI number to linux irq number
The Intel SoC DTS uses a hardcoded GSI number, before this commit it was passing it to request_irq as if it were a linux irq number, but there is no 1:1 mapping so in essence it was requesting a random interrupt. Besides this causing the DTS driver to not actually get an interrupt if the thermal thresholds are exceeded this also is causing an interrupt conflict on some devices since the linux irq 86 which is being requested is already in use, leading to oopses like this: genirq: Flags mismatch irq 86. 00002001 (soc_dts) vs. 00000083 (volume_down) CPU: 0 PID: 601 Comm: systemd-udevd Tainted: G C OE 4.17.0-rc6+ #45 Hardware name: Insyde i86/Type2 - Board Product Name, BIOS CHUWI.D86JLBNR03 01/14/2015 Call Trace: dump_stack+0x5c/0x80 __setup_irq.cold.50+0x4e/0xac ? request_threaded_irq+0xad/0x160 request_threaded_irq+0xf5/0x160 ? 0xffffffffc0a93000 intel_soc_thermal_init+0x74/0x1000 [intel_soc_dts_thermal] This commit makes the intel_soc_dts_thermal.c code call acpi_register_gsi() to translate the hardcoded IO-APIC GSI number (86) to a linux irq, so that the dts code uses the right interrupt and we no longer get an oops about an irq conflict. Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Zhang Rui <[email protected]>
1 parent d72e90f commit 54c5848

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

drivers/thermal/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ config INTEL_SOC_DTS_IOSF_CORE
360360

361361
config INTEL_SOC_DTS_THERMAL
362362
tristate "Intel SoCs DTS thermal driver"
363-
depends on X86 && PCI
363+
depends on X86 && PCI && ACPI
364364
select INTEL_SOC_DTS_IOSF_CORE
365365
select THERMAL_WRITABLE_TRIPS
366366
help

drivers/thermal/intel_soc_dts_thermal.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1717

18+
#include <linux/acpi.h>
1819
#include <linux/module.h>
1920
#include <linux/interrupt.h>
2021
#include <asm/cpu_device_id.h>
@@ -31,6 +32,7 @@ MODULE_PARM_DESC(crit_offset,
3132
/* IRQ 86 is a fixed APIC interrupt for BYT DTS Aux threshold notifications */
3233
#define BYT_SOC_DTS_APIC_IRQ 86
3334

35+
static int soc_dts_thres_gsi;
3436
static int soc_dts_thres_irq;
3537
static struct intel_soc_dts_sensors *soc_dts;
3638

@@ -65,7 +67,21 @@ static int __init intel_soc_thermal_init(void)
6567
return err;
6668
}
6769

68-
soc_dts_thres_irq = (int)match_cpu->driver_data;
70+
soc_dts_thres_gsi = (int)match_cpu->driver_data;
71+
if (soc_dts_thres_gsi) {
72+
/*
73+
* Note the flags here MUST match the firmware defaults, rather
74+
* then the request_irq flags, otherwise we get an EBUSY error.
75+
*/
76+
soc_dts_thres_irq = acpi_register_gsi(NULL, soc_dts_thres_gsi,
77+
ACPI_LEVEL_SENSITIVE,
78+
ACPI_ACTIVE_LOW);
79+
if (soc_dts_thres_irq < 0) {
80+
pr_warn("intel_soc_dts: Could not get IRQ for GSI %d, err %d\n",
81+
soc_dts_thres_gsi, soc_dts_thres_irq);
82+
soc_dts_thres_irq = 0;
83+
}
84+
}
6985

7086
if (soc_dts_thres_irq) {
7187
err = request_threaded_irq(soc_dts_thres_irq, NULL,
@@ -90,17 +106,21 @@ static int __init intel_soc_thermal_init(void)
90106
return 0;
91107

92108
error_trips:
93-
if (soc_dts_thres_irq)
109+
if (soc_dts_thres_irq) {
94110
free_irq(soc_dts_thres_irq, soc_dts);
111+
acpi_unregister_gsi(soc_dts_thres_gsi);
112+
}
95113
intel_soc_dts_iosf_exit(soc_dts);
96114

97115
return err;
98116
}
99117

100118
static void __exit intel_soc_thermal_exit(void)
101119
{
102-
if (soc_dts_thres_irq)
120+
if (soc_dts_thres_irq) {
103121
free_irq(soc_dts_thres_irq, soc_dts);
122+
acpi_unregister_gsi(soc_dts_thres_gsi);
123+
}
104124
intel_soc_dts_iosf_exit(soc_dts);
105125
}
106126

0 commit comments

Comments
 (0)