Commit 07c455ee authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'platform-drivers-x86-v4.15-1' of git://git.infradead.org/linux-platform-drivers-x86

Pull x86 platform driver updates from Andy Shevchenko:
 "Here is the collected material against Platform Drivers x86 subsystem.
  It's rather bit busy cycle for PDx86, mostly due to Dell SMBIOS driver
  activity

  For this cycle we have quite an update for the Dell SMBIOS driver
  including WMI work to provide an interface for SMBIOS tokens via sysfs
  and WMI support for 2017+ Dell laptop models. SMM dispatcher code is
  split into a separate driver followed by a new WMI dispatcher. The
  latter provides a character device interface to user space.

  The git history also contains a merge of immutable branch from Wolfram
  Sang in order to apply a dependent fix to the Intel CherryTrail
  Battery Management driver.

  Other Intel drivers got a lot of cleanups. The Turbo Boost Max 3.0
  support is added for Intel Skylake.

  Peaq WMI hotkeys driver gets its own maintainer and white list of
  supported models.

  Silead DMI is expanded to support few additional platforms.

  Tablet mode via GMMS ACPI method is added to support some ThinkPad
  tablets.

  new driver:
   - Add driver to force WMI Thunderbolt controller power status

  asus-wmi:
   -  Add lightbar led support

  dell-laptop:
   -  Allocate buffer before rfkill use

  dell-smbios:
   -  fix string overflow
   -  Add filtering support
   -  Introduce dispatcher for SMM calls
   -  Add a sysfs interface for SMBIOS tokens
   -  only run if proper oem string is detected
   -  Prefix class/select with cmd_
   -  Add pr_fmt definition to driver

  dell-smbios-smm:
   -  test for WSMT

  dell-smbios-wmi:
   -  release mutex lock on WMI call failure
   -  introduce userspace interface
   -  Add new WMI dispatcher driver

  dell-smo8800:
   -  remove redundant assignments to byte_data

  dell-wmi:
   -  don't check length returned
   -  clean up wmi descriptor check
   -  increase severity of some failures
   -  Do not match on descriptor GUID modalias
   -  Label driver as handling notifications

  dell-*wmi*:
   -  Relay failed initial probe to dependent drivers

  dell-wmi-descriptor:
   -  check if memory was allocated
   -  split WMI descriptor into it's own driver

  fujitsu-laptop:
   -  Fix radio LED detection
   -  Don't oops when FUJ02E3 is not presnt

  hp_accel:
   -  Add quirk for HP ProBook 440 G4

  hp-wmi:
   -  Fix tablet mode detection for convertibles

  ideapad-laptop:
   -  Add Lenovo Yoga 920-13IKB to no_hw_rfkill dmi list

  intel_cht_int33fe:
   -  Update fusb302 type string, add properties
   -  make a couple of local functions static
   -  Work around BIOS bug on some devices

  intel-hid:
   -  Power button suspend on Dell Latitude 7275

  intel_ips:
   -  Convert timers to use timer_setup()
   -  Remove FSF address from GPL notice
   -  Remove unneeded fields and label
   -  Keep pointer to struct device
   -  Use PCI_VDEVICE() macro
   -  Switch to new PCI IRQ allocation API
   -  Simplify error handling via devres API

  intel_pmc_ipc:
   -  Revert Use MFD framework to create dependent devices
   -  Use MFD framework to create dependent devices
   -  Use spin_lock to protect GCR updates
   -  Use devm_* calls in driver probe function

  intel_punit_ipc:
   -  Fix resource ioremap warning

  intel_telemetry:
   -  Remove useless default in Kconfig
   -  Add needed inclusion
   -  cleanup redundant headers
   -  Fix typos
   -  Fix load failure info

  intel_telemetry_debugfs:
   -  Use standard ARRAY_SIZE() macro

  intel_turbo_max_3:
   -  Add Skylake platform

  intel-wmi-thunderbolt:
   -  Silence error cases

  mlx-platform:
   -  make a couple of structures static

  peaq_wmi:
   -  Fix missing terminating entry for peaq_dmi_table

  peaq-wmi:
   -  Remove unnecessary checks from peaq_wmi_exit
   -  Add DMI check before binding to the WMI interface
   -  Revert Blacklist Lenovo ideapad 700-15ISK
   -  Blacklist Lenovo ideapad 700-15ISK

  silead_dmi:
   -  Add silead, home-button property to some tablets
   -  Add entry for the Digma e200 tablet
   -  Fix GP-electronic T701 entry
   -  Add entry for the Chuwi Hi8 Pro tablet

  sony-laptop:
   -  Drop variable assignment in sony_nc_setup_rfkill()
   -  Fix error handling in sony_nc_setup_rfkill()

  thinkpad_acpi:
   -  Implement tablet mode using GMMS method

  tools/wmi:
   -  add a sample for dell smbios communication over WMI

  wmi:
   -  release mutex on module acquistion failure
   -  create userspace interface for drivers
   -  Don't allow drivers to get each other's GUIDs
   -  Add new method wmidev_evaluate_method
   -  Destroy on cleanup rather than unregister
   -  Cleanup exit routine in reverse order of init
   -  Sort include list"

