mirror of https://gitee.com/openkylin/linux.git
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: ACPI: video: prevent NULL deref in acpi_get_pci_dev() eeepc-laptop: add rfkill support for the 3G modem in Eee PC 901 Go eeepc-laptop: get the right value for CMSG eeepc-laptop: makes get_acpi() returns -ENODEV eeepc-laptop: right parent device eeepc-laptop: rfkill refactoring eeepc-laptop.c: use pr_fmt and pr_<level> eeepc-laptop: Register as a pci-hotplug device
This commit is contained in:
commit
cf2acfb205
|
@ -395,7 +395,7 @@ struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
|
||||||
fn = adr & 0xffff;
|
fn = adr & 0xffff;
|
||||||
|
|
||||||
pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn));
|
pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn));
|
||||||
if (hnd == handle)
|
if (!pdev || hnd == handle)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pbus = pdev->subordinate;
|
pbus = pdev->subordinate;
|
||||||
|
|
|
@ -357,6 +357,8 @@ config EEEPC_LAPTOP
|
||||||
depends on RFKILL || RFKILL = n
|
depends on RFKILL || RFKILL = n
|
||||||
select BACKLIGHT_CLASS_DEVICE
|
select BACKLIGHT_CLASS_DEVICE
|
||||||
select HWMON
|
select HWMON
|
||||||
|
select HOTPLUG
|
||||||
|
select HOTPLUG_PCI if PCI
|
||||||
---help---
|
---help---
|
||||||
This driver supports the Fn-Fx keys on Eee PC laptops.
|
This driver supports the Fn-Fx keys on Eee PC laptops.
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
@ -31,6 +33,7 @@
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/rfkill.h>
|
#include <linux/rfkill.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
|
#include <linux/pci_hotplug.h>
|
||||||
|
|
||||||
#define EEEPC_LAPTOP_VERSION "0.1"
|
#define EEEPC_LAPTOP_VERSION "0.1"
|
||||||
|
|
||||||
|
@ -40,11 +43,6 @@
|
||||||
#define EEEPC_HOTK_DEVICE_NAME "Hotkey"
|
#define EEEPC_HOTK_DEVICE_NAME "Hotkey"
|
||||||
#define EEEPC_HOTK_HID "ASUS010"
|
#define EEEPC_HOTK_HID "ASUS010"
|
||||||
|
|
||||||
#define EEEPC_LOG EEEPC_HOTK_FILE ": "
|
|
||||||
#define EEEPC_ERR KERN_ERR EEEPC_LOG
|
|
||||||
#define EEEPC_WARNING KERN_WARNING EEEPC_LOG
|
|
||||||
#define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG
|
|
||||||
#define EEEPC_INFO KERN_INFO EEEPC_LOG
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definitions for Asus EeePC
|
* Definitions for Asus EeePC
|
||||||
|
@ -141,8 +139,10 @@ struct eeepc_hotk {
|
||||||
u16 event_count[128]; /* count for each event */
|
u16 event_count[128]; /* count for each event */
|
||||||
struct input_dev *inputdev;
|
struct input_dev *inputdev;
|
||||||
u16 *keycode_map;
|
u16 *keycode_map;
|
||||||
struct rfkill *eeepc_wlan_rfkill;
|
struct rfkill *wlan_rfkill;
|
||||||
struct rfkill *eeepc_bluetooth_rfkill;
|
struct rfkill *bluetooth_rfkill;
|
||||||
|
struct rfkill *wwan3g_rfkill;
|
||||||
|
struct hotplug_slot *hotplug_slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The actual device the driver binds to */
|
/* The actual device the driver binds to */
|
||||||
|
@ -213,6 +213,15 @@ static struct acpi_driver eeepc_hotk_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* PCI hotplug ops */
|
||||||
|
static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value);
|
||||||
|
|
||||||
|
static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.get_adapter_status = eeepc_get_adapter_status,
|
||||||
|
.get_power_status = eeepc_get_adapter_status,
|
||||||
|
};
|
||||||
|
|
||||||
/* The backlight device /sys/class/backlight */
|
/* The backlight device /sys/class/backlight */
|
||||||
static struct backlight_device *eeepc_backlight_device;
|
static struct backlight_device *eeepc_backlight_device;
|
||||||
|
|
||||||
|
@ -274,20 +283,20 @@ static int set_acpi(int cm, int value)
|
||||||
if (method == NULL)
|
if (method == NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
if (write_acpi_int(ehotk->handle, method, value, NULL))
|
if (write_acpi_int(ehotk->handle, method, value, NULL))
|
||||||
printk(EEEPC_WARNING "Error writing %s\n", method);
|
pr_warning("Error writing %s\n", method);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_acpi(int cm)
|
static int get_acpi(int cm)
|
||||||
{
|
{
|
||||||
int value = -1;
|
int value = -ENODEV;
|
||||||
if ((ehotk->cm_supported & (0x1 << cm))) {
|
if ((ehotk->cm_supported & (0x1 << cm))) {
|
||||||
const char *method = cm_getv[cm];
|
const char *method = cm_getv[cm];
|
||||||
if (method == NULL)
|
if (method == NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
if (read_acpi_int(ehotk->handle, method, &value))
|
if (read_acpi_int(ehotk->handle, method, &value))
|
||||||
printk(EEEPC_WARNING "Error reading %s\n", method);
|
pr_warning("Error reading %s\n", method);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -359,13 +368,19 @@ static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
|
||||||
|
|
||||||
rv = parse_arg(buf, count, &value);
|
rv = parse_arg(buf, count, &value);
|
||||||
if (rv > 0)
|
if (rv > 0)
|
||||||
set_acpi(cm, value);
|
value = set_acpi(cm, value);
|
||||||
|
if (value < 0)
|
||||||
|
return value;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t show_sys_acpi(int cm, char *buf)
|
static ssize_t show_sys_acpi(int cm, char *buf)
|
||||||
{
|
{
|
||||||
return sprintf(buf, "%d\n", get_acpi(cm));
|
int value = get_acpi(cm);
|
||||||
|
|
||||||
|
if (value < 0)
|
||||||
|
return value;
|
||||||
|
return sprintf(buf, "%d\n", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
|
#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
|
||||||
|
@ -539,6 +554,28 @@ static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cmsg_quirk(int cm, const char *name)
|
||||||
|
{
|
||||||
|
int dummy;
|
||||||
|
|
||||||
|
/* Some BIOSes do not report cm although it is avaliable.
|
||||||
|
Check if cm_getv[cm] works and, if yes, assume cm should be set. */
|
||||||
|
if (!(ehotk->cm_supported & (1 << cm))
|
||||||
|
&& !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) {
|
||||||
|
pr_info("%s (%x) not reported by BIOS,"
|
||||||
|
" enabling anyway\n", name, 1 << cm);
|
||||||
|
ehotk->cm_supported |= 1 << cm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmsg_quirks(void)
|
||||||
|
{
|
||||||
|
cmsg_quirk(CM_ASL_LID, "LID");
|
||||||
|
cmsg_quirk(CM_ASL_TYPE, "TYPE");
|
||||||
|
cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER");
|
||||||
|
cmsg_quirk(CM_ASL_TPD, "TPD");
|
||||||
|
}
|
||||||
|
|
||||||
static int eeepc_hotk_check(void)
|
static int eeepc_hotk_check(void)
|
||||||
{
|
{
|
||||||
const struct key_entry *key;
|
const struct key_entry *key;
|
||||||
|
@ -551,26 +588,24 @@ static int eeepc_hotk_check(void)
|
||||||
if (ehotk->device->status.present) {
|
if (ehotk->device->status.present) {
|
||||||
if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
|
if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
|
||||||
&buffer)) {
|
&buffer)) {
|
||||||
printk(EEEPC_ERR "Hotkey initialization failed\n");
|
pr_err("Hotkey initialization failed\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n",
|
pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
|
||||||
ehotk->init_flag);
|
|
||||||
}
|
}
|
||||||
/* get control methods supported */
|
/* get control methods supported */
|
||||||
if (read_acpi_int(ehotk->handle, "CMSG"
|
if (read_acpi_int(ehotk->handle, "CMSG"
|
||||||
, &ehotk->cm_supported)) {
|
, &ehotk->cm_supported)) {
|
||||||
printk(EEEPC_ERR
|
pr_err("Get control methods supported failed\n");
|
||||||
"Get control methods supported failed\n");
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
printk(EEEPC_INFO
|
cmsg_quirks();
|
||||||
"Get control methods supported: 0x%x\n",
|
pr_info("Get control methods supported: 0x%x\n",
|
||||||
ehotk->cm_supported);
|
ehotk->cm_supported);
|
||||||
}
|
}
|
||||||
ehotk->inputdev = input_allocate_device();
|
ehotk->inputdev = input_allocate_device();
|
||||||
if (!ehotk->inputdev) {
|
if (!ehotk->inputdev) {
|
||||||
printk(EEEPC_INFO "Unable to allocate input device\n");
|
pr_info("Unable to allocate input device\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ehotk->inputdev->name = "Asus EeePC extra buttons";
|
ehotk->inputdev->name = "Asus EeePC extra buttons";
|
||||||
|
@ -589,12 +624,12 @@ static int eeepc_hotk_check(void)
|
||||||
}
|
}
|
||||||
result = input_register_device(ehotk->inputdev);
|
result = input_register_device(ehotk->inputdev);
|
||||||
if (result) {
|
if (result) {
|
||||||
printk(EEEPC_INFO "Unable to register input device\n");
|
pr_info("Unable to register input device\n");
|
||||||
input_free_device(ehotk->inputdev);
|
input_free_device(ehotk->inputdev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printk(EEEPC_ERR "Hotkey device not present, aborting\n");
|
pr_err("Hotkey device not present, aborting\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -612,6 +647,19 @@ static int notify_brn(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
|
||||||
|
u8 *value)
|
||||||
|
{
|
||||||
|
int val = get_acpi(CM_ASL_WLAN);
|
||||||
|
|
||||||
|
if (val == 1 || val == 0)
|
||||||
|
*value = val;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void eeepc_rfkill_hotplug(void)
|
static void eeepc_rfkill_hotplug(void)
|
||||||
{
|
{
|
||||||
struct pci_dev *dev;
|
struct pci_dev *dev;
|
||||||
|
@ -619,7 +667,7 @@ static void eeepc_rfkill_hotplug(void)
|
||||||
bool blocked;
|
bool blocked;
|
||||||
|
|
||||||
if (!bus) {
|
if (!bus) {
|
||||||
printk(EEEPC_WARNING "Unable to find PCI bus 1?\n");
|
pr_warning("Unable to find PCI bus 1?\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,7 +683,7 @@ static void eeepc_rfkill_hotplug(void)
|
||||||
if (dev) {
|
if (dev) {
|
||||||
pci_bus_assign_resources(bus);
|
pci_bus_assign_resources(bus);
|
||||||
if (pci_bus_add_device(dev))
|
if (pci_bus_add_device(dev))
|
||||||
printk(EEEPC_ERR "Unable to hotplug wifi\n");
|
pr_err("Unable to hotplug wifi\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dev = pci_get_slot(bus, 0);
|
dev = pci_get_slot(bus, 0);
|
||||||
|
@ -645,7 +693,7 @@ static void eeepc_rfkill_hotplug(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked);
|
rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
|
static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
|
||||||
|
@ -718,8 +766,7 @@ static int eeepc_register_rfkill_notifier(char *node)
|
||||||
eeepc_rfkill_notify,
|
eeepc_rfkill_notify,
|
||||||
NULL);
|
NULL);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
printk(EEEPC_WARNING
|
pr_warning("Failed to register notify on %s\n", node);
|
||||||
"Failed to register notify on %s\n", node);
|
|
||||||
} else
|
} else
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
@ -738,19 +785,66 @@ static void eeepc_unregister_rfkill_notifier(char *node)
|
||||||
ACPI_SYSTEM_NOTIFY,
|
ACPI_SYSTEM_NOTIFY,
|
||||||
eeepc_rfkill_notify);
|
eeepc_rfkill_notify);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
printk(EEEPC_ERR
|
pr_err("Error removing rfkill notify handler %s\n",
|
||||||
"Error removing rfkill notify handler %s\n",
|
|
||||||
node);
|
node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
|
||||||
|
{
|
||||||
|
kfree(hotplug_slot->info);
|
||||||
|
kfree(hotplug_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eeepc_setup_pci_hotplug(void)
|
||||||
|
{
|
||||||
|
int ret = -ENOMEM;
|
||||||
|
struct pci_bus *bus = pci_find_bus(0, 1);
|
||||||
|
|
||||||
|
if (!bus) {
|
||||||
|
pr_err("Unable to find wifi PCI bus\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
|
||||||
|
if (!ehotk->hotplug_slot)
|
||||||
|
goto error_slot;
|
||||||
|
|
||||||
|
ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!ehotk->hotplug_slot->info)
|
||||||
|
goto error_info;
|
||||||
|
|
||||||
|
ehotk->hotplug_slot->private = ehotk;
|
||||||
|
ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
|
||||||
|
ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
|
||||||
|
eeepc_get_adapter_status(ehotk->hotplug_slot,
|
||||||
|
&ehotk->hotplug_slot->info->adapter_status);
|
||||||
|
|
||||||
|
ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
|
||||||
|
if (ret) {
|
||||||
|
pr_err("Unable to register hotplug slot - %d\n", ret);
|
||||||
|
goto error_register;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error_register:
|
||||||
|
kfree(ehotk->hotplug_slot->info);
|
||||||
|
error_info:
|
||||||
|
kfree(ehotk->hotplug_slot);
|
||||||
|
ehotk->hotplug_slot = NULL;
|
||||||
|
error_slot:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int eeepc_hotk_add(struct acpi_device *device)
|
static int eeepc_hotk_add(struct acpi_device *device)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n");
|
pr_notice(EEEPC_HOTK_NAME "\n");
|
||||||
ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
|
ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
|
||||||
if (!ehotk)
|
if (!ehotk)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -764,53 +858,8 @@ static int eeepc_hotk_add(struct acpi_device *device)
|
||||||
if (result)
|
if (result)
|
||||||
goto ehotk_fail;
|
goto ehotk_fail;
|
||||||
|
|
||||||
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
|
|
||||||
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
|
|
||||||
|
|
||||||
if (get_acpi(CM_ASL_WLAN) != -1) {
|
|
||||||
ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan",
|
|
||||||
&device->dev,
|
|
||||||
RFKILL_TYPE_WLAN,
|
|
||||||
&eeepc_rfkill_ops,
|
|
||||||
(void *)CM_ASL_WLAN);
|
|
||||||
|
|
||||||
if (!ehotk->eeepc_wlan_rfkill)
|
|
||||||
goto wlan_fail;
|
|
||||||
|
|
||||||
rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill,
|
|
||||||
get_acpi(CM_ASL_WLAN) != 1);
|
|
||||||
result = rfkill_register(ehotk->eeepc_wlan_rfkill);
|
|
||||||
if (result)
|
|
||||||
goto wlan_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
|
|
||||||
ehotk->eeepc_bluetooth_rfkill =
|
|
||||||
rfkill_alloc("eeepc-bluetooth",
|
|
||||||
&device->dev,
|
|
||||||
RFKILL_TYPE_BLUETOOTH,
|
|
||||||
&eeepc_rfkill_ops,
|
|
||||||
(void *)CM_ASL_BLUETOOTH);
|
|
||||||
|
|
||||||
if (!ehotk->eeepc_bluetooth_rfkill)
|
|
||||||
goto bluetooth_fail;
|
|
||||||
|
|
||||||
rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill,
|
|
||||||
get_acpi(CM_ASL_BLUETOOTH) != 1);
|
|
||||||
result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
|
|
||||||
if (result)
|
|
||||||
goto bluetooth_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bluetooth_fail:
|
|
||||||
rfkill_destroy(ehotk->eeepc_bluetooth_rfkill);
|
|
||||||
rfkill_unregister(ehotk->eeepc_wlan_rfkill);
|
|
||||||
wlan_fail:
|
|
||||||
rfkill_destroy(ehotk->eeepc_wlan_rfkill);
|
|
||||||
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
|
|
||||||
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
|
|
||||||
ehotk_fail:
|
ehotk_fail:
|
||||||
kfree(ehotk);
|
kfree(ehotk);
|
||||||
ehotk = NULL;
|
ehotk = NULL;
|
||||||
|
@ -823,16 +872,13 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
|
||||||
if (!device || !acpi_driver_data(device))
|
if (!device || !acpi_driver_data(device))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
|
|
||||||
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
|
|
||||||
|
|
||||||
kfree(ehotk);
|
kfree(ehotk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eeepc_hotk_resume(struct acpi_device *device)
|
static int eeepc_hotk_resume(struct acpi_device *device)
|
||||||
{
|
{
|
||||||
if (ehotk->eeepc_wlan_rfkill) {
|
if (ehotk->wlan_rfkill) {
|
||||||
bool wlan;
|
bool wlan;
|
||||||
|
|
||||||
/* Workaround - it seems that _PTS disables the wireless
|
/* Workaround - it seems that _PTS disables the wireless
|
||||||
|
@ -844,14 +890,13 @@ static int eeepc_hotk_resume(struct acpi_device *device)
|
||||||
wlan = get_acpi(CM_ASL_WLAN);
|
wlan = get_acpi(CM_ASL_WLAN);
|
||||||
set_acpi(CM_ASL_WLAN, wlan);
|
set_acpi(CM_ASL_WLAN, wlan);
|
||||||
|
|
||||||
rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill,
|
rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
|
||||||
wlan != 1);
|
|
||||||
|
|
||||||
eeepc_rfkill_hotplug();
|
eeepc_rfkill_hotplug();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ehotk->eeepc_bluetooth_rfkill)
|
if (ehotk->bluetooth_rfkill)
|
||||||
rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill,
|
rfkill_set_sw_state(ehotk->bluetooth_rfkill,
|
||||||
get_acpi(CM_ASL_BLUETOOTH) != 1);
|
get_acpi(CM_ASL_BLUETOOTH) != 1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -973,10 +1018,16 @@ static void eeepc_backlight_exit(void)
|
||||||
|
|
||||||
static void eeepc_rfkill_exit(void)
|
static void eeepc_rfkill_exit(void)
|
||||||
{
|
{
|
||||||
if (ehotk->eeepc_wlan_rfkill)
|
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
|
||||||
rfkill_unregister(ehotk->eeepc_wlan_rfkill);
|
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
|
||||||
if (ehotk->eeepc_bluetooth_rfkill)
|
if (ehotk->wlan_rfkill)
|
||||||
rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
|
rfkill_unregister(ehotk->wlan_rfkill);
|
||||||
|
if (ehotk->bluetooth_rfkill)
|
||||||
|
rfkill_unregister(ehotk->bluetooth_rfkill);
|
||||||
|
if (ehotk->wwan3g_rfkill)
|
||||||
|
rfkill_unregister(ehotk->wwan3g_rfkill);
|
||||||
|
if (ehotk->hotplug_slot)
|
||||||
|
pci_hp_deregister(ehotk->hotplug_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eeepc_input_exit(void)
|
static void eeepc_input_exit(void)
|
||||||
|
@ -1011,6 +1062,75 @@ static void __exit eeepc_laptop_exit(void)
|
||||||
platform_driver_unregister(&platform_driver);
|
platform_driver_unregister(&platform_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int eeepc_new_rfkill(struct rfkill **rfkill,
|
||||||
|
const char *name, struct device *dev,
|
||||||
|
enum rfkill_type type, int cm)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = get_acpi(cm);
|
||||||
|
if (result < 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
*rfkill = rfkill_alloc(name, dev, type,
|
||||||
|
&eeepc_rfkill_ops, (void *)(unsigned long)cm);
|
||||||
|
|
||||||
|
if (!*rfkill)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
|
||||||
|
result = rfkill_register(*rfkill);
|
||||||
|
if (result) {
|
||||||
|
rfkill_destroy(*rfkill);
|
||||||
|
*rfkill = NULL;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int eeepc_rfkill_init(struct device *dev)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
|
||||||
|
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
|
||||||
|
|
||||||
|
result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
|
||||||
|
"eeepc-wlan", dev,
|
||||||
|
RFKILL_TYPE_WLAN, CM_ASL_WLAN);
|
||||||
|
|
||||||
|
if (result && result != -ENODEV)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
|
||||||
|
"eeepc-bluetooth", dev,
|
||||||
|
RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
|
||||||
|
|
||||||
|
if (result && result != -ENODEV)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill,
|
||||||
|
"eeepc-wwan3g", dev,
|
||||||
|
RFKILL_TYPE_WWAN, CM_ASL_3G);
|
||||||
|
|
||||||
|
if (result && result != -ENODEV)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
result = eeepc_setup_pci_hotplug();
|
||||||
|
/*
|
||||||
|
* If we get -EBUSY then something else is handling the PCI hotplug -
|
||||||
|
* don't fail in this case
|
||||||
|
*/
|
||||||
|
if (result == -EBUSY)
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (result && result != -ENODEV)
|
||||||
|
eeepc_rfkill_exit();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static int eeepc_backlight_init(struct device *dev)
|
static int eeepc_backlight_init(struct device *dev)
|
||||||
{
|
{
|
||||||
struct backlight_device *bd;
|
struct backlight_device *bd;
|
||||||
|
@ -1018,8 +1138,7 @@ static int eeepc_backlight_init(struct device *dev)
|
||||||
bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
|
bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
|
||||||
NULL, &eeepcbl_ops);
|
NULL, &eeepcbl_ops);
|
||||||
if (IS_ERR(bd)) {
|
if (IS_ERR(bd)) {
|
||||||
printk(EEEPC_ERR
|
pr_err("Could not register eeepc backlight device\n");
|
||||||
"Could not register eeepc backlight device\n");
|
|
||||||
eeepc_backlight_device = NULL;
|
eeepc_backlight_device = NULL;
|
||||||
return PTR_ERR(bd);
|
return PTR_ERR(bd);
|
||||||
}
|
}
|
||||||
|
@ -1038,8 +1157,7 @@ static int eeepc_hwmon_init(struct device *dev)
|
||||||
|
|
||||||
hwmon = hwmon_device_register(dev);
|
hwmon = hwmon_device_register(dev);
|
||||||
if (IS_ERR(hwmon)) {
|
if (IS_ERR(hwmon)) {
|
||||||
printk(EEEPC_ERR
|
pr_err("Could not register eeepc hwmon device\n");
|
||||||
"Could not register eeepc hwmon device\n");
|
|
||||||
eeepc_hwmon_device = NULL;
|
eeepc_hwmon_device = NULL;
|
||||||
return PTR_ERR(hwmon);
|
return PTR_ERR(hwmon);
|
||||||
}
|
}
|
||||||
|
@ -1065,19 +1183,6 @@ static int __init eeepc_laptop_init(void)
|
||||||
acpi_bus_unregister_driver(&eeepc_hotk_driver);
|
acpi_bus_unregister_driver(&eeepc_hotk_driver);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
dev = acpi_get_physical_device(ehotk->device->handle);
|
|
||||||
|
|
||||||
if (!acpi_video_backlight_support()) {
|
|
||||||
result = eeepc_backlight_init(dev);
|
|
||||||
if (result)
|
|
||||||
goto fail_backlight;
|
|
||||||
} else
|
|
||||||
printk(EEEPC_INFO "Backlight controlled by ACPI video "
|
|
||||||
"driver\n");
|
|
||||||
|
|
||||||
result = eeepc_hwmon_init(dev);
|
|
||||||
if (result)
|
|
||||||
goto fail_hwmon;
|
|
||||||
|
|
||||||
eeepc_enable_camera();
|
eeepc_enable_camera();
|
||||||
|
|
||||||
|
@ -1097,7 +1202,33 @@ static int __init eeepc_laptop_init(void)
|
||||||
&platform_attribute_group);
|
&platform_attribute_group);
|
||||||
if (result)
|
if (result)
|
||||||
goto fail_sysfs;
|
goto fail_sysfs;
|
||||||
|
|
||||||
|
dev = &platform_device->dev;
|
||||||
|
|
||||||
|
if (!acpi_video_backlight_support()) {
|
||||||
|
result = eeepc_backlight_init(dev);
|
||||||
|
if (result)
|
||||||
|
goto fail_backlight;
|
||||||
|
} else
|
||||||
|
pr_info("Backlight controlled by ACPI video "
|
||||||
|
"driver\n");
|
||||||
|
|
||||||
|
result = eeepc_hwmon_init(dev);
|
||||||
|
if (result)
|
||||||
|
goto fail_hwmon;
|
||||||
|
|
||||||
|
result = eeepc_rfkill_init(dev);
|
||||||
|
if (result)
|
||||||
|
goto fail_rfkill;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
fail_rfkill:
|
||||||
|
eeepc_hwmon_exit();
|
||||||
|
fail_hwmon:
|
||||||
|
eeepc_backlight_exit();
|
||||||
|
fail_backlight:
|
||||||
|
sysfs_remove_group(&platform_device->dev.kobj,
|
||||||
|
&platform_attribute_group);
|
||||||
fail_sysfs:
|
fail_sysfs:
|
||||||
platform_device_del(platform_device);
|
platform_device_del(platform_device);
|
||||||
fail_platform_device2:
|
fail_platform_device2:
|
||||||
|
@ -1105,12 +1236,7 @@ static int __init eeepc_laptop_init(void)
|
||||||
fail_platform_device1:
|
fail_platform_device1:
|
||||||
platform_driver_unregister(&platform_driver);
|
platform_driver_unregister(&platform_driver);
|
||||||
fail_platform_driver:
|
fail_platform_driver:
|
||||||
eeepc_hwmon_exit();
|
|
||||||
fail_hwmon:
|
|
||||||
eeepc_backlight_exit();
|
|
||||||
fail_backlight:
|
|
||||||
eeepc_input_exit();
|
eeepc_input_exit();
|
||||||
eeepc_rfkill_exit();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue