Merge branch 'linus' into test

Conflicts:
	MAINTAINERS
	arch/x86/kernel/acpi/boot.c
	arch/x86/kernel/acpi/sleep.c
	drivers/acpi/Kconfig
	drivers/pnp/Makefile
	drivers/pnp/quirks.c

Signed-off-by: Len Brown <[email protected]>
This commit is contained in:
Len Brown 2008-10-22 23:57:26 -04:00
commit 057316cc6a
7289 changed files with 578807 additions and 188282 deletions

View file

@ -253,6 +253,9 @@ config ACPI_ASUS
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86 && INPUT
select INPUT_POLLDEV
select NET
select RFKILL
select BACKLIGHT_CLASS_DEVICE
---help---
This driver adds support for access to certain system settings

View file

@ -431,7 +431,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
}
static struct device_attribute alarm_attr = {
.attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
.attr = {.name = "alarm", .mode = 0644},
.show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store,
};

View file

@ -260,116 +260,3 @@ static int __init init_acpi_device_notify(void)
}
arch_initcall(init_acpi_device_notify);
#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
#ifdef CONFIG_PM
static u32 rtc_handler(void *context)
{
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
return ACPI_INTERRUPT_HANDLED;
}
static inline void rtc_wake_setup(void)
{
acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
/*
* After the RTC handler is installed, the Fixed_RTC event should
* be disabled. Only when the RTC alarm is set will it be enabled.
*/
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
}
static void rtc_wake_on(struct device *dev)
{
acpi_clear_event(ACPI_EVENT_RTC);
acpi_enable_event(ACPI_EVENT_RTC, 0);
}
static void rtc_wake_off(struct device *dev)
{
acpi_disable_event(ACPI_EVENT_RTC, 0);
}
#else
#define rtc_wake_setup() do{}while(0)
#define rtc_wake_on NULL
#define rtc_wake_off NULL
#endif
/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
* its device node and pass extra config data. This helps its driver use
* capabilities that the now-obsolete mc146818 didn't have, and informs it
* that this board's RTC is wakeup-capable (per ACPI spec).
*/
#include <linux/mc146818rtc.h>
static struct cmos_rtc_board_info rtc_info;
/* PNP devices are registered in a subsys_initcall();
* ACPI specifies the PNP IDs to use.
*/
#include <linux/pnp.h>
static int __init pnp_match(struct device *dev, void *data)
{
static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", };
struct pnp_dev *pnp = to_pnp_dev(dev);
int i;
for (i = 0; i < ARRAY_SIZE(ids); i++) {
if (compare_pnp_id(pnp->id, ids[i]) != 0)
return 1;
}
return 0;
}
static struct device *__init get_rtc_dev(void)
{
return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match);
}
static int __init acpi_rtc_init(void)
{
struct device *dev = get_rtc_dev();
if (acpi_disabled)
return 0;
if (dev) {
rtc_wake_setup();
rtc_info.wake_on = rtc_wake_on;
rtc_info.wake_off = rtc_wake_off;
/* workaround bug in some ACPI tables */
if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
DBG("bogus FADT month_alarm\n");
acpi_gbl_FADT.month_alarm = 0;
}
rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
rtc_info.rtc_century = acpi_gbl_FADT.century;
/* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
printk(PREFIX "RTC can wake from S4\n");
dev->platform_data = &rtc_info;
/* RTC always wakes from S1/S2/S3, and often S4/STD */
device_init_wakeup(dev, 1);
put_device(dev);
} else
DBG("RTC unavailable?\n");
return 0;
}
/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */
fs_initcall(acpi_rtc_init);
#endif

View file

@ -463,7 +463,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
}
static struct device_attribute alarm_attr = {
.attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
.attr = {.name = "alarm", .mode = 0644},
.show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store,
};

View file

@ -120,13 +120,13 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
spin_unlock_irqrestore(&rtc_lock, flags);
if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
BCD_TO_BIN(sec);
BCD_TO_BIN(min);
BCD_TO_BIN(hr);
BCD_TO_BIN(day);
BCD_TO_BIN(mo);
BCD_TO_BIN(yr);
BCD_TO_BIN(cent);
sec = bcd2bin(sec);
min = bcd2bin(min);
hr = bcd2bin(hr);
day = bcd2bin(day);
mo = bcd2bin(mo);
yr = bcd2bin(yr);
cent = bcd2bin(cent);
}
/* we're trusting the FADT (see above) */
@ -204,7 +204,7 @@ static u32 cmos_bcd_read(int offset, int rtc_control)
{
u32 val = CMOS_READ(offset);
if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
BCD_TO_BIN(val);
val = bcd2bin(val);
return val;
}
@ -212,7 +212,7 @@ static u32 cmos_bcd_read(int offset, int rtc_control)
static void cmos_bcd_write(u32 val, int offset, int rtc_control)
{
if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
BIN_TO_BCD(val);
val = bin2bcd(val);
CMOS_WRITE(val, offset);
}

View file

@ -115,7 +115,6 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
table_attr->attr.read = acpi_table_show;
table_attr->attr.attr.name = table_attr->name;
table_attr->attr.attr.mode = 0444;
table_attr->attr.attr.owner = THIS_MODULE;
return;
}