* tag 'platform-drivers-x86-v4.15-1' of git://git.infradead.org/linux-platform-drivers-x86: (74 commits)
  platform/x86: silead_dmi: Add silead, home-button property to some tablets
  platform/x86: dell-laptop: Allocate buffer before rfkill use
  platform/x86: dell-*wmi*: Relay failed initial probe to dependent drivers
  platform/x86: dell-wmi-descriptor: check if memory was allocated
  platform/x86: Revert intel_pmc_ipc: Use MFD framework to create dependent devices
  platform/x86: dell-smbios-wmi: release mutex lock on WMI call failure
  platform/x86: wmi: release mutex on module acquistion failure
  platform/x86: dell-smbios: fix string overflow
  platform/x86: intel_pmc_ipc: Use MFD framework to create dependent devices
  platform/x86: intel_punit_ipc: Fix resource ioremap warning
  platform/x86: dell-smo8800: remove redundant assignments to byte_data
  platform/x86: hp-wmi: Fix tablet mode detection for convertibles
  platform/x86: intel_ips: Convert timers to use timer_setup()
  platform/x86: sony-laptop: Drop variable assignment in sony_nc_setup_rfkill()
  platform/x86: sony-laptop: Fix error handling in sony_nc_setup_rfkill()
  tools/wmi: add a sample for dell smbios communication over WMI
  platform/x86: dell-smbios-wmi: introduce userspace interface
  platform/x86: wmi: create userspace interface for drivers
  platform/x86: dell-smbios: Add filtering support
  platform/x86: dell-smbios-smm: test for WSMT
  ...
