platform/x86: bitland-mifs-wmi: Fix NULL pointer dereference during suspend/resume

The driver registers two distinct WMI devices: a control device
(BITLAND_WMI_CONTROL) and an event device (BITLAND_WMI_EVENT). During
the probe phase, the event device handling path returns early before
initializing the platform profile device (data->pp_dev), leaving it
NULL.

However, the PM sleep operations are registered globally for the WMI
driver and are triggered for both devices. When entering suspend, the
event device invokes bitland_mifs_wmi_suspend(), which passes the
uninitialized data->pp_dev (NULL) into laptop_profile_get(). This leads
to a NULL pointer dereference inside dev_get_drvdata(), causing a
kernel Oops and halting the suspend sequence.

Fix this by adding a validity check for data->pp_dev in both the suspend
and resume callbacks, safely skipping profile operations for the event
device.

Fixes: dc1ec4fa86 ("platform/x86: bitland-mifs-wmi: Add new Bitland MIFS WMI driver")
Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Signed-off-by: Mingyou Chen <qby140326@gmail.com>
Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Link: https://patch.msgid.link/20260701120140.430659-1-qby140326@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
This commit is contained in:
Mingyou Chen 2026-07-01 20:01:39 +08:00 committed by Ilpo Järvinen
parent a0738abd04
commit d3666875c7
No known key found for this signature in database
GPG Key ID: 59AC4F6153E5CE31

View File

@ -300,6 +300,10 @@ static int bitland_mifs_wmi_suspend(struct device *dev)
enum platform_profile_option profile;
int ret;
/* Skip event device */
if (!data->pp_dev)
return 0;
ret = laptop_profile_get(data->pp_dev, &profile);
if (ret == 0)
data->saved_profile = profile;
@ -311,6 +315,10 @@ static int bitland_mifs_wmi_resume(struct device *dev)
{
struct bitland_mifs_wmi_data *data = dev_get_drvdata(dev);
/* Skip event device */
if (!data->pp_dev)
return 0;
dev_dbg(dev, "Resuming, restoring profile %d\n", data->saved_profile);
return laptop_profile_set(dev, data->saved_profile);
}