platform-drivers-x86 for v4.14-1

Several fixes from static analysis and message noise reduction. Correct
 WMI core and related drivers to evaluate instance number 0x0 in
 accordance with the documentation. Add intel-telemetry support for
 Gemini Lake. Various individual driver fixes noted below.
 
 Two commits appear here which were previously merged during the 4.13 RC
 cycle:
 - baa5480b05 platform/x86: dell-wmi: Fix driver interface version query
 - c801603e6d platform/x86: intel-vbtn: match power button on press rather than release
 
 dell-wmi:
  - Update dell_wmi_check_descriptor_buffer() to new model
 
 intel-vbtn:
  - reduce unnecessary messages for normal users
  - match power button on press rather than release
 
 intel-hid:
  - reduce unnecessary messages for normal users
 
 thinkpad_acpi:
  - Fix warning about deprecated hwmon_device_register
 
 wmi:
  - Fix check for method instance number
 
 ideapad-laptop:
  - Expose conservation mode switch
 
 intel_pmc_core:
  - Make the driver PCH family agnostic
 
 peaq-wmi:
  - Evaluate wmi method with instance number 0x0
  - silence a static checker warning
 
 mxm-wmi:
  - Evaluate wmi method with instance number 0x0
 
 asus-wmi:
  - Evaluate wmi method with instance number 0x0
 
 intel_scu_ipc:
  - make intel_scu_ipc_pdata_t const
 
 intel_mid_powerbtn:
  - make mid_pb_ddata const
  - fix error return code in mid_pb_probe()
 
 hp-wmi:
  - Remove unused macro helper
  - Correctly determine method id in WMI calls
 
 dell-wmi:
  - Fix driver interface version query
 
 intel_telemetry:
  - remove redundant macro definition
  - Add GLK PSS Event Table
 
 alienware-wmi:
  - fix format string overflow warning
 
 ibm_rtl:
  - remove unnecessary static in ibm_rtl_write()
 
 msi-wmi:
  - remove unnecessary static in msi_wmi_notify()
 -----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJZsvdiAAoJEKbMaAwKp364V+UIAI27WP1MKQ6zKiXAt6TTLQww
 RGbeTrgxsHwxIp1ioo3MZtRa4uTMrJ/A/Es7nzZBSAAp8qPLOCaZYGtsH0tYkzcc
 zGLw+q5EBEjiMiq8WvkgD+NLq6icdsB0MUuuh06y34/LWiOwpp9wNemszHO9Vo2/
 vc5PkgNmMx5K4zJvl6A3JAY98XlXxG65vYMrsIL17EFwZjuixrcCjDY86HKxEnNV
 tmfJ1Mhiu5HnDniCgRubdRBo4LwAeRdrXXkrsTZip+4RuXvm0gvxHujwgllIY4Ns
 m6xFXQApaGtXxd9vcSBHXE7whTgWrb7yPhUQzgt/Dd3E6ywF2THfn5jvwJUEflc=
 =LuAp
 -----END PGP SIGNATURE-----

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

Pull x86 platform driver updates from Darren Hart:
 "Several fixes from static analysis and message noise reduction.
  Correct WMI core and related drivers to evaluate instance number 0x0
  in accordance with the documentation. Add intel-telemetry support for
  Gemini Lake. Various individual driver fixes noted below.

  dell-wmi:
   - Update dell_wmi_check_descriptor_buffer() to new model

  intel-vbtn:
   - reduce unnecessary messages for normal users
   - match power button on press rather than release

  intel-hid:
   - reduce unnecessary messages for normal users

  thinkpad_acpi:
   - Fix warning about deprecated hwmon_device_register

  wmi:
   - Fix check for method instance number

  ideapad-laptop:
   - Expose conservation mode switch

  intel_pmc_core:
   - Make the driver PCH family agnostic

  peaq-wmi:
   - Evaluate wmi method with instance number 0x0
   - silence a static checker warning

  mxm-wmi:
   - Evaluate wmi method with instance number 0x0

  asus-wmi:
   - Evaluate wmi method with instance number 0x0

  intel_scu_ipc:
   - make intel_scu_ipc_pdata_t const

  intel_mid_powerbtn:
   - make mid_pb_ddata const
   - fix error return code in mid_pb_probe()

  hp-wmi:
   - Remove unused macro helper
   - Correctly determine method id in WMI calls

  dell-wmi:
   - Fix driver interface version query

  intel_telemetry:
   - remove redundant macro definition
   - Add GLK PSS Event Table

  alienware-wmi:
   - fix format string overflow warning

  ibm_rtl:
   - remove unnecessary static in ibm_rtl_write()

  msi-wmi:
   - remove unnecessary static in msi_wmi_notify()"

* tag 'platform-drivers-x86-v4.14-1' of git://git.infradead.org/linux-platform-drivers-x86: (23 commits)
  platform/x86: dell-wmi: Update dell_wmi_check_descriptor_buffer() to new model
  platform/x86: intel-vbtn: reduce unnecessary messages for normal users
  platform/x86: intel-hid: reduce unnecessary messages for normal users
  platform/x86: thinkpad_acpi: Fix warning about deprecated hwmon_device_register
  platform/x86: wmi: Fix check for method instance number
  platform/x86: ideapad-laptop: Expose conservation mode switch
  platform/x86: intel_pmc_core: Make the driver PCH family agnostic
  platform/x86: peaq-wmi: Evaluate wmi method with instance number 0x0
  platform/x86: mxm-wmi: Evaluate wmi method with instance number 0x0
  platform/x86: asus-wmi: Evaluate wmi method with instance number 0x0
  platform/x86: intel_scu_ipc: make intel_scu_ipc_pdata_t const
  platform/x86: intel_mid_powerbtn: make mid_pb_ddata const
  platform/x86: intel_mid_powerbtn: fix error return code in mid_pb_probe()
  platform/x86: hp-wmi: Remove unused macro helper
  platform/x86: hp-wmi: Correctly determine method id in WMI calls
  platform/x86: intel-vbtn: match power button on press rather than release
  platform/x86: dell-wmi: Fix driver interface version query
  platform/x86: intel_telemetry: remove redundant macro definition
  platform/x86: intel_telemetry: Add GLK PSS Event Table
  platform/x86: alienware-wmi: fix format string overflow warning
  ...