View file

@ -3,6 +3,7 @@
*
*
* Copyright (C) 2002-2004 John Belmonte
* Copyright (C) 2008 Philip Langdale
*
* 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
@ -33,7 +34,7 @@
*
*/
#define TOSHIBA_ACPI_VERSION "0.18"
#define TOSHIBA_ACPI_VERSION "0.19"
#define PROC_INTERFACE_VERSION 1
#include <linux/kernel.h>
@ -42,6 +43,9 @@
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/input-polldev.h>
#include <asm/uaccess.h>
@ -90,6 +94,7 @@ MODULE_LICENSE("GPL");
#define HCI_VIDEO_OUT 0x001c
#define HCI_HOTKEY_EVENT 0x001e
#define HCI_LCD_BRIGHTNESS 0x002a
#define HCI_WIRELESS 0x0056
/* field definitions */
#define HCI_LCD_BRIGHTNESS_BITS 3
@ -98,9 +103,14 @@ MODULE_LICENSE("GPL");
#define HCI_VIDEO_OUT_LCD 0x1
#define HCI_VIDEO_OUT_CRT 0x2
#define HCI_VIDEO_OUT_TV 0x4
#define HCI_WIRELESS_KILL_SWITCH 0x01
#define HCI_WIRELESS_BT_PRESENT 0x0f
#define HCI_WIRELESS_BT_ATTACH 0x40
#define HCI_WIRELESS_BT_POWER 0x80
static const struct acpi_device_id toshiba_device_ids[] = {
{"TOS6200", 0},
{"TOS6208", 0},
{"TOS1900", 0},
{"", 0},
};
@ -193,7 +203,7 @@ static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
return status;
}
/* common hci tasks (get or set one value)
/* common hci tasks (get or set one or two value)
*
* In addition to the ACPI status, the HCI system returns a result which
* may be useful (such as "not supported").
@ -218,6 +228,152 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result)
return status;
}
static acpi_status hci_write2(u32 reg, u32 in1, u32 in2, u32 *result)
{
u32 in[HCI_WORDS] = { HCI_SET, reg, in1, in2, 0, 0 };
u32 out[HCI_WORDS];
acpi_status status = hci_raw(in, out);
*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
return status;
}
static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
{
u32 in[HCI_WORDS] = { HCI_GET, reg, *out1, *out2, 0, 0 };
u32 out[HCI_WORDS];
acpi_status status = hci_raw(in, out);
*out1 = out[2];
*out2 = out[3];
*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
return status;
}
struct toshiba_acpi_dev {
struct platform_device *p_dev;
struct rfkill *rfk_dev;
struct input_polled_dev *poll_dev;
const char *bt_name;
const char *rfk_name;
bool last_rfk_state;
struct mutex mutex;
};
static struct toshiba_acpi_dev toshiba_acpi = {
.bt_name = "Toshiba Bluetooth",
.rfk_name = "Toshiba RFKill Switch",
.last_rfk_state = false,
};
/* Bluetooth rfkill handlers */
static u32 hci_get_bt_present(bool *present)
{
u32 hci_result;
u32 value, value2;
value = 0;
value2 = 0;
hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
if (hci_result == HCI_SUCCESS)
*present = (value & HCI_WIRELESS_BT_PRESENT) ? true : false;
return hci_result;
}
static u32 hci_get_bt_on(bool *on)
{
u32 hci_result;
u32 value, value2;
value = 0;
value2 = 0x0001;
hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
if (hci_result == HCI_SUCCESS)
*on = (value & HCI_WIRELESS_BT_POWER) &&
(value & HCI_WIRELESS_BT_ATTACH);
return hci_result;
}
static u32 hci_get_radio_state(bool *radio_state)
{
u32 hci_result;
u32 value, value2;
value = 0;
value2 = 0x0001;
hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
*radio_state = value & HCI_WIRELESS_KILL_SWITCH;
return hci_result;
}
static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state)
{
u32 result1, result2;
u32 value;
bool radio_state;
struct toshiba_acpi_dev *dev = data;
value = (state == RFKILL_STATE_UNBLOCKED);
if (hci_get_radio_state(&radio_state) != HCI_SUCCESS)
return -EFAULT;
switch (state) {
case RFKILL_STATE_UNBLOCKED:
if (!radio_state)
return -EPERM;
break;
case RFKILL_STATE_SOFT_BLOCKED:
break;
default:
return -EINVAL;
}
mutex_lock(&dev->mutex);
hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1);
hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2);
mutex_unlock(&dev->mutex);
if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS)
return -EFAULT;
return 0;
}
static void bt_poll_rfkill(struct input_polled_dev *poll_dev)
{
bool state_changed;
bool new_rfk_state;
bool value;
u32 hci_result;
struct toshiba_acpi_dev *dev = poll_dev->private;
hci_result = hci_get_radio_state(&value);
if (hci_result != HCI_SUCCESS)
return; /* Can't do anything useful */
new_rfk_state = value;
mutex_lock(&dev->mutex);
state_changed = new_rfk_state != dev->last_rfk_state;
dev->last_rfk_state = new_rfk_state;
mutex_unlock(&dev->mutex);
if (unlikely(state_changed)) {
rfkill_force_state(dev->rfk_dev,
new_rfk_state ?
RFKILL_STATE_SOFT_BLOCKED :
RFKILL_STATE_HARD_BLOCKED);
input_report_switch(poll_dev->input, SW_RFKILL_ALL,
new_rfk_state);
}
}
static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
static struct backlight_device *toshiba_backlight_device;
static int force_fan;
@ -547,6 +703,14 @@ static struct backlight_ops toshiba_backlight_data = {
static void toshiba_acpi_exit(void)
{
if (toshiba_acpi.poll_dev) {
input_unregister_polled_device(toshiba_acpi.poll_dev);
input_free_polled_device(toshiba_acpi.poll_dev);
}
if (toshiba_acpi.rfk_dev)
rfkill_unregister(toshiba_acpi.rfk_dev);
if (toshiba_backlight_device)
backlight_device_unregister(toshiba_backlight_device);
@ -555,6 +719,8 @@ static void toshiba_acpi_exit(void)
if (toshiba_proc_dir)
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
platform_device_unregister(toshiba_acpi.p_dev);
return;
}
@ -562,6 +728,10 @@ static int __init toshiba_acpi_init(void)
{
acpi_status status = AE_OK;
u32 hci_result;
bool bt_present;
bool bt_on;
bool radio_on;
int ret = 0;
if (acpi_disabled)
return -ENODEV;
@ -578,6 +748,18 @@ static int __init toshiba_acpi_init(void)
TOSHIBA_ACPI_VERSION);
printk(MY_INFO " HCI method: %s\n", method_hci);
mutex_init(&toshiba_acpi.mutex);
toshiba_acpi.p_dev = platform_device_register_simple("toshiba_acpi",
-1, NULL, 0);
if (IS_ERR(toshiba_acpi.p_dev)) {
ret = PTR_ERR(toshiba_acpi.p_dev);
printk(MY_ERR "unable to register platform device\n");
toshiba_acpi.p_dev = NULL;
toshiba_acpi_exit();
return ret;
}
force_fan = 0;
key_event_valid = 0;
@ -586,19 +768,23 @@ static int __init toshiba_acpi_init(void)
toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir);
if (!toshiba_proc_dir) {
status = AE_ERROR;
toshiba_acpi_exit();
return -ENODEV;
} else {
toshiba_proc_dir->owner = THIS_MODULE;
status = add_device();
if (ACPI_FAILURE(status))
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
if (ACPI_FAILURE(status)) {
toshiba_acpi_exit();
return -ENODEV;
}
}
toshiba_backlight_device = backlight_device_register("toshiba",NULL,
toshiba_backlight_device = backlight_device_register("toshiba",
&toshiba_acpi.p_dev->dev,
NULL,
&toshiba_backlight_data);
if (IS_ERR(toshiba_backlight_device)) {
int ret = PTR_ERR(toshiba_backlight_device);
ret = PTR_ERR(toshiba_backlight_device);
printk(KERN_ERR "Could not register toshiba backlight device\n");
toshiba_backlight_device = NULL;
@ -607,7 +793,66 @@ static int __init toshiba_acpi_init(void)
}
toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
/* Register rfkill switch for Bluetooth */
if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev,
RFKILL_TYPE_BLUETOOTH);
if (!toshiba_acpi.rfk_dev) {
printk(MY_ERR "unable to allocate rfkill device\n");
toshiba_acpi_exit();
return -ENOMEM;
}
toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name;
toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio;
toshiba_acpi.rfk_dev->user_claim_unsupported = 1;
toshiba_acpi.rfk_dev->data = &toshiba_acpi;
if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) {
toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED;
} else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS &&
radio_on) {
toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED;
} else {
toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED;
}
ret = rfkill_register(toshiba_acpi.rfk_dev);
if (ret) {
printk(MY_ERR "unable to register rfkill device\n");
toshiba_acpi_exit();
return -ENOMEM;
}
}
/* Register input device for kill switch */
toshiba_acpi.poll_dev = input_allocate_polled_device();
if (!toshiba_acpi.poll_dev) {
printk(MY_ERR "unable to allocate kill-switch input device\n");
toshiba_acpi_exit();
return -ENOMEM;
}
toshiba_acpi.poll_dev->private = &toshiba_acpi;
toshiba_acpi.poll_dev->poll = bt_poll_rfkill;
toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */
toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name;
toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST;
toshiba_acpi.poll_dev->input->id.vendor = 0x0930; /* Toshiba USB ID */
set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
input_report_switch(toshiba_acpi.poll_dev->input, SW_RFKILL_ALL, TRUE);
ret = input_register_polled_device(toshiba_acpi.poll_dev);
if (ret) {
printk(MY_ERR "unable to register kill-switch input device\n");
rfkill_free(toshiba_acpi.rfk_dev);
toshiba_acpi.rfk_dev = NULL;
toshiba_acpi_exit();
return ret;
}
return 0;
}
module_init(toshiba_acpi_init);