summaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/asus_acpi.c67
-rw-r--r--drivers/acpi/battery.c14
-rw-r--r--drivers/acpi/ec.c1096
-rw-r--r--drivers/acpi/events/evrgnini.c13
-rw-r--r--drivers/acpi/ibm_acpi.c2
-rw-r--r--drivers/acpi/processor_idle.c101
-rw-r--r--drivers/acpi/sbs.c20
7 files changed, 426 insertions, 887 deletions
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index e9ee4c52a5f6..c7ac9297a204 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -138,6 +138,7 @@ struct asus_hotk {
S2x, //S200 (J1 reported), Victor MP-XP7210
W1N, //W1000N
W5A, //W5A
+ W3V, //W3030V
xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
//(Centrino)
END_MODEL
@@ -376,6 +377,17 @@ static struct model_data model_conf[END_MODEL] = {
.display_get = "\\ADVG"},
{
+ .name = "W3V",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = xxN_PREFIX "_Q10",
+ .lcd_status = "\\BKLT",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"},
+
+ {
.name = "xxN",
.mt_mled = "MLED",
/* WLED present, but not controlled by ACPI */
@@ -555,11 +567,11 @@ static int
write_led(const char __user * buffer, unsigned long count,
char *ledname, int ledmask, int invert)
{
- int value;
+ int rv, value;
int led_out = 0;
- count = parse_arg(buffer, count, &value);
- if (count > 0)
+ rv = parse_arg(buffer, count, &value);
+ if (rv > 0)
led_out = value ? 1 : 0;
hotk->status =
@@ -572,7 +584,7 @@ write_led(const char __user * buffer, unsigned long count,
printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
ledname);
- return count;
+ return rv;
}
/*
@@ -607,20 +619,18 @@ static int
proc_write_ledd(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
- int value;
+ int rv, value;
- count = parse_arg(buffer, count, &value);
- if (count > 0) {
+ rv = parse_arg(buffer, count, &value);
+ if (rv > 0) {
if (!write_acpi_int
(hotk->handle, hotk->methods->mt_ledd, value, NULL))
printk(KERN_WARNING
"Asus ACPI: LED display write failed\n");
else
hotk->ledd_status = (u32) value;
- } else if (count < 0)
- printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
-
- return count;
+ }
+ return rv;
}
/*
@@ -761,12 +771,12 @@ static int
proc_write_lcd(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
- int value;
+ int rv, value;
- count = parse_arg(buffer, count, &value);
- if (count > 0)
+ rv = parse_arg(buffer, count, &value);
+ if (rv > 0)
set_lcd_state(value);
- return count;
+ return rv;
}
static int read_brightness(void)
@@ -830,18 +840,15 @@ static int
proc_write_brn(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
- int value;
+ int rv, value;
- count = parse_arg(buffer, count, &value);
- if (count > 0) {
+ rv = parse_arg(buffer, count, &value);
+ if (rv > 0) {
value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
/* 0 <= value <= 15 */
set_brightness(value);
- } else if (count < 0) {
- printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
}
-
- return count;
+ return rv;
}
static void set_display(int value)
@@ -880,15 +887,12 @@ static int
proc_write_disp(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
- int value;
+ int rv, value;
- count = parse_arg(buffer, count, &value);
- if (count > 0)
+ rv = parse_arg(buffer, count, &value);
+ if (rv > 0)
set_display(value);
- else if (count < 0)
- printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
-
- return count;
+ return rv;
}
typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
@@ -1097,6 +1101,8 @@ static int asus_model_match(char *model)
return A4G;
else if (strncmp(model, "W1N", 3) == 0)
return W1N;
+ else if (strncmp(model, "W3V", 3) == 0)
+ return W3V;
else if (strncmp(model, "W5A", 3) == 0)
return W5A;
else
@@ -1200,9 +1206,10 @@ static int asus_hotk_get_info(void)
hotk->methods->mt_wled = NULL;
/* L5D's WLED is not controlled by ACPI */
else if (strncmp(string, "M2N", 3) == 0 ||
+ strncmp(string, "W3V", 3) == 0 ||
strncmp(string, "S1N", 3) == 0)
hotk->methods->mt_wled = "WLED";
- /* M2N and S1N have a usable WLED */
+ /* M2N, S1N and W3V have a usable WLED */
else if (asus_info) {
if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
hotk->methods->mled_status = NULL;
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 9810e2a55d0a..026e40755cdd 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -64,6 +64,7 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
static int acpi_battery_add(struct acpi_device *device);
static int acpi_battery_remove(struct acpi_device *device, int type);
+static int acpi_battery_resume(struct acpi_device *device, int status);
static struct acpi_driver acpi_battery_driver = {
.name = ACPI_BATTERY_DRIVER_NAME,
@@ -71,6 +72,7 @@ static struct acpi_driver acpi_battery_driver = {
.ids = ACPI_BATTERY_HID,
.ops = {
.add = acpi_battery_add,
+ .resume = acpi_battery_resume,
.remove = acpi_battery_remove,
},
};
@@ -753,6 +755,18 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
return 0;
}
+/* this is needed to learn about changes made in suspended state */
+static int acpi_battery_resume(struct acpi_device *device, int state)
+{
+ struct acpi_battery *battery;
+
+ if (!device)
+ return -EINVAL;
+
+ battery = device->driver_data;
+ return acpi_battery_check(battery);
+}
+
static int __init acpi_battery_init(void)
{
int result;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e5d796362854..e6d4b084dca2 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -45,206 +45,143 @@ ACPI_MODULE_NAME("acpi_ec")
#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver"
#define ACPI_EC_DEVICE_NAME "Embedded Controller"
#define ACPI_EC_FILE_INFO "info"
+
+/* EC status register */
#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
-#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */
-#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */
-#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
-#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
-#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
-#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
+
+/* EC commands */
#define ACPI_EC_COMMAND_READ 0x80
#define ACPI_EC_COMMAND_WRITE 0x81
#define ACPI_EC_BURST_ENABLE 0x82
#define ACPI_EC_BURST_DISABLE 0x83
#define ACPI_EC_COMMAND_QUERY 0x84
-#define EC_POLL 0xFF
-#define EC_INTR 0x00
+
+/* EC events */
+enum {
+ ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
+ ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
+};
+
+#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
+#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
+#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
+#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
+
+enum {
+ EC_INTR = 1, /* Output buffer full */
+ EC_POLL, /* Input buffer empty */
+};
+
static int acpi_ec_remove(struct acpi_device *device, int type);
static int acpi_ec_start(struct acpi_device *device);
static int acpi_ec_stop(struct acpi_device *device, int type);
-static int acpi_ec_intr_add(struct acpi_device *device);
-static int acpi_ec_poll_add(struct acpi_device *device);
+static int acpi_ec_add(struct acpi_device *device);
static struct acpi_driver acpi_ec_driver = {
.name = ACPI_EC_DRIVER_NAME,
.class = ACPI_EC_CLASS,
.ids = ACPI_EC_HID,
.ops = {
- .add = acpi_ec_intr_add,
+ .add = acpi_ec_add,
.remove = acpi_ec_remove,
.start = acpi_ec_start,
.stop = acpi_ec_stop,
},
};
-union acpi_ec {
- struct {
- u32 mode;
- acpi_handle handle;
- unsigned long uid;
- unsigned long gpe_bit;
- struct acpi_generic_address status_addr;
- struct acpi_generic_address command_addr;
- struct acpi_generic_address data_addr;
- unsigned long global_lock;
- } common;
-
- struct {
- u32 mode;
- acpi_handle handle;
- unsigned long uid;
- unsigned long gpe_bit;
- struct acpi_generic_address status_addr;
- struct acpi_generic_address command_addr;
- struct acpi_generic_address data_addr;
- unsigned long global_lock;
- unsigned int expect_event;
- atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
- atomic_t pending_gpe;
- struct semaphore sem;
- wait_queue_head_t wait;
- } intr;
-
- struct {
- u32 mode;
- acpi_handle handle;
- unsigned long uid;
- unsigned long gpe_bit;
- struct acpi_generic_address status_addr;
- struct acpi_generic_address command_addr;
- struct acpi_generic_address data_addr;
- unsigned long global_lock;
- struct semaphore sem;
- } poll;
-};
-static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event);
-static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event);
-static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data);
-static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data);
-static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data);
-static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data);
-static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data);
-static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data);
-static void acpi_ec_gpe_poll_query(void *ec_cxt);
-static void acpi_ec_gpe_intr_query(void *ec_cxt);
-static u32 acpi_ec_gpe_poll_handler(void *data);
-static u32 acpi_ec_gpe_intr_handler(void *data);
-static acpi_status __init
-acpi_fake_ecdt_poll_callback(acpi_handle handle,
- u32 Level, void *context, void **retval);
-
-static acpi_status __init
-acpi_fake_ecdt_intr_callback(acpi_handle handle,
- u32 Level, void *context, void **retval);
-
-static int __init acpi_ec_poll_get_real_ecdt(void);
-static int __init acpi_ec_intr_get_real_ecdt(void);
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
-static union acpi_ec *ec_ecdt;
+struct acpi_ec {
+ acpi_handle handle;
+ unsigned long uid;
+ unsigned long gpe_bit;
+ unsigned long command_addr;
+ unsigned long data_addr;
+ unsigned long global_lock;
+ struct semaphore sem;
+ unsigned int expect_event;
+ atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
+ wait_queue_head_t wait;
+} *ec_ecdt;
/* External interfaces use first EC only, so remember */
static struct acpi_device *first_ec;
-static int acpi_ec_poll_mode = EC_INTR;
+static int acpi_ec_mode = EC_INTR;
/* --------------------------------------------------------------------------
Transaction Management
-------------------------------------------------------------------------- */
-static u32 acpi_ec_read_status(union acpi_ec *ec)
+static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
{
- u32 status = 0;
-
- acpi_hw_low_level_read(8, &status, &ec->common.status_addr);
- return status;
+ return inb(ec->command_addr);
}
-static int acpi_ec_wait(union acpi_ec *ec, u8 event)
+static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
{
- if (acpi_ec_poll_mode)
- return acpi_ec_poll_wait(ec, event);
- else
- return acpi_ec_intr_wait(ec, event);
+ return inb(ec->data_addr);
}
-static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event)
+static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
{
- u32 acpi_ec_status = 0;
- u32 i = ACPI_EC_UDELAY_COUNT;
+ outb(command, ec->command_addr);
+}
- if (!ec)
- return -EINVAL;
+static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
+{
+ outb(data, ec->data_addr);
+}
- /* Poll the EC status register waiting for the event to occur. */
+static int acpi_ec_check_status(u8 status, u8 event)
+{
switch (event) {
- case ACPI_EC_EVENT_OBF:
- do {
- acpi_hw_low_level_read(8, &acpi_ec_status,
- &ec->common.status_addr);
- if (acpi_ec_status & ACPI_EC_FLAG_OBF)
- return 0;
- udelay(ACPI_EC_UDELAY);
- } while (--i > 0);
+ case ACPI_EC_EVENT_OBF_1:
+ if (status & ACPI_EC_FLAG_OBF)
+ return 1;
break;
- case ACPI_EC_EVENT_IBE:
- do {
- acpi_hw_low_level_read(8, &acpi_ec_status,
- &ec->common.status_addr);
- if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
- return 0;
- udelay(ACPI_EC_UDELAY);
- } while (--i > 0);
+ case ACPI_EC_EVENT_IBF_0:
+ if (!(status & ACPI_EC_FLAG_IBF))
+ return 1;
break;
default:
- return -EINVAL;
+ break;
}
- return -ETIME;
+ return 0;
}
-static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
-{
- int result = 0;
-
- ec->intr.expect_event = event;
- smp_mb();
+static int acpi_ec_wait(struct acpi_ec *ec, u8 event)
+{
+ int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0;
+ long time_left;
- switch (event) {
- case ACPI_EC_EVENT_IBE:
- if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) {
- ec->intr.expect_event = 0;
- return 0;
- }
- break;
- default:
- break;
+ ec->expect_event = event;
+ if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
+ ec->expect_event = 0;
+ return 0;
}
- result = wait_event_timeout(ec->intr.wait,
- !ec->intr.expect_event,
+ do {
+ if (acpi_ec_mode == EC_POLL) {
+ udelay(ACPI_EC_UDELAY);
+ } else {
+ time_left = wait_event_timeout(ec->wait,
+ !ec->expect_event,
msecs_to_jiffies(ACPI_EC_DELAY));
-
- ec->intr.expect_event = 0;
- smp_mb();
-
- /*
- * Verify that the event in question has actually happened by
- * querying EC status. Do the check even if operation timed-out
- * to make sure that we did not miss interrupt.
- */
- switch (event) {
- case ACPI_EC_EVENT_OBF:
- if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
+ if (time_left > 0) {
+ ec->expect_event = 0;
+ return 0;
+ }
+ }
+ if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
+ ec->expect_event = 0;
return 0;
- break;
+ }
+ } while (--i > 0);
- case ACPI_EC_EVENT_IBE:
- if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
- return 0;
- break;
- }
+ ec->expect_event = 0;
return -ETIME;
}
@@ -254,272 +191,150 @@ static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
* Note: samsung nv5000 doesn't work with ec burst mode.
* http://bugzilla.kernel.org/show_bug.cgi?id=4980
*/
-int acpi_ec_enter_burst_mode(union acpi_ec *ec)
+int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
{
- u32 tmp = 0;
- int status = 0;
+ u8 tmp = 0;
+ u8 status = 0;
status = acpi_ec_read_status(ec);
if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
if (status)
goto end;
- acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE,
- &ec->common.command_addr);
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
+ acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE);
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
+ tmp = acpi_ec_read_data(ec);
if (tmp != 0x90) { /* Burst ACK byte */
return -EINVAL;
}
}
- atomic_set(&ec->intr.leaving_burst, 0);
+ atomic_set(&ec->leaving_burst, 0);
return 0;
- end:
- ACPI_EXCEPTION ((AE_INFO, status, "EC wait, burst mode");
+ end:
+ ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode"));
return -1;
}
-int acpi_ec_leave_burst_mode(union acpi_ec *ec)
+int acpi_ec_leave_burst_mode(struct acpi_ec *ec)
{
- int status = 0;
+ u8 status = 0;
status = acpi_ec_read_status(ec);
if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){
- status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
if(status)
goto end;
- acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
- acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
- }
- atomic_set(&ec->intr.leaving_burst, 1);
+ acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE);
+ acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+ }
+ atomic_set(&ec->leaving_burst, 1);
return 0;
-end:
- ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode");
+ end:
+ ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"));
return -1;
}
#endif /* ACPI_FUTURE_USAGE */
-static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data)
-{
- if (acpi_ec_poll_mode)
- return acpi_ec_poll_read(ec, address, data);
- else
- return acpi_ec_intr_read(ec, address, data);
-}
-static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data)
-{
- if (acpi_ec_poll_mode)
- return acpi_ec_poll_write(ec, address, data);
- else
- return acpi_ec_intr_write(ec, address, data);
-}
-static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data)
+static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
+ const u8 *wdata, unsigned wdata_len,
+ u8 *rdata, unsigned rdata_len)
{
- acpi_status status = AE_OK;
- int result = 0;
- u32 glk = 0;
+ int result;
+ acpi_ec_write_cmd(ec, command);
- if (!ec || !data)
- return -EINVAL;
-
- *data = 0;
-
- if (ec->common.global_lock) {
- status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
- if (ACPI_FAILURE(status))
- return -ENODEV;
+ for (; wdata_len > 0; wdata_len --) {
+ result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+ if (result)
+ return result;
+ acpi_ec_write_data(ec, *(wdata++));
}
- if (down_interruptible(&ec->poll.sem)) {
- result = -ERESTARTSYS;
- goto end_nosem;
+ if (command == ACPI_EC_COMMAND_WRITE) {
+ result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+ if (result)
+ return result;
}
-
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
- &ec->common.command_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (result)
- goto end;
-
- acpi_hw_low_level_write(8, address, &ec->common.data_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (result)
- goto end;
-
- acpi_hw_low_level_read(8, data, &ec->common.data_addr);
-
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
- *data, address));
-
- end:
- up(&ec->poll.sem);
-end_nosem:
- if (ec->common.global_lock)
- acpi_release_global_lock(glk);
-
- return result;
-}
-
-static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data)
-{
- int result = 0;
- acpi_status status = AE_OK;
- u32 glk = 0;
+ for (; rdata_len > 0; rdata_len --) {
+ result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
+ if (result)
+ return result;
- if (!ec)
- return -EINVAL;
-
- if (ec->common.global_lock) {
- status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
- if (ACPI_FAILURE(status))
- return -ENODEV;
- }
-
- if (down_interruptible(&ec->poll.sem)) {
- result = -ERESTARTSYS;
- goto end_nosem;
+ *(rdata++) = acpi_ec_read_data(ec);
}
-
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
- &ec->common.command_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (result)
- goto end;
-
- acpi_hw_low_level_write(8, address, &ec->common.data_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (result)
- goto end;
-
- acpi_hw_low_level_write(8, data, &ec->common.data_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (result)
- goto end;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
- data, address));
-
- end:
- up(&ec->poll.sem);
-end_nosem:
- if (ec->common.global_lock)
- acpi_release_global_lock(glk);
-
- return result;
+ return 0;
}
-static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data)
+static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
+ const u8 *wdata, unsigned wdata_len,
+ u8 *rdata, unsigned rdata_len)
{
- int status = 0;
+ int status;
u32 glk;
-
- if (!ec || !data)
+ if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
return -EINVAL;
- *data = 0;
+ if (rdata)
+ memset(rdata, 0, rdata_len);
- if (ec->common.global_lock) {
+ if (ec->global_lock) {
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
if (ACPI_FAILURE(status))
return -ENODEV;
}
+ down(&ec->sem);
- WARN_ON(in_interrupt());
- down(&ec->intr.sem);
-
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+ status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
if (status) {
printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
goto end;
}
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
- &ec->common.command_addr);
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (status) {
- printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
- }
- acpi_hw_low_level_write(8, address, &ec->common.data_addr);
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (status) {
- printk(KERN_DEBUG PREFIX "read EC, OB not full\n");
- goto end;
- }
- acpi_hw_low_level_read(8, data, &ec->common.data_addr);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
- *data, address));
+ status = acpi_ec_transaction_unlocked(ec, command,
+ wdata, wdata_len,
+ rdata, rdata_len);
- end:
- up(&ec->intr.sem);
+end:
+ up(&ec->sem);
- if (ec->common.global_lock)
+ if (ec->global_lock)
acpi_release_global_lock(glk);
return status;
}
-static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data)
+static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
{
- int status = 0;
- u32 glk;
-
-
- if (!ec)
- return -EINVAL;
-
- if (ec->common.global_lock) {
- status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
- if (ACPI_FAILURE(status))
- return -ENODEV;
- }
-
- WARN_ON(in_interrupt());
- down(&ec->intr.sem);
-
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (status) {
- printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
- }
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
- &ec->common.command_addr);
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (status) {
- printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
- }
-
- acpi_hw_low_level_write(8, address, &ec->common.data_addr);
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (status) {
- printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
- }
-
- acpi_hw_low_level_write(8, data, &ec->common.data_addr);
+ int result;
+ u8 d;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
- data, address));
-
- up(&ec->intr.sem);
-
- if (ec->common.global_lock)
- acpi_release_global_lock(glk);
+ result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ,
+ &address, 1, &d, 1);
+ *data = d;
+ return result;
+}
- return status;
+static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
+{
+ u8 wdata[2] = { address, data };
+ return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
+ wdata, 2, NULL, 0);
}
/*
* Externally callable EC access functions. For now, assume 1 EC only
*/
-int ec_read(u8 addr, u8 * val)
+int ec_read(u8 addr, u8 *val)
{
- union acpi_ec *ec;
+ struct acpi_ec *ec;
int err;
- u32 temp_data;
+ u8 temp_data;
if (!first_ec)
return -ENODEV;
@@ -539,7 +354,7 @@ EXPORT_SYMBOL(ec_read);
int ec_write(u8 addr, u8 val)
{
- union acpi_ec *ec;
+ struct acpi_ec *ec;
int err;
if (!first_ec)
@@ -554,255 +369,106 @@ int ec_write(u8 addr, u8 val)
EXPORT_SYMBOL(ec_write);
-static int acpi_ec_query(union acpi_ec *ec, u32 * data)
-{
- if (acpi_ec_poll_mode)
- return acpi_ec_poll_query(ec, data);
- else
- return acpi_ec_intr_query(ec, data);
-}
-static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data)
+extern int ec_transaction(u8 command,
+ const u8 *wdata, unsigned wdata_len,
+ u8 *rdata, unsigned rdata_len)
{
- int result = 0;
- acpi_status status = AE_OK;
- u32 glk = 0;
-
-
- if (!ec || !data)
- return -EINVAL;
-
- *data = 0;
-
- if (ec->common.global_lock) {
- status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
- if (ACPI_FAILURE(status))
- return -ENODEV;
- }
+ struct acpi_ec *ec;
- /*
- * Query the EC to find out which _Qxx method we need to evaluate.
- * Note that successful completion of the query causes the ACPI_EC_SCI
- * bit to be cleared (and thus clearing the interrupt source).
- */
- if (down_interruptible(&ec->poll.sem)) {
- result = -ERESTARTSYS;
- goto end_nosem;
- }
-
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
- &ec->common.command_addr);
- result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (result)
- goto end;
-
- acpi_hw_low_level_read(8, data, &ec->common.data_addr);
- if (!*data)
- result = -ENODATA;
+ if (!first_ec)
+ return -ENODEV;
- end:
- up(&ec->poll.sem);
-end_nosem:
- if (ec->common.global_lock)
- acpi_release_global_lock(glk);
+ ec = acpi_driver_data(first_ec);
- return result;
+ return acpi_ec_transaction(ec, command, wdata,
+ wdata_len, rdata, rdata_len);
}
-static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data)
-{
- int status = 0;
- u32 glk;
-
- if (!ec || !data)
- return -EINVAL;
- *data = 0;
-
- if (ec->common.global_lock) {
- status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
- if (ACPI_FAILURE(status))
- return -ENODEV;
- }
+EXPORT_SYMBOL(ec_transaction);
- down(&ec->intr.sem);
+static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
+{
+ int result;
+ u8 d;
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
- if (status) {
- printk(KERN_DEBUG PREFIX "query EC, IB not empty\n");
- goto end;
- }
- /*
- * Query the EC to find out which _Qxx method we need to evaluate.
- * Note that successful completion of the query causes the ACPI_EC_SCI
- * bit to be cleared (and thus clearing the interrupt source).
- */
- acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
- &ec->common.command_addr);
- status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
- if (status) {
- printk(KERN_DEBUG PREFIX "query EC, OB not full\n");
- goto end;
- }
+ if (!ec || !data)
+ return -EINVAL;
- acpi_hw_low_level_read(8, data, &ec->common.data_addr);
- if (!*data)
- status = -ENODATA;
+ /*
+ * Query the EC to find out which _Qxx method we need to evaluate.
+ * Note that successful completion of the query causes the ACPI_EC_SCI
+ * bit to be cleared (and thus clearing the interrupt source).
+ */
- end:
- up(&ec->intr.sem);
+ result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1);
+ if (result)
+ return result;
- if (ec->common.global_lock)
- acpi_release_global_lock(glk);
+ if (!d)
+ return -ENODATA;
- return status;
+ *data = d;
+ return 0;
}
/* --------------------------------------------------------------------------
Event Management
-------------------------------------------------------------------------- */
-union acpi_ec_query_data {
+struct acpi_ec_query_data {
acpi_handle handle;
u8 data;
};
static void acpi_ec_gpe_query(void *ec_cxt)
{
- if (acpi_ec_poll_mode)
- acpi_ec_gpe_poll_query(ec_cxt);
- else
- acpi_ec_gpe_intr_query(ec_cxt);
-}
-
-static void acpi_ec_gpe_poll_query(void *ec_cxt)
-{
- union acpi_ec *ec = (union acpi_ec *)ec_cxt;
- u32 value = 0;
- static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
- const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
- };
-
+ struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
+ u8 value = 0;
+ static char object_name[8];
- if (!ec_cxt)
+ if (!ec)
goto end;
- if (down_interruptible (&ec->poll.sem)) {
- return;
- }
- acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
- up(&ec->poll.sem);
-
- /* TBD: Implement asynch events!
- * NOTE: All we care about are EC-SCI's. Other EC events are
- * handled via polling (yuck!). This is because some systems
- * treat EC-SCIs as level (versus EDGE!) triggered, preventing
- * a purely interrupt-driven approach (grumble, grumble).
- */
+ value = acpi_ec_read_status(ec);
+
if (!(value & ACPI_EC_FLAG_SCI))
goto end;
if (acpi_ec_query(ec, &value))
goto end;
- object_name[2] = hex[((value >> 4) & 0x0F)];
- object_name[3] = hex[(value & 0x0F)];
-
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
+ snprintf(object_name, 8, "_Q%2.2X", value);
- acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
- end:
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-}
-static void acpi_ec_gpe_intr_query(void *ec_cxt)
-{
- union acpi_ec *ec = (union acpi_ec *)ec_cxt;
- u32 value;
- int result = -ENODATA;
- static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
- const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
- };
+ acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
-
- if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
- result = acpi_ec_query(ec, &value);
-
- if (result)
- goto end;
-
- object_name[2] = hex[((value >> 4) & 0x0F)];
- object_name[3] = hex[(value & 0x0F)];
-
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
-
- acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
end:
- atomic_dec(&ec->intr.pending_gpe);
- return;
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
}
static u32 acpi_ec_gpe_handler(void *data)
{
- if (acpi_ec_poll_mode)
- return acpi_ec_gpe_poll_handler(data);
- else
- return acpi_ec_gpe_intr_handler(data);
-}
-static u32 acpi_ec_gpe_poll_handler(void *data)
-{
acpi_status status = AE_OK;
- union acpi_ec *ec = (union acpi_ec *)data;
-
- if (!ec)
- return ACPI_INTERRUPT_NOT_HANDLED;
-
- acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
-
- status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec);
-
- if (status == AE_OK)
- return ACPI_INTERRUPT_HANDLED;
- else
- return ACPI_INTERRUPT_NOT_HANDLED;
-}
-static u32 acpi_ec_gpe_intr_handler(void *data)
-{
- acpi_status status = AE_OK;
- u32 value;
- union acpi_ec *ec = (union acpi_ec *)data;
-
- if (!ec)
- return ACPI_INTERRUPT_NOT_HANDLED;
+ u8 value;
+ struct acpi_ec *ec = (struct acpi_ec *)data;
- acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
+ acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
value = acpi_ec_read_status(ec);
- switch (ec->intr.expect_event) {
- case ACPI_EC_EVENT_OBF:
- if (!(value & ACPI_EC_FLAG_OBF))
- break;
- ec->intr.expect_event = 0;
- wake_up(&ec->intr.wait);
- break;
- case ACPI_EC_EVENT_IBE:
- if ((value & ACPI_EC_FLAG_IBF))
- break;
- ec->intr.expect_event = 0;
- wake_up(&ec->intr.wait);
- break;
- default:
- break;
+ if (acpi_ec_mode == EC_INTR) {
+ if (acpi_ec_check_status(value, ec->expect_event)) {
+ ec->expect_event = 0;
+ wake_up(&ec->wait);
+ }
}
if (value & ACPI_EC_FLAG_SCI) {
- atomic_add(1, &ec->intr.pending_gpe);
- status = acpi_os_execute(OSL_EC_BURST_HANDLER,
- acpi_ec_gpe_query, ec);
+ status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
return status == AE_OK ?
ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
}
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
return status == AE_OK ?
ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
}
@@ -833,7 +499,7 @@ acpi_ec_space_handler(u32 function,
void *handler_context, void *region_context)
{
int result = 0;
- union acpi_ec *ec = NULL;
+ struct acpi_ec *ec = NULL;
u64 temp = *value;
acpi_integer f_v = 0;
int i = 0;
@@ -843,18 +509,16 @@ acpi_ec_space_handler(u32 function,
return AE_BAD_PARAMETER;
if (bit_width != 8 && acpi_strict) {
- printk(KERN_WARNING PREFIX
- "acpi_ec_space_handler: bit_width should be 8\n");
return AE_BAD_PARAMETER;
}
- ec = (union acpi_ec *)handler_context;
+ ec = (struct acpi_ec *)handler_context;
next_byte:
switch (function) {
case ACPI_READ:
temp = 0;
- result = acpi_ec_read(ec, (u8) address, (u32 *) & temp);
+ result = acpi_ec_read(ec, (u8) address, (u8 *) &temp);
break;
case ACPI_WRITE:
result = acpi_ec_write(ec, (u8) address, (u8) temp);
@@ -905,20 +569,20 @@ static struct proc_dir_entry *acpi_ec_dir;
static int acpi_ec_read_info(struct seq_file *seq, void *offset)
{
- union acpi_ec *ec = (union acpi_ec *)seq->private;
+ struct acpi_ec *ec = (struct acpi_ec *)seq->private;
if (!ec)
goto end;
seq_printf(seq, "gpe bit: 0x%02x\n",
- (u32) ec->common.gpe_bit);
+ (u32) ec->gpe_bit);
seq_printf(seq, "ports: 0x%02x, 0x%02x\n",
- (u32) ec->common.status_addr.address,
- (u32) ec->common.data_addr.address);
+ (u32) ec->command_addr,
+ (u32) ec->data_addr);
seq_printf(seq, "use global lock: %s\n",
- ec->common.global_lock ? "yes" : "no");
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+ ec->global_lock ? "yes" : "no");
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
end:
return 0;
@@ -929,7 +593,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_ec_read_info, PDE(inode)->data);
}
-static const struct file_operations acpi_ec_info_ops = {
+static struct file_operations acpi_ec_info_ops = {
.open = acpi_ec_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -978,101 +642,35 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
Driver Interface
-------------------------------------------------------------------------- */
-static int acpi_ec_poll_add(struct acpi_device *device)
+static int acpi_ec_add(struct acpi_device *device)
{
int result = 0;
acpi_status status = AE_OK;
- union acpi_ec *ec = NULL;
+ struct acpi_ec *ec = NULL;
if (!device)
return -EINVAL;
- ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+ ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!ec)
return -ENOMEM;
- memset(ec, 0, sizeof(union acpi_ec));
-
- ec->common.handle = device->handle;
- ec->common.uid = -1;
- init_MUTEX(&ec->poll.sem);
- strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
- strcpy(acpi_device_class(device), ACPI_EC_CLASS);
- acpi_driver_data(device) = ec;
-
- /* Use the global lock for all EC transactions? */
- acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
- &ec->common.global_lock);
-
- /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
- http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
- if (ec_ecdt) {
- acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
- ACPI_ADR_SPACE_EC,
- &acpi_ec_space_handler);
-
- acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
- &acpi_ec_gpe_handler);
-
- kfree(ec_ecdt);
+ memset(ec, 0, sizeof(struct acpi_ec));
+
+ ec->handle = device->handle;
+ ec->uid = -1;
+ init_MUTEX(&ec->sem);
+ if (acpi_ec_mode == EC_INTR) {
+ atomic_set(&ec->leaving_burst, 1);
+ init_waitqueue_head(&ec->wait);
}
-
- /* Get GPE bit assignment (EC events). */
- /* TODO: Add support for _GPE returning a package */
- status =
- acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
- &ec->common.gpe_bit);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit"));
- result = -ENODEV;
- goto end;
- }
-
- result = acpi_ec_add_fs(device);
- if (result)
- goto end;
-
- printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n",
- acpi_device_name(device), acpi_device_bid(device),
- (u32) ec->common.gpe_bit);
-
- if (!first_ec)
- first_ec = device;
-
- end:
- if (result)
- kfree(ec);
-
- return result;
-}
-static int acpi_ec_intr_add(struct acpi_device *device)
-{
- int result = 0;
- acpi_status status = AE_OK;
- union acpi_ec *ec = NULL;
-
-
- if (!device)
- return -EINVAL;
-
- ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
- if (!ec)
- return -ENOMEM;
- memset(ec, 0, sizeof(union acpi_ec));
-
- ec->common.handle = device->handle;
- ec->common.uid = -1;
- atomic_set(&ec->intr.pending_gpe, 0);
- atomic_set(&ec->intr.leaving_burst, 1);
- init_MUTEX(&ec->intr.sem);
- init_waitqueue_head(&ec->intr.wait);
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
acpi_driver_data(device) = ec;
/* Use the global lock for all EC transactions? */
- acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
- &ec->common.global_lock);
+ acpi_evaluate_integer(ec->handle, "_GLK", NULL,
+ &ec->global_lock);
/* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
@@ -1081,7 +679,7 @@ static int acpi_ec_intr_add(struct acpi_device *device)
ACPI_ADR_SPACE_EC,
&acpi_ec_space_handler);
- acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
+ acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
&acpi_ec_gpe_handler);
kfree(ec_ecdt);
@@ -1090,10 +688,10 @@ static int acpi_ec_intr_add(struct acpi_device *device)
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
status =
- acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
- &ec->common.gpe_bit);
+ acpi_evaluate_integer(ec->handle, "_GPE", NULL,
+ &ec->gpe_bit);
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Obtaining GPE bit assignment\n");
+ ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment"));
result = -ENODEV;
goto end;
}
@@ -1102,14 +700,14 @@ static int acpi_ec_intr_add(struct acpi_device *device)
if (result)
goto end;
- printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
acpi_device_name(device), acpi_device_bid(device),
- (u32) ec->common.gpe_bit);
+ (u32) ec->gpe_bit));
if (!first_ec)
first_ec = device;
- end:
+ end:
if (result)
kfree(ec);
@@ -1118,7 +716,7 @@ static int acpi_ec_intr_add(struct acpi_device *device)
static int acpi_ec_remove(struct acpi_device *device, int type)
{
- union acpi_ec *ec = NULL;
+ struct acpi_ec *ec = NULL;
if (!device)
@@ -1136,8 +734,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
static acpi_status
acpi_ec_io_ports(struct acpi_resource *resource, void *context)
{
- union acpi_ec *ec = (union acpi_ec *)context;
- struct acpi_generic_address *addr;
+ struct acpi_ec *ec = (struct acpi_ec *)context;
if (resource->type != ACPI_RESOURCE_TYPE_IO) {
return AE_OK;
@@ -1148,26 +745,21 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context)
* the second address region returned is the status/command
* port.
*/
- if (ec->common.data_addr.register_bit_width == 0) {
- addr = &ec->common.data_addr;
- } else if (ec->common.command_addr.register_bit_width == 0) {
- addr = &ec->common.command_addr;
+ if (ec->data_addr == 0) {
+ ec->data_addr = resource->data.io.minimum;
+ } else if (ec->command_addr == 0) {
+ ec->command_addr = resource->data.io.minimum;
} else {
return AE_CTRL_TERMINATE;
}
- addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
- addr->register_bit_width = 8;
- addr->register_bit_offset = 0;
- addr->address = resource->data.io.minimum;
-
return AE_OK;
}
static int acpi_ec_start(struct acpi_device *device)
{
acpi_status status = AE_OK;
- union acpi_ec *ec = NULL;
+ struct acpi_ec *ec = NULL;
if (!device)
@@ -1181,39 +773,35 @@ static int acpi_ec_start(struct acpi_device *device)
/*
* Get I/O port addresses. Convert to GAS format.
*/
- status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS,
+ status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
acpi_ec_io_ports, ec);
- if (ACPI_FAILURE(status)
- || ec->common.command_addr.register_bit_width == 0) {
- printk(KERN_ERR PREFIX "Error getting I/O port addresses\n");
+ if (ACPI_FAILURE(status) || ec->command_addr == 0) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "Error getting I/O port addresses"));
return -ENODEV;
}
- ec->common.status_addr = ec->common.command_addr;
-
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
- (u32) ec->common.gpe_bit,
- (u32) ec->common.command_addr.address,
- (u32) ec->common.data_addr.address));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
+ ec->gpe_bit, ec->command_addr, ec->data_addr));
/*
* Install GPE handler
*/
- status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit,
+ status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
ACPI_GPE_EDGE_TRIGGERED,
&acpi_ec_gpe_handler, ec);
if (ACPI_FAILURE(status)) {
return -ENODEV;
}
- acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
- acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+ acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+ acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
- status = acpi_install_address_space_handler(ec->common.handle,
+ status = acpi_install_address_space_handler(ec->handle,
ACPI_ADR_SPACE_EC,
&acpi_ec_space_handler,
&acpi_ec_space_setup, ec);
if (ACPI_FAILURE(status)) {
- acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
+ acpi_remove_gpe_handler(NULL, ec->gpe_bit,
&acpi_ec_gpe_handler);
return -ENODEV;
}
@@ -1224,7 +812,7 @@ static int acpi_ec_start(struct acpi_device *device)
static int acpi_ec_stop(struct acpi_device *device, int type)
{
acpi_status status = AE_OK;
- union acpi_ec *ec = NULL;
+ struct acpi_ec *ec = NULL;
if (!device)
@@ -1232,14 +820,14 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
ec = acpi_driver_data(device);
- status = acpi_remove_address_space_handler(ec->common.handle,
+ status = acpi_remove_address_space_handler(ec->handle,
ACPI_ADR_SPACE_EC,
&acpi_ec_space_handler);
if (ACPI_FAILURE(status))
return -ENODEV;
status =
- acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
+ acpi_remove_gpe_handler(NULL, ec->gpe_bit,
&acpi_ec_gpe_handler);
if (ACPI_FAILURE(status))
return -ENODEV;
@@ -1251,76 +839,30 @@ static acpi_status __init
acpi_fake_ecdt_callback(acpi_handle handle,
u32 Level, void *context, void **retval)
{
-
- if (acpi_ec_poll_mode)
- return acpi_fake_ecdt_poll_callback(handle,
- Level, context, retval);
- else
- return acpi_fake_ecdt_intr_callback(handle,
- Level, context, retval);
-}
-
-static acpi_status __init
-acpi_fake_ecdt_poll_callback(acpi_handle handle,
- u32 Level, void *context, void **retval)
-{
- acpi_status status;
-
- status = acpi_walk_resources(handle, METHOD_NAME__CRS,
- acpi_ec_io_ports, ec_ecdt);
- if (ACPI_FAILURE(status))
- return status;
- ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
-
- ec_ecdt->common.uid = -1;
- acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
-
- status =
- acpi_evaluate_integer(handle, "_GPE", NULL,
- &ec_ecdt->common.gpe_bit);
- if (ACPI_FAILURE(status))
- return status;
- init_MUTEX(&ec_ecdt->poll.sem);
- ec_ecdt->common.global_lock = TRUE;
- ec_ecdt->common.handle = handle;
-
- printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
- (u32) ec_ecdt->common.gpe_bit,
- (u32) ec_ecdt->common.command_addr.address,
- (u32) ec_ecdt->common.data_addr.address);
-
- return AE_CTRL_TERMINATE;
-}
-
-static acpi_status __init
-acpi_fake_ecdt_intr_callback(acpi_handle handle,
- u32 Level, void *context, void **retval)
-{
acpi_status status;
- init_MUTEX(&ec_ecdt->intr.sem);
- init_waitqueue_head(&ec_ecdt->intr.wait);
+ init_MUTEX(&ec_ecdt->sem);
+ if (acpi_ec_mode == EC_INTR) {
+ init_waitqueue_head(&ec_ecdt->wait);
+ }
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
acpi_ec_io_ports, ec_ecdt);
if (ACPI_FAILURE(status))
return status;
- ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
- ec_ecdt->common.uid = -1;
- acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
+ ec_ecdt->uid = -1;
+ acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
status =
acpi_evaluate_integer(handle, "_GPE", NULL,
- &ec_ecdt->common.gpe_bit);
+ &ec_ecdt->gpe_bit);
if (ACPI_FAILURE(status))
return status;
- ec_ecdt->common.global_lock = TRUE;
- ec_ecdt->common.handle = handle;
+ ec_ecdt->global_lock = TRUE;
+ ec_ecdt->handle = handle;
- printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
- (u32) ec_ecdt->common.gpe_bit,
- (u32) ec_ecdt->common.command_addr.address,
- (u32) ec_ecdt->common.data_addr.address);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
+ ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr));
return AE_CTRL_TERMINATE;
}
@@ -1340,14 +882,14 @@ static int __init acpi_ec_fake_ecdt(void)
acpi_status status;
int ret = 0;
- printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT"));
- ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+ ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!ec_ecdt) {
ret = -ENOMEM;
goto error;
}
- memset(ec_ecdt, 0, sizeof(union acpi_ec));
+ memset(ec_ecdt, 0, sizeof(struct acpi_ec));
status = acpi_get_devices(ACPI_EC_HID,
acpi_fake_ecdt_callback, NULL, NULL);
@@ -1355,24 +897,16 @@ static int __init acpi_ec_fake_ecdt(void)
kfree(ec_ecdt);
ec_ecdt = NULL;
ret = -ENODEV;
+ ACPI_EXCEPTION((AE_INFO, status, "Can't make an fake ECDT"));
goto error;
}
return 0;
- error:
- printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
+ error:
return ret;
}
static int __init acpi_ec_get_real_ecdt(void)
{
- if (acpi_ec_poll_mode)
- return acpi_ec_poll_get_real_ecdt();
- else
- return acpi_ec_intr_get_real_ecdt();
-}
-
-static int __init acpi_ec_poll_get_real_ecdt(void)
-{
acpi_status status;
struct acpi_table_ecdt *ecdt_ptr;
@@ -1382,80 +916,36 @@ static int __init acpi_ec_poll_get_real_ecdt(void)
if (ACPI_FAILURE(status))
return -ENODEV;
- printk(KERN_INFO PREFIX "Found ECDT\n");
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
/*
* Generate a temporary ec context to use until the namespace is scanned
*/
- ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+ ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!ec_ecdt)
return -ENOMEM;
- memset(ec_ecdt, 0, sizeof(union acpi_ec));
-
- ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
- ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
- ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
- ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
- init_MUTEX(&ec_ecdt->poll.sem);
- /* use the GL just to be safe */
- ec_ecdt->common.global_lock = TRUE;
- ec_ecdt->common.uid = ecdt_ptr->uid;
+ memset(ec_ecdt, 0, sizeof(struct acpi_ec));
- status =
- acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
- if (ACPI_FAILURE(status)) {
- goto error;
+ init_MUTEX(&ec_ecdt->sem);
+ if (acpi_ec_mode == EC_INTR) {
+ init_waitqueue_head(&ec_ecdt->wait);
}
-
- return 0;
- error:
- printk(KERN_ERR PREFIX "Could not use ECDT\n");
- kfree(ec_ecdt);
- ec_ecdt = NULL;
-
- return -ENODEV;
-}
-
-static int __init acpi_ec_intr_get_real_ecdt(void)
-{
- acpi_status status;
- struct acpi_table_ecdt *ecdt_ptr;
-
- status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
- (struct acpi_table_header **)
- &ecdt_ptr);
- if (ACPI_FAILURE(status))
- return -ENODEV;
-
- printk(KERN_INFO PREFIX "Found ECDT\n");
-
- /*
- * Generate a temporary ec context to use until the namespace is scanned
- */
- ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
- if (!ec_ecdt)
- return -ENOMEM;
- memset(ec_ecdt, 0, sizeof(union acpi_ec));
-
- init_MUTEX(&ec_ecdt->intr.sem);
- init_waitqueue_head(&ec_ecdt->intr.wait);
- ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
- ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
- ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
- ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
+ ec_ecdt->command_addr = ecdt_ptr->ec_control.address;
+ ec_ecdt->data_addr = ecdt_ptr->ec_data.address;
+ ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
/* use the GL just to be safe */
- ec_ecdt->common.global_lock = TRUE;
- ec_ecdt->common.uid = ecdt_ptr->uid;
+ ec_ecdt->global_lock = TRUE;
+ ec_ecdt->uid = ecdt_ptr->uid;
status =
- acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
+ acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
if (ACPI_FAILURE(status)) {
goto error;
}
return 0;
- error:
- printk(KERN_ERR PREFIX "Could not use ECDT\n");
+ error:
+ ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
kfree(ec_ecdt);
ec_ecdt = NULL;
@@ -1480,14 +970,14 @@ int __init acpi_ec_ecdt_probe(void)
/*
* Install GPE handler
*/
- status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
+ status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
ACPI_GPE_EDGE_TRIGGERED,
&acpi_ec_gpe_handler, ec_ecdt);
if (ACPI_FAILURE(status)) {
goto error;
}
- acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
- acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR);
+ acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+ acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_EC,
@@ -1495,7 +985,7 @@ int __init acpi_ec_ecdt_probe(void)
&acpi_ec_space_setup,
ec_ecdt);
if (ACPI_FAILURE(status)) {
- acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
+ acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
&acpi_ec_gpe_handler);
goto error;
}
@@ -1503,7 +993,7 @@ int __init acpi_ec_ecdt_probe(void)
return 0;
error:
- printk(KERN_ERR PREFIX "Could not use ECDT\n");
+ ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
kfree(ec_ecdt);
ec_ecdt = NULL;
@@ -1562,13 +1052,13 @@ static int __init acpi_ec_set_intr_mode(char *str)
return 0;
if (intr) {
- acpi_ec_poll_mode = EC_INTR;
- acpi_ec_driver.ops.add = acpi_ec_intr_add;
+ acpi_ec_mode = EC_INTR;
} else {
- acpi_ec_poll_mode = EC_POLL;
- acpi_ec_driver.ops.add = acpi_ec_poll_add;
+ acpi_ec_mode = EC_POLL;
}
- printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling");
+ acpi_ec_driver.ops.add = acpi_ec_add;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling"));
+
return 1;
}
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 5b3c7a85eb9a..203d1359190a 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -225,13 +225,12 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
if (!
(ACPI_STRNCMP
(object_hID.value, PCI_ROOT_HID_STRING,
- sizeof(PCI_ROOT_HID_STRING))
- ||
- !(ACPI_STRNCMP
- (object_hID.value,
- PCI_EXPRESS_ROOT_HID_STRING,
- sizeof(PCI_EXPRESS_ROOT_HID_STRING)))))
- {
+ sizeof(PCI_ROOT_HID_STRING)))
+ ||
+ !(ACPI_STRNCMP
+ (object_hID.value,
+ PCI_EXPRESS_ROOT_HID_STRING,
+ sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
/* Install a handler for this PCI root bridge */
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 15fc12482ba0..003a9876c968 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1702,13 +1702,11 @@ static struct ibm_struct ibms[] = {
.name = "brightness",
.read = brightness_read,
.write = brightness_write,
- .experimental = 1,
},
{
.name = "volume",
.read = volume_read,
.write = volume_write,
- .experimental = 1,
},
{
.name = "fan",
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 0a395fca843b..429a39dbd75d 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -219,6 +219,23 @@ static void acpi_safe_halt(void)
static atomic_t c3_cpu_count;
+/* Common C-state entry for C2, C3, .. */
+static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
+{
+ if (cstate->space_id == ACPI_CSTATE_FFH) {
+ /* Call into architectural FFH based C-state */
+ acpi_processor_ffh_cstate_enter(cstate);
+ } else {
+ int unused;
+ /* IO port based C-state */
+ inb(cstate->address);
+ /* Dummy wait op - must do something useless after P_LVL2 read
+ because chipsets cannot guarantee that STPCLK# signal
+ gets asserted in time to freeze execution properly. */
+ unused = inl(acpi_fadt.xpm_tmr_blk.address);
+ }
+}
+
static void acpi_processor_idle(void)
{
struct acpi_processor *pr = NULL;
@@ -361,11 +378,7 @@ static void acpi_processor_idle(void)
/* Get start time (ticks) */
t1 = inl(acpi_fadt.xpm_tmr_blk.address);
/* Invoke C2 */
- inb(cx->address);
- /* Dummy wait op - must do something useless after P_LVL2 read
- because chipsets cannot guarantee that STPCLK# signal
- gets asserted in time to freeze execution properly. */
- t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+ acpi_cstate_enter(cx);
/* Get end time (ticks) */
t2 = inl(acpi_fadt.xpm_tmr_blk.address);
@@ -401,9 +414,7 @@ static void acpi_processor_idle(void)
/* Get start time (ticks) */
t1 = inl(acpi_fadt.xpm_tmr_blk.address);
/* Invoke C3 */
- inb(cx->address);
- /* Dummy wait op (see above) */
- t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+ acpi_cstate_enter(cx);
/* Get end time (ticks) */
t2 = inl(acpi_fadt.xpm_tmr_blk.address);
if (pr->flags.bm_check) {
@@ -628,20 +639,16 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
return 0;
}
-static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr)
+static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
{
-
- /* Zero initialize all the C-states info. */
- memset(pr->power.states, 0, sizeof(pr->power.states));
-
- /* set the first C-State to C1 */
- pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
-
- /* the C0 state only exists as a filler in our array,
- * and all processors need to support C1 */
+ if (!pr->power.states[ACPI_STATE_C1].valid) {
+ /* set the first C-State to C1 */
+ /* all processors need to support C1 */
+ pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
+ pr->power.states[ACPI_STATE_C1].valid = 1;
+ }
+ /* the C0 state only exists as a filler in our array */
pr->power.states[ACPI_STATE_C0].valid = 1;
- pr->power.states[ACPI_STATE_C1].valid = 1;
-
return 0;
}
@@ -658,12 +665,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
if (nocst)
return -ENODEV;
- current_count = 1;
-
- /* Zero initialize C2 onwards and prepare for fresh CST lookup */
- for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++)
- memset(&(pr->power.states[i]), 0,
- sizeof(struct acpi_processor_cx));
+ current_count = 0;
status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
if (ACPI_FAILURE(status)) {
@@ -718,22 +720,39 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
(reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
continue;
- cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
- 0 : reg->address;
-
/* There should be an easy way to extract an integer... */
obj = (union acpi_object *)&(element->package.elements[1]);
if (obj->type != ACPI_TYPE_INTEGER)
continue;
cx.type = obj->integer.value;
-
- if ((cx.type != ACPI_STATE_C1) &&
- (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
- continue;
-
- if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3))
- continue;
+ /*
+ * Some buggy BIOSes won't list C1 in _CST -
+ * Let acpi_processor_get_power_info_default() handle them later
+ */
+ if (i == 1 && cx.type != ACPI_STATE_C1)
+ current_count++;
+
+ cx.address = reg->address;
+ cx.index = current_count + 1;
+
+ cx.space_id = ACPI_CSTATE_SYSTEMIO;
+ if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
+ if (acpi_processor_ffh_cstate_probe
+ (pr->id, &cx, reg) == 0) {
+ cx.space_id = ACPI_CSTATE_FFH;
+ } else if (cx.type != ACPI_STATE_C1) {
+ /*
+ * C1 is a special case where FIXED_HARDWARE
+ * can be handled in non-MWAIT way as well.
+ * In that case, save this _CST entry info.
+ * That is, we retain space_id of SYSTEM_IO for
+ * halt based C1.
+ * Otherwise, ignore this info and continue.
+ */
+ continue;
+ }
+ }
obj = (union acpi_object *)&(element->package.elements[2]);
if (obj->type != ACPI_TYPE_INTEGER)
@@ -938,12 +957,18 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
/* NOTE: the idle thread may not be running while calling
* this function */
- /* Adding C1 state */
- acpi_processor_get_power_info_default_c1(pr);
+ /* Zero initialize all the C-states info. */
+ memset(pr->power.states, 0, sizeof(pr->power.states));
+
result = acpi_processor_get_power_info_cst(pr);
if (result == -ENODEV)
acpi_processor_get_power_info_fadt(pr);
+ if (result)
+ return result;
+
+ acpi_processor_get_power_info_default(pr);
+
pr->power.count = acpi_processor_power_verify(pr);
/*
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 62bef0b3b614..8908a975e575 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -98,11 +98,11 @@ static int update_info_mode = UPDATE_INFO_MODE;
static int update_time = UPDATE_TIME;
static int update_time2 = UPDATE_TIME2;
-module_param(capacity_mode, int, CAPACITY_UNIT);
-module_param(update_mode, int, UPDATE_MODE);
-module_param(update_info_mode, int, UPDATE_INFO_MODE);
-module_param(update_time, int, UPDATE_TIME);
-module_param(update_time2, int, UPDATE_TIME2);
+module_param(capacity_mode, int, 0);
+module_param(update_mode, int, 0);
+module_param(update_info_mode, int, 0);
+module_param(update_time, int, 0);
+module_param(update_time2, int, 0);
static int acpi_sbs_add(struct acpi_device *device);
static int acpi_sbs_remove(struct acpi_device *device, int type);
@@ -1685,10 +1685,16 @@ static int acpi_sbs_add(struct acpi_device *device)
int acpi_sbs_remove(struct acpi_device *device, int type)
{
- struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device);
+ struct acpi_sbs *sbs = NULL;
int id;
- if (!device || !sbs) {
+ if (!device) {
+ return -EINVAL;
+ }
+
+ sbs = (struct acpi_sbs *)acpi_driver_data(device);
+
+ if (!sbs) {
return -EINVAL;
}