This commit is contained in:
Linus Torvalds 2017-09-08 16:04:50 -07:00
Родитель ee89252b9e 00ebbeb39b
Коммит 0e271fd59f
20 изменённых файлов: 278 добавлений и 119 удалений

Просмотреть файл

@ -121,8 +121,9 @@ space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/.
Sysfs device attributes for the sensors and fan are on the Sysfs device attributes for the sensors and fan are on the
thinkpad_hwmon device's sysfs attribute space, but you should locate it thinkpad_hwmon device's sysfs attribute space, but you should locate it
looking for a hwmon device with the name attribute of "thinkpad", or looking for a hwmon device with the name attribute of "thinkpad", or
better yet, through libsensors. better yet, through libsensors. For 4.14+ sysfs attributes were moved to the
hwmon device (/sys/bus/platform/devices/thinkpad_hwmon/hwmon/hwmon? or
/sys/class/hwmon/hwmon?).
Driver version Driver version
-------------- --------------
@ -1478,3 +1479,7 @@ Sysfs interface changelog:
0x020700: Support for mute-only mixers. 0x020700: Support for mute-only mixers.
Volume control in read-only mode by default. Volume control in read-only mode by default.
Marker for ALSA mixer support. Marker for ALSA mixer support.
0x030000: Thermal and fan sysfs attributes were moved to the hwmon
device instead of being attached to the backing platform
device.

Просмотреть файл

@ -255,12 +255,13 @@ static int parse_rgb(const char *buf, struct platform_zone *zone)
static struct platform_zone *match_zone(struct device_attribute *attr) static struct platform_zone *match_zone(struct device_attribute *attr)
{ {
int i; u8 zone;
for (i = 0; i < quirks->num_zones; i++) {
if ((struct device_attribute *)zone_data[i].attr == attr) { for (zone = 0; zone < quirks->num_zones; zone++) {
if ((struct device_attribute *)zone_data[zone].attr == attr) {
pr_debug("alienware-wmi: matched zone location: %d\n", pr_debug("alienware-wmi: matched zone location: %d\n",
zone_data[i].location); zone_data[zone].location);
return &zone_data[i]; return &zone_data[zone];
} }
} }
return NULL; return NULL;
@ -420,7 +421,7 @@ static DEVICE_ATTR(lighting_control_state, 0644, show_control_state,
static int alienware_zone_init(struct platform_device *dev) static int alienware_zone_init(struct platform_device *dev)
{ {
int i; u8 zone;
char buffer[10]; char buffer[10];
char *name; char *name;
@ -457,19 +458,19 @@ static int alienware_zone_init(struct platform_device *dev)
if (!zone_data) if (!zone_data)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < quirks->num_zones; i++) { for (zone = 0; zone < quirks->num_zones; zone++) {
sprintf(buffer, "zone%02X", i); sprintf(buffer, "zone%02hhX", zone);
name = kstrdup(buffer, GFP_KERNEL); name = kstrdup(buffer, GFP_KERNEL);
if (name == NULL) if (name == NULL)
return 1; return 1;
sysfs_attr_init(&zone_dev_attrs[i].attr); sysfs_attr_init(&zone_dev_attrs[zone].attr);
zone_dev_attrs[i].attr.name = name; zone_dev_attrs[zone].attr.name = name;
zone_dev_attrs[i].attr.mode = 0644; zone_dev_attrs[zone].attr.mode = 0644;
zone_dev_attrs[i].show = zone_show; zone_dev_attrs[zone].show = zone_show;
zone_dev_attrs[i].store = zone_set; zone_dev_attrs[zone].store = zone_set;
zone_data[i].location = i; zone_data[zone].location = zone;
zone_attrs[i] = &zone_dev_attrs[i].attr; zone_attrs[zone] = &zone_dev_attrs[zone].attr;
zone_data[i].attr = &zone_dev_attrs[i]; zone_data[zone].attr = &zone_dev_attrs[zone];
} }
zone_attrs[quirks->num_zones] = &dev_attr_lighting_control_state.attr; zone_attrs[quirks->num_zones] = &dev_attr_lighting_control_state.attr;
zone_attribute_group.attrs = zone_attrs; zone_attribute_group.attrs = zone_attrs;
@ -481,12 +482,13 @@ static int alienware_zone_init(struct platform_device *dev)
static void alienware_zone_exit(struct platform_device *dev) static void alienware_zone_exit(struct platform_device *dev)
{ {
u8 zone;
sysfs_remove_group(&dev->dev.kobj, &zone_attribute_group); sysfs_remove_group(&dev->dev.kobj, &zone_attribute_group);
led_classdev_unregister(&global_led); led_classdev_unregister(&global_led);
if (zone_dev_attrs) { if (zone_dev_attrs) {
int i; for (zone = 0; zone < quirks->num_zones; zone++)
for (i = 0; i < quirks->num_zones; i++) kfree(zone_dev_attrs[zone].attr.name);
kfree(zone_dev_attrs[i].attr.name);
} }
kfree(zone_dev_attrs); kfree(zone_dev_attrs);
kfree(zone_data); kfree(zone_data);

Просмотреть файл

@ -299,7 +299,7 @@ static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
union acpi_object *obj; union acpi_object *obj;
u32 tmp = 0; u32 tmp = 0;
status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id, status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
&input, &output); &input, &output);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
@ -1946,7 +1946,7 @@ static int show_call(struct seq_file *m, void *data)
acpi_status status; acpi_status status;
status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
1, asus->debug.method_id, 0, asus->debug.method_id,
&input, &output); &input, &output);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))

Просмотреть файл

