forked from Minki/linux
Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86
Pull x86 platform driver updates from Matthew Garrett: "Nothing overly exciting here - a couple of new drivers that don't do a great deal, along with some miscellaneous fixes and a couple of small feature enablement patches" * 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86: x86 platform drivers: fix gpio leak toshiba_acpi: Add dependency on SERIO_I8042 asus-nb-wmi: set wapf=4 for ASUSTeK COMPUTER INC. 1015E/U Add trivial driver to disable Intel Smart Connect Add support driver for Intel Rapid Start Technology hp-wmi: add supports for POST code error asus-wmi: control wlan-led only if wapf == 4 drivers/platform/x86/intel_ips: Convert to module_pci_driver asus-nb-wmi: ignore ALS notification key code asus-wmi: append newline to messages x86: asus-laptop: fix invalid point access x86: msi-laptop: fix memleak amilo-rfkill: Add dependency on SERIO_I8042 dell-laptop: fix error return code in dell_init() hp-wmi: Enable hotkeys on some systems
This commit is contained in:
commit
63345b4794
21
Documentation/ABI/testing/sysfs-driver-intel-rapid-start
Normal file
21
Documentation/ABI/testing/sysfs-driver-intel-rapid-start
Normal file
@ -0,0 +1,21 @@
|
||||
What: /sys/bus/acpi/intel-rapid-start/wakeup_events
|
||||
Date: July 2, 2013
|
||||
KernelVersion: 3.11
|
||||
Contact: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Description: An integer representing a set of wakeup events as follows:
|
||||
1: Wake to enter hibernation when the wakeup timer expires
|
||||
2: Wake to enter hibernation when the battery reaches a
|
||||
critical level
|
||||
|
||||
These values are ORed together. For example, a value of 3
|
||||
indicates that the system will wake to enter hibernation when
|
||||
either the wakeup timer expires or the battery reaches a
|
||||
critical level.
|
||||
|
||||
What: /sys/bus/acpi/intel-rapid-start/wakeup_time
|
||||
Date: July 2, 2013
|
||||
KernelVersion: 3.11
|
||||
Contact: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Description: An integer representing the length of time the system will
|
||||
remain asleep before waking up to enter hibernation.
|
||||
This value is in minutes.
|
@ -176,6 +176,7 @@ config FUJITSU_TABLET
|
||||
config AMILO_RFKILL
|
||||
tristate "Fujitsu-Siemens Amilo rfkill support"
|
||||
depends on RFKILL
|
||||
depends on SERIO_I8042
|
||||
---help---
|
||||
This is a driver for enabling wifi on some Fujitsu-Siemens Amilo
|
||||
laptops.
|
||||
@ -591,6 +592,7 @@ config ACPI_TOSHIBA
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
depends on INPUT
|
||||
depends on RFKILL || RFKILL = n
|
||||
depends on SERIO_I8042 || SERIO_I8042 = n
|
||||
select INPUT_POLLDEV
|
||||
select INPUT_SPARSEKMAP
|
||||
---help---
|
||||
@ -781,6 +783,32 @@ config APPLE_GMUX
|
||||
graphics as well as the backlight. Currently only backlight
|
||||
control is supported by the driver.
|
||||
|
||||
config INTEL_RST
|
||||
tristate "Intel Rapid Start Technology Driver"
|
||||
depends on ACPI
|
||||
---help---
|
||||
This driver provides support for modifying paramaters on systems
|
||||
equipped with Intel's Rapid Start Technology. When put in an ACPI
|
||||
sleep state, these devices will wake after either a configured
|
||||
timeout or when the system battery reaches a critical state,
|
||||
automatically copying memory contents to disk. On resume, the
|
||||
firmware will copy the memory contents back to RAM and resume the OS
|
||||
as usual.
|
||||
|
||||
config INTEL_SMARTCONNECT
|
||||
tristate "Intel Smart Connect disabling driver"
|
||||
depends on ACPI
|
||||
---help---
|
||||
Intel Smart Connect is a technology intended to permit devices to
|
||||
update state by resuming for a short period of time at regular
|
||||
intervals. If a user enables this functionality under Windows and
|
||||
then reboots into Linux, the system may remain configured to resume
|
||||
on suspend. In the absence of any userspace to support it, the system
|
||||
will then remain awake until something triggers another suspend.
|
||||
|
||||
This driver checks to determine whether the device has Intel Smart
|
||||
Connect enabled, and if so disables it.
|
||||
|
||||
config PVPANIC
|
||||
tristate "pvpanic device support"
|
||||
depends on ACPI
|
||||
|
@ -51,5 +51,7 @@ obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
|
||||
obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
|
||||
obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
|
||||
obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
|
||||
obj-$(CONFIG_INTEL_RST) += intel-rst.o
|
||||
obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o
|
||||
|
||||
obj-$(CONFIG_PVPANIC) += pvpanic.o
|
||||
|
@ -1935,7 +1935,6 @@ fail_input:
|
||||
fail_backlight:
|
||||
asus_platform_exit(asus);
|
||||
fail_platform:
|
||||
kfree(asus->name);
|
||||
kfree(asus);
|
||||
|
||||
return result;
|
||||
|
@ -180,6 +180,24 @@ static struct dmi_system_id asus_quirks[] = {
|
||||
},
|
||||
.driver_data = &quirk_asus_x401u,
|
||||
},
|
||||
{
|
||||
.callback = dmi_matched,
|
||||
.ident = "ASUSTeK COMPUTER INC. 1015E",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "1015E"),
|
||||
},
|
||||
.driver_data = &quirk_asus_x401u,
|
||||
},
|
||||
{
|
||||
.callback = dmi_matched,
|
||||
.ident = "ASUSTeK COMPUTER INC. 1015U",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "1015U"),
|
||||
},
|
||||
.driver_data = &quirk_asus_x401u,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
@ -256,6 +274,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
|
||||
{ KE_KEY, 0xB5, { KEY_CALC } },
|
||||
{ KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
|
||||
{ KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
|
||||
{ KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */
|
||||
{ KE_END, 0},
|
||||
};
|
||||
|
||||
|
@ -558,7 +558,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (wlan_led_presence(asus)) {
|
||||
if (wlan_led_presence(asus) && (asus->driver->quirks->wapf == 4)) {
|
||||
INIT_WORK(&asus->wlan_led_work, wlan_led_update);
|
||||
|
||||
asus->wlan_led.name = "asus::wlan";
|
||||
@ -886,7 +886,8 @@ static int asus_new_rfkill(struct asus_wmi *asus,
|
||||
if (!*rfkill)
|
||||
return -EINVAL;
|
||||
|
||||
if (dev_id == ASUS_WMI_DEVID_WLAN)
|
||||
if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
|
||||
(asus->driver->quirks->wapf == 4))
|
||||
rfkill_set_led_trigger_name(*rfkill, "asus-wlan");
|
||||
|
||||
rfkill_init_sw_state(*rfkill, !result);
|
||||
@ -1045,7 +1046,7 @@ static ssize_t asus_hwmon_pwm1(struct device *dev,
|
||||
else if (value == 3)
|
||||
value = 255;
|
||||
else if (value != 0) {
|
||||
pr_err("Unknown fan speed %#x", value);
|
||||
pr_err("Unknown fan speed %#x\n", value);
|
||||
value = -1;
|
||||
}
|
||||
|
||||
@ -1557,11 +1558,11 @@ static int asus_wmi_platform_init(struct asus_wmi *asus)
|
||||
|
||||
/* INIT enable hotkeys on some models */
|
||||
if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
|
||||
pr_info("Initialization: %#x", rv);
|
||||
pr_info("Initialization: %#x\n", rv);
|
||||
|
||||
/* We don't know yet what to do with this version... */
|
||||
if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
|
||||
pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF);
|
||||
pr_info("BIOS WMI version: %d.%d\n", rv >> 16, rv & 0xFF);
|
||||
asus->spec = rv;
|
||||
}
|
||||
|
||||
@ -1572,7 +1573,7 @@ static int asus_wmi_platform_init(struct asus_wmi *asus)
|
||||
* The significance of others is yet to be found.
|
||||
*/
|
||||
if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
|
||||
pr_info("SFUN value: %#x", rv);
|
||||
pr_info("SFUN value: %#x\n", rv);
|
||||
asus->sfun = rv;
|
||||
}
|
||||
|
||||
@ -1712,7 +1713,7 @@ static int asus_wmi_debugfs_init(struct asus_wmi *asus)
|
||||
|
||||
asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
|
||||
if (!asus->debug.root) {
|
||||
pr_err("failed to create debugfs directory");
|
||||
pr_err("failed to create debugfs directory\n");
|
||||
goto error_debugfs;
|
||||
}
|
||||
|
||||
@ -1985,17 +1986,17 @@ EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
|
||||
static int __init asus_wmi_init(void)
|
||||
{
|
||||
if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
|
||||
pr_info("Asus Management GUID not found");
|
||||
pr_info("Asus Management GUID not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pr_info("ASUS WMI generic driver loaded");
|
||||
pr_info("ASUS WMI generic driver loaded\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit asus_wmi_exit(void)
|
||||
{
|
||||
pr_info("ASUS WMI generic driver unloaded");
|
||||
pr_info("ASUS WMI generic driver unloaded\n");
|
||||
}
|
||||
|
||||
module_init(asus_wmi_init);
|
||||
|
@ -551,9 +551,10 @@ static int __init dell_init(void)
|
||||
* is passed to SMI handler.
|
||||
*/
|
||||
bufferpage = alloc_page(GFP_KERNEL | GFP_DMA32);
|
||||
|
||||
if (!bufferpage)
|
||||
if (!bufferpage) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_buffer;
|
||||
}
|
||||
buffer = page_address(bufferpage);
|
||||
|
||||
if (quirks && quirks->touchpad_led)
|
||||
|
@ -53,8 +53,10 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
|
||||
#define HPWMI_ALS_QUERY 0x3
|
||||
#define HPWMI_HARDWARE_QUERY 0x4
|
||||
#define HPWMI_WIRELESS_QUERY 0x5
|
||||
#define HPWMI_BIOS_QUERY 0x9
|
||||
#define HPWMI_HOTKEY_QUERY 0xc
|
||||
#define HPWMI_WIRELESS2_QUERY 0x1b
|
||||
#define HPWMI_POSTCODEERROR_QUERY 0x2a
|
||||
|
||||
enum hp_wmi_radio {
|
||||
HPWMI_WIFI = 0,
|
||||
@ -291,6 +293,19 @@ static int hp_wmi_tablet_state(void)
|
||||
return (state & 0x4) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int hp_wmi_enable_hotkeys(void)
|
||||
{
|
||||
int ret;
|
||||
int query = 0x6e;
|
||||
|
||||
ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, 1, &query, sizeof(query),
|
||||
0);
|
||||
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hp_wmi_set_block(void *data, bool blocked)
|
||||
{
|
||||
enum hp_wmi_radio r = (enum hp_wmi_radio) data;
|
||||
@ -386,6 +401,16 @@ static int hp_wmi_rfkill2_refresh(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hp_wmi_post_code_state(void)
|
||||
{
|
||||
int state = 0;
|
||||
int ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 0, &state,
|
||||
sizeof(state), sizeof(state));
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
return state;
|
||||
}
|
||||
|
||||
static ssize_t show_display(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
@ -431,6 +456,16 @@ static ssize_t show_tablet(struct device *dev, struct device_attribute *attr,
|
||||
return sprintf(buf, "%d\n", value);
|
||||
}
|
||||
|
||||
static ssize_t show_postcode(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
/* Get the POST error code of previous boot failure. */
|
||||
int value = hp_wmi_post_code_state();
|
||||
if (value < 0)
|
||||
return -EINVAL;
|
||||
return sprintf(buf, "0x%x\n", value);
|
||||
}
|
||||
|
||||
static ssize_t set_als(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
@ -443,11 +478,33 @@ static ssize_t set_als(struct device *dev, struct device_attribute *attr,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_postcode(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
u32 tmp;
|
||||
long unsigned int tmp2;
|
||||
|
||||
ret = kstrtoul(buf, 10, &tmp2);
|
||||
if (ret || tmp2 != 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Clear the POST error code. It is kept until until cleared. */
|
||||
tmp = (u32) tmp2;
|
||||
ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 1, &tmp,
|
||||
sizeof(tmp), sizeof(tmp));
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(display, S_IRUGO, show_display, NULL);
|
||||
static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL);
|
||||
static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als);
|
||||
static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
|
||||
static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
|
||||
static DEVICE_ATTR(postcode, S_IRUGO | S_IWUSR, show_postcode, set_postcode);
|
||||
|
||||
static void hp_wmi_notify(u32 value, void *context)
|
||||
{
|
||||
@ -628,6 +685,7 @@ static void cleanup_sysfs(struct platform_device *device)
|
||||
device_remove_file(&device->dev, &dev_attr_als);
|
||||
device_remove_file(&device->dev, &dev_attr_dock);
|
||||
device_remove_file(&device->dev, &dev_attr_tablet);
|
||||
device_remove_file(&device->dev, &dev_attr_postcode);
|
||||
}
|
||||
|
||||
static int hp_wmi_rfkill_setup(struct platform_device *device)
|
||||
@ -843,6 +901,9 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
|
||||
if (err)
|
||||
goto add_sysfs_error;
|
||||
err = device_create_file(&device->dev, &dev_attr_tablet);
|
||||
if (err)
|
||||
goto add_sysfs_error;
|
||||
err = device_create_file(&device->dev, &dev_attr_postcode);
|
||||
if (err)
|
||||
goto add_sysfs_error;
|
||||
return 0;
|
||||
@ -948,6 +1009,8 @@ static int __init hp_wmi_init(void)
|
||||
err = hp_wmi_input_setup();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
hp_wmi_enable_hotkeys();
|
||||
}
|
||||
|
||||
if (bios_capable) {
|
||||
|
209
drivers/platform/x86/intel-rst.c
Normal file
209
drivers/platform/x86/intel-rst.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static ssize_t irst_show_wakeup_events(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct acpi_device *acpi;
|
||||
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *result;
|
||||
acpi_status status;
|
||||
|
||||
acpi = to_acpi_device(dev);
|
||||
|
||||
status = acpi_evaluate_object(acpi->handle, "GFFS", NULL, &output);
|
||||
if (!ACPI_SUCCESS(status))
|
||||
return -EINVAL;
|
||||
|
||||
result = output.pointer;
|
||||
|
||||
if (result->type != ACPI_TYPE_INTEGER) {
|
||||
kfree(result);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%lld\n", result->integer.value);
|
||||
}
|
||||
|
||||
static ssize_t irst_store_wakeup_events(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct acpi_device *acpi;
|
||||
struct acpi_object_list input;
|
||||
union acpi_object param;
|
||||
acpi_status status;
|
||||
unsigned long value;
|
||||
int error;
|
||||
|
||||
acpi = to_acpi_device(dev);
|
||||
|
||||
error = kstrtoul(buf, 0, &value);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
param.type = ACPI_TYPE_INTEGER;
|
||||
param.integer.value = value;
|
||||
|
||||
input.count = 1;
|
||||
input.pointer = ¶m;
|
||||
|
||||
status = acpi_evaluate_object(acpi->handle, "SFFS", &input, NULL);
|
||||
|
||||
if (!ACPI_SUCCESS(status))
|
||||
return -EINVAL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct device_attribute irst_wakeup_attr = {
|
||||
.attr = { .name = "wakeup_events", .mode = 0600 },
|
||||
.show = irst_show_wakeup_events,
|
||||
.store = irst_store_wakeup_events
|
||||
};
|
||||
|
||||
static ssize_t irst_show_wakeup_time(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct acpi_device *acpi;
|
||||
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *result;
|
||||
acpi_status status;
|
||||
|
||||
acpi = to_acpi_device(dev);
|
||||
|
||||
status = acpi_evaluate_object(acpi->handle, "GFTV", NULL, &output);
|
||||
if (!ACPI_SUCCESS(status))
|
||||
return -EINVAL;
|
||||
|
||||
result = output.pointer;
|
||||
|
||||
if (result->type != ACPI_TYPE_INTEGER) {
|
||||
kfree(result);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%lld\n", result->integer.value);
|
||||
}
|
||||
|
||||
static ssize_t irst_store_wakeup_time(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct acpi_device *acpi;
|
||||
struct acpi_object_list input;
|
||||
union acpi_object param;
|
||||
acpi_status status;
|
||||
unsigned long value;
|
||||
int error;
|
||||
|
||||
acpi = to_acpi_device(dev);
|
||||
|
||||
error = kstrtoul(buf, 0, &value);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
param.type = ACPI_TYPE_INTEGER;
|
||||
param.integer.value = value;
|
||||
|
||||
input.count = 1;
|
||||
input.pointer = ¶m;
|
||||
|
||||
status = acpi_evaluate_object(acpi->handle, "SFTV", &input, NULL);
|
||||
|
||||
if (!ACPI_SUCCESS(status))
|
||||
return -EINVAL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct device_attribute irst_timeout_attr = {
|
||||
.attr = { .name = "wakeup_time", .mode = 0600 },
|
||||
.show = irst_show_wakeup_time,
|
||||
.store = irst_store_wakeup_time
|
||||
};
|
||||
|
||||
static int irst_add(struct acpi_device *acpi)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
error = device_create_file(&acpi->dev, &irst_timeout_attr);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = device_create_file(&acpi->dev, &irst_wakeup_attr);
|
||||
if (error)
|
||||
goto out_timeout;
|
||||
|
||||
return 0;
|
||||
|
||||
out_timeout:
|
||||
device_remove_file(&acpi->dev, &irst_timeout_attr);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int irst_remove(struct acpi_device *acpi)
|
||||
{
|
||||
device_remove_file(&acpi->dev, &irst_wakeup_attr);
|
||||
device_remove_file(&acpi->dev, &irst_timeout_attr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id irst_ids[] = {
|
||||
{"INT3392", 0},
|
||||
{"", 0}
|
||||
};
|
||||
|
||||
static struct acpi_driver irst_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "intel_rapid_start",
|
||||
.class = "intel_rapid_start",
|
||||
.ids = irst_ids,
|
||||
.ops = {
|
||||
.add = irst_add,
|
||||
.remove = irst_remove,
|
||||
},
|
||||
};
|
||||
|
||||
static int irst_init(void)
|
||||
{
|
||||
return acpi_bus_register_driver(&irst_driver);
|
||||
}
|
||||
|
||||
static void irst_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&irst_driver);
|
||||
}
|
||||
|
||||
module_init(irst_init);
|
||||
module_exit(irst_exit);
|
||||
|
||||
MODULE_DEVICE_TABLE(acpi, irst_ids);
|
90
drivers/platform/x86/intel-smartconnect.c
Normal file
90
drivers/platform/x86/intel-smartconnect.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <acpi/acpi_drivers.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int smartconnect_acpi_init(struct acpi_device *acpi)
|
||||
{
|
||||
struct acpi_object_list input;
|
||||
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *result;
|
||||
union acpi_object param;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_object(acpi->handle, "GAOS", NULL, &output);
|
||||
if (!ACPI_SUCCESS(status))
|
||||
return -EINVAL;
|
||||
|
||||
result = output.pointer;
|
||||
|
||||
if (result->type != ACPI_TYPE_INTEGER) {
|
||||
kfree(result);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (result->integer.value & 0x1) {
|
||||
param.type = ACPI_TYPE_INTEGER;
|
||||
param.integer.value = 0;
|
||||
|
||||
input.count = 1;
|
||||
input.pointer = ¶m;
|
||||
|
||||
dev_info(&acpi->dev, "Disabling Intel Smart Connect\n");
|
||||
status = acpi_evaluate_object(acpi->handle, "SAOS", &input,
|
||||
NULL);
|
||||
}
|
||||
|
||||
kfree(result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id smartconnect_ids[] = {
|
||||
{"INT33A0", 0},
|
||||
{"", 0}
|
||||
};
|
||||
|
||||
static struct acpi_driver smartconnect_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "intel_smart_connect",
|
||||
.class = "intel_smart_connect",
|
||||
.ids = smartconnect_ids,
|
||||
.ops = {
|
||||
.add = smartconnect_acpi_init,
|
||||
},
|
||||
};
|
||||
|
||||
static int smartconnect_init(void)
|
||||
{
|
||||
return acpi_bus_register_driver(&smartconnect_driver);
|
||||
}
|
||||
|
||||
static void smartconnect_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&smartconnect_driver);
|
||||
}
|
||||
|
||||
module_init(smartconnect_init);
|
||||
module_exit(smartconnect_exit);
|
||||
|
||||
MODULE_DEVICE_TABLE(acpi, smartconnect_ids);
|
@ -1731,18 +1731,7 @@ static struct pci_driver ips_pci_driver = {
|
||||
.shutdown = ips_shutdown,
|
||||
};
|
||||
|
||||
static int __init ips_init(void)
|
||||
{
|
||||
return pci_register_driver(&ips_pci_driver);
|
||||
}
|
||||
module_init(ips_init);
|
||||
|
||||
static void ips_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&ips_pci_driver);
|
||||
return;
|
||||
}
|
||||
module_exit(ips_exit);
|
||||
module_pci_driver(ips_pci_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jesse Barnes <jbarnes@virtuousgeek.org>");
|
||||
|
@ -288,7 +288,7 @@ static int platform_pmic_gpio_probe(struct platform_device *pdev)
|
||||
retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg);
|
||||
if (retval) {
|
||||
pr_warn("Interrupt request failed\n");
|
||||
goto err;
|
||||
goto fail_request_irq;
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
@ -299,6 +299,10 @@ static int platform_pmic_gpio_probe(struct platform_device *pdev)
|
||||
irq_set_chip_data(i + pg->irq_base, pg);
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail_request_irq:
|
||||
if (gpiochip_remove(&pg->chip))
|
||||
pr_err("gpiochip_remove failed\n");
|
||||
err:
|
||||
iounmap(pg->gpiointr);
|
||||
err2:
|
||||
|
@ -1098,29 +1098,29 @@ static int __init msi_init(void)
|
||||
|
||||
ret = platform_device_add(msipf_device);
|
||||
if (ret)
|
||||
goto fail_platform_device1;
|
||||
goto fail_device_add;
|
||||
|
||||
if (quirks->load_scm_model && (load_scm_model_init(msipf_device) < 0)) {
|
||||
ret = -EINVAL;
|
||||
goto fail_platform_device1;
|
||||
goto fail_scm_model_init;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&msipf_device->dev.kobj,
|
||||
&msipf_attribute_group);
|
||||
if (ret)
|
||||
goto fail_platform_device2;
|
||||
goto fail_create_group;
|
||||
|
||||
if (!quirks->old_ec_model) {
|
||||
if (threeg_exists)
|
||||
ret = device_create_file(&msipf_device->dev,
|
||||
&dev_attr_threeg);
|
||||
if (ret)
|
||||
goto fail_platform_device2;
|
||||
goto fail_create_attr;
|
||||
} else {
|
||||
ret = sysfs_create_group(&msipf_device->dev.kobj,
|
||||
&msipf_old_attribute_group);
|
||||
if (ret)
|
||||
goto fail_platform_device2;
|
||||
goto fail_create_attr;
|
||||
|
||||
/* Disable automatic brightness control by default because
|
||||
* this module was probably loaded to do brightness control in
|
||||
@ -1134,26 +1134,22 @@ static int __init msi_init(void)
|
||||
|
||||
return 0;
|
||||
|
||||
fail_platform_device2:
|
||||
|
||||
fail_create_attr:
|
||||
sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
|
||||
fail_create_group:
|
||||
if (quirks->load_scm_model) {
|
||||
i8042_remove_filter(msi_laptop_i8042_filter);
|
||||
cancel_delayed_work_sync(&msi_rfkill_dwork);
|
||||
cancel_work_sync(&msi_rfkill_work);
|
||||
rfkill_cleanup();
|
||||
}
|
||||
fail_scm_model_init:
|
||||
platform_device_del(msipf_device);
|
||||
|
||||
fail_platform_device1:
|
||||
|
||||
fail_device_add:
|
||||
platform_device_put(msipf_device);
|
||||
|
||||
fail_platform_driver:
|
||||
|
||||
platform_driver_unregister(&msipf_driver);
|
||||
|
||||
fail_backlight:
|
||||
|
||||
backlight_device_unregister(msibl_device);
|
||||
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user