forked from Minki/linux
Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86
Pull x86 platform drivers update from Matthew Garrett: "Nothing amazingly special here. Some cleanups, a new driver to support a single button on some new HPs, a tiny amount of hardware enablement" * 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86: ipc: add intel-mid's pci id macros hp-wireless: new driver for hp wireless button for Windows 8 toshiba_acpi: Support RFKILL hotkey scancode hp_accel: Add a new PnP ID HPQ6007 for new HP laptops sony-laptop: remove unnecessary assigment of len fujitsu-laptop: fix error return code dell-laptop: Only install the i8042 filter when rfkill is active X86 platform: New BayTrail IOSF-SB MBI driver drivers: platform: Include appropriate header file in mxm-wmi.c drivers: platform: Mark functions as static in hp_accel.c dell-laptop: rkill whitelist Precision models ipc: simplify platform data approach asus-wmi: Convert to use devm_hwmon_device_register_with_groups compal-laptop: Use devm_hwmon_device_register_with_groups compal-laptop: Replace SENSOR_DEVICE_ATTR with DEVICE_ATTR eeepc-laptop: Convert to use devm_hwmon_device_register_with_groups compal-laptop: Use devm_kzalloc to allocate local data structure dell-laptop: fix to return error code in dell_send_intensity()
This commit is contained in:
commit
b7a8399edf
@ -197,6 +197,17 @@ config HP_ACCEL
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called hp_accel.
|
||||
|
||||
config HP_WIRELESS
|
||||
tristate "HP WIRELESS"
|
||||
depends on ACPI
|
||||
depends on INPUT
|
||||
help
|
||||
This driver provides supports for new HP wireless button for Windows 8.
|
||||
On such systems the driver should load automatically (via ACPI alias).
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called hp-wireless.
|
||||
|
||||
config HP_WMI
|
||||
tristate "HP WMI extras"
|
||||
depends on ACPI_WMI
|
||||
@ -808,4 +819,12 @@ config PVPANIC
|
||||
a paravirtualized device provided by QEMU; it lets a virtual machine
|
||||
(guest) communicate panic events to the host.
|
||||
|
||||
config INTEL_BAYTRAIL_MBI
|
||||
tristate
|
||||
depends on PCI
|
||||
---help---
|
||||
Needed on Baytrail platforms for access to the IOSF Sideband Mailbox
|
||||
Interface. This is a requirement for systems that need to configure
|
||||
the PUNIT for power management features such as RAPL.
|
||||
|
||||
endif # X86_PLATFORM_DEVICES
|
||||
|
@ -16,6 +16,7 @@ obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
|
||||
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
|
||||
obj-$(CONFIG_ACERHDF) += acerhdf.o
|
||||
obj-$(CONFIG_HP_ACCEL) += hp_accel.o
|
||||
obj-$(CONFIG_HP_WIRELESS) += hp-wireless.o
|
||||
obj-$(CONFIG_HP_WMI) += hp-wmi.o
|
||||
obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o
|
||||
obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
|
||||
@ -54,3 +55,4 @@ obj-$(CONFIG_INTEL_RST) += intel-rst.o
|
||||
obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o
|
||||
|
||||
obj-$(CONFIG_PVPANIC) += pvpanic.o
|
||||
obj-$(CONFIG_INTEL_BAYTRAIL_MBI) += intel_baytrail.o
|
||||
|
@ -183,7 +183,6 @@ struct asus_wmi {
|
||||
|
||||
struct input_dev *inputdev;
|
||||
struct backlight_device *backlight_device;
|
||||
struct device *hwmon_device;
|
||||
struct platform_device *platform_device;
|
||||
|
||||
struct led_classdev wlan_led;
|
||||
@ -1072,20 +1071,12 @@ static ssize_t asus_hwmon_temp1(struct device *dev,
|
||||
return sprintf(buf, "%d\n", value);
|
||||
}
|
||||
|
||||
static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL, 0);
|
||||
|
||||
static ssize_t
|
||||
show_name(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "asus\n");
|
||||
}
|
||||
static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
|
||||
static DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL);
|
||||
static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
|
||||
|
||||
static struct attribute *hwmon_attributes[] = {
|
||||
&sensor_dev_attr_pwm1.dev_attr.attr,
|
||||
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_name.dev_attr.attr,
|
||||
&dev_attr_pwm1.attr,
|
||||
&dev_attr_temp1_input.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -1099,9 +1090,9 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
|
||||
int dev_id = -1;
|
||||
u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
|
||||
|
||||
if (attr == &sensor_dev_attr_pwm1.dev_attr.attr)
|
||||
if (attr == &dev_attr_pwm1.attr)
|
||||
dev_id = ASUS_WMI_DEVID_FAN_CTRL;
|
||||
else if (attr == &sensor_dev_attr_temp1_input.dev_attr.attr)
|
||||
else if (attr == &dev_attr_temp1_input.attr)
|
||||
dev_id = ASUS_WMI_DEVID_THERMAL_CTRL;
|
||||
|
||||
if (dev_id != -1) {
|
||||
@ -1136,35 +1127,20 @@ static struct attribute_group hwmon_attribute_group = {
|
||||
.is_visible = asus_hwmon_sysfs_is_visible,
|
||||
.attrs = hwmon_attributes
|
||||
};
|
||||
|
||||
static void asus_wmi_hwmon_exit(struct asus_wmi *asus)
|
||||
{
|
||||
struct device *hwmon;
|
||||
|
||||
hwmon = asus->hwmon_device;
|
||||
if (!hwmon)
|
||||
return;
|
||||
sysfs_remove_group(&hwmon->kobj, &hwmon_attribute_group);
|
||||
hwmon_device_unregister(hwmon);
|
||||
asus->hwmon_device = NULL;
|
||||
}
|
||||
__ATTRIBUTE_GROUPS(hwmon_attribute);
|
||||
|
||||
static int asus_wmi_hwmon_init(struct asus_wmi *asus)
|
||||
{
|
||||
struct device *hwmon;
|
||||
int result;
|
||||
|
||||
hwmon = hwmon_device_register(&asus->platform_device->dev);
|
||||
hwmon = hwmon_device_register_with_groups(&asus->platform_device->dev,
|
||||
"asus", asus,
|
||||
hwmon_attribute_groups);
|
||||
if (IS_ERR(hwmon)) {
|
||||
pr_err("Could not register asus hwmon device\n");
|
||||
return PTR_ERR(hwmon);
|
||||
}
|
||||
dev_set_drvdata(hwmon, asus);
|
||||
asus->hwmon_device = hwmon;
|
||||
result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group);
|
||||
if (result)
|
||||
asus_wmi_hwmon_exit(asus);
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1835,7 +1811,6 @@ fail_backlight:
|
||||
fail_rfkill:
|
||||
asus_wmi_led_exit(asus);
|
||||
fail_leds:
|
||||
asus_wmi_hwmon_exit(asus);
|
||||
fail_hwmon:
|
||||
asus_wmi_input_exit(asus);
|
||||
fail_input:
|
||||
@ -1853,7 +1828,6 @@ static int asus_wmi_remove(struct platform_device *device)
|
||||
wmi_remove_notify_handler(asus->driver->event_guid);
|
||||
asus_wmi_backlight_exit(asus);
|
||||
asus_wmi_input_exit(asus);
|
||||
asus_wmi_hwmon_exit(asus);
|
||||
asus_wmi_led_exit(asus);
|
||||
asus_wmi_rfkill_exit(asus);
|
||||
asus_wmi_debugfs_exit(asus);
|
||||
|
@ -173,8 +173,7 @@
|
||||
/* ======= */
|
||||
struct compal_data{
|
||||
/* Fan control */
|
||||
struct device *hwmon_dev;
|
||||
int pwm_enable; /* 0:full on, 1:set by pwm1, 2:control by moterboard */
|
||||
int pwm_enable; /* 0:full on, 1:set by pwm1, 2:control by motherboard */
|
||||
unsigned char curr_pwm;
|
||||
|
||||
/* Power supply */
|
||||
@ -402,15 +401,6 @@ SIMPLE_MASKED_STORE_SHOW(wake_up_wlan, WAKE_UP_ADDR, WAKE_UP_WLAN)
|
||||
SIMPLE_MASKED_STORE_SHOW(wake_up_key, WAKE_UP_ADDR, WAKE_UP_KEY)
|
||||
SIMPLE_MASKED_STORE_SHOW(wake_up_mouse, WAKE_UP_ADDR, WAKE_UP_MOUSE)
|
||||
|
||||
|
||||
/* General hwmon interface */
|
||||
static ssize_t hwmon_name_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s\n", DRIVER_NAME);
|
||||
}
|
||||
|
||||
|
||||
/* Fan control interface */
|
||||
static ssize_t pwm_enable_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -665,56 +655,56 @@ static DEVICE_ATTR(wake_up_key,
|
||||
static DEVICE_ATTR(wake_up_mouse,
|
||||
0644, wake_up_mouse_show, wake_up_mouse_store);
|
||||
|
||||
static SENSOR_DEVICE_ATTR(name, S_IRUGO, hwmon_name_show, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, fan_show, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, temp_cpu, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, temp_cpu_local, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, temp_cpu_DTS, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, temp_northbridge, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, temp_vga, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, temp_SKIN, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, label_cpu, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, label_cpu_local, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, label_cpu_DTS, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, label_northbridge, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, label_vga, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, label_SKIN, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, pwm_show, pwm_store, 1);
|
||||
static SENSOR_DEVICE_ATTR(pwm1_enable,
|
||||
S_IRUGO | S_IWUSR, pwm_enable_show, pwm_enable_store, 0);
|
||||
static DEVICE_ATTR(fan1_input, S_IRUGO, fan_show, NULL);
|
||||
static DEVICE_ATTR(temp1_input, S_IRUGO, temp_cpu, NULL);
|
||||
static DEVICE_ATTR(temp2_input, S_IRUGO, temp_cpu_local, NULL);
|
||||
static DEVICE_ATTR(temp3_input, S_IRUGO, temp_cpu_DTS, NULL);
|
||||
static DEVICE_ATTR(temp4_input, S_IRUGO, temp_northbridge, NULL);
|
||||
static DEVICE_ATTR(temp5_input, S_IRUGO, temp_vga, NULL);
|
||||
static DEVICE_ATTR(temp6_input, S_IRUGO, temp_SKIN, NULL);
|
||||
static DEVICE_ATTR(temp1_label, S_IRUGO, label_cpu, NULL);
|
||||
static DEVICE_ATTR(temp2_label, S_IRUGO, label_cpu_local, NULL);
|
||||
static DEVICE_ATTR(temp3_label, S_IRUGO, label_cpu_DTS, NULL);
|
||||
static DEVICE_ATTR(temp4_label, S_IRUGO, label_northbridge, NULL);
|
||||
static DEVICE_ATTR(temp5_label, S_IRUGO, label_vga, NULL);
|
||||
static DEVICE_ATTR(temp6_label, S_IRUGO, label_SKIN, NULL);
|
||||
static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, pwm_show, pwm_store);
|
||||
static DEVICE_ATTR(pwm1_enable,
|
||||
S_IRUGO | S_IWUSR, pwm_enable_show, pwm_enable_store);
|
||||
|
||||
static struct attribute *compal_attributes[] = {
|
||||
static struct attribute *compal_platform_attrs[] = {
|
||||
&dev_attr_wake_up_pme.attr,
|
||||
&dev_attr_wake_up_modem.attr,
|
||||
&dev_attr_wake_up_lan.attr,
|
||||
&dev_attr_wake_up_wlan.attr,
|
||||
&dev_attr_wake_up_key.attr,
|
||||
&dev_attr_wake_up_mouse.attr,
|
||||
/* Maybe put the sensor-stuff in a separate hwmon-driver? That way,
|
||||
* the hwmon sysfs won't be cluttered with the above files. */
|
||||
&sensor_dev_attr_name.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm1.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp2_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp3_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp4_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp5_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp6_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp1_label.dev_attr.attr,
|
||||
&sensor_dev_attr_temp2_label.dev_attr.attr,
|
||||
&sensor_dev_attr_temp3_label.dev_attr.attr,
|
||||
&sensor_dev_attr_temp4_label.dev_attr.attr,
|
||||
&sensor_dev_attr_temp5_label.dev_attr.attr,
|
||||
&sensor_dev_attr_temp6_label.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group compal_attribute_group = {
|
||||
.attrs = compal_attributes
|
||||
static struct attribute_group compal_platform_attr_group = {
|
||||
.attrs = compal_platform_attrs
|
||||
};
|
||||
|
||||
static struct attribute *compal_hwmon_attrs[] = {
|
||||
&dev_attr_pwm1_enable.attr,
|
||||
&dev_attr_pwm1.attr,
|
||||
&dev_attr_fan1_input.attr,
|
||||
&dev_attr_temp1_input.attr,
|
||||
&dev_attr_temp2_input.attr,
|
||||
&dev_attr_temp3_input.attr,
|
||||
&dev_attr_temp4_input.attr,
|
||||
&dev_attr_temp5_input.attr,
|
||||
&dev_attr_temp6_input.attr,
|
||||
&dev_attr_temp1_label.attr,
|
||||
&dev_attr_temp2_label.attr,
|
||||
&dev_attr_temp3_label.attr,
|
||||
&dev_attr_temp4_label.attr,
|
||||
&dev_attr_temp5_label.attr,
|
||||
&dev_attr_temp6_label.attr,
|
||||
NULL
|
||||
};
|
||||
ATTRIBUTE_GROUPS(compal_hwmon);
|
||||
|
||||
static int compal_probe(struct platform_device *);
|
||||
static int compal_remove(struct platform_device *);
|
||||
static struct platform_driver compal_driver = {
|
||||
@ -1021,30 +1011,28 @@ static int compal_probe(struct platform_device *pdev)
|
||||
{
|
||||
int err;
|
||||
struct compal_data *data;
|
||||
struct device *hwmon_dev;
|
||||
|
||||
if (!extra_features)
|
||||
return 0;
|
||||
|
||||
/* Fan control */
|
||||
data = kzalloc(sizeof(struct compal_data), GFP_KERNEL);
|
||||
data = devm_kzalloc(&pdev->dev, sizeof(struct compal_data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
initialize_fan_control_data(data);
|
||||
|
||||
err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group);
|
||||
if (err) {
|
||||
kfree(data);
|
||||
err = sysfs_create_group(&pdev->dev.kobj, &compal_platform_attr_group);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
data->hwmon_dev = hwmon_device_register(&pdev->dev);
|
||||
if (IS_ERR(data->hwmon_dev)) {
|
||||
err = PTR_ERR(data->hwmon_dev);
|
||||
sysfs_remove_group(&pdev->dev.kobj,
|
||||
&compal_attribute_group);
|
||||
kfree(data);
|
||||
return err;
|
||||
hwmon_dev = hwmon_device_register_with_groups(&pdev->dev,
|
||||
DRIVER_NAME, data,
|
||||
compal_hwmon_groups);
|
||||
if (IS_ERR(hwmon_dev)) {
|
||||
err = PTR_ERR(hwmon_dev);
|
||||
goto remove;
|
||||
}
|
||||
|
||||
/* Power supply */
|
||||
@ -1054,6 +1042,10 @@ static int compal_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
return 0;
|
||||
|
||||
remove:
|
||||
sysfs_remove_group(&pdev->dev.kobj, &compal_platform_attr_group);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit compal_cleanup(void)
|
||||
@ -1080,12 +1072,9 @@ static int compal_remove(struct platform_device *pdev)
|
||||
pwm_disable_control();
|
||||
|
||||
data = platform_get_drvdata(pdev);
|
||||
hwmon_device_unregister(data->hwmon_dev);
|
||||
power_supply_unregister(&data->psy);
|
||||
|
||||
kfree(data);
|
||||
|
||||
sysfs_remove_group(&pdev->dev.kobj, &compal_attribute_group);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &compal_platform_attr_group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -559,19 +559,45 @@ static void dell_update_rfkill(struct work_struct *ignored)
|
||||
}
|
||||
static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill);
|
||||
|
||||
static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
|
||||
struct serio *port)
|
||||
{
|
||||
static bool extended;
|
||||
|
||||
if (str & 0x20)
|
||||
return false;
|
||||
|
||||
if (unlikely(data == 0xe0)) {
|
||||
extended = true;
|
||||
return false;
|
||||
} else if (unlikely(extended)) {
|
||||
switch (data) {
|
||||
case 0x8:
|
||||
schedule_delayed_work(&dell_rfkill_work,
|
||||
round_jiffies_relative(HZ / 4));
|
||||
break;
|
||||
}
|
||||
extended = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int __init dell_setup_rfkill(void)
|
||||
{
|
||||
int status;
|
||||
int ret;
|
||||
int status, ret, whitelisted;
|
||||
const char *product;
|
||||
|
||||
/*
|
||||
* rfkill causes trouble on various non Latitudes, according to Dell
|
||||
* actually testing the rfkill functionality is only done on Latitudes.
|
||||
* rfkill support causes trouble on various models, mostly Inspirons.
|
||||
* So we whitelist certain series, and don't support rfkill on others.
|
||||
*/
|
||||
whitelisted = 0;
|
||||
product = dmi_get_system_info(DMI_PRODUCT_NAME);
|
||||
if (!force_rfkill && (!product || strncmp(product, "Latitude", 8)))
|
||||
if (product && (strncmp(product, "Latitude", 8) == 0 ||
|
||||
strncmp(product, "Precision", 9) == 0))
|
||||
whitelisted = 1;
|
||||
if (!force_rfkill && !whitelisted)
|
||||
return 0;
|
||||
|
||||
get_buffer();
|
||||
@ -633,7 +659,16 @@ static int __init dell_setup_rfkill(void)
|
||||
goto err_wwan;
|
||||
}
|
||||
|
||||
ret = i8042_install_filter(dell_laptop_i8042_filter);
|
||||
if (ret) {
|
||||
pr_warn("Unable to install key filter\n");
|
||||
goto err_filter;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_filter:
|
||||
if (wwan_rfkill)
|
||||
rfkill_unregister(wwan_rfkill);
|
||||
err_wwan:
|
||||
rfkill_destroy(wwan_rfkill);
|
||||
if (bluetooth_rfkill)
|
||||
@ -684,7 +719,7 @@ static int dell_send_intensity(struct backlight_device *bd)
|
||||
|
||||
out:
|
||||
release_buffer();
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dell_get_intensity(struct backlight_device *bd)
|
||||
@ -755,30 +790,6 @@ static void touchpad_led_exit(void)
|
||||
led_classdev_unregister(&touchpad_led);
|
||||
}
|
||||
|
||||
static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
|
||||
struct serio *port)
|
||||
{
|
||||
static bool extended;
|
||||
|
||||
if (str & 0x20)
|
||||
return false;
|
||||
|
||||
if (unlikely(data == 0xe0)) {
|
||||
extended = true;
|
||||
return false;
|
||||
} else if (unlikely(extended)) {
|
||||
switch (data) {
|
||||
case 0x8:
|
||||
schedule_delayed_work(&dell_rfkill_work,
|
||||
round_jiffies_relative(HZ / 4));
|
||||
break;
|
||||
}
|
||||
extended = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int __init dell_init(void)
|
||||
{
|
||||
int max_intensity = 0;
|
||||
@ -828,12 +839,6 @@ static int __init dell_init(void)
|
||||
goto fail_rfkill;
|
||||
}
|
||||
|
||||
ret = i8042_install_filter(dell_laptop_i8042_filter);
|
||||
if (ret) {
|
||||
pr_warn("Unable to install key filter\n");
|
||||
goto fail_filter;
|
||||
}
|
||||
|
||||
if (quirks && quirks->touchpad_led)
|
||||
touchpad_led_init(&platform_device->dev);
|
||||
|
||||
@ -885,7 +890,6 @@ static int __init dell_init(void)
|
||||
fail_backlight:
|
||||
i8042_remove_filter(dell_laptop_i8042_filter);
|
||||
cancel_delayed_work_sync(&dell_rfkill_work);
|
||||
fail_filter:
|
||||
dell_cleanup_rfkill();
|
||||
fail_rfkill:
|
||||
free_page((unsigned long)bufferpage);
|
||||
|
@ -165,7 +165,6 @@ struct eeepc_laptop {
|
||||
|
||||
struct platform_device *platform_device;
|
||||
struct acpi_device *device; /* the device we are in */
|
||||
struct device *hwmon_device;
|
||||
struct backlight_device *backlight_device;
|
||||
|
||||
struct input_dev *inputdev;
|
||||
@ -1068,7 +1067,7 @@ static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
|
||||
{ \
|
||||
return store_sys_hwmon(_get, buf, count); \
|
||||
} \
|
||||
static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
|
||||
static DEVICE_ATTR(_name, _mode, show_##_name, store_##_name);
|
||||
|
||||
EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
|
||||
EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
|
||||
@ -1076,55 +1075,26 @@ EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
|
||||
EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
|
||||
eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
|
||||
|
||||
static ssize_t
|
||||
show_name(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "eeepc\n");
|
||||
}
|
||||
static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
|
||||
|
||||
static struct attribute *hwmon_attributes[] = {
|
||||
&sensor_dev_attr_pwm1.dev_attr.attr,
|
||||
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
|
||||
&sensor_dev_attr_name.dev_attr.attr,
|
||||
static struct attribute *hwmon_attrs[] = {
|
||||
&dev_attr_pwm1.attr,
|
||||
&dev_attr_fan1_input.attr,
|
||||
&dev_attr_pwm1_enable.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group hwmon_attribute_group = {
|
||||
.attrs = hwmon_attributes
|
||||
};
|
||||
|
||||
static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
|
||||
{
|
||||
struct device *hwmon;
|
||||
|
||||
hwmon = eeepc->hwmon_device;
|
||||
if (!hwmon)
|
||||
return;
|
||||
sysfs_remove_group(&hwmon->kobj,
|
||||
&hwmon_attribute_group);
|
||||
hwmon_device_unregister(hwmon);
|
||||
eeepc->hwmon_device = NULL;
|
||||
}
|
||||
ATTRIBUTE_GROUPS(hwmon);
|
||||
|
||||
static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
|
||||
{
|
||||
struct device *dev = &eeepc->platform_device->dev;
|
||||
struct device *hwmon;
|
||||
int result;
|
||||
|
||||
hwmon = hwmon_device_register(&eeepc->platform_device->dev);
|
||||
hwmon = devm_hwmon_device_register_with_groups(dev, "eeepc", NULL,
|
||||
hwmon_groups);
|
||||
if (IS_ERR(hwmon)) {
|
||||
pr_err("Could not register eeepc hwmon device\n");
|
||||
eeepc->hwmon_device = NULL;
|
||||
return PTR_ERR(hwmon);
|
||||
}
|
||||
eeepc->hwmon_device = hwmon;
|
||||
result = sysfs_create_group(&hwmon->kobj,
|
||||
&hwmon_attribute_group);
|
||||
if (result)
|
||||
eeepc_hwmon_exit(eeepc);
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1480,7 +1450,6 @@ static int eeepc_acpi_add(struct acpi_device *device)
|
||||
fail_rfkill:
|
||||
eeepc_led_exit(eeepc);
|
||||
fail_led:
|
||||
eeepc_hwmon_exit(eeepc);
|
||||
fail_hwmon:
|
||||
eeepc_input_exit(eeepc);
|
||||
fail_input:
|
||||
@ -1500,7 +1469,6 @@ static int eeepc_acpi_remove(struct acpi_device *device)
|
||||
eeepc_backlight_exit(eeepc);
|
||||
eeepc_rfkill_exit(eeepc);
|
||||
eeepc_input_exit(eeepc);
|
||||
eeepc_hwmon_exit(eeepc);
|
||||
eeepc_led_exit(eeepc);
|
||||
eeepc_platform_exit(eeepc);
|
||||
|
||||
|
@ -633,7 +633,6 @@ static struct dmi_system_id fujitsu_dmi_table[] = {
|
||||
|
||||
static int acpi_fujitsu_add(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
int state = 0;
|
||||
struct input_dev *input;
|
||||
int error;
|
||||
@ -669,8 +668,8 @@ static int acpi_fujitsu_add(struct acpi_device *device)
|
||||
if (error)
|
||||
goto err_free_input_dev;
|
||||
|
||||
result = acpi_bus_update_power(fujitsu->acpi_handle, &state);
|
||||
if (result) {
|
||||
error = acpi_bus_update_power(fujitsu->acpi_handle, &state);
|
||||
if (error) {
|
||||
pr_err("Error reading power state\n");
|
||||
goto err_unregister_input_dev;
|
||||
}
|
||||
@ -700,7 +699,7 @@ static int acpi_fujitsu_add(struct acpi_device *device)
|
||||
fujitsu->max_brightness = FUJITSU_LCD_N_LEVELS;
|
||||
get_lcd_level();
|
||||
|
||||
return result;
|
||||
return 0;
|
||||
|
||||
err_unregister_input_dev:
|
||||
input_unregister_device(input);
|
||||
@ -708,7 +707,7 @@ err_unregister_input_dev:
|
||||
err_free_input_dev:
|
||||
input_free_device(input);
|
||||
err_stop:
|
||||
return result;
|
||||
return error;
|
||||
}
|
||||
|
||||
static int acpi_fujitsu_remove(struct acpi_device *device)
|
||||
@ -831,8 +830,8 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
|
||||
if (error)
|
||||
goto err_free_input_dev;
|
||||
|
||||
result = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state);
|
||||
if (result) {
|
||||
error = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state);
|
||||
if (error) {
|
||||
pr_err("Error reading power state\n");
|
||||
goto err_unregister_input_dev;
|
||||
}
|
||||
@ -907,7 +906,7 @@ err_free_input_dev:
|
||||
err_free_fifo:
|
||||
kfifo_free(&fujitsu_hotkey->fifo);
|
||||
err_stop:
|
||||
return result;
|
||||
return error;
|
||||
}
|
||||
|
||||
static int acpi_fujitsu_hotkey_remove(struct acpi_device *device)
|
||||
|
132
drivers/platform/x86/hp-wireless.c
Normal file
132
drivers/platform/x86/hp-wireless.c
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* hp-wireless button for Windows 8
|
||||
*
|
||||
* Copyright (C) 2014 Alex Hung <alex.hung@canonical.com>
|
||||
*
|
||||
* 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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Alex Hung");
|
||||
MODULE_ALIAS("acpi*:HPQ6001:*");
|
||||
|
||||
static struct input_dev *hpwl_input_dev;
|
||||
|
||||
static const struct acpi_device_id hpwl_ids[] = {
|
||||
{"HPQ6001", 0},
|
||||
{"", 0},
|
||||
};
|
||||
|
||||
static int hp_wireless_input_setup(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
hpwl_input_dev = input_allocate_device();
|
||||
if (!hpwl_input_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
hpwl_input_dev->name = "HP Wireless hotkeys";
|
||||
hpwl_input_dev->phys = "hpq6001/input0";
|
||||
hpwl_input_dev->id.bustype = BUS_HOST;
|
||||
hpwl_input_dev->evbit[0] = BIT(EV_KEY);
|
||||
set_bit(KEY_RFKILL, hpwl_input_dev->keybit);
|
||||
|
||||
err = input_register_device(hpwl_input_dev);
|
||||
if (err)
|
||||
goto err_free_dev;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_dev:
|
||||
input_free_device(hpwl_input_dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void hp_wireless_input_destroy(void)
|
||||
{
|
||||
input_unregister_device(hpwl_input_dev);
|
||||
}
|
||||
|
||||
static void hpwl_notify(struct acpi_device *acpi_dev, u32 event)
|
||||
{
|
||||
if (event != 0x80) {
|
||||
pr_info("Received unknown event (0x%x)\n", event);
|
||||
return;
|
||||
}
|
||||
|
||||
input_report_key(hpwl_input_dev, KEY_RFKILL, 1);
|
||||
input_sync(hpwl_input_dev);
|
||||
input_report_key(hpwl_input_dev, KEY_RFKILL, 0);
|
||||
input_sync(hpwl_input_dev);
|
||||
}
|
||||
|
||||
static int hpwl_add(struct acpi_device *device)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hp_wireless_input_setup();
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hpwl_remove(struct acpi_device *device)
|
||||
{
|
||||
hp_wireless_input_destroy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct acpi_driver hpwl_driver = {
|
||||
.name = "hp-wireless",
|
||||
.owner = THIS_MODULE,
|
||||
.ids = hpwl_ids,
|
||||
.ops = {
|
||||
.add = hpwl_add,
|
||||
.remove = hpwl_remove,
|
||||
.notify = hpwl_notify,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init hpwl_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
pr_info("Initializing HPQ6001 module\n");
|
||||
err = acpi_bus_register_driver(&hpwl_driver);
|
||||
if (err) {
|
||||
pr_err("Unable to register HP wireless control driver.\n");
|
||||
goto error_acpi_register;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_acpi_register:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit hpwl_exit(void)
|
||||
{
|
||||
pr_info("Exiting HPQ6001 module\n");
|
||||
acpi_bus_unregister_driver(&hpwl_driver);
|
||||
}
|
||||
|
||||
module_init(hpwl_init);
|
||||
module_exit(hpwl_exit);
|
@ -77,6 +77,7 @@ static inline void delayed_sysfs_set(struct led_classdev *led_cdev,
|
||||
static struct acpi_device_id lis3lv02d_device_ids[] = {
|
||||
{"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */
|
||||
{"HPQ6000", 0}, /* HP Mobile Data Protection System PNP */
|
||||
{"HPQ6007", 0}, /* HP Mobile Data Protection System PNP */
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
|
||||
@ -88,7 +89,7 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
|
||||
static int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
|
||||
{
|
||||
struct acpi_device *dev = lis3->bus_priv;
|
||||
if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI,
|
||||
@ -106,7 +107,7 @@ int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret)
|
||||
static int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret)
|
||||
{
|
||||
struct acpi_device *dev = lis3->bus_priv;
|
||||
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
|
||||
@ -129,7 +130,7 @@ int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret)
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
|
||||
static int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
|
||||
{
|
||||
struct acpi_device *dev = lis3->bus_priv;
|
||||
unsigned long long ret; /* Not used when writting */
|
||||
|
224
drivers/platform/x86/intel_baytrail.c
Normal file
224
drivers/platform/x86/intel_baytrail.c
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Baytrail IOSF-SB MailBox Interface Driver
|
||||
* Copyright (c) 2013, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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.
|
||||
*
|
||||
*
|
||||
* The IOSF-SB is a fabric bus available on Atom based SOC's that uses a
|
||||
* mailbox interface (MBI) to communicate with mutiple devices. This
|
||||
* driver implements BayTrail-specific access to this interface.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "intel_baytrail.h"
|
||||
|
||||
static DEFINE_SPINLOCK(iosf_mbi_lock);
|
||||
|
||||
static inline u32 iosf_mbi_form_mcr(u8 op, u8 port, u8 offset)
|
||||
{
|
||||
return (op << 24) | (port << 16) | (offset << 8) | BT_MBI_ENABLE;
|
||||
}
|
||||
|
||||
static struct pci_dev *mbi_pdev; /* one mbi device */
|
||||
|
||||
/* Hold lock before calling */
|
||||
static int iosf_mbi_pci_read_mdr(u32 mcrx, u32 mcr, u32 *mdr)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!mbi_pdev)
|
||||
return -ENODEV;
|
||||
|
||||
if (mcrx) {
|
||||
result = pci_write_config_dword(mbi_pdev,
|
||||
BT_MBI_MCRX_OFFSET, mcrx);
|
||||
if (result < 0)
|
||||
goto iosf_mbi_read_err;
|
||||
}
|
||||
|
||||
result = pci_write_config_dword(mbi_pdev,
|
||||
BT_MBI_MCR_OFFSET, mcr);
|
||||
if (result < 0)
|
||||
goto iosf_mbi_read_err;
|
||||
|
||||
result = pci_read_config_dword(mbi_pdev,
|
||||
BT_MBI_MDR_OFFSET, mdr);
|
||||
if (result < 0)
|
||||
goto iosf_mbi_read_err;
|
||||
|
||||
return 0;
|
||||
|
||||
iosf_mbi_read_err:
|
||||
dev_err(&mbi_pdev->dev, "error: PCI config operation returned %d\n",
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Hold lock before calling */
|
||||
static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!mbi_pdev)
|
||||
return -ENODEV;
|
||||
|
||||
result = pci_write_config_dword(mbi_pdev,
|
||||
BT_MBI_MDR_OFFSET, mdr);
|
||||
if (result < 0)
|
||||
goto iosf_mbi_write_err;
|
||||
|
||||
if (mcrx) {
|
||||
result = pci_write_config_dword(mbi_pdev,
|
||||
BT_MBI_MCRX_OFFSET, mcrx);
|
||||
if (result < 0)
|
||||
goto iosf_mbi_write_err;
|
||||
}
|
||||
|
||||
result = pci_write_config_dword(mbi_pdev,
|
||||
BT_MBI_MCR_OFFSET, mcr);
|
||||
if (result < 0)
|
||||
goto iosf_mbi_write_err;
|
||||
|
||||
return 0;
|
||||
|
||||
iosf_mbi_write_err:
|
||||
dev_err(&mbi_pdev->dev, "error: PCI config operation returned %d\n",
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int bt_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr)
|
||||
{
|
||||
u32 mcr, mcrx;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/*Access to the GFX unit is handled by GPU code */
|
||||
BUG_ON(port == BT_MBI_UNIT_GFX);
|
||||
|
||||
mcr = iosf_mbi_form_mcr(opcode, port, offset & BT_MBI_MASK_LO);
|
||||
mcrx = offset & BT_MBI_MASK_HI;
|
||||
|
||||
spin_lock_irqsave(&iosf_mbi_lock, flags);
|
||||
ret = iosf_mbi_pci_read_mdr(mcrx, mcr, mdr);
|
||||
spin_unlock_irqrestore(&iosf_mbi_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(bt_mbi_read);
|
||||
|
||||
int bt_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr)
|
||||
{
|
||||
u32 mcr, mcrx;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/*Access to the GFX unit is handled by GPU code */
|
||||
BUG_ON(port == BT_MBI_UNIT_GFX);
|
||||
|
||||
mcr = iosf_mbi_form_mcr(opcode, port, offset & BT_MBI_MASK_LO);
|
||||
mcrx = offset & BT_MBI_MASK_HI;
|
||||
|
||||
spin_lock_irqsave(&iosf_mbi_lock, flags);
|
||||
ret = iosf_mbi_pci_write_mdr(mcrx, mcr, mdr);
|
||||
spin_unlock_irqrestore(&iosf_mbi_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(bt_mbi_write);
|
||||
|
||||
int bt_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask)
|
||||
{
|
||||
u32 mcr, mcrx;
|
||||
u32 value;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/*Access to the GFX unit is handled by GPU code */
|
||||
BUG_ON(port == BT_MBI_UNIT_GFX);
|
||||
|
||||
mcr = iosf_mbi_form_mcr(opcode, port, offset & BT_MBI_MASK_LO);
|
||||
mcrx = offset & BT_MBI_MASK_HI;
|
||||
|
||||
spin_lock_irqsave(&iosf_mbi_lock, flags);
|
||||
|
||||
/* Read current mdr value */
|
||||
ret = iosf_mbi_pci_read_mdr(mcrx, mcr & BT_MBI_RD_MASK, &value);
|
||||
if (ret < 0) {
|
||||
spin_unlock_irqrestore(&iosf_mbi_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Apply mask */
|
||||
value &= ~mask;
|
||||
mdr &= mask;
|
||||
value |= mdr;
|
||||
|
||||
/* Write back */
|
||||
ret = iosf_mbi_pci_write_mdr(mcrx, mcr | BT_MBI_WR_MASK, value);
|
||||
|
||||
spin_unlock_irqrestore(&iosf_mbi_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(bt_mbi_modify);
|
||||
|
||||
static int iosf_mbi_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *unused)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "error: could not enable device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
mbi_pdev = pci_dev_get(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(iosf_mbi_pci_ids) = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0F00) },
|
||||
{ 0, },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, iosf_mbi_pci_ids);
|
||||
|
||||
static struct pci_driver iosf_mbi_pci_driver = {
|
||||
.name = "iosf_mbi_pci",
|
||||
.probe = iosf_mbi_probe,
|
||||
.id_table = iosf_mbi_pci_ids,
|
||||
};
|
||||
|
||||
static int __init bt_mbi_init(void)
|
||||
{
|
||||
return pci_register_driver(&iosf_mbi_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit bt_mbi_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&iosf_mbi_pci_driver);
|
||||
if (mbi_pdev) {
|
||||
pci_dev_put(mbi_pdev);
|
||||
mbi_pdev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
module_init(bt_mbi_init);
|
||||
module_exit(bt_mbi_exit);
|
||||
|
||||
MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
|
||||
MODULE_DESCRIPTION("BayTrail Mailbox Interface accessor");
|
||||
MODULE_LICENSE("GPL v2");
|
90
drivers/platform/x86/intel_baytrail.h
Normal file
90
drivers/platform/x86/intel_baytrail.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* intel_baytrail.h: MailBox access support for Intel BayTrail platforms
|
||||
*/
|
||||
|
||||
#ifndef INTEL_BAYTRAIL_MBI_SYMS_H
|
||||
#define INTEL_BAYTRAIL_MBI_SYMS_H
|
||||
|
||||
#define BT_MBI_MCR_OFFSET 0xD0
|
||||
#define BT_MBI_MDR_OFFSET 0xD4
|
||||
#define BT_MBI_MCRX_OFFSET 0xD8
|
||||
|
||||
#define BT_MBI_RD_MASK 0xFEFFFFFF
|
||||
#define BT_MBI_WR_MASK 0X01000000
|
||||
|
||||
#define BT_MBI_MASK_HI 0xFFFFFF00
|
||||
#define BT_MBI_MASK_LO 0x000000FF
|
||||
#define BT_MBI_ENABLE 0xF0
|
||||
|
||||
/* BT-SB unit access methods */
|
||||
#define BT_MBI_UNIT_AUNIT 0x00
|
||||
#define BT_MBI_UNIT_SMC 0x01
|
||||
#define BT_MBI_UNIT_CPU 0x02
|
||||
#define BT_MBI_UNIT_BUNIT 0x03
|
||||
#define BT_MBI_UNIT_PMC 0x04
|
||||
#define BT_MBI_UNIT_GFX 0x06
|
||||
#define BT_MBI_UNIT_SMI 0x0C
|
||||
#define BT_MBI_UNIT_USB 0x43
|
||||
#define BT_MBI_UNIT_SATA 0xA3
|
||||
#define BT_MBI_UNIT_PCIE 0xA6
|
||||
|
||||
/* Read/write opcodes */
|
||||
#define BT_MBI_AUNIT_READ 0x10
|
||||
#define BT_MBI_AUNIT_WRITE 0x11
|
||||
#define BT_MBI_SMC_READ 0x10
|
||||
#define BT_MBI_SMC_WRITE 0x11
|
||||
#define BT_MBI_CPU_READ 0x10
|
||||
#define BT_MBI_CPU_WRITE 0x11
|
||||
#define BT_MBI_BUNIT_READ 0x10
|
||||
#define BT_MBI_BUNIT_WRITE 0x11
|
||||
#define BT_MBI_PMC_READ 0x06
|
||||
#define BT_MBI_PMC_WRITE 0x07
|
||||
#define BT_MBI_GFX_READ 0x00
|
||||
#define BT_MBI_GFX_WRITE 0x01
|
||||
#define BT_MBI_SMIO_READ 0x06
|
||||
#define BT_MBI_SMIO_WRITE 0x07
|
||||
#define BT_MBI_USB_READ 0x06
|
||||
#define BT_MBI_USB_WRITE 0x07
|
||||
#define BT_MBI_SATA_READ 0x00
|
||||
#define BT_MBI_SATA_WRITE 0x01
|
||||
#define BT_MBI_PCIE_READ 0x00
|
||||
#define BT_MBI_PCIE_WRITE 0x01
|
||||
|
||||
/**
|
||||
* bt_mbi_read() - MailBox Interface read command
|
||||
* @port: port indicating subunit being accessed
|
||||
* @opcode: port specific read or write opcode
|
||||
* @offset: register address offset
|
||||
* @mdr: register data to be read
|
||||
*
|
||||
* Locking is handled by spinlock - cannot sleep.
|
||||
* Return: Nonzero on error
|
||||
*/
|
||||
int bt_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr);
|
||||
|
||||
/**
|
||||
* bt_mbi_write() - MailBox unmasked write command
|
||||
* @port: port indicating subunit being accessed
|
||||
* @opcode: port specific read or write opcode
|
||||
* @offset: register address offset
|
||||
* @mdr: register data to be written
|
||||
*
|
||||
* Locking is handled by spinlock - cannot sleep.
|
||||
* Return: Nonzero on error
|
||||
*/
|
||||
int bt_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr);
|
||||
|
||||
/**
|
||||
* bt_mbi_modify() - MailBox masked write command
|
||||
* @port: port indicating subunit being accessed
|
||||
* @opcode: port specific read or write opcode
|
||||
* @offset: register address offset
|
||||
* @mdr: register data being modified
|
||||
* @mask: mask indicating bits in mdr to be modified
|
||||
*
|
||||
* Locking is handled by spinlock - cannot sleep.
|
||||
* Return: Nonzero on error
|
||||
*/
|
||||
int bt_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask);
|
||||
|
||||
#endif /* INTEL_BAYTRAIL_MBI_SYMS_H */
|
@ -62,12 +62,10 @@
|
||||
#define IPC_RWBUF_SIZE 20 /* IPC Read buffer Size */
|
||||
#define IPC_IOC 0x100 /* IPC command register IOC bit */
|
||||
|
||||
enum {
|
||||
SCU_IPC_LINCROFT,
|
||||
SCU_IPC_PENWELL,
|
||||
SCU_IPC_CLOVERVIEW,
|
||||
SCU_IPC_TANGIER,
|
||||
};
|
||||
#define PCI_DEVICE_ID_LINCROFT 0x082a
|
||||
#define PCI_DEVICE_ID_PENWELL 0x080e
|
||||
#define PCI_DEVICE_ID_CLOVERVIEW 0x08ea
|
||||
#define PCI_DEVICE_ID_TANGIER 0x11a0
|
||||
|
||||
/* intel scu ipc driver data*/
|
||||
struct intel_scu_ipc_pdata_t {
|
||||
@ -78,35 +76,29 @@ struct intel_scu_ipc_pdata_t {
|
||||
u8 irq_mode;
|
||||
};
|
||||
|
||||
static struct intel_scu_ipc_pdata_t intel_scu_ipc_pdata[] = {
|
||||
[SCU_IPC_LINCROFT] = {
|
||||
.ipc_base = 0xff11c000,
|
||||
.i2c_base = 0xff12b000,
|
||||
.ipc_len = 0x100,
|
||||
.i2c_len = 0x10,
|
||||
.irq_mode = 0,
|
||||
},
|
||||
[SCU_IPC_PENWELL] = {
|
||||
.ipc_base = 0xff11c000,
|
||||
.i2c_base = 0xff12b000,
|
||||
.ipc_len = 0x100,
|
||||
.i2c_len = 0x10,
|
||||
.irq_mode = 1,
|
||||
},
|
||||
[SCU_IPC_CLOVERVIEW] = {
|
||||
.ipc_base = 0xff11c000,
|
||||
.i2c_base = 0xff12b000,
|
||||
.ipc_len = 0x100,
|
||||
.i2c_len = 0x10,
|
||||
.irq_mode = 1,
|
||||
},
|
||||
[SCU_IPC_TANGIER] = {
|
||||
.ipc_base = 0xff009000,
|
||||
.i2c_base = 0xff00d000,
|
||||
.ipc_len = 0x100,
|
||||
.i2c_len = 0x10,
|
||||
.irq_mode = 0,
|
||||
},
|
||||
static struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = {
|
||||
.ipc_base = 0xff11c000,
|
||||
.i2c_base = 0xff12b000,
|
||||
.ipc_len = 0x100,
|
||||
.i2c_len = 0x10,
|
||||
.irq_mode = 0,
|
||||
};
|
||||
|
||||
/* Penwell and Cloverview */
|
||||
static struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
|
||||
.ipc_base = 0xff11c000,
|
||||
.i2c_base = 0xff12b000,
|
||||
.ipc_len = 0x100,
|
||||
.i2c_len = 0x10,
|
||||
.irq_mode = 1,
|
||||
};
|
||||
|
||||
static struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
|
||||
.ipc_base = 0xff009000,
|
||||
.i2c_base = 0xff00d000,
|
||||
.ipc_len = 0x100,
|
||||
.i2c_len = 0x10,
|
||||
.irq_mode = 0,
|
||||
};
|
||||
|
||||
static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id);
|
||||
@ -583,15 +575,14 @@ static irqreturn_t ioc(int irq, void *dev_id)
|
||||
*/
|
||||
static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
int err, pid;
|
||||
int err;
|
||||
struct intel_scu_ipc_pdata_t *pdata;
|
||||
resource_size_t pci_resource;
|
||||
|
||||
if (ipcdev.pdev) /* We support only one SCU */
|
||||
return -EBUSY;
|
||||
|
||||
pid = id->driver_data;
|
||||
pdata = &intel_scu_ipc_pdata[pid];
|
||||
pdata = (struct intel_scu_ipc_pdata_t *)id->driver_data;
|
||||
|
||||
ipcdev.pdev = pci_dev_get(dev);
|
||||
ipcdev.irq_mode = pdata->irq_mode;
|
||||
@ -650,11 +641,21 @@ static void ipc_remove(struct pci_dev *pdev)
|
||||
}
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(pci_ids) = {
|
||||
{PCI_VDEVICE(INTEL, 0x082a), SCU_IPC_LINCROFT},
|
||||
{PCI_VDEVICE(INTEL, 0x080e), SCU_IPC_PENWELL},
|
||||
{PCI_VDEVICE(INTEL, 0x08ea), SCU_IPC_CLOVERVIEW},
|
||||
{PCI_VDEVICE(INTEL, 0x11a0), SCU_IPC_TANGIER},
|
||||
{ 0,}
|
||||
{
|
||||
PCI_VDEVICE(INTEL, PCI_DEVICE_ID_LINCROFT),
|
||||
(kernel_ulong_t)&intel_scu_ipc_lincroft_pdata,
|
||||
}, {
|
||||
PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PENWELL),
|
||||
(kernel_ulong_t)&intel_scu_ipc_penwell_pdata,
|
||||
}, {
|
||||
PCI_VDEVICE(INTEL, PCI_DEVICE_ID_CLOVERVIEW),
|
||||
(kernel_ulong_t)&intel_scu_ipc_penwell_pdata,
|
||||
}, {
|
||||
PCI_VDEVICE(INTEL, PCI_DEVICE_ID_TANGIER),
|
||||
(kernel_ulong_t)&intel_scu_ipc_tangier_pdata,
|
||||
}, {
|
||||
0,
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, pci_ids);
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mxm-wmi.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
MODULE_AUTHOR("Dave Airlie");
|
||||
|
@ -789,7 +789,7 @@ static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value,
|
||||
void *buffer, size_t buflen)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t len = len;
|
||||
size_t len;
|
||||
union acpi_object *object = __call_snc_method(handle, name, value);
|
||||
|
||||
if (!object)
|
||||
|
@ -149,6 +149,7 @@ static const struct acpi_device_id toshiba_device_ids[] = {
|
||||
MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);
|
||||
|
||||
static const struct key_entry toshiba_acpi_keymap[] = {
|
||||
{ KE_KEY, 0x9e, { KEY_RFKILL } },
|
||||
{ KE_KEY, 0x101, { KEY_MUTE } },
|
||||
{ KE_KEY, 0x102, { KEY_ZOOMOUT } },
|
||||
{ KE_KEY, 0x103, { KEY_ZOOMIN } },
|
||||
|
Loading…
Reference in New Issue
Block a user