@ -48,7 +48,6 @@ MODULE_LICENSE("GPL");
#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492" #define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
#define DELL_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492" #define DELL_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492"
static u32 dell_wmi_interface_version;
static bool wmi_requires_smbios_request; static bool wmi_requires_smbios_request;
MODULE_ALIAS("wmi:"DELL_EVENT_GUID); MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
@ -56,6 +55,7 @@ MODULE_ALIAS("wmi:"DELL_DESCRIPTOR_GUID);
struct dell_wmi_priv { struct dell_wmi_priv {
struct input_dev *input_dev; struct input_dev *input_dev;
u32 interface_version;
}; };
static int __init dmi_matched(const struct dmi_system_id *dmi) static int __init dmi_matched(const struct dmi_system_id *dmi)
@ -348,6 +348,7 @@ static void dell_wmi_process_key(struct wmi_device *wdev, int type, int code)
static void dell_wmi_notify(struct wmi_device *wdev, static void dell_wmi_notify(struct wmi_device *wdev,
union acpi_object *obj) union acpi_object *obj)
{ {
struct dell_wmi_priv *priv = dev_get_drvdata(&wdev->dev);
u16 *buffer_entry, *buffer_end; u16 *buffer_entry, *buffer_end;
acpi_size buffer_size; acpi_size buffer_size;
int len, i; int len, i;
@ -376,7 +377,7 @@ static void dell_wmi_notify(struct wmi_device *wdev,
* So to prevent reading garbage from buffer we will process only first * So to prevent reading garbage from buffer we will process only first
* one event on devices with WMI interface version 0. * one event on devices with WMI interface version 0.
*/ */
if (dell_wmi_interface_version == 0 && buffer_entry < buffer_end) if (priv->interface_version == 0 && buffer_entry < buffer_end)
if (buffer_end > buffer_entry + buffer_entry[0] + 1) if (buffer_end > buffer_entry + buffer_entry[0] + 1)
buffer_end = buffer_entry + buffer_entry[0] + 1; buffer_end = buffer_entry + buffer_entry[0] + 1;
@ -626,61 +627,67 @@ static void dell_wmi_input_destroy(struct wmi_device *wdev)
* WMI Interface Version 8 4 <version> * WMI Interface Version 8 4 <version>
* WMI buffer length 12 4 4096 * WMI buffer length 12 4 4096
*/ */
static int dell_wmi_check_descriptor_buffer(void) static int dell_wmi_check_descriptor_buffer(struct wmi_device *wdev)
{ {
struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; struct dell_wmi_priv *priv = dev_get_drvdata(&wdev->dev);
union acpi_object *obj; union acpi_object *obj = NULL;
acpi_status status; struct wmi_device *desc_dev;
u32 *buffer; u32 *buffer;
int ret;
status = wmi_query_block(DELL_DESCRIPTOR_GUID, 0, &out); desc_dev = wmidev_get_other_guid(wdev, DELL_DESCRIPTOR_GUID);
if (ACPI_FAILURE(status)) { if (!desc_dev) {
pr_err("Cannot read Dell descriptor buffer - %d\n", status); dev_err(&wdev->dev, "Dell WMI descriptor does not exist\n");
return status; return -ENODEV;
} }
obj = (union acpi_object *)out.pointer; obj = wmidev_block_query(desc_dev, 0);
if (!obj) { if (!obj) {
pr_err("Dell descriptor buffer is empty\n"); dev_err(&wdev->dev, "failed to read Dell WMI descriptor\n");
return -EINVAL; ret = -EIO;
goto out;
} }
if (obj->type != ACPI_TYPE_BUFFER) { if (obj->type != ACPI_TYPE_BUFFER) {
pr_err("Cannot read Dell descriptor buffer\n"); dev_err(&wdev->dev, "Dell descriptor has wrong type\n");
kfree(obj); ret = -EINVAL;
return -EINVAL; goto out;
} }
if (obj->buffer.length != 128) { if (obj->buffer.length != 128) {
pr_err("Dell descriptor buffer has invalid length (%d)\n", dev_err(&wdev->dev,
"Dell descriptor buffer has invalid length (%d)\n",
obj->buffer.length); obj->buffer.length);
if (obj->buffer.length < 16) { if (obj->buffer.length < 16) {
kfree(obj); ret = -EINVAL;
return -EINVAL; goto out;
} }
} }
buffer = (u32 *)obj->buffer.pointer; buffer = (u32 *)obj->buffer.pointer;
if (buffer[0] != 0x4C4C4544 && buffer[1] != 0x494D5720) if (buffer[0] != 0x4C4C4544 && buffer[1] != 0x494D5720)
pr_warn("Dell descriptor buffer has invalid signature (%*ph)\n", dev_warn(&wdev->dev, "Dell descriptor buffer has invalid signature (%*ph)\n",
8, buffer); 8, buffer);
if (buffer[2] != 0 && buffer[2] != 1) if (buffer[2] != 0 && buffer[2] != 1)
pr_warn("Dell descriptor buffer has unknown version (%d)\n", dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%d)\n",
buffer[2]); buffer[2]);
if (buffer[3] != 4096) if (buffer[3] != 4096)
pr_warn("Dell descriptor buffer has invalid buffer length (%d)\n", dev_warn(&wdev->dev, "Dell descriptor buffer has invalid buffer length (%d)\n",
buffer[3]); buffer[3]);
dell_wmi_interface_version = buffer[2]; priv->interface_version = buffer[2];
ret = 0;
pr_info("Detected Dell WMI interface version %u\n", dev_info(&wdev->dev, "Detected Dell WMI interface version %u\n",
dell_wmi_interface_version); priv->interface_version);
out:
kfree(obj); kfree(obj);
return 0; put_device(&desc_dev->dev);
return ret;
} }
/* /*
@ -717,17 +724,19 @@ static int dell_wmi_events_set_enabled(bool enable)
static int dell_wmi_probe(struct wmi_device *wdev) static int dell_wmi_probe(struct wmi_device *wdev)
{ {
struct dell_wmi_priv *priv;
int err; int err;
struct dell_wmi_priv *priv = devm_kzalloc( priv = devm_kzalloc(
&wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL); &wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
dev_set_drvdata(&wdev->dev, priv);
err = dell_wmi_check_descriptor_buffer(); err = dell_wmi_check_descriptor_buffer(wdev);
if (err) if (err)
return err; return err;
dev_set_drvdata(&wdev->dev, priv);
return dell_wmi_input_setup(wdev); return dell_wmi_input_setup(wdev);
} }

Просмотреть файл

@ -107,13 +107,6 @@ enum hp_wmi_hardware_mask {
HPWMI_TABLET_MASK = 0x04, HPWMI_TABLET_MASK = 0x04,
}; };
#define BIOS_ARGS_INIT(write, ctype, size) \
(struct bios_args) { .signature = 0x55434553, \
.command = (write) ? 0x2 : 0x1, \
.commandtype = (ctype), \
.datasize = (size), \
.data = 0 }
struct bios_return { struct bios_return {
u32 sigpass; u32 sigpass;
u32 return_code; u32 return_code;
@ -188,6 +181,22 @@ struct rfkill2_device {
static int rfkill2_count; static int rfkill2_count;
static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES]; static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
/* map output size to the corresponding WMI method id */
static inline int encode_outsize_for_pvsz(int outsize)
{
if (outsize > 4096)
return -EINVAL;
if (outsize > 1024)
return 5;
if (outsize > 128)
return 4;
if (outsize > 4)
return 3;
if (outsize > 0)
return 2;
return 1;
}
/* /*
* hp_wmi_perform_query * hp_wmi_perform_query
* *
@ -211,6 +220,7 @@ static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
static int hp_wmi_perform_query(int query, enum hp_wmi_command command, static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
void *buffer, int insize, int outsize) void *buffer, int insize, int outsize)
{ {
int mid;
struct bios_return *bios_return; struct bios_return *bios_return;
int actual_outsize; int actual_outsize;
union acpi_object *obj; union acpi_object *obj;
@ -225,11 +235,15 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
int ret = 0; int ret = 0;
mid = encode_outsize_for_pvsz(outsize);
if (WARN_ON(mid < 0))
return mid;
if (WARN_ON(insize > sizeof(args.data))) if (WARN_ON(insize > sizeof(args.data)))
return -EINVAL; return -EINVAL;
memcpy(&args.data, buffer, insize); memcpy(&args.data, buffer, insize);
wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output); wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
obj = output.pointer; obj = output.pointer;

Просмотреть файл

@ -103,7 +103,7 @@ static void rtl_port_unmap(void __iomem *addr)
static int ibm_rtl_write(u8 value) static int ibm_rtl_write(u8 value)
{ {
int ret = 0, count = 0; int ret = 0, count = 0;
static u32 cmd_port_val; u32 cmd_port_val;
RTL_DEBUG("%s(%d)\n", __func__, value); RTL_DEBUG("%s(%d)\n", __func__, value);

Просмотреть файл

@ -42,6 +42,8 @@
#define IDEAPAD_RFKILL_DEV_NUM (3) #define IDEAPAD_RFKILL_DEV_NUM (3)
#define BM_CONSERVATION_BIT (5)
#define CFG_BT_BIT (16) #define CFG_BT_BIT (16)
#define CFG_3G_BIT (17) #define CFG_3G_BIT (17)
#define CFG_WIFI_BIT (18) #define CFG_WIFI_BIT (18)
@ -54,6 +56,11 @@ static const char *const ideapad_wmi_fnesc_events[] = {
}; };
#endif #endif
enum {
BMCMD_CONSERVATION_ON = 3,
BMCMD_CONSERVATION_OFF = 5,
};
enum { enum {
VPCCMD_R_VPC1 = 0x10, VPCCMD_R_VPC1 = 0x10,
VPCCMD_R_BL_MAX, VPCCMD_R_BL_MAX,
@ -123,6 +130,23 @@ static int read_method_int(acpi_handle handle, const char *method, int *val)
} }
} }
static int method_gbmd(acpi_handle handle, unsigned long *ret)
{
int result, val;
result = read_method_int(handle, "GBMD", &val);
*ret = val;
return result;
}
static int method_sbmc(acpi_handle handle, int cmd)
{
acpi_status status;
status = acpi_execute_simple_method(handle, "SBMC", cmd);
return ACPI_FAILURE(status) ? -1 : 0;
}
static int method_vpcr(acpi_handle handle, int cmd, int *ret) static int method_vpcr(acpi_handle handle, int cmd, int *ret)
{ {
acpi_status status; acpi_status status;
@ -250,6 +274,13 @@ static int debugfs_status_show(struct seq_file *s, void *data)
if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value)) if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value))
seq_printf(s, "Camera status:\t%s(%lu)\n", seq_printf(s, "Camera status:\t%s(%lu)\n",
value ? "On" : "Off", value); value ? "On" : "Off", value);
seq_puts(s, "=====================\n");
if (!method_gbmd(priv->adev->handle, &value)) {
seq_printf(s, "Conservation mode:\t%s(%lu)\n",
test_bit(BM_CONSERVATION_BIT, &value) ? "On" : "Off",
value);
}
return 0; return 0;
} }
@ -456,10 +487,45 @@ static ssize_t __maybe_unused touchpad_store(struct device *dev,
static DEVICE_ATTR_RO(touchpad); static DEVICE_ATTR_RO(touchpad);
static ssize_t conservation_mode_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct ideapad_private *priv = dev_get_drvdata(dev);
unsigned long result;
if (method_gbmd(priv->adev->handle, &result))
return sprintf(buf, "-1\n");
return sprintf(buf, "%u\n", test_bit(BM_CONSERVATION_BIT, &result));
}
static ssize_t conservation_mode_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct ideapad_private *priv = dev_get_drvdata(dev);
bool state;
int ret;
ret = kstrtobool(buf, &state);
if (ret)
return ret;
ret = method_sbmc(priv->adev->handle, state ?
BMCMD_CONSERVATION_ON :
BMCMD_CONSERVATION_OFF);
if (ret < 0)
return -EIO;
return count;
}
static DEVICE_ATTR_RW(conservation_mode);
static struct attribute *ideapad_attributes[] = { static struct attribute *ideapad_attributes[] = {
&dev_attr_camera_power.attr, &dev_attr_camera_power.attr,
&dev_attr_fan_mode.attr, &dev_attr_fan_mode.attr,
&dev_attr_touchpad.attr, &dev_attr_touchpad.attr,
&dev_attr_conservation_mode.attr,
NULL NULL
}; };
@ -477,6 +543,9 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
unsigned long value; unsigned long value;
supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN, supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
&value); &value);
} else if (attr == &dev_attr_conservation_mode.attr) {
supported = acpi_has_method(priv->adev->handle, "GBMD") &&
acpi_has_method(priv->adev->handle, "SBMC");
} else } else
supported = true; supported = true;

Просмотреть файл

@ -230,7 +230,7 @@ wakeup:
if (event != 0xc0) { if (event != 0xc0) {
if (!priv->array || if (!priv->array ||
!sparse_keymap_report_event(priv->array, event, 1, true)) !sparse_keymap_report_event(priv->array, event, 1, true))
dev_info(&device->dev, "unknown event 0x%x\n", event); dev_dbg(&device->dev, "unknown event 0x%x\n", event);
return; return;
} }
@ -241,7 +241,7 @@ wakeup:
} }
if (!sparse_keymap_report_event(priv->input_dev, ev_index, 1, true)) if (!sparse_keymap_report_event(priv->input_dev, ev_index, 1, true))
dev_info(&device->dev, "unknown event index 0x%llx\n", dev_dbg(&device->dev, "unknown event index 0x%llx\n",
ev_index); ev_index);
} }

Просмотреть файл

@ -83,7 +83,7 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
} else if (sparse_keymap_report_event(priv->input_dev, event, 1, true)) { } else if (sparse_keymap_report_event(priv->input_dev, event, 1, true)) {
return; return;
} }
dev_info(&device->dev, "unknown event index 0x%x\n", event); dev_dbg(&device->dev, "unknown event index 0x%x\n", event);
} }
static int intel_vbtn_probe(struct platform_device *device) static int intel_vbtn_probe(struct platform_device *device)

Просмотреть файл

@ -108,13 +108,13 @@ static irqreturn_t mid_pb_isr(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static struct mid_pb_ddata mfld_ddata = { static const struct mid_pb_ddata mfld_ddata = {
.mirqlvl1_addr = INTEL_MSIC_IRQLVL1MSK, .mirqlvl1_addr = INTEL_MSIC_IRQLVL1MSK,
.pbstat_addr = INTEL_MSIC_PBSTATUS, .pbstat_addr = INTEL_MSIC_PBSTATUS,
.pbstat_mask = MSIC_PB_LEVEL, .pbstat_mask = MSIC_PB_LEVEL,
}; };
static struct mid_pb_ddata mrfld_ddata = { static const struct mid_pb_ddata mrfld_ddata = {
.mirqlvl1_addr = BCOVE_IRQLVL1MSK, .mirqlvl1_addr = BCOVE_IRQLVL1MSK,
.pbstat_addr = BCOVE_PBSTATUS, .pbstat_addr = BCOVE_PBSTATUS,
.pbstat_mask = BCOVE_PB_LEVEL, .pbstat_mask = BCOVE_PB_LEVEL,
@ -142,8 +142,10 @@ static int mid_pb_probe(struct platform_device *pdev)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
if (irq < 0) if (irq < 0) {
return -EINVAL; dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq);
return irq;
}
input = devm_input_allocate_device(&pdev->dev); input = devm_input_allocate_device(&pdev->dev);
if (!input) if (!input)

Просмотреть файл

@ -110,6 +110,13 @@ static const struct pmc_reg_map spt_reg_map = {
.pfear_sts = spt_pfear_map, .pfear_sts = spt_pfear_map,
.mphy_sts = spt_mphy_map, .mphy_sts = spt_mphy_map,
.pll_sts = spt_pll_map, .pll_sts = spt_pll_map,
.slp_s0_offset = SPT_PMC_SLP_S0_RES_COUNTER_OFFSET,
.ltr_ignore_offset = SPT_PMC_LTR_IGNORE_OFFSET,
.regmap_length = SPT_PMC_MMIO_REG_LEN,
.ppfear0_offset = SPT_PMC_XRAM_PPFEAR0A,
.ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES,
.pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET,
.pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT,
}; };
static const struct pci_device_id pmc_pci_ids[] = { static const struct pci_device_id pmc_pci_ids[] = {
@ -157,12 +164,13 @@ static inline u32 pmc_core_adjust_slp_s0_step(u32 value)
int intel_pmc_slp_s0_counter_read(u32 *data) int intel_pmc_slp_s0_counter_read(u32 *data)
{ {
struct pmc_dev *pmcdev = &pmc; struct pmc_dev *pmcdev = &pmc;
const struct pmc_reg_map *map = pmcdev->map;
u32 value; u32 value;
if (!pmcdev->has_slp_s0_res) if (!pmcdev->has_slp_s0_res)
return -EACCES; return -EACCES;
value = pmc_core_reg_read(pmcdev, SPT_PMC_SLP_S0_RES_COUNTER_OFFSET); value = pmc_core_reg_read(pmcdev, map->slp_s0_offset);
*data = pmc_core_adjust_slp_s0_step(value); *data = pmc_core_adjust_slp_s0_step(value);
return 0; return 0;
@ -172,9 +180,10 @@ EXPORT_SYMBOL_GPL(intel_pmc_slp_s0_counter_read);
static int pmc_core_dev_state_get(void *data, u64 *val) static int pmc_core_dev_state_get(void *data, u64 *val)
{ {
struct pmc_dev *pmcdev = data; struct pmc_dev *pmcdev = data;
const struct pmc_reg_map *map = pmcdev->map;
u32 value; u32 value;
value = pmc_core_reg_read(pmcdev, SPT_PMC_SLP_S0_RES_COUNTER_OFFSET); value = pmc_core_reg_read(pmcdev, map->slp_s0_offset);
*val = pmc_core_adjust_slp_s0_step(value); *val = pmc_core_adjust_slp_s0_step(value);
return 0; return 0;
@ -187,8 +196,8 @@ static int pmc_core_check_read_lock_bit(void)
struct pmc_dev *pmcdev = &pmc; struct pmc_dev *pmcdev = &pmc;
u32 value; u32 value;
value = pmc_core_reg_read(pmcdev, SPT_PMC_PM_CFG_OFFSET); value = pmc_core_reg_read(pmcdev, pmcdev->map->pm_cfg_offset);
return value & BIT(SPT_PMC_READ_DISABLE_BIT); return value & BIT(pmcdev->map->pm_read_disable_bit);
} }
#if IS_ENABLED(CONFIG_DEBUG_FS) #if IS_ENABLED(CONFIG_DEBUG_FS)
@ -204,12 +213,13 @@ static int pmc_core_ppfear_sts_show(struct seq_file *s, void *unused)
{ {
struct pmc_dev *pmcdev = s->private; struct pmc_dev *pmcdev = s->private;
const struct pmc_bit_map *map = pmcdev->map->pfear_sts; const struct pmc_bit_map *map = pmcdev->map->pfear_sts;
u8 pf_regs[NUM_ENTRIES]; u8 pf_regs[PPFEAR_MAX_NUM_ENTRIES];
int index, iter; int index, iter;
iter = SPT_PMC_XRAM_PPFEAR0A; iter = pmcdev->map->ppfear0_offset;
for (index = 0; index < NUM_ENTRIES; index++, iter++) for (index = 0; index < pmcdev->map->ppfear_buckets &&
index < PPFEAR_MAX_NUM_ENTRIES; index++, iter++)
pf_regs[index] = pmc_core_reg_read_byte(pmcdev, iter); pf_regs[index] = pmc_core_reg_read_byte(pmcdev, iter);
for (index = 0; map[index].name; index++) for (index = 0; map[index].name; index++)
@ -376,6 +386,7 @@ static ssize_t pmc_core_ltr_ignore_write(struct file *file, const char __user
*userbuf, size_t count, loff_t *ppos) *userbuf, size_t count, loff_t *ppos)
{ {
struct pmc_dev *pmcdev = &pmc; struct pmc_dev *pmcdev = &pmc;
const struct pmc_reg_map *map = pmcdev->map;
u32 val, buf_size, fd; u32 val, buf_size, fd;
int err = 0; int err = 0;
@ -392,9 +403,9 @@ static ssize_t pmc_core_ltr_ignore_write(struct file *file, const char __user
goto out_unlock; goto out_unlock;
} }
fd = pmc_core_reg_read(pmcdev, SPT_PMC_LTR_IGNORE_OFFSET); fd = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset);
fd |= (1U << val); fd |= (1U << val);
pmc_core_reg_write(pmcdev, SPT_PMC_LTR_IGNORE_OFFSET, fd); pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, fd);
out_unlock: out_unlock:
mutex_unlock(&pmcdev->lock); mutex_unlock(&pmcdev->lock);
@ -530,8 +541,8 @@ static int pmc_core_probe(struct pci_dev *dev, const struct pci_device_id *id)
} }
mutex_init(&pmcdev->lock); mutex_init(&pmcdev->lock);
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
pmcdev->map = map; pmcdev->map = map;
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
err = pmc_core_dbgfs_register(pmcdev); err = pmc_core_dbgfs_register(pmcdev);
if (err < 0) if (err < 0)

Просмотреть файл

@ -38,7 +38,8 @@
#define SPT_PMC_SLP_S0_RES_COUNTER_STEP 0x64 #define SPT_PMC_SLP_S0_RES_COUNTER_STEP 0x64
#define PMC_BASE_ADDR_MASK ~(SPT_PMC_MMIO_REG_LEN - 1) #define PMC_BASE_ADDR_MASK ~(SPT_PMC_MMIO_REG_LEN - 1)
#define MTPMC_MASK 0xffff0000 #define MTPMC_MASK 0xffff0000
#define NUM_ENTRIES 5 #define PPFEAR_MAX_NUM_ENTRIES 5
#define SPT_PPFEAR_NUM_ENTRIES 5
#define SPT_PMC_READ_DISABLE_BIT 0x16 #define SPT_PMC_READ_DISABLE_BIT 0x16
#define SPT_PMC_MSG_FULL_STS_BIT 0x18 #define SPT_PMC_MSG_FULL_STS_BIT 0x18
#define NUM_RETRIES 100 #define NUM_RETRIES 100
@ -126,10 +127,37 @@ struct pmc_bit_map {
u32 bit_mask; u32 bit_mask;
}; };
/**
* struct pmc_reg_map - Structure used to define parameter unique to a
PCH family
* @pfear_sts: Maps name of IP block to PPFEAR* bit
* @mphy_sts: Maps name of MPHY lane to MPHY status lane status bit
* @pll_sts: Maps name of PLL to corresponding bit status
* @slp_s0_offset: PWRMBASE offset to read SLP_S0 residency
* @ltr_ignore_offset: PWRMBASE offset to read/write LTR ignore bit
* @base_address: Base address of PWRMBASE defined in BIOS writer guide
* @regmap_length: Length of memory to map from PWRMBASE address to access
* @ppfear0_offset: PWRMBASE offset to to read PPFEAR*
* @ppfear_buckets: Number of 8 bits blocks to read all IP blocks from
* PPFEAR
* @pm_cfg_offset: PWRMBASE offset to PM_CFG register
* @pm_read_disable_bit: Bit index to read PMC_READ_DISABLE
*
* Each PCH has unique set of register offsets and bit indexes. This structure
* captures them to have a common implementation.
*/
struct pmc_reg_map { struct pmc_reg_map {
const struct pmc_bit_map *pfear_sts; const struct pmc_bit_map *pfear_sts;
const struct pmc_bit_map *mphy_sts; const struct pmc_bit_map *mphy_sts;
const struct pmc_bit_map *pll_sts; const struct pmc_bit_map *pll_sts;
const u32 slp_s0_offset;
const u32 ltr_ignore_offset;
const u32 base_address;
const int regmap_length;
const u32 ppfear0_offset;
const int ppfear_buckets;
const u32 pm_cfg_offset;
const int pm_read_disable_bit;
}; };
/** /**

Просмотреть файл

@ -72,20 +72,20 @@ struct intel_scu_ipc_pdata_t {
u8 irq_mode; u8 irq_mode;
}; };
static struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = { static const struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = {
.i2c_base = 0xff12b000, .i2c_base = 0xff12b000,
.i2c_len = 0x10, .i2c_len = 0x10,
.irq_mode = 0, .irq_mode = 0,
}; };
/* Penwell and Cloverview */ /* Penwell and Cloverview */
static struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = { static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
.i2c_base = 0xff12b000, .i2c_base = 0xff12b000,
.i2c_len = 0x10, .i2c_len = 0x10,
.irq_mode = 1, .irq_mode = 1,
}; };
static struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = { static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
.i2c_base = 0xff00d000, .i2c_base = 0xff00d000,
.i2c_len = 0x10, .i2c_len = 0x10,
.irq_mode = 0, .irq_mode = 0,

Просмотреть файл

@ -331,6 +331,7 @@ static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = { static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_debugfs_conf), TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_debugfs_conf),
TELEM_DEBUGFS_CPU(INTEL_FAM6_ATOM_GEMINI_LAKE, telem_apl_debugfs_conf),
{} {}
}; };