parents 1deab8ce aaa40965
What: /dev/wmi/dell-smbios
Date: November 2017
KernelVersion: 4.15
Contact: "Mario Limonciello" <mario.limonciello@dell.com>
Description:
Perform SMBIOS calls on supported Dell machines.
through the Dell ACPI-WMI interface.
IOCTL's and buffer formats are defined in:
<uapi/linux/wmi.h>
1) To perform an SMBIOS call from userspace, you'll need to
first determine the minimum size of the calling interface
buffer for your machine.
Platforms that contain larger buffers can return larger
objects from the system firmware.
Commonly this size is either 4k or 32k.
To determine the size of the buffer read() a u64 dword from
the WMI character device /dev/wmi/dell-smbios.
2) After you've determined the minimum size of the calling
interface buffer, you can allocate a structure that represents
the structure documented above.
3) In the 'length' object store the size of the buffer you
determined above and allocated.
4) In this buffer object, prepare as necessary for the SMBIOS
call you're interested in. Typically SMBIOS buffers have
"class", "select", and "input" defined to values that coincide
with the data you are interested in.
Documenting class/select/input values is outside of the scope
of this documentation. Check with the libsmbios project for
further documentation on these values.
6) Run the call by using ioctl() as described in the header.
7) The output will be returned in the buffer object.
8) Be sure to free up your allocated object.
What: /sys/devices/platform/<platform>/tokens/*
Date: November 2017
KernelVersion: 4.15
Contact: "Mario Limonciello" <mario.limonciello@dell.com>
Description:
A read-only description of Dell platform tokens
available on the machine.
Each token attribute is available as a pair of
sysfs attributes readable by a process with
CAP_SYS_ADMIN.
For example the token ID "5" would be available
as the following attributes:
0005_location
0005_value
Tokens will vary from machine to machine, and
only tokens available on that machine will be
displayed.
What: /sys/devices/platform/<platform>/force_power
Date: September 2017
KernelVersion: 4.15
Contact: "Mario Limonciello" <mario.limonciello@dell.com>
Description:
Modify the platform force power state, influencing
Thunderbolt controllers to turn on or off when no
devices are connected (write-only)
There are two available states:
* 0 -> Force power disabled
* 1 -> Force power enabled
......@@ -221,3 +221,18 @@ The driver will create one virtual ethernet interface per Thunderbolt
port which are named like ``thunderbolt0`` and so on. From this point
you can either use standard userspace tools like ``ifconfig`` to
configure the interface or let your GUI to handle it automatically.
Forcing power
-------------
Many OEMs include a method that can be used to force the power of a
thunderbolt controller to an "On" state even if nothing is connected.
If supported by your machine this will be exposed by the WMI bus with
a sysfs attribute called "force_power".
For example the intel-wmi-thunderbolt driver exposes this attribute in:
/sys/devices/platform/PNP0C14:00/wmi_bus/wmi_bus-PNP0C14:00/86CCFD48-205E-4A77-9C48-2021CBEDE341/force_power
To force the power to on, write 1 to this attribute file.
To disable force power, write 0 to this attribute file.
Note: it's currently not possible to query the force power state of a platform.
......@@ -384,6 +384,7 @@ ACPI WMI DRIVER
L: platform-driver-x86@vger.kernel.org
S: Orphan
F: drivers/platform/x86/wmi.c
F: include/uapi/linux/wmi.h
AD1889 ALSA SOUND DRIVER
M: Thibaut Varene <T-Bone@parisc-linux.org>
......@@ -4030,6 +4031,26 @@ M: "Maciej W. Rozycki" <macro@linux-mips.org>
S: Maintained
F: drivers/net/fddi/defxx.*
DELL SMBIOS DRIVER
M: Pali Rohár <pali.rohar@gmail.com>
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell-smbios.*
DELL SMBIOS SMM DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell-smbios-smm.c
DELL SMBIOS WMI DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell-smbios-wmi.c
F: tools/wmi/dell-smbios-example.c
DELL LAPTOP DRIVER
M: Matthew Garrett <mjg59@srcf.ucam.org>
M: Pali Rohár <pali.rohar@gmail.com>
......@@ -4059,12 +4080,17 @@ S: Maintained
F: Documentation/dcdbas.txt
F: drivers/firmware/dcdbas.*
DELL WMI EXTRAS DRIVER
DELL WMI NOTIFICATIONS DRIVER
M: Matthew Garrett <mjg59@srcf.ucam.org>
M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained
F: drivers/platform/x86/dell-wmi.c
DELL WMI DESCRIPTOR DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
S: Maintained
F: drivers/platform/x86/dell-wmi-descriptor.c
DELTA ST MEDIA DRIVER
M: Hugues Fruchet <hugues.fruchet@st.com>
L: linux-media@vger.kernel.org
......@@ -7181,6 +7207,11 @@ F: Documentation/wimax/README.i2400m
F: drivers/net/wimax/i2400m/
F: include/uapi/linux/wimax/i2400m.h
INTEL WMI THUNDERBOLT FORCE POWER DRIVER
M: Mario Limonciello <mario.limonciello@dell.com>
S: Maintained
F: drivers/platform/x86/intel-wmi-thunderbolt.c
INTEL(R) TRACE HUB
M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
S: Supported
......@@ -10630,6 +10661,12 @@ S: Maintained
F: crypto/pcrypt.c
F: include/crypto/pcrypt.h
PEAQ WMI HOTKEYS DRIVER
M: Hans de Goede <hdegoede@redhat.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/peaq-wmi.c
PER-CPU MEMORY ALLOCATOR
M: Tejun Heo <tj@kernel.org>
M: Christoph Lameter <cl@linux.com>
......
......@@ -93,12 +93,33 @@ config ASUS_LAPTOP
config DELL_SMBIOS
tristate
select DCDBAS
config DELL_SMBIOS_WMI
tristate "Dell SMBIOS calling interface (WMI implementation)"
depends on ACPI_WMI
select DELL_WMI_DESCRIPTOR
default ACPI_WMI
select DELL_SMBIOS
---help---
This provides an implementation for the Dell SMBIOS calling interface
communicated over ACPI-WMI.
If you have a Dell computer from >2007 you should say Y or M here.
If you aren't sure and this module doesn't work for your computer
it just won't load.
config DELL_SMBIOS_SMM
tristate "Dell SMBIOS calling interface (SMM implementation)"
depends on DCDBAS
default DCDBAS
select DELL_SMBIOS
---help---
This module provides common functions for kernel modules using
Dell SMBIOS.
This provides an implementation for the Dell SMBIOS calling interface
communicated over SMI/SMM.
If you have a Dell laptop, say Y or M here.
If you have a Dell computer from <=2017 you should say Y or M here.
If you aren't sure and this module doesn't work for your computer
it just won't load.
config DELL_LAPTOP
tristate "Dell Laptop Extras"
......@@ -116,11 +137,12 @@ config DELL_LAPTOP
laptops (except for some models covered by the Compal driver).
config DELL_WMI
tristate "Dell WMI extras"
tristate "Dell WMI notifications"
depends on ACPI_WMI
depends on DMI
depends on INPUT
depends on ACPI_VIDEO || ACPI_VIDEO = n
select DELL_WMI_DESCRIPTOR
select DELL_SMBIOS
select INPUT_SPARSEKMAP
---help---
......@@ -129,6 +151,10 @@ config DELL_WMI
To compile this driver as a module, choose M here: the module will
be called dell-wmi.
config DELL_WMI_DESCRIPTOR
tristate
depends on ACPI_WMI
config DELL_WMI_AIO
tristate "WMI Hotkeys for Dell All-In-One series"
depends on ACPI_WMI
......@@ -658,6 +684,19 @@ config WMI_BMOF
To compile this driver as a module, choose M here: the module will
be called wmi-bmof.
config INTEL_WMI_THUNDERBOLT
tristate "Intel WMI thunderbolt force power driver"
depends on ACPI_WMI
default ACPI_WMI
---help---
Say Y here if you want to be able to use the WMI interface on select
systems to force the power control of Intel Thunderbolt controllers.
This is useful for updating the firmware when devices are not plugged
into the controller.
To compile this driver as a module, choose M here: the module will
be called intel-wmi-thunderbolt.
config MSI_WMI
tristate "MSI WMI extras"
depends on ACPI_WMI
......@@ -793,7 +832,7 @@ config ACPI_CMPC
config INTEL_CHT_INT33FE
tristate "Intel Cherry Trail ACPI INT33FE Driver"
depends on X86 && ACPI && I2C
depends on X86 && ACPI && I2C && REGULATOR
---help---
This driver add support for the INT33FE ACPI device found on
some Intel Cherry Trail devices.
......@@ -804,6 +843,10 @@ config INTEL_CHT_INT33FE
This driver instantiates i2c-clients for these, so that standard
i2c drivers for these chips can bind to the them.
If you enable this driver it is advised to also select
CONFIG_TYPEC_FUSB302=m, CONFIG_CHARGER_BQ24190=m and
CONFIG_BATTERY_MAX17042=m.
config INTEL_INT0002_VGPIO
tristate "Intel ACPI INT0002 Virtual GPIO driver"
depends on GPIOLIB && ACPI
......@@ -1088,7 +1131,6 @@ config INTEL_PUNIT_IPC
config INTEL_TELEMETRY
tristate "Intel SoC Telemetry Driver"
default n
depends on INTEL_PMC_IPC && INTEL_PUNIT_IPC && X86_64
---help---
This driver provides interfaces to configure and use
......
......@@ -13,8 +13,11 @@ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o
obj-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o
obj-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o
obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
obj-$(CONFIG_DELL_WMI) += dell-wmi.o
obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o
obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
......@@ -40,6 +43,7 @@ obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o
obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o
obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o
obj-$(CONFIG_INTEL_WMI_THUNDERBOLT) += intel-wmi-thunderbolt.o
# toshiba_acpi must link after wmi to ensure that wmi devices are found
# before toshiba_acpi initializes
......
......@@ -119,6 +119,7 @@ MODULE_LICENSE("GPL");
#define ASUS_WMI_DEVID_BRIGHTNESS 0x00050012
#define ASUS_WMI_DEVID_KBD_BACKLIGHT 0x00050021
#define ASUS_WMI_DEVID_LIGHT_SENSOR 0x00050022 /* ?? */
#define ASUS_WMI_DEVID_LIGHTBAR 0x00050025
/* Misc */
#define ASUS_WMI_DEVID_CAMERA 0x00060013
......@@ -148,6 +149,7 @@ MODULE_LICENSE("GPL");
#define ASUS_WMI_DSTS_BIOS_BIT 0x00040000
#define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
#define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F
#define ASUS_FAN_DESC "cpu_fan"
#define ASUS_FAN_MFUN 0x13
......@@ -222,10 +224,13 @@ struct asus_wmi {
int tpd_led_wk;
struct led_classdev kbd_led;
int kbd_led_wk;
struct led_classdev lightbar_led;
int lightbar_led_wk;
struct workqueue_struct *led_workqueue;
struct work_struct tpd_led_work;
struct work_struct kbd_led_work;
struct work_struct wlan_led_work;
struct work_struct lightbar_led_work;
struct asus_rfkill wlan;
struct asus_rfkill bluetooth;
......@@ -567,6 +572,48 @@ static enum led_brightness wlan_led_get(struct led_classdev *led_cdev)
return result & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
}
static void lightbar_led_update(struct work_struct *work)
{
struct asus_wmi *asus;
int ctrl_param;
asus = container_of(work, struct asus_wmi, lightbar_led_work);
ctrl_param = asus->lightbar_led_wk;
asus_wmi_set_devstate(ASUS_WMI_DEVID_LIGHTBAR, ctrl_param, NULL);
}
static void lightbar_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
struct asus_wmi *asus;
asus = container_of(led_cdev, struct asus_wmi, lightbar_led);
asus->lightbar_led_wk = !!value;
queue_work(asus->led_workqueue, &asus->lightbar_led_work);
}
static enum led_brightness lightbar_led_get(struct led_classdev *led_cdev)
{
struct asus_wmi *asus;
u32 result;
asus = container_of(led_cdev, struct asus_wmi, lightbar_led);
asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_LIGHTBAR, &result);
return result & ASUS_WMI_DSTS_LIGHTBAR_MASK;
}
static int lightbar_led_presence(struct asus_wmi *asus)
{
u32 result;
asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_LIGHTBAR, &result);
return result & ASUS_WMI_DSTS_PRESENCE_BIT;
}
static void asus_wmi_led_exit(struct asus_wmi *asus)
{
if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
......@@ -575,6 +622,8 @@ static void asus_wmi_led_exit(struct asus_wmi *asus)
led_classdev_unregister(&asus->tpd_led);
if (!IS_ERR_OR_NULL(asus->wlan_led.dev))
led_classdev_unregister(&asus->wlan_led);
if (!IS_ERR_OR_NULL(asus->lightbar_led.dev))
led_classdev_unregister(&asus->lightbar_led);
if (asus->led_workqueue)
destroy_workqueue(asus->led_workqueue);
}
......@@ -630,6 +679,20 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
rv = led_classdev_register(&asus->platform_device->dev,
&asus->wlan_led);
if (rv)
goto error;
}
if (lightbar_led_presence(asus)) {
INIT_WORK(&asus->lightbar_led_work, lightbar_led_update);
asus->lightbar_led.name = "asus::lightbar";
asus->lightbar_led.brightness_set = lightbar_led_set;
asus->lightbar_led.brightness_get = lightbar_led_get;
asus->lightbar_led.max_brightness = 1;
rv = led_classdev_register(&asus->platform_device->dev,
&asus->lightbar_led);
}
error:
......
......@@ -35,18 +35,6 @@
#include "dell-rbtn.h"
#include "dell-smbios.h"
#define BRIGHTNESS_TOKEN 0x7d
#define KBD_LED_OFF_TOKEN 0x01E1
#define KBD_LED_ON_TOKEN 0x01E2
#define KBD_LED_AUTO_TOKEN 0x01E3
#define KBD_LED_AUTO_25_TOKEN 0x02EA
#define KBD_LED_AUTO_50_TOKEN 0x02EB
#define KBD_LED_AUTO_75_TOKEN 0x02EC
#define KBD_LED_AUTO_100_TOKEN 0x02F6
#define GLOBAL_MIC_MUTE_ENABLE 0x0364
#define GLOBAL_MIC_MUTE_DISABLE 0x0365
#define KBD_LED_AC_TOKEN 0x0451
struct quirk_entry {
u8 touchpad_led;
......@@ -85,6 +73,7 @@ static struct platform_driver platform_driver = {
}
};
static struct calling_interface_buffer *buffer;
static struct platform_device *platform_device;
static struct backlight_device *dell_backlight_device;
static struct rfkill *wifi_rfkill;
......@@ -283,6 +272,27 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
{ }
};
void dell_set_arguments(u32 arg0, u32 arg1, u32 arg2, u32 arg3)
{
memset(buffer, 0, sizeof(struct calling_interface_buffer));
buffer->input[0] = arg0;
buffer->input[1] = arg1;
buffer->input[2] = arg2;
buffer->input[3] = arg3;
}
int dell_send_request(u16 class, u16 select)
{
int ret;
buffer->cmd_class = class;
buffer->cmd_select = select;
ret = dell_smbios_call(buffer);
if (ret != 0)
return ret;
return dell_smbios_error(buffer->output[0]);
}
/*
* Derived from information in smbios-wireless-ctl:
*
......@@ -405,7 +415,6 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
static int dell_rfkill_set(void *data, bool blocked)
{
struct calling_interface_buffer *buffer;
int disable = blocked ? 1 : 0;
unsigned long radio = (unsigned long)data;
int hwswitch_bit = (unsigned long)data - 1;
......@@ -413,20 +422,16 @@ static int dell_rfkill_set(void *data, bool blocked)
int status;
int ret;
buffer = dell_smbios_get_buffer();
dell_smbios_send_request(17, 11);
ret = buffer->output[0];
dell_set_arguments(0, 0, 0, 0);
ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
if (ret)
return ret;
status = buffer->output[1];
if (ret != 0)
goto out;
dell_smbios_clear_buffer();
buffer->input[0] = 0x2;
dell_smbios_send_request(17, 11);
ret = buffer->output[0];
dell_set_arguments(0x2, 0, 0, 0);
ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
if (ret)
return ret;
hwswitch = buffer->output[1];
/* If the hardware switch controls this radio, and the hardware
......@@ -435,28 +440,19 @@ static int dell_rfkill_set(void *data, bool blocked)
(status & BIT(0)) && !(status & BIT(16)))
disable = 1;
dell_smbios_clear_buffer();
buffer->input[0] = (1 | (radio<<8) | (disable << 16));
dell_smbios_send_request(17, 11);
ret = buffer->output[0];
out:
dell_smbios_release_buffer();
return dell_smbios_error(ret);
dell_set_arguments(1 | (radio<<8) | (disable << 16), 0, 0, 0);
ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
return ret;
}
/* Must be called with the buffer held */
static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
int status,
struct calling_interface_buffer *buffer)
int status)
{
if (status & BIT(0)) {
/* Has hw-switch, sync sw_state to BIOS */
int block = rfkill_blocked(rfkill);
dell_smbios_clear_buffer();
buffer->input[0] = (1 | (radio << 8) | (block << 16));
dell_smbios_send_request(17, 11);
dell_set_arguments(1 | (radio << 8) | (block << 16), 0, 0, 0);
dell_send_request(CLASS_INFO, SELECT_RFKILL);
} else {
/* No hw-switch, sync BIOS state to sw_state */
rfkill_set_sw_state(rfkill, !!(status & BIT(radio + 16)));
......@@ -472,32 +468,23 @@ static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio,
static void dell_rfkill_query(struct rfkill *rfkill, void *data)
{
struct calling_interface_buffer *buffer;
int radio = ((unsigned long)data & 0xF);
int hwswitch;
int status;
int ret;
buffer = dell_smbios_get_buffer();
dell_smbios_send_request(17, 11);
ret = buffer->output[0];
dell_set_arguments(0, 0, 0, 0);
ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
status = buffer->output[1];
if (ret != 0 || !(status & BIT(0))) {
dell_smbios_release_buffer();
return;
}
dell_smbios_clear_buffer();
buffer->input[0] = 0x2;
dell_smbios_send_request(17, 11);
ret = buffer->output[0];
dell_set_arguments(0, 0x2, 0, 0);
ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
hwswitch = buffer->output[1];
dell_smbios_release_buffer();
if (ret != 0)
return;
......@@ -513,27 +500,23 @@ static struct dentry *dell_laptop_dir;
static int dell_debugfs_show(struct seq_file *s, void *data)
{
struct calling_interface_buffer *buffer;
int hwswitch_state;
int hwswitch_ret;
int status;
int ret;
buffer = dell_smbios_get_buffer();
dell_smbios_send_request(17, 11);
ret = buffer->output[0];
dell_set_arguments(0, 0, 0, 0);
ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
if (ret)
return ret;
status = buffer->output[1];
dell_smbios_clear_buffer();
buffer->input[0] = 0x2;
dell_smbios_send_request(17, 11);
hwswitch_ret = buffer->output[0];
dell_set_arguments(0, 0x2, 0, 0);
hwswitch_ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
if (hwswitch_ret)
return hwswitch_ret;
hwswitch_state = buffer->output[1];
dell_smbios_release_buffer();
seq_printf(s, "return:\t%d\n", ret);
seq_printf(s, "status:\t0x%X\n", status);
seq_printf(s, "Bit 0 : Hardware switch supported: %lu\n",
......@@ -613,46 +596,36 @@ static const struct file_operations dell_debugfs_fops = {
static void dell_update_rfkill(struct work_struct *ignored)
{
struct calling_interface_buffer *buffer;
int hwswitch = 0;
int status;
int ret;
buffer = dell_smbios_get_buffer();
dell_smbios_send_request(17, 11);
ret = buffer->output[0];
dell_set_arguments(0, 0, 0, 0);
ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
status = buffer->output[1];
if (ret != 0)
goto out;
dell_smbios_clear_buffer();
return;
buffer->input[0] = 0x2;
dell_smbios_send_request(17, 11);