I've been working with a user that has a Lenovo Legion Y530-15ICH where booting Ubuntu 18.10 (kernel 4.18.0-8) results in the radios being disabled by the platform driver "ideapad-laptop". Unloading or blacklisting the module solves the issue but disables other platform ACPI interfaces.
We investigated the issue extensively and built the module with additional logic without solving the issue. It is well-known that some Lenovo models do not have a separate hardware radio kill switch (this model uses hot-keys Fn + F7) and need to use a DMI match to disable the rfkill logic.
We used dmidecode to get the correct Version string:
Handle 0x0001, DMI type 1, 27 bytes
System Information
Manufacturer: LENOVO
Product Name: 81FV
Version: Lenovo Legion Y530-15ICH
Serial Number: PF18CD10
UUID: A44F71C1-5E3D-11E8-9379-8C16458E3F9D
Wake-up Type: Power Switch
SKU Number: LENOVO_MT_81FV_BU_idea_FM_Legion Y530-15ICH
Family: Legion Y530-15ICH
We then added printk(KERN_NOTICE ... in the module's platform_driver.probe function ideapad_acpi_add() both at entry and later to report the DMI and status of the hardware switch control flag:
I've been working with a user that has a Lenovo Legion Y530-15ICH where booting Ubuntu 18.10 (kernel 4.18.0-8) results in the radios being disabled by the platform driver "ideapad-laptop". Unloading or blacklisting the module solves the issue but disables other platform ACPI interfaces.
The system has the most recent firmware:
[ 0.000000] DMI: LENOVO 81FV/LNVNB161216, BIOS 8JCN44WW 08/13/2018
The wifi device is:
00:14.3 Network controller [0280]: Intel Corporation Wireless-AC 9560 [Jefferson Peak] [8086:a370] (rev 10)
Subsystem: Intel Corporation Wireless-AC 9560 [Jefferson Peak] [8086:0034]
Kernel driver in use: iwlwifi
We investigated the issue extensively and built the module with additional logic without solving the issue. It is well-known that some Lenovo models do not have a separate hardware radio kill switch (this model uses hot-keys Fn + F7) and need to use a DMI match to disable the rfkill logic.
We used dmidecode to get the correct Version string:
Handle 0x0001, DMI type 1, 27 bytes 5E3D-11E8- 9379-8C16458E3F 9D MT_81FV_ BU_idea_ FM_Legion Y530-15ICH
System Information
Manufacturer: LENOVO
Product Name: 81FV
Version: Lenovo Legion Y530-15ICH
Serial Number: PF18CD10
UUID: A44F71C1-
Wake-up Type: Power Switch
SKU Number: LENOVO_
Family: Legion Y530-15ICH
and added it to no_hw_rfkill_ list[]:
{
DMI_ MATCH(DMI_ SYS_VENDOR, "LENOVO"),
DMI_ MATCH(DMI_ PRODUCT_ VERSION, "Lenovo Legion Y530-15ICH"),
.ident = "Lenovo Legion Y530-15ICH",
.matches = {
},
},
However, rfkill was still listing the platform devices "ideapad_wlan" and "ideapad_ bluetooth" :
/sys/class/ rfkill/ rfkill0/ hard=1 rfkill/ rfkill0/ index=0 rfkill/ rfkill0/ name=ideapad_ wlan rfkill/ rfkill0/ persistent= 1 rfkill/ rfkill0/ soft=0 rfkill/ rfkill0/ state=2 rfkill/ rfkill0/ type=wlan rfkill/ rfkill0/ uevent= RFKILL_ NAME=ideapad_ wlan RFKILL_TYPE=wlan RFKILL_STATE=2 rfkill/ rfkill1/ hard=1 rfkill/ rfkill1/ index=1 rfkill/ rfkill1/ name=ideapad_ bluetooth rfkill/ rfkill1/ persistent= 1 rfkill/ rfkill1/ soft=1 rfkill/ rfkill1/ state=2 rfkill/ rfkill1/ type=bluetooth rfkill/ rfkill1/ uevent= RFKILL_ NAME=ideapad_ bluetooth RFKILL_ TYPE=bluetooth RFKILL_STATE=2 rfkill/ rfkill3/ hard=0 rfkill/ rfkill3/ index=3 rfkill/ rfkill3/ name=phy0 rfkill/ rfkill3/ persistent= 0 rfkill/ rfkill3/ soft=0 rfkill/ rfkill3/ state=1 rfkill/ rfkill3/ type=wlan rfkill/ rfkill3/ uevent= RFKILL_ NAME=phy0 RFKILL_TYPE=wlan RFKILL_STATE=1 rfkill/ rfkill4/ hard=0 rfkill/ rfkill4/ index=4 rfkill/ rfkill4/ name=hci0 rfkill/ rfkill4/ persistent= 0 rfkill/ rfkill4/ soft=1 rfkill/ rfkill4/ state=0 rfkill/ rfkill4/ type=bluetooth rfkill/ rfkill4/ uevent= RFKILL_ NAME=hci0 RFKILL_ TYPE=bluetooth RFKILL_STATE=0
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
/sys/class/
We then added printk(KERN_NOTICE ... in the module's platform_ driver. probe function ideapad_acpi_add() both at entry and later to report the DMI and status of the hardware switch control flag:
diff -u /home/all/ SourceCode/ linux/linux/ drivers/ platform/ x86/ideapad- laptop. c ./ideapad-laptop.c SourceCode/ linux/linux/ drivers/ platform/ x86/ideapad- laptop. c 2018-10-14 01:46:49.506088219 +0100 DMI_SYS_ VENDOR, "LENOVO"), DMI_PRODUCT_ VERSION, "Lenovo Legion Y530-15ICH"),
.ident = "Lenovo Legion Y720-15IKB",
.matches = {
DMI_ MATCH(DMI_ SYS_VENDOR, "LENOVO"),
--- /home/all/
+++ ./ideapad-laptop.c 2018-10-14 06:19:48.843813865 +0100
@@ -1147,6 +1147,13 @@
},
},
{
+ .ident = "Lenovo Legion Y530-15ICH",
+ .matches = {
+ DMI_MATCH(
+ DMI_MATCH(
+ },
+ },
+ {
@@ -1239,6 +1246,7 @@
int cfg;
struct ideapad_private *priv;
struct acpi_device *adev;
+ const char *dmi_vendor, *dmi_version;
ret = acpi_bus_ get_device( ACPI_HANDLE( &pdev-> dev), &adev);
priv-> platform_ device = pdev;
priv-> has_hw_ rfkill_ switch = !dmi_check_ system( no_hw_rfkill_ list);
if (ret)
@@ -1257,6 +1265,10 @@
+ dmi_vendor = dmi_get_ system_ info(DMI_ SYS_VENDOR) ; system_ info(DMI_ PRODUCT_ VERSION) ; rfkill_ switch= %d\n", dmi_vendor, dmi_version, priv->has_ hw_rfkill_ switch) ; sysfs_init( priv);
return ret;
+ dmi_version = dmi_get_
+ printk(KERN_NOTICE "DMI: %s, %s. has_hw_
+
ret = ideapad_
if (ret)
And this revealed that the function is not being called - the KERN_NOTICE messages do not appear in 'dmesg' output.
This suggests:
static const struct acpi_device_id ideapad_ device_ ids[] = {
{ "VPC2004", 0},
is not being matched via platform_ driver. driver. acpi_match_ table = ACPI_PTR( ideapad_ device_ ids),
We then decompiled the ACPI DSDT and confirmed that _HID is being set to VPC2004:
grep -C4 VPC2004 dsdt.dsl LPCB.EC0)
Device (VPC0)
Name (_HID, "VPC2004") // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
Name (_VPC, 0xFC0DF516)
Name (VPCD, Zero)
Method (_STA, 0, NotSerialized) // _STA: Status
Scope (\_SB.PCI0.
{
{
At this point we're not sure what the next step should be. Wifi works correctly with the module blacklisted but it would be good to fix this properly.