Просмотреть файл

@ -46,7 +46,6 @@
#define TELEM_SAMPLING_DEFAULT_PERIOD 0xD #define TELEM_SAMPLING_DEFAULT_PERIOD 0xD
#define TELEM_MAX_EVENTS_SRAM 28 #define TELEM_MAX_EVENTS_SRAM 28
#define TELEM_MAX_OS_ALLOCATED_EVENTS 20
#define TELEM_SSRAM_STARTTIME_OFFSET 8 #define TELEM_SSRAM_STARTTIME_OFFSET 8
#define TELEM_SSRAM_EVTLOG_OFFSET 16 #define TELEM_SSRAM_EVTLOG_OFFSET 16
@ -153,6 +152,30 @@ static struct telemetry_evtmap
{"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40}, {"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40},
}; };
static struct telemetry_evtmap
telemetry_glk_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
{"IA_CORE0_C6_RES", 0x0400},
{"IA_CORE0_C6_CTR", 0x0000},
{"IA_MODULE0_C7_RES", 0x0410},
{"IA_MODULE0_C7_CTR", 0x000C},
{"IA_C0_RES", 0x0805},
{"PCS_LTR", 0x2801},
{"PSTATES", 0x2802},
{"SOC_S0I3_RES", 0x0407},
{"SOC_S0I3_CTR", 0x0008},
{"PCS_S0I3_CTR", 0x0007},
{"PCS_C1E_RES", 0x0414},
{"PCS_IDLE_STATUS", 0x2806},
{"IA_PERF_LIMITS", 0x280B},
{"GT_PERF_LIMITS", 0x280C},
{"PCS_WAKEUP_S0IX_CTR", 0x0025},
{"PCS_IDLE_BLOCKED", 0x2C00},
{"PCS_S0IX_BLOCKED", 0x2C01},
{"PCS_S0IX_WAKE_REASONS", 0x2C02},
{"PCS_LTR_BLOCKING", 0x2C03},
{"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40},
};
/* APL specific Data */ /* APL specific Data */
static struct telemetry_plt_config telem_apl_config = { static struct telemetry_plt_config telem_apl_config = {
.pss_config = { .pss_config = {
@ -163,8 +186,19 @@ static struct telemetry_plt_config telem_apl_config = {
}, },
}; };
/* GLK specific Data */
static struct telemetry_plt_config telem_glk_config = {
.pss_config = {
.telem_evts = telemetry_glk_pss_default_events,
},
.ioss_config = {
.telem_evts = telemetry_apl_ioss_default_events,
},
};
static const struct x86_cpu_id telemetry_cpu_ids[] = { static const struct x86_cpu_id telemetry_cpu_ids[] = {
TELEM_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_config), TELEM_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_config),
TELEM_CPU(INTEL_FAM6_ATOM_GEMINI_LAKE, telem_glk_config),
{} {}
}; };

Просмотреть файл

@ -184,7 +184,7 @@ static const struct backlight_ops msi_backlight_ops = {
static void msi_wmi_notify(u32 value, void *context) static void msi_wmi_notify(u32 value, void *context)
{ {
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
static struct key_entry *key; struct key_entry *key;
union acpi_object *obj; union acpi_object *obj;
acpi_status status; acpi_status status;

Просмотреть файл

@ -53,7 +53,7 @@ int mxm_wmi_call_mxds(int adapter)
printk("calling mux switch %d\n", adapter); printk("calling mux switch %d\n", adapter);
status = wmi_evaluate_method(MXM_WMMX_GUID, 0x1, adapter, &input, status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
&output); &output);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
@ -78,7 +78,7 @@ int mxm_wmi_call_mxmx(int adapter)
printk("calling mux switch %d\n", adapter); printk("calling mux switch %d\n", adapter);
status = wmi_evaluate_method(MXM_WMMX_GUID, 0x1, adapter, &input, status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
&output); &output);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))

Просмотреть файл

@ -39,7 +39,7 @@ static void peaq_wmi_poll(struct input_polled_dev *dev)
struct acpi_buffer input = { sizeof(dummy), &dummy }; struct acpi_buffer input = { sizeof(dummy), &dummy };
struct acpi_buffer output = { sizeof(obj), &obj }; struct acpi_buffer output = { sizeof(obj), &obj };
status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 1, status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 0,
PEAQ_DOLBY_BUTTON_METHOD_ID, PEAQ_DOLBY_BUTTON_METHOD_ID,
&input, &output); &input, &output);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
@ -51,7 +51,7 @@ static void peaq_wmi_poll(struct input_polled_dev *dev)
return; return;
} }
if (peaq_ignore_events_counter && --peaq_ignore_events_counter >= 0) if (peaq_ignore_events_counter && peaq_ignore_events_counter--)
return; return;
if (obj.integer.value) { if (obj.integer.value) {

Просмотреть файл

@ -24,7 +24,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define TPACPI_VERSION "0.25" #define TPACPI_VERSION "0.25"
#define TPACPI_SYSFS_VERSION 0x020700 #define TPACPI_SYSFS_VERSION 0x030000
/* /*
* Changelog: * Changelog:
@ -6342,7 +6342,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
switch (thermal_read_mode) { switch (thermal_read_mode) {
case TPACPI_THERMAL_TPEC_16: case TPACPI_THERMAL_TPEC_16:
res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, res = sysfs_create_group(&tpacpi_hwmon->kobj,
&thermal_temp_input16_group); &thermal_temp_input16_group);
if (res) if (res)
return res; return res;
@ -6350,7 +6350,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
case TPACPI_THERMAL_TPEC_8: case TPACPI_THERMAL_TPEC_8:
case TPACPI_THERMAL_ACPI_TMP07: case TPACPI_THERMAL_ACPI_TMP07:
case TPACPI_THERMAL_ACPI_UPDT: case TPACPI_THERMAL_ACPI_UPDT:
res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, res = sysfs_create_group(&tpacpi_hwmon->kobj,
&thermal_temp_input8_group); &thermal_temp_input8_group);
if (res) if (res)
return res; return res;
@ -6367,13 +6367,13 @@ static void thermal_exit(void)
{ {
switch (thermal_read_mode) { switch (thermal_read_mode) {
case TPACPI_THERMAL_TPEC_16: case TPACPI_THERMAL_TPEC_16:
sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, sysfs_remove_group(&tpacpi_hwmon->kobj,
&thermal_temp_input16_group); &thermal_temp_input16_group);
break; break;
case TPACPI_THERMAL_TPEC_8: case TPACPI_THERMAL_TPEC_8:
case TPACPI_THERMAL_ACPI_TMP07: case TPACPI_THERMAL_ACPI_TMP07:
case TPACPI_THERMAL_ACPI_UPDT: case TPACPI_THERMAL_ACPI_UPDT:
sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, sysfs_remove_group(&tpacpi_hwmon->kobj,
&thermal_temp_input8_group); &thermal_temp_input8_group);
break; break;
case TPACPI_THERMAL_NONE: case TPACPI_THERMAL_NONE:
@ -8696,7 +8696,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
fan_attributes[ARRAY_SIZE(fan_attributes)-2] = fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
&dev_attr_fan2_input.attr; &dev_attr_fan2_input.attr;
} }
rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, rc = sysfs_create_group(&tpacpi_hwmon->kobj,
&fan_attr_group); &fan_attr_group);
if (rc < 0) if (rc < 0)
return rc; return rc;
@ -8704,7 +8704,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
&driver_attr_fan_watchdog); &driver_attr_fan_watchdog);
if (rc < 0) { if (rc < 0) {
sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, sysfs_remove_group(&tpacpi_hwmon->kobj,
&fan_attr_group); &fan_attr_group);
return rc; return rc;
} }
@ -8719,7 +8719,7 @@ static void fan_exit(void)
"cancelling any pending fan watchdog tasks\n"); "cancelling any pending fan watchdog tasks\n");
/* FIXME: can we really do this unconditionally? */ /* FIXME: can we really do this unconditionally? */
sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); sysfs_remove_group(&tpacpi_hwmon->kobj, &fan_attr_group);
driver_remove_file(&tpacpi_hwmon_pdriver.driver, driver_remove_file(&tpacpi_hwmon_pdriver.driver,
&driver_attr_fan_watchdog); &driver_attr_fan_watchdog);
@ -9149,16 +9149,6 @@ static void hotkey_driver_event(const unsigned int scancode)
tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode); tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
} }
/* sysfs name ---------------------------------------------------------- */
static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME);
}
static DEVICE_ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* /proc support */ /* /proc support */
@ -9696,8 +9686,6 @@ static void thinkpad_acpi_module_exit(void)
if (tpacpi_hwmon) if (tpacpi_hwmon)
hwmon_device_unregister(tpacpi_hwmon); hwmon_device_unregister(tpacpi_hwmon);
if (tp_features.sensors_pdev_attrs_registered)
device_remove_file(&tpacpi_sensors_pdev->dev, &dev_attr_name);
if (tpacpi_sensors_pdev) if (tpacpi_sensors_pdev)
platform_device_unregister(tpacpi_sensors_pdev); platform_device_unregister(tpacpi_sensors_pdev);
if (tpacpi_pdev) if (tpacpi_pdev)
@ -9818,14 +9806,10 @@ static int __init thinkpad_acpi_module_init(void)
thinkpad_acpi_module_exit(); thinkpad_acpi_module_exit();
return ret; return ret;
} }
ret = device_create_file(&tpacpi_sensors_pdev->dev, &dev_attr_name);
if (ret) {
pr_err("unable to create sysfs hwmon device attributes\n");
thinkpad_acpi_module_exit();
return ret;
}
tp_features.sensors_pdev_attrs_registered = 1; tp_features.sensors_pdev_attrs_registered = 1;
tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev); tpacpi_hwmon = hwmon_device_register_with_groups(
&tpacpi_sensors_pdev->dev, TPACPI_NAME, NULL, NULL);
if (IS_ERR(tpacpi_hwmon)) { if (IS_ERR(tpacpi_hwmon)) {
ret = PTR_ERR(tpacpi_hwmon); ret = PTR_ERR(tpacpi_hwmon);
tpacpi_hwmon = NULL; tpacpi_hwmon = NULL;

Просмотреть файл

@ -218,7 +218,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
if (!(block->flags & ACPI_WMI_METHOD)) if (!(block->flags & ACPI_WMI_METHOD))
return AE_BAD_DATA; return AE_BAD_DATA;
if (block->instance_count < instance) if (block->instance_count <= instance)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
input.count = 2; input.count = 2;
@ -265,7 +265,7 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
block = &wblock->gblock; block = &wblock->gblock;
handle = wblock->acpi_device->handle; handle = wblock->acpi_device->handle;
if (block->instance_count < instance) if (block->instance_count <= instance)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
/* Check GUID is a data block */ /* Check GUID is a data block */
@ -392,7 +392,7 @@ acpi_status wmi_set_block(const char *guid_string, u8 instance,
block = &wblock->gblock; block = &wblock->gblock;
handle = wblock->acpi_device->handle; handle = wblock->acpi_device->handle;
if (block->instance_count < instance) if (block->instance_count <= instance)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
/* Check GUID is a data block */ /* Check GUID is a data block */