aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-15 14:02:52 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-15 14:02:52 -0400
commit0b269d8462a9f0058afb46eaee56e0732acf16c4 (patch)
treef6f5d801b0f991b34b7a71394370fc31746883bb /drivers
parented75ded7dd3fdb647df4efefc5d11158e3d182be (diff)
parent9aaed2b42d00d4abb2748d72d599a8033600e2bf (diff)
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: (28 commits) ACPI: check battery status on resume for un/plug events during sleep ACPICA: Fix incorrect handling of PCI Express Root Bridge _HID ACPI: asus_acpi: don't printk on writing garbage to proc files ACPI: asus_acpi: fix proc files parsing ACPI: SCI interrupt source override ACPI: fix printk format warnings ACPI: fix section for CPU init functions ACPI: update comments in motherboard.c ACPI: acpi_pci_link_set() can allocate with either GFP_ATOMIC or GFP_KERNEL ACPI: fix potential OOPS in power driver with CONFIG_ACPI_DEBUG ACPI: ibm_acpi: delete obsolete documentation ACPI: created a dedicated workqueue for notify() execution ACPI: Remove deferred execution from global lock acquire wakeup path MSI S270 Laptop support: backlight, wlan, bluetooth states ACPI: EC: export ec_transaction() for msi-laptop driver ACPI: EC: Simplify acpi_hw_low_level*() with inb()/outb(). ACPI: EC: Unify poll and interrupt gpe handlers ACPI: EC: Unify poll and interrupt mode transaction functions ACPI: EC: Remove unused variables and duplicated code ACPI: EC: Remove unnecessary delay added by previous transation patch. ...
Diffstat (limited to 'drivers')
-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/evmisc.c14
-rw-r--r--drivers/acpi/events/evrgnini.c13
-rw-r--r--drivers/acpi/ibm_acpi.c2
-rw-r--r--drivers/acpi/motherboard.c6
-rw-r--r--drivers/acpi/osl.c34
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/power.c9
-rw-r--r--drivers/acpi/processor_core.c2
-rw-r--r--drivers/acpi/processor_idle.c103
-rw-r--r--drivers/acpi/sbs.c20
-rw-r--r--drivers/acpi/tables/tbget.c2
-rw-r--r--drivers/acpi/tables/tbrsdt.c2
-rw-r--r--drivers/misc/Kconfig19
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/msi-laptop.c395
18 files changed, 869 insertions, 932 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 {
138 S2x, //S200 (J1 reported), Victor MP-XP7210 138 S2x, //S200 (J1 reported), Victor MP-XP7210
139 W1N, //W1000N 139 W1N, //W1000N
140 W5A, //W5A 140 W5A, //W5A
141 W3V, //W3030V
141 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N 142 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
142 //(Centrino) 143 //(Centrino)
143 END_MODEL 144 END_MODEL
@@ -376,6 +377,17 @@ static struct model_data model_conf[END_MODEL] = {
376 .display_get = "\\ADVG"}, 377 .display_get = "\\ADVG"},
377 378
378 { 379 {
380 .name = "W3V",
381 .mt_mled = "MLED",
382 .mt_wled = "WLED",
383 .mt_lcd_switch = xxN_PREFIX "_Q10",
384 .lcd_status = "\\BKLT",
385 .brightness_set = "SPLV",
386 .brightness_get = "GPLV",
387 .display_set = "SDSP",
388 .display_get = "\\INFB"},
389
390 {
379 .name = "xxN", 391 .name = "xxN",
380 .mt_mled = "MLED", 392 .mt_mled = "MLED",
381/* WLED present, but not controlled by ACPI */ 393/* WLED present, but not controlled by ACPI */
@@ -555,11 +567,11 @@ static int
555write_led(const char __user * buffer, unsigned long count, 567write_led(const char __user * buffer, unsigned long count,
556 char *ledname, int ledmask, int invert) 568 char *ledname, int ledmask, int invert)
557{ 569{
558 int value; 570 int rv, value;
559 int led_out = 0; 571 int led_out = 0;
560 572
561 count = parse_arg(buffer, count, &value); 573 rv = parse_arg(buffer, count, &value);
562 if (count > 0) 574 if (rv > 0)
563 led_out = value ? 1 : 0; 575 led_out = value ? 1 : 0;
564 576
565 hotk->status = 577 hotk->status =
@@ -572,7 +584,7 @@ write_led(const char __user * buffer, unsigned long count,
572 printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", 584 printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
573 ledname); 585 ledname);
574 586
575 return count; 587 return rv;
576} 588}
577 589
578/* 590/*
@@ -607,20 +619,18 @@ static int
607proc_write_ledd(struct file *file, const char __user * buffer, 619proc_write_ledd(struct file *file, const char __user * buffer,
608 unsigned long count, void *data) 620 unsigned long count, void *data)
609{ 621{
610 int value; 622 int rv, value;
611 623
612 count = parse_arg(buffer, count, &value); 624 rv = parse_arg(buffer, count, &value);
613 if (count > 0) { 625 if (rv > 0) {
614 if (!write_acpi_int 626 if (!write_acpi_int
615 (hotk->handle, hotk->methods->mt_ledd, value, NULL)) 627 (hotk->handle, hotk->methods->mt_ledd, value, NULL))
616 printk(KERN_WARNING 628 printk(KERN_WARNING
617 "Asus ACPI: LED display write failed\n"); 629 "Asus ACPI: LED display write failed\n");
618 else 630 else
619 hotk->ledd_status = (u32) value; 631 hotk->ledd_status = (u32) value;
620 } else if (count < 0) 632 }
621 printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); 633 return rv;
622
623 return count;
624} 634}
625 635
626/* 636/*
@@ -761,12 +771,12 @@ static int
761proc_write_lcd(struct file *file, const char __user * buffer, 771proc_write_lcd(struct file *file, const char __user * buffer,
762 unsigned long count, void *data) 772 unsigned long count, void *data)
763{ 773{
764 int value; 774 int rv, value;
765 775
766 count = parse_arg(buffer, count, &value); 776 rv = parse_arg(buffer, count, &value);
767 if (count > 0) 777 if (rv > 0)
768 set_lcd_state(value); 778 set_lcd_state(value);
769 return count; 779 return rv;
770} 780}
771 781
772static int read_brightness(void) 782static int read_brightness(void)
@@ -830,18 +840,15 @@ static int
830proc_write_brn(struct file *file, const char __user * buffer, 840proc_write_brn(struct file *file, const char __user * buffer,
831 unsigned long count, void *data) 841 unsigned long count, void *data)
832{ 842{
833 int value; 843 int rv, value;
834 844
835 count = parse_arg(buffer, count, &value); 845 rv = parse_arg(buffer, count, &value);
836 if (count > 0) { 846 if (rv > 0) {
837 value = (0 < value) ? ((15 < value) ? 15 : value) : 0; 847 value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
838 /* 0 <= value <= 15 */ 848 /* 0 <= value <= 15 */
839 set_brightness(value); 849 set_brightness(value);
840 } else if (count < 0) {
841 printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
842 } 850 }
843 851 return rv;
844 return count;
845} 852}
846 853
847static void set_display(int value) 854static void set_display(int value)
@@ -880,15 +887,12 @@ static int
880proc_write_disp(struct file *file, const char __user * buffer, 887proc_write_disp(struct file *file, const char __user * buffer,
881 unsigned long count, void *data) 888 unsigned long count, void *data)
882{ 889{
883 int value; 890 int rv, value;
884 891
885 count = parse_arg(buffer, count, &value); 892 rv = parse_arg(buffer, count, &value);
886 if (count > 0) 893 if (rv > 0)
887 set_display(value); 894 set_display(value);
888 else if (count < 0) 895 return rv;
889 printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
890
891 return count;
892} 896}
893 897
894typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, 898typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
@@ -1097,6 +1101,8 @@ static int asus_model_match(char *model)
1097 return A4G; 1101 return A4G;
1098 else if (strncmp(model, "W1N", 3) == 0) 1102 else if (strncmp(model, "W1N", 3) == 0)
1099 return W1N; 1103 return W1N;
1104 else if (strncmp(model, "W3V", 3) == 0)
1105 return W3V;
1100 else if (strncmp(model, "W5A", 3) == 0) 1106 else if (strncmp(model, "W5A", 3) == 0)
1101 return W5A; 1107 return W5A;
1102 else 1108 else
@@ -1200,9 +1206,10 @@ static int asus_hotk_get_info(void)
1200 hotk->methods->mt_wled = NULL; 1206 hotk->methods->mt_wled = NULL;
1201 /* L5D's WLED is not controlled by ACPI */ 1207 /* L5D's WLED is not controlled by ACPI */
1202 else if (strncmp(string, "M2N", 3) == 0 || 1208 else if (strncmp(string, "M2N", 3) == 0 ||
1209 strncmp(string, "W3V", 3) == 0 ||
1203 strncmp(string, "S1N", 3) == 0) 1210 strncmp(string, "S1N", 3) == 0)
1204 hotk->methods->mt_wled = "WLED"; 1211 hotk->methods->mt_wled = "WLED";
1205 /* M2N and S1N have a usable WLED */ 1212 /* M2N, S1N and W3V have a usable WLED */
1206 else if (asus_info) { 1213 else if (asus_info) {
1207 if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) 1214 if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
1208 hotk->methods->mled_status = NULL; 1215 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);
64 64
65static int acpi_battery_add(struct acpi_device *device); 65static int acpi_battery_add(struct acpi_device *device);
66static int acpi_battery_remove(struct acpi_device *device, int type); 66static int acpi_battery_remove(struct acpi_device *device, int type);
67static int acpi_battery_resume(struct acpi_device *device, int status);
67 68
68static struct acpi_driver acpi_battery_driver = { 69static struct acpi_driver acpi_battery_driver = {
69 .name = ACPI_BATTERY_DRIVER_NAME, 70 .name = ACPI_BATTERY_DRIVER_NAME,
@@ -71,6 +72,7 @@ static struct acpi_driver acpi_battery_driver = {
71 .ids = ACPI_BATTERY_HID, 72 .ids = ACPI_BATTERY_HID,
72 .ops = { 73 .ops = {
73 .add = acpi_battery_add, 74 .add = acpi_battery_add,
75 .resume = acpi_battery_resume,
74 .remove = acpi_battery_remove, 76 .remove = acpi_battery_remove,
75 }, 77 },
76}; 78};
@@ -753,6 +755,18 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
753 return 0; 755 return 0;
754} 756}
755 757
758/* this is needed to learn about changes made in suspended state */
759static int acpi_battery_resume(struct acpi_device *device, int state)
760{
761 struct acpi_battery *battery;
762
763 if (!device)
764 return -EINVAL;
765
766 battery = device->driver_data;
767 return acpi_battery_check(battery);
768}
769
756static int __init acpi_battery_init(void) 770static int __init acpi_battery_init(void)
757{ 771{
758 int result; 772 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")
45#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" 45#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver"
46#define ACPI_EC_DEVICE_NAME "Embedded Controller" 46#define ACPI_EC_DEVICE_NAME "Embedded Controller"
47#define ACPI_EC_FILE_INFO "info" 47#define ACPI_EC_FILE_INFO "info"
48
49/* EC status register */
48#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 50#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
49#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 51#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
50#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ 52#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
51#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ 53#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
52#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ 54
53#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ 55/* EC commands */
54#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
55#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
56#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
57#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
58#define ACPI_EC_COMMAND_READ 0x80 56#define ACPI_EC_COMMAND_READ 0x80
59#define ACPI_EC_COMMAND_WRITE 0x81 57#define ACPI_EC_COMMAND_WRITE 0x81
60#define ACPI_EC_BURST_ENABLE 0x82 58#define ACPI_EC_BURST_ENABLE 0x82
61#define ACPI_EC_BURST_DISABLE 0x83 59#define ACPI_EC_BURST_DISABLE 0x83
62#define ACPI_EC_COMMAND_QUERY 0x84 60#define ACPI_EC_COMMAND_QUERY 0x84
63#define EC_POLL 0xFF 61
64#define EC_INTR 0x00 62/* EC events */
63enum {
64 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
65 ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
66};
67
68#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
69#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
70#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
71#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
72
73enum {
74 EC_INTR = 1, /* Output buffer full */
75 EC_POLL, /* Input buffer empty */
76};
77
65static int acpi_ec_remove(struct acpi_device *device, int type); 78static int acpi_ec_remove(struct acpi_device *device, int type);
66static int acpi_ec_start(struct acpi_device *device); 79static int acpi_ec_start(struct acpi_device *device);
67static int acpi_ec_stop(struct acpi_device *device, int type); 80static int acpi_ec_stop(struct acpi_device *device, int type);
68static int acpi_ec_intr_add(struct acpi_device *device); 81static int acpi_ec_add(struct acpi_device *device);
69static int acpi_ec_poll_add(struct acpi_device *device);
70 82
71static struct acpi_driver acpi_ec_driver = { 83static struct acpi_driver acpi_ec_driver = {
72 .name = ACPI_EC_DRIVER_NAME, 84 .name = ACPI_EC_DRIVER_NAME,
73 .class = ACPI_EC_CLASS, 85 .class = ACPI_EC_CLASS,
74 .ids = ACPI_EC_HID, 86 .ids = ACPI_EC_HID,
75 .ops = { 87 .ops = {
76 .add = acpi_ec_intr_add, 88 .add = acpi_ec_add,
77 .remove = acpi_ec_remove, 89 .remove = acpi_ec_remove,
78 .start = acpi_ec_start, 90 .start = acpi_ec_start,
79 .stop = acpi_ec_stop, 91 .stop = acpi_ec_stop,
80 }, 92 },
81}; 93};
82union acpi_ec {
83 struct {
84 u32 mode;
85 acpi_handle handle;
86 unsigned long uid;
87 unsigned long gpe_bit;
88 struct acpi_generic_address status_addr;
89 struct acpi_generic_address command_addr;
90 struct acpi_generic_address data_addr;
91 unsigned long global_lock;
92 } common;
93
94 struct {
95 u32 mode;
96 acpi_handle handle;
97 unsigned long uid;
98 unsigned long gpe_bit;
99 struct acpi_generic_address status_addr;
100 struct acpi_generic_address command_addr;
101 struct acpi_generic_address data_addr;
102 unsigned long global_lock;
103 unsigned int expect_event;
104 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
105 atomic_t pending_gpe;
106 struct semaphore sem;
107 wait_queue_head_t wait;
108 } intr;
109
110 struct {
111 u32 mode;
112 acpi_handle handle;
113 unsigned long uid;
114 unsigned long gpe_bit;
115 struct acpi_generic_address status_addr;
116 struct acpi_generic_address command_addr;
117 struct acpi_generic_address data_addr;
118 unsigned long global_lock;
119 struct semaphore sem;
120 } poll;
121};
122 94
123static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event);
124static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event);
125static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data);
126static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data);
127static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data);
128static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data);
129static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data);
130static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data);
131static void acpi_ec_gpe_poll_query(void *ec_cxt);
132static void acpi_ec_gpe_intr_query(void *ec_cxt);
133static u32 acpi_ec_gpe_poll_handler(void *data);
134static u32 acpi_ec_gpe_intr_handler(void *data);
135static acpi_status __init
136acpi_fake_ecdt_poll_callback(acpi_handle handle,
137 u32 Level, void *context, void **retval);
138
139static acpi_status __init
140acpi_fake_ecdt_intr_callback(acpi_handle handle,
141 u32 Level, void *context, void **retval);
142
143static int __init acpi_ec_poll_get_real_ecdt(void);
144static int __init acpi_ec_intr_get_real_ecdt(void);
145/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 95/* If we find an EC via the ECDT, we need to keep a ptr to its context */
146static union acpi_ec *ec_ecdt; 96struct acpi_ec {
97 acpi_handle handle;
98 unsigned long uid;
99 unsigned long gpe_bit;
100 unsigned long command_addr;
101 unsigned long data_addr;
102 unsigned long global_lock;
103 struct semaphore sem;
104 unsigned int expect_event;
105 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
106 wait_queue_head_t wait;
107} *ec_ecdt;
147 108
148/* External interfaces use first EC only, so remember */ 109/* External interfaces use first EC only, so remember */
149static struct acpi_device *first_ec; 110static struct acpi_device *first_ec;
150static int acpi_ec_poll_mode = EC_INTR; 111static int acpi_ec_mode = EC_INTR;
151 112
152/* -------------------------------------------------------------------------- 113/* --------------------------------------------------------------------------
153 Transaction Management 114 Transaction Management
154 -------------------------------------------------------------------------- */ 115 -------------------------------------------------------------------------- */
155 116
156static u32 acpi_ec_read_status(union acpi_ec *ec) 117static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
157{ 118{
158 u32 status = 0; 119 return inb(ec->command_addr);
159
160 acpi_hw_low_level_read(8, &status, &ec->common.status_addr);
161 return status;
162} 120}
163 121
164static int acpi_ec_wait(union acpi_ec *ec, u8 event) 122static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
165{ 123{
166 if (acpi_ec_poll_mode) 124 return inb(ec->data_addr);
167 return acpi_ec_poll_wait(ec, event);
168 else
169 return acpi_ec_intr_wait(ec, event);
170} 125}
171 126
172static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event) 127static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
173{ 128{
174 u32 acpi_ec_status = 0; 129 outb(command, ec->command_addr);
175 u32 i = ACPI_EC_UDELAY_COUNT; 130}
176 131
177 if (!ec) 132static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
178 return -EINVAL; 133{
134 outb(data, ec->data_addr);
135}
179 136
180 /* Poll the EC status register waiting for the event to occur. */ 137static int acpi_ec_check_status(u8 status, u8 event)
138{
181 switch (event) { 139 switch (event) {
182 case ACPI_EC_EVENT_OBF: 140 case ACPI_EC_EVENT_OBF_1:
183 do { 141 if (status & ACPI_EC_FLAG_OBF)
184 acpi_hw_low_level_read(8, &acpi_ec_status, 142 return 1;
185 &ec->common.status_addr);
186 if (acpi_ec_status & ACPI_EC_FLAG_OBF)
187 return 0;
188 udelay(ACPI_EC_UDELAY);
189 } while (--i > 0);
190 break; 143 break;
191 case ACPI_EC_EVENT_IBE: 144 case ACPI_EC_EVENT_IBF_0:
192 do { 145 if (!(status & ACPI_EC_FLAG_IBF))
193 acpi_hw_low_level_read(8, &acpi_ec_status, 146 return 1;
194 &ec->common.status_addr);
195 if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
196 return 0;
197 udelay(ACPI_EC_UDELAY);
198 } while (--i > 0);
199 break; 147 break;
200 default: 148 default:
201 return -EINVAL; 149 break;
202 } 150 }
203 151
204 return -ETIME; 152 return 0;
205} 153}
206static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
207{
208 int result = 0;
209
210 154
211 ec->intr.expect_event = event; 155static int acpi_ec_wait(struct acpi_ec *ec, u8 event)
212 smp_mb(); 156{
157 int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0;
158 long time_left;
213 159
214 switch (event) { 160 ec->expect_event = event;
215 case ACPI_EC_EVENT_IBE: 161 if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
216 if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) { 162 ec->expect_event = 0;
217 ec->intr.expect_event = 0; 163 return 0;
218 return 0;
219 }
220 break;
221 default:
222 break;
223 } 164 }
224 165
225 result = wait_event_timeout(ec->intr.wait, 166 do {
226 !ec->intr.expect_event, 167 if (acpi_ec_mode == EC_POLL) {
168 udelay(ACPI_EC_UDELAY);
169 } else {
170 time_left = wait_event_timeout(ec->wait,
171 !ec->expect_event,
227 msecs_to_jiffies(ACPI_EC_DELAY)); 172 msecs_to_jiffies(ACPI_EC_DELAY));
228 173 if (time_left > 0) {
229 ec->intr.expect_event = 0; 174 ec->expect_event = 0;
230 smp_mb(); 175 return 0;
231 176 }
232 /* 177 }
233 * Verify that the event in question has actually happened by 178 if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
234 * querying EC status. Do the check even if operation timed-out 179 ec->expect_event = 0;
235 * to make sure that we did not miss interrupt.
236 */
237 switch (event) {
238 case ACPI_EC_EVENT_OBF:
239 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
240 return 0; 180 return 0;
241 break; 181 }
182 } while (--i > 0);
242 183
243 case ACPI_EC_EVENT_IBE: 184 ec->expect_event = 0;
244 if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
245 return 0;
246 break;
247 }
248 185
249 return -ETIME; 186 return -ETIME;
250} 187}
@@ -254,272 +191,150 @@ static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
254 * Note: samsung nv5000 doesn't work with ec burst mode. 191 * Note: samsung nv5000 doesn't work with ec burst mode.
255 * http://bugzilla.kernel.org/show_bug.cgi?id=4980 192 * http://bugzilla.kernel.org/show_bug.cgi?id=4980
256 */ 193 */
257int acpi_ec_enter_burst_mode(union acpi_ec *ec) 194int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
258{ 195{
259 u32 tmp = 0; 196 u8 tmp = 0;
260 int status = 0; 197 u8 status = 0;
261 198
262 199
263 status = acpi_ec_read_status(ec); 200 status = acpi_ec_read_status(ec);
264 if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { 201 if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
265 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 202 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
266 if (status) 203 if (status)
267 goto end; 204 goto end;
268 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, 205 acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE);
269 &ec->common.command_addr); 206 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
270 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 207 tmp = acpi_ec_read_data(ec);
271 acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
272 if (tmp != 0x90) { /* Burst ACK byte */ 208 if (tmp != 0x90) { /* Burst ACK byte */
273 return -EINVAL; 209 return -EINVAL;
274 } 210 }
275 } 211 }
276 212
277 atomic_set(&ec->intr.leaving_burst, 0); 213 atomic_set(&ec->leaving_burst, 0);
278 return 0; 214 return 0;
279 end: 215 end:
280 ACPI_EXCEPTION ((AE_INFO, status, "EC wait, burst mode"); 216 ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode"));
281 return -1; 217 return -1;
282} 218}
283 219
284int acpi_ec_leave_burst_mode(union acpi_ec *ec) 220int acpi_ec_leave_burst_mode(struct acpi_ec *ec)
285{ 221{
286 int status = 0; 222 u8 status = 0;
287 223
288 224
289 status = acpi_ec_read_status(ec); 225 status = acpi_ec_read_status(ec);
290 if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ 226 if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){
291 status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); 227 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
292 if(status) 228 if(status)
293 goto end; 229 goto end;
294 acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); 230 acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE);
295 acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); 231 acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
296 } 232 }
297 atomic_set(&ec->intr.leaving_burst, 1); 233 atomic_set(&ec->leaving_burst, 1);
298 return 0; 234 return 0;
299end: 235 end:
300 ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"); 236 ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"));
301 return -1; 237 return -1;
302} 238}
303#endif /* ACPI_FUTURE_USAGE */ 239#endif /* ACPI_FUTURE_USAGE */
304 240
305static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) 241static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
306{ 242 const u8 *wdata, unsigned wdata_len,
307 if (acpi_ec_poll_mode) 243 u8 *rdata, unsigned rdata_len)
308 return acpi_ec_poll_read(ec, address, data);
309 else
310 return acpi_ec_intr_read(ec, address, data);
311}
312static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data)
313{
314 if (acpi_ec_poll_mode)
315 return acpi_ec_poll_write(ec, address, data);
316 else
317 return acpi_ec_intr_write(ec, address, data);
318}
319static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data)
320{ 244{
321 acpi_status status = AE_OK; 245 int result;
322 int result = 0;
323 u32 glk = 0;
324 246
247 acpi_ec_write_cmd(ec, command);
325 248
326 if (!ec || !data) 249 for (; wdata_len > 0; wdata_len --) {
327 return -EINVAL; 250 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
328 251 if (result)
329 *data = 0; 252 return result;
330 253 acpi_ec_write_data(ec, *(wdata++));
331 if (ec->common.global_lock) {
332 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
333 if (ACPI_FAILURE(status))
334 return -ENODEV;
335 } 254 }
336 255
337 if (down_interruptible(&ec->poll.sem)) { 256 if (command == ACPI_EC_COMMAND_WRITE) {
338 result = -ERESTARTSYS; 257 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
339 goto end_nosem; 258 if (result)
259 return result;
340 } 260 }
341
342 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
343 &ec->common.command_addr);
344 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
345 if (result)
346 goto end;
347
348 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
349 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
350 if (result)
351 goto end;
352
353 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
354
355 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
356 *data, address));
357
358 end:
359 up(&ec->poll.sem);
360end_nosem:
361 if (ec->common.global_lock)
362 acpi_release_global_lock(glk);
363
364 return result;
365}
366
367static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data)
368{
369 int result = 0;
370 acpi_status status = AE_OK;
371 u32 glk = 0;
372 261
262 for (; rdata_len > 0; rdata_len --) {
263 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
264 if (result)
265 return result;
373 266
374 if (!ec) 267 *(rdata++) = acpi_ec_read_data(ec);
375 return -EINVAL;
376
377 if (ec->common.global_lock) {
378 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
379 if (ACPI_FAILURE(status))
380 return -ENODEV;
381 }
382
383 if (down_interruptible(&ec->poll.sem)) {
384 result = -ERESTARTSYS;
385 goto end_nosem;
386 } 268 }
387
388 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
389 &ec->common.command_addr);
390 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
391 if (result)
392 goto end;
393
394 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
395 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
396 if (result)
397 goto end;
398
399 acpi_hw_low_level_write(8, data, &ec->common.data_addr);
400 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
401 if (result)
402 goto end;
403 269
404 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", 270 return 0;
405 data, address));
406
407 end:
408 up(&ec->poll.sem);
409end_nosem:
410 if (ec->common.global_lock)
411 acpi_release_global_lock(glk);
412
413 return result;
414} 271}
415 272
416static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data) 273static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
274 const u8 *wdata, unsigned wdata_len,
275 u8 *rdata, unsigned rdata_len)
417{ 276{
418 int status = 0; 277 int status;
419 u32 glk; 278 u32 glk;
420 279
421 280 if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
422 if (!ec || !data)
423 return -EINVAL; 281 return -EINVAL;
424 282
425 *data = 0; 283 if (rdata)
284 memset(rdata, 0, rdata_len);
426 285
427 if (ec->common.global_lock) { 286 if (ec->global_lock) {
428 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); 287 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
429 if (ACPI_FAILURE(status)) 288 if (ACPI_FAILURE(status))
430 return -ENODEV; 289 return -ENODEV;
431 } 290 }
291 down(&ec->sem);
432 292
433 WARN_ON(in_interrupt()); 293 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
434 down(&ec->intr.sem);
435
436 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
437 if (status) { 294 if (status) {
438 printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); 295 printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
439 goto end; 296 goto end;
440 } 297 }
441 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
442 &ec->common.command_addr);
443 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
444 if (status) {
445 printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
446 }
447 298
448 acpi_hw_low_level_write(8, address, &ec->common.data_addr); 299 status = acpi_ec_transaction_unlocked(ec, command,
449 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 300 wdata, wdata_len,
450 if (status) { 301 rdata, rdata_len);
451 printk(KERN_DEBUG PREFIX "read EC, OB not full\n");
452 goto end;
453 }
454 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
455 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
456 *data, address));
457 302
458 end: 303end:
459 up(&ec->intr.sem); 304 up(&ec->sem);
460 305
461 if (ec->common.global_lock) 306 if (ec->global_lock)
462 acpi_release_global_lock(glk); 307 acpi_release_global_lock(glk);
463 308
464 return status; 309 return status;
465} 310}
466 311
467static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data) 312static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
468{ 313{
469 int status = 0; 314 int result;
470 u32 glk; 315 u8 d;
471
472
473 if (!ec)
474 return -EINVAL;
475
476 if (ec->common.global_lock) {
477 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
478 if (ACPI_FAILURE(status))
479 return -ENODEV;
480 }
481
482 WARN_ON(in_interrupt());
483 down(&ec->intr.sem);
484
485 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
486 if (status) {
487 printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
488 }
489 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
490 &ec->common.command_addr);
491 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
492 if (status) {
493 printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
494 }
495
496 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
497 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
498 if (status) {
499 printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
500 }
501
502 acpi_hw_low_level_write(8, data, &ec->common.data_addr);
503 316
504 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", 317 result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ,
505 data, address)); 318 &address, 1, &d, 1);
506 319 *data = d;
507 up(&ec->intr.sem); 320 return result;
508 321}
509 if (ec->common.global_lock)
510 acpi_release_global_lock(glk);
511 322
512 return status; 323static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
324{
325 u8 wdata[2] = { address, data };
326 return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
327 wdata, 2, NULL, 0);
513} 328}
514 329
515/* 330/*
516 * Externally callable EC access functions. For now, assume 1 EC only 331 * Externally callable EC access functions. For now, assume 1 EC only
517 */ 332 */
518int ec_read(u8 addr, u8 * val) 333int ec_read(u8 addr, u8 *val)
519{ 334{
520 union acpi_ec *ec; 335 struct acpi_ec *ec;
521 int err; 336 int err;
522 u32 temp_data; 337 u8 temp_data;
523 338
524 if (!first_ec) 339 if (!first_ec)
525 return -ENODEV; 340 return -ENODEV;
@@ -539,7 +354,7 @@ EXPORT_SYMBOL(ec_read);
539 354
540int ec_write(u8 addr, u8 val) 355int ec_write(u8 addr, u8 val)
541{ 356{
542 union acpi_ec *ec; 357 struct acpi_ec *ec;
543 int err; 358 int err;
544 359
545 if (!first_ec) 360 if (!first_ec)
@@ -554,255 +369,106 @@ int ec_write(u8 addr, u8 val)
554 369
555EXPORT_SYMBOL(ec_write); 370EXPORT_SYMBOL(ec_write);
556 371
557static int acpi_ec_query(union acpi_ec *ec, u32 * data) 372extern int ec_transaction(u8 command,
558{ 373 const u8 *wdata, unsigned wdata_len,
559 if (acpi_ec_poll_mode) 374 u8 *rdata, unsigned rdata_len)
560 return acpi_ec_poll_query(ec, data);
561 else
562 return acpi_ec_intr_query(ec, data);
563}
564static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data)
565{ 375{
566 int result = 0; 376 struct acpi_ec *ec;
567 acpi_status status = AE_OK;
568 u32 glk = 0;
569
570
571 if (!ec || !data)
572 return -EINVAL;
573
574 *data = 0;
575
576 if (ec->common.global_lock) {
577 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
578 if (ACPI_FAILURE(status))
579 return -ENODEV;
580 }
581 377
582 /* 378 if (!first_ec)
583 * Query the EC to find out which _Qxx method we need to evaluate. 379 return -ENODEV;
584 * Note that successful completion of the query causes the ACPI_EC_SCI
585 * bit to be cleared (and thus clearing the interrupt source).
586 */
587 if (down_interruptible(&ec->poll.sem)) {
588 result = -ERESTARTSYS;
589 goto end_nosem;
590 }
591
592 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
593 &ec->common.command_addr);
594 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
595 if (result)
596 goto end;
597
598 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
599 if (!*data)
600 result = -ENODATA;
601 380
602 end: 381 ec = acpi_driver_data(first_ec);
603 up(&ec->poll.sem);
604end_nosem:
605 if (ec->common.global_lock)
606 acpi_release_global_lock(glk);
607 382
608 return result; 383 return acpi_ec_transaction(ec, command, wdata,
384 wdata_len, rdata, rdata_len);
609} 385}
610static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data)
611{
612 int status = 0;
613 u32 glk;
614
615 386
616 if (!ec || !data) 387EXPORT_SYMBOL(ec_transaction);
617 return -EINVAL;
618 *data = 0;
619
620 if (ec->common.global_lock) {
621 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
622 if (ACPI_FAILURE(status))
623 return -ENODEV;
624 }
625 388
626 down(&ec->intr.sem); 389static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
390{
391 int result;
392 u8 d;
627 393
628 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 394 if (!ec || !data)
629 if (status) { 395 return -EINVAL;
630 printk(KERN_DEBUG PREFIX "query EC, IB not empty\n");
631 goto end;
632 }
633 /*
634 * Query the EC to find out which _Qxx method we need to evaluate.
635 * Note that successful completion of the query causes the ACPI_EC_SCI
636 * bit to be cleared (and thus clearing the interrupt source).
637 */
638 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
639 &ec->common.command_addr);
640 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
641 if (status) {
642 printk(KERN_DEBUG PREFIX "query EC, OB not full\n");
643 goto end;
644 }
645 396
646 acpi_hw_low_level_read(8, data, &ec->common.data_addr); 397 /*
647 if (!*data) 398 * Query the EC to find out which _Qxx method we need to evaluate.
648 status = -ENODATA; 399 * Note that successful completion of the query causes the ACPI_EC_SCI
400 * bit to be cleared (and thus clearing the interrupt source).
401 */
649 402
650 end: 403 result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1);
651 up(&ec->intr.sem); 404 if (result)
405 return result;
652 406
653 if (ec->common.global_lock) 407 if (!d)
654 acpi_release_global_lock(glk); 408 return -ENODATA;
655 409
656 return status; 410 *data = d;
411 return 0;
657} 412}
658 413
659/* -------------------------------------------------------------------------- 414/* --------------------------------------------------------------------------
660 Event Management 415 Event Management
661 -------------------------------------------------------------------------- */ 416 -------------------------------------------------------------------------- */
662 417
663union acpi_ec_query_data { 418struct acpi_ec_query_data {
664 acpi_handle handle; 419 acpi_handle handle;
665 u8 data; 420 u8 data;
666}; 421};
667 422
668static void acpi_ec_gpe_query(void *ec_cxt) 423static void acpi_ec_gpe_query(void *ec_cxt)
669{ 424{
670 if (acpi_ec_poll_mode) 425 struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
671 acpi_ec_gpe_poll_query(ec_cxt); 426 u8 value = 0;
672 else 427 static char object_name[8];
673 acpi_ec_gpe_intr_query(ec_cxt);
674}
675
676static void acpi_ec_gpe_poll_query(void *ec_cxt)
677{
678 union acpi_ec *ec = (union acpi_ec *)ec_cxt;
679 u32 value = 0;
680 static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
681 const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
682 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
683 };
684
685 428
686 if (!ec_cxt) 429 if (!ec)
687 goto end; 430 goto end;
688 431
689 if (down_interruptible (&ec->poll.sem)) { 432 value = acpi_ec_read_status(ec);
690 return; 433
691 }
692 acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
693 up(&ec->poll.sem);
694
695 /* TBD: Implement asynch events!
696 * NOTE: All we care about are EC-SCI's. Other EC events are
697 * handled via polling (yuck!). This is because some systems
698 * treat EC-SCIs as level (versus EDGE!) triggered, preventing
699 * a purely interrupt-driven approach (grumble, grumble).
700 */
701 if (!(value & ACPI_EC_FLAG_SCI)) 434 if (!(value & ACPI_EC_FLAG_SCI))
702 goto end; 435 goto end;
703 436
704 if (acpi_ec_query(ec, &value)) 437 if (acpi_ec_query(ec, &value))
705 goto end; 438 goto end;
706 439
707 object_name[2] = hex[((value >> 4) & 0x0F)]; 440 snprintf(object_name, 8, "_Q%2.2X", value);
708 object_name[3] = hex[(value & 0x0F)];
709
710 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
711 441
712 acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); 442 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
713 443
714 end: 444 acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
715 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
716}
717static void acpi_ec_gpe_intr_query(void *ec_cxt)
718{
719 union acpi_ec *ec = (union acpi_ec *)ec_cxt;
720 u32 value;
721 int result = -ENODATA;
722 static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
723 const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
724 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
725 };
726 445
727
728 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
729 result = acpi_ec_query(ec, &value);
730
731 if (result)
732 goto end;
733
734 object_name[2] = hex[((value >> 4) & 0x0F)];
735 object_name[3] = hex[(value & 0x0F)];
736
737 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
738
739 acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
740 end: 446 end:
741 atomic_dec(&ec->intr.pending_gpe); 447 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
742 return;
743} 448}
744 449
745static u32 acpi_ec_gpe_handler(void *data) 450static u32 acpi_ec_gpe_handler(void *data)
746{ 451{
747 if (acpi_ec_poll_mode)
748 return acpi_ec_gpe_poll_handler(data);
749 else
750 return acpi_ec_gpe_intr_handler(data);
751}
752static u32 acpi_ec_gpe_poll_handler(void *data)
753{
754 acpi_status status = AE_OK; 452 acpi_status status = AE_OK;
755 union acpi_ec *ec = (union acpi_ec *)data; 453 u8 value;
756 454 struct acpi_ec *ec = (struct acpi_ec *)data;
757 if (!ec)
758 return ACPI_INTERRUPT_NOT_HANDLED;
759
760 acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
761
762 status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec);
763
764 if (status == AE_OK)
765 return ACPI_INTERRUPT_HANDLED;
766 else
767 return ACPI_INTERRUPT_NOT_HANDLED;
768}
769static u32 acpi_ec_gpe_intr_handler(void *data)
770{
771 acpi_status status = AE_OK;
772 u32 value;
773 union acpi_ec *ec = (union acpi_ec *)data;
774
775 if (!ec)
776 return ACPI_INTERRUPT_NOT_HANDLED;
777 455
778 acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); 456 acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
779 value = acpi_ec_read_status(ec); 457 value = acpi_ec_read_status(ec);
780 458
781 switch (ec->intr.expect_event) { 459 if (acpi_ec_mode == EC_INTR) {
782 case ACPI_EC_EVENT_OBF: 460 if (acpi_ec_check_status(value, ec->expect_event)) {
783 if (!(value & ACPI_EC_FLAG_OBF)) 461 ec->expect_event = 0;
784 break; 462 wake_up(&ec->wait);
785 ec->intr.expect_event = 0; 463 }
786 wake_up(&ec->intr.wait);
787 break;
788 case ACPI_EC_EVENT_IBE:
789 if ((value & ACPI_EC_FLAG_IBF))
790 break;
791 ec->intr.expect_event = 0;
792 wake_up(&ec->intr.wait);
793 break;
794 default:
795 break;
796 } 464 }
797 465
798 if (value & ACPI_EC_FLAG_SCI) { 466 if (value & ACPI_EC_FLAG_SCI) {
799 atomic_add(1, &ec->intr.pending_gpe); 467 status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
800 status = acpi_os_execute(OSL_EC_BURST_HANDLER,
801 acpi_ec_gpe_query, ec);
802 return status == AE_OK ? 468 return status == AE_OK ?
803 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; 469 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
804 } 470 }
805 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); 471 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
806 return status == AE_OK ? 472 return status == AE_OK ?
807 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; 473 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
808} 474}
@@ -833,7 +499,7 @@ acpi_ec_space_handler(u32 function,
833 void *handler_context, void *region_context) 499 void *handler_context, void *region_context)
834{ 500{
835 int result = 0; 501 int result = 0;
836 union acpi_ec *ec = NULL; 502 struct acpi_ec *ec = NULL;
837 u64 temp = *value; 503 u64 temp = *value;
838 acpi_integer f_v = 0; 504 acpi_integer f_v = 0;
839 int i = 0; 505 int i = 0;
@@ -843,18 +509,16 @@ acpi_ec_space_handler(u32 function,
843 return AE_BAD_PARAMETER; 509 return AE_BAD_PARAMETER;
844 510
845 if (bit_width != 8 && acpi_strict) { 511 if (bit_width != 8 && acpi_strict) {
846 printk(KERN_WARNING PREFIX
847 "acpi_ec_space_handler: bit_width should be 8\n");
848 return AE_BAD_PARAMETER; 512 return AE_BAD_PARAMETER;
849 } 513 }
850 514
851 ec = (union acpi_ec *)handler_context; 515 ec = (struct acpi_ec *)handler_context;
852 516
853 next_byte: 517 next_byte:
854 switch (function) { 518 switch (function) {
855 case ACPI_READ: 519 case ACPI_READ:
856 temp = 0; 520 temp = 0;
857 result = acpi_ec_read(ec, (u8) address, (u32 *) & temp); 521 result = acpi_ec_read(ec, (u8) address, (u8 *) &temp);
858 break; 522 break;
859 case ACPI_WRITE: 523 case ACPI_WRITE:
860 result = acpi_ec_write(ec, (u8) address, (u8) temp); 524 result = acpi_ec_write(ec, (u8) address, (u8) temp);
@@ -905,20 +569,20 @@ static struct proc_dir_entry *acpi_ec_dir;
905 569
906static int acpi_ec_read_info(struct seq_file *seq, void *offset) 570static int acpi_ec_read_info(struct seq_file *seq, void *offset)
907{ 571{
908 union acpi_ec *ec = (union acpi_ec *)seq->private; 572 struct acpi_ec *ec = (struct acpi_ec *)seq->private;
909 573
910 574
911 if (!ec) 575 if (!ec)
912 goto end; 576 goto end;
913 577
914 seq_printf(seq, "gpe bit: 0x%02x\n", 578 seq_printf(seq, "gpe bit: 0x%02x\n",
915 (u32) ec->common.gpe_bit); 579 (u32) ec->gpe_bit);
916 seq_printf(seq, "ports: 0x%02x, 0x%02x\n", 580 seq_printf(seq, "ports: 0x%02x, 0x%02x\n",
917 (u32) ec->common.status_addr.address, 581 (u32) ec->command_addr,
918 (u32) ec->common.data_addr.address); 582 (u32) ec->data_addr);
919 seq_printf(seq, "use global lock: %s\n", 583 seq_printf(seq, "use global lock: %s\n",
920 ec->common.global_lock ? "yes" : "no"); 584 ec->global_lock ? "yes" : "no");
921 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); 585 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
922 586
923 end: 587 end:
924 return 0; 588 return 0;
@@ -929,7 +593,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
929 return single_open(file, acpi_ec_read_info, PDE(inode)->data); 593 return single_open(file, acpi_ec_read_info, PDE(inode)->data);
930} 594}
931 595
932static const struct file_operations acpi_ec_info_ops = { 596static struct file_operations acpi_ec_info_ops = {
933 .open = acpi_ec_info_open_fs, 597 .open = acpi_ec_info_open_fs,
934 .read = seq_read, 598 .read = seq_read,
935 .llseek = seq_lseek, 599 .llseek = seq_lseek,
@@ -978,101 +642,35 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
978 Driver Interface 642 Driver Interface
979 -------------------------------------------------------------------------- */ 643 -------------------------------------------------------------------------- */
980 644
981static int acpi_ec_poll_add(struct acpi_device *device) 645static int acpi_ec_add(struct acpi_device *device)
982{ 646{
983 int result = 0; 647 int result = 0;
984 acpi_status status = AE_OK; 648 acpi_status status = AE_OK;
985 union acpi_ec *ec = NULL; 649 struct acpi_ec *ec = NULL;
986 650
987 651
988 if (!device) 652 if (!device)
989 return -EINVAL; 653 return -EINVAL;
990 654
991 ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); 655 ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
992 if (!ec) 656 if (!ec)
993 return -ENOMEM; 657 return -ENOMEM;
994 memset(ec, 0, sizeof(union acpi_ec)); 658 memset(ec, 0, sizeof(struct acpi_ec));
995 659
996 ec->common.handle = device->handle; 660 ec->handle = device->handle;
997 ec->common.uid = -1; 661 ec->uid = -1;
998 init_MUTEX(&ec->poll.sem); 662 init_MUTEX(&ec->sem);
999 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); 663 if (acpi_ec_mode == EC_INTR) {
1000 strcpy(acpi_device_class(device), ACPI_EC_CLASS); 664 atomic_set(&ec->leaving_burst, 1);
1001 acpi_driver_data(device) = ec; 665 init_waitqueue_head(&ec->wait);
1002
1003 /* Use the global lock for all EC transactions? */
1004 acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
1005 &ec->common.global_lock);
1006
1007 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
1008 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
1009 if (ec_ecdt) {
1010 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
1011 ACPI_ADR_SPACE_EC,
1012 &acpi_ec_space_handler);
1013
1014 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
1015 &acpi_ec_gpe_handler);
1016
1017 kfree(ec_ecdt);
1018 } 666 }
1019
1020 /* Get GPE bit assignment (EC events). */
1021 /* TODO: Add support for _GPE returning a package */
1022 status =
1023 acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
1024 &ec->common.gpe_bit);
1025 if (ACPI_FAILURE(status)) {
1026 ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit"));
1027 result = -ENODEV;
1028 goto end;
1029 }
1030
1031 result = acpi_ec_add_fs(device);
1032 if (result)
1033 goto end;
1034
1035 printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n",
1036 acpi_device_name(device), acpi_device_bid(device),
1037 (u32) ec->common.gpe_bit);
1038
1039 if (!first_ec)
1040 first_ec = device;
1041
1042 end:
1043 if (result)
1044 kfree(ec);
1045
1046 return result;
1047}
1048static int acpi_ec_intr_add(struct acpi_device *device)
1049{
1050 int result = 0;
1051 acpi_status status = AE_OK;
1052 union acpi_ec *ec = NULL;
1053
1054
1055 if (!device)
1056 return -EINVAL;
1057
1058 ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1059 if (!ec)
1060 return -ENOMEM;
1061 memset(ec, 0, sizeof(union acpi_ec));
1062
1063 ec->common.handle = device->handle;
1064 ec->common.uid = -1;
1065 atomic_set(&ec->intr.pending_gpe, 0);
1066 atomic_set(&ec->intr.leaving_burst, 1);
1067 init_MUTEX(&ec->intr.sem);
1068 init_waitqueue_head(&ec->intr.wait);
1069 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); 667 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
1070 strcpy(acpi_device_class(device), ACPI_EC_CLASS); 668 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
1071 acpi_driver_data(device) = ec; 669 acpi_driver_data(device) = ec;
1072 670
1073 /* Use the global lock for all EC transactions? */ 671 /* Use the global lock for all EC transactions? */
1074 acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, 672 acpi_evaluate_integer(ec->handle, "_GLK", NULL,
1075 &ec->common.global_lock); 673 &ec->global_lock);
1076 674
1077 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: 675 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
1078 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ 676 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
@@ -1081,7 +679,7 @@ static int acpi_ec_intr_add(struct acpi_device *device)
1081 ACPI_ADR_SPACE_EC, 679 ACPI_ADR_SPACE_EC,
1082 &acpi_ec_space_handler); 680 &acpi_ec_space_handler);
1083 681
1084 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, 682 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
1085 &acpi_ec_gpe_handler); 683 &acpi_ec_gpe_handler);
1086 684
1087 kfree(ec_ecdt); 685 kfree(ec_ecdt);
@@ -1090,10 +688,10 @@ static int acpi_ec_intr_add(struct acpi_device *device)
1090 /* Get GPE bit assignment (EC events). */ 688 /* Get GPE bit assignment (EC events). */
1091 /* TODO: Add support for _GPE returning a package */ 689 /* TODO: Add support for _GPE returning a package */
1092 status = 690 status =
1093 acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, 691 acpi_evaluate_integer(ec->handle, "_GPE", NULL,
1094 &ec->common.gpe_bit); 692 &ec->gpe_bit);
1095 if (ACPI_FAILURE(status)) { 693 if (ACPI_FAILURE(status)) {
1096 printk(KERN_ERR PREFIX "Obtaining GPE bit assignment\n"); 694 ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment"));
1097 result = -ENODEV; 695 result = -ENODEV;
1098 goto end; 696 goto end;
1099 } 697 }
@@ -1102,14 +700,14 @@ static int acpi_ec_intr_add(struct acpi_device *device)
1102 if (result) 700 if (result)
1103 goto end; 701 goto end;
1104 702
1105 printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n", 703 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
1106 acpi_device_name(device), acpi_device_bid(device), 704 acpi_device_name(device), acpi_device_bid(device),
1107 (u32) ec->common.gpe_bit); 705 (u32) ec->gpe_bit));
1108 706
1109 if (!first_ec) 707 if (!first_ec)
1110 first_ec = device; 708 first_ec = device;
1111 709
1112 end: 710 end:
1113 if (result) 711 if (result)
1114 kfree(ec); 712 kfree(ec);
1115 713
@@ -1118,7 +716,7 @@ static int acpi_ec_intr_add(struct acpi_device *device)
1118 716
1119static int acpi_ec_remove(struct acpi_device *device, int type) 717static int acpi_ec_remove(struct acpi_device *device, int type)
1120{ 718{
1121 union acpi_ec *ec = NULL; 719 struct acpi_ec *ec = NULL;
1122 720
1123 721
1124 if (!device) 722 if (!device)
@@ -1136,8 +734,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
1136static acpi_status 734static acpi_status
1137acpi_ec_io_ports(struct acpi_resource *resource, void *context) 735acpi_ec_io_ports(struct acpi_resource *resource, void *context)
1138{ 736{
1139 union acpi_ec *ec = (union acpi_ec *)context; 737 struct acpi_ec *ec = (struct acpi_ec *)context;
1140 struct acpi_generic_address *addr;
1141 738
1142 if (resource->type != ACPI_RESOURCE_TYPE_IO) { 739 if (resource->type != ACPI_RESOURCE_TYPE_IO) {
1143 return AE_OK; 740 return AE_OK;
@@ -1148,26 +745,21 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context)
1148 * the second address region returned is the status/command 745 * the second address region returned is the status/command
1149 * port. 746 * port.
1150 */ 747 */
1151 if (ec->common.data_addr.register_bit_width == 0) { 748 if (ec->data_addr == 0) {
1152 addr = &ec->common.data_addr; 749 ec->data_addr = resource->data.io.minimum;
1153 } else if (ec->common.command_addr.register_bit_width == 0) { 750 } else if (ec->command_addr == 0) {
1154 addr = &ec->common.command_addr; 751 ec->command_addr = resource->data.io.minimum;
1155 } else { 752 } else {
1156 return AE_CTRL_TERMINATE; 753 return AE_CTRL_TERMINATE;
1157 } 754 }
1158 755
1159 addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
1160 addr->register_bit_width = 8;
1161 addr->register_bit_offset = 0;
1162 addr->address = resource->data.io.minimum;
1163
1164 return AE_OK; 756 return AE_OK;
1165} 757}
1166 758
1167static int acpi_ec_start(struct acpi_device *device) 759static int acpi_ec_start(struct acpi_device *device)
1168{ 760{
1169 acpi_status status = AE_OK; 761 acpi_status status = AE_OK;
1170 union acpi_ec *ec = NULL; 762 struct acpi_ec *ec = NULL;
1171 763
1172 764
1173 if (!device) 765 if (!device)
@@ -1181,39 +773,35 @@ static int acpi_ec_start(struct acpi_device *device)
1181 /* 773 /*
1182 * Get I/O port addresses. Convert to GAS format. 774 * Get I/O port addresses. Convert to GAS format.
1183 */ 775 */
1184 status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS, 776 status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
1185 acpi_ec_io_ports, ec); 777 acpi_ec_io_ports, ec);
1186 if (ACPI_FAILURE(status) 778 if (ACPI_FAILURE(status) || ec->command_addr == 0) {
1187 || ec->common.command_addr.register_bit_width == 0) { 779 ACPI_EXCEPTION((AE_INFO, status,
1188 printk(KERN_ERR PREFIX "Error getting I/O port addresses\n"); 780 "Error getting I/O port addresses"));
1189 return -ENODEV; 781 return -ENODEV;
1190 } 782 }
1191 783
1192 ec->common.status_addr = ec->common.command_addr; 784 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
1193 785 ec->gpe_bit, ec->command_addr, ec->data_addr));
1194 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
1195 (u32) ec->common.gpe_bit,
1196 (u32) ec->common.command_addr.address,
1197 (u32) ec->common.data_addr.address));
1198 786
1199 /* 787 /*
1200 * Install GPE handler 788 * Install GPE handler
1201 */ 789 */
1202 status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit, 790 status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
1203 ACPI_GPE_EDGE_TRIGGERED, 791 ACPI_GPE_EDGE_TRIGGERED,
1204 &acpi_ec_gpe_handler, ec); 792 &acpi_ec_gpe_handler, ec);
1205 if (ACPI_FAILURE(status)) { 793 if (ACPI_FAILURE(status)) {
1206 return -ENODEV; 794 return -ENODEV;
1207 } 795 }
1208 acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); 796 acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
1209 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); 797 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
1210 798
1211 status = acpi_install_address_space_handler(ec->common.handle, 799 status = acpi_install_address_space_handler(ec->handle,
1212 ACPI_ADR_SPACE_EC, 800 ACPI_ADR_SPACE_EC,
1213 &acpi_ec_space_handler, 801 &acpi_ec_space_handler,
1214 &acpi_ec_space_setup, ec); 802 &acpi_ec_space_setup, ec);
1215 if (ACPI_FAILURE(status)) { 803 if (ACPI_FAILURE(status)) {
1216 acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, 804 acpi_remove_gpe_handler(NULL, ec->gpe_bit,
1217 &acpi_ec_gpe_handler); 805 &acpi_ec_gpe_handler);
1218 return -ENODEV; 806 return -ENODEV;
1219 } 807 }
@@ -1224,7 +812,7 @@ static int acpi_ec_start(struct acpi_device *device)
1224static int acpi_ec_stop(struct acpi_device *device, int type) 812static int acpi_ec_stop(struct acpi_device *device, int type)
1225{ 813{
1226 acpi_status status = AE_OK; 814 acpi_status status = AE_OK;
1227 union acpi_ec *ec = NULL; 815 struct acpi_ec *ec = NULL;
1228 816
1229 817
1230 if (!device) 818 if (!device)
@@ -1232,14 +820,14 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
1232 820
1233 ec = acpi_driver_data(device); 821 ec = acpi_driver_data(device);
1234 822
1235 status = acpi_remove_address_space_handler(ec->common.handle, 823 status = acpi_remove_address_space_handler(ec->handle,
1236 ACPI_ADR_SPACE_EC, 824 ACPI_ADR_SPACE_EC,
1237 &acpi_ec_space_handler); 825 &acpi_ec_space_handler);
1238 if (ACPI_FAILURE(status)) 826 if (ACPI_FAILURE(status))
1239 return -ENODEV; 827 return -ENODEV;
1240 828
1241 status = 829 status =
1242 acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, 830 acpi_remove_gpe_handler(NULL, ec->gpe_bit,
1243 &acpi_ec_gpe_handler); 831 &acpi_ec_gpe_handler);
1244 if (ACPI_FAILURE(status)) 832 if (ACPI_FAILURE(status))
1245 return -ENODEV; 833 return -ENODEV;
@@ -1251,76 +839,30 @@ static acpi_status __init
1251acpi_fake_ecdt_callback(acpi_handle handle, 839acpi_fake_ecdt_callback(acpi_handle handle,
1252 u32 Level, void *context, void **retval) 840 u32 Level, void *context, void **retval)
1253{ 841{
1254
1255 if (acpi_ec_poll_mode)
1256 return acpi_fake_ecdt_poll_callback(handle,
1257 Level, context, retval);
1258 else
1259 return acpi_fake_ecdt_intr_callback(handle,
1260 Level, context, retval);
1261}
1262
1263static acpi_status __init
1264acpi_fake_ecdt_poll_callback(acpi_handle handle,
1265 u32 Level, void *context, void **retval)
1266{
1267 acpi_status status;
1268
1269 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
1270 acpi_ec_io_ports, ec_ecdt);
1271 if (ACPI_FAILURE(status))
1272 return status;
1273 ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
1274
1275 ec_ecdt->common.uid = -1;
1276 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
1277
1278 status =
1279 acpi_evaluate_integer(handle, "_GPE", NULL,
1280 &ec_ecdt->common.gpe_bit);
1281 if (ACPI_FAILURE(status))
1282 return status;
1283 init_MUTEX(&ec_ecdt->poll.sem);
1284 ec_ecdt->common.global_lock = TRUE;
1285 ec_ecdt->common.handle = handle;
1286
1287 printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
1288 (u32) ec_ecdt->common.gpe_bit,
1289 (u32) ec_ecdt->common.command_addr.address,
1290 (u32) ec_ecdt->common.data_addr.address);
1291
1292 return AE_CTRL_TERMINATE;
1293}
1294
1295static acpi_status __init
1296acpi_fake_ecdt_intr_callback(acpi_handle handle,
1297 u32 Level, void *context, void **retval)
1298{
1299 acpi_status status; 842 acpi_status status;
1300 843
1301 init_MUTEX(&ec_ecdt->intr.sem); 844 init_MUTEX(&ec_ecdt->sem);
1302 init_waitqueue_head(&ec_ecdt->intr.wait); 845 if (acpi_ec_mode == EC_INTR) {
846 init_waitqueue_head(&ec_ecdt->wait);
847 }
1303 status = acpi_walk_resources(handle, METHOD_NAME__CRS, 848 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
1304 acpi_ec_io_ports, ec_ecdt); 849 acpi_ec_io_ports, ec_ecdt);
1305 if (ACPI_FAILURE(status)) 850 if (ACPI_FAILURE(status))
1306 return status; 851 return status;
1307 ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
1308 852
1309 ec_ecdt->common.uid = -1; 853 ec_ecdt->uid = -1;
1310 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); 854 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
1311 855
1312 status = 856 status =
1313 acpi_evaluate_integer(handle, "_GPE", NULL, 857 acpi_evaluate_integer(handle, "_GPE", NULL,
1314 &ec_ecdt->common.gpe_bit); 858 &ec_ecdt->gpe_bit);
1315 if (ACPI_FAILURE(status)) 859 if (ACPI_FAILURE(status))
1316 return status; 860 return status;
1317 ec_ecdt->common.global_lock = TRUE; 861 ec_ecdt->global_lock = TRUE;
1318 ec_ecdt->common.handle = handle; 862 ec_ecdt->handle = handle;
1319 863
1320 printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", 864 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
1321 (u32) ec_ecdt->common.gpe_bit, 865 ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr));
1322 (u32) ec_ecdt->common.command_addr.address,
1323 (u32) ec_ecdt->common.data_addr.address);
1324 866
1325 return AE_CTRL_TERMINATE; 867 return AE_CTRL_TERMINATE;
1326} 868}
@@ -1340,14 +882,14 @@ static int __init acpi_ec_fake_ecdt(void)
1340 acpi_status status; 882 acpi_status status;
1341 int ret = 0; 883 int ret = 0;
1342 884
1343 printk(KERN_INFO PREFIX "Try to make an fake ECDT\n"); 885 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT"));
1344 886
1345 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); 887 ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
1346 if (!ec_ecdt) { 888 if (!ec_ecdt) {
1347 ret = -ENOMEM; 889 ret = -ENOMEM;
1348 goto error; 890 goto error;
1349 } 891 }
1350 memset(ec_ecdt, 0, sizeof(union acpi_ec)); 892 memset(ec_ecdt, 0, sizeof(struct acpi_ec));
1351 893
1352 status = acpi_get_devices(ACPI_EC_HID, 894 status = acpi_get_devices(ACPI_EC_HID,
1353 acpi_fake_ecdt_callback, NULL, NULL); 895 acpi_fake_ecdt_callback, NULL, NULL);
@@ -1355,24 +897,16 @@ static int __init acpi_ec_fake_ecdt(void)
1355 kfree(ec_ecdt); 897 kfree(ec_ecdt);
1356 ec_ecdt = NULL; 898 ec_ecdt = NULL;
1357 ret = -ENODEV; 899 ret = -ENODEV;
900 ACPI_EXCEPTION((AE_INFO, status, "Can't make an fake ECDT"));
1358 goto error; 901 goto error;
1359 } 902 }
1360 return 0; 903 return 0;
1361 error: 904 error:
1362 printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
1363 return ret; 905 return ret;
1364} 906}
1365 907
1366static int __init acpi_ec_get_real_ecdt(void) 908static int __init acpi_ec_get_real_ecdt(void)
1367{ 909{
1368 if (acpi_ec_poll_mode)
1369 return acpi_ec_poll_get_real_ecdt();
1370 else
1371 return acpi_ec_intr_get_real_ecdt();
1372}
1373
1374static int __init acpi_ec_poll_get_real_ecdt(void)
1375{
1376 acpi_status status; 910 acpi_status status;
1377 struct acpi_table_ecdt *ecdt_ptr; 911 struct acpi_table_ecdt *ecdt_ptr;
1378 912
@@ -1382,80 +916,36 @@ static int __init acpi_ec_poll_get_real_ecdt(void)
1382 if (ACPI_FAILURE(status)) 916 if (ACPI_FAILURE(status))
1383 return -ENODEV; 917 return -ENODEV;
1384 918
1385 printk(KERN_INFO PREFIX "Found ECDT\n"); 919 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
1386 920
1387 /* 921 /*
1388 * Generate a temporary ec context to use until the namespace is scanned 922 * Generate a temporary ec context to use until the namespace is scanned
1389 */ 923 */
1390 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); 924 ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
1391 if (!ec_ecdt) 925 if (!ec_ecdt)
1392 return -ENOMEM; 926 return -ENOMEM;
1393 memset(ec_ecdt, 0, sizeof(union acpi_ec)); 927 memset(ec_ecdt, 0, sizeof(struct acpi_ec));
1394
1395 ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
1396 ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
1397 ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
1398 ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
1399 init_MUTEX(&ec_ecdt->poll.sem);
1400 /* use the GL just to be safe */
1401 ec_ecdt->common.global_lock = TRUE;
1402 ec_ecdt->common.uid = ecdt_ptr->uid;
1403 928
1404 status = 929 init_MUTEX(&ec_ecdt->sem);
1405 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); 930 if (acpi_ec_mode == EC_INTR) {
1406 if (ACPI_FAILURE(status)) { 931 init_waitqueue_head(&ec_ecdt->wait);
1407 goto error;
1408 } 932 }
1409 933 ec_ecdt->command_addr = ecdt_ptr->ec_control.address;
1410 return 0; 934 ec_ecdt->data_addr = ecdt_ptr->ec_data.address;
1411 error: 935 ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
1412 printk(KERN_ERR PREFIX "Could not use ECDT\n");
1413 kfree(ec_ecdt);
1414 ec_ecdt = NULL;
1415
1416 return -ENODEV;
1417}
1418
1419static int __init acpi_ec_intr_get_real_ecdt(void)
1420{
1421 acpi_status status;
1422 struct acpi_table_ecdt *ecdt_ptr;
1423
1424 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
1425 (struct acpi_table_header **)
1426 &ecdt_ptr);
1427 if (ACPI_FAILURE(status))
1428 return -ENODEV;
1429
1430 printk(KERN_INFO PREFIX "Found ECDT\n");
1431
1432 /*
1433 * Generate a temporary ec context to use until the namespace is scanned
1434 */
1435 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1436 if (!ec_ecdt)
1437 return -ENOMEM;
1438 memset(ec_ecdt, 0, sizeof(union acpi_ec));
1439
1440 init_MUTEX(&ec_ecdt->intr.sem);
1441 init_waitqueue_head(&ec_ecdt->intr.wait);
1442 ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
1443 ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
1444 ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
1445 ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
1446 /* use the GL just to be safe */ 936 /* use the GL just to be safe */
1447 ec_ecdt->common.global_lock = TRUE; 937 ec_ecdt->global_lock = TRUE;
1448 ec_ecdt->common.uid = ecdt_ptr->uid; 938 ec_ecdt->uid = ecdt_ptr->uid;
1449 939
1450 status = 940 status =
1451 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); 941 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
1452 if (ACPI_FAILURE(status)) { 942 if (ACPI_FAILURE(status)) {
1453 goto error; 943 goto error;
1454 } 944 }
1455 945
1456 return 0; 946 return 0;
1457 error: 947 error:
1458 printk(KERN_ERR PREFIX "Could not use ECDT\n"); 948 ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
1459 kfree(ec_ecdt); 949 kfree(ec_ecdt);
1460 ec_ecdt = NULL; 950 ec_ecdt = NULL;
1461 951
@@ -1480,14 +970,14 @@ int __init acpi_ec_ecdt_probe(void)
1480 /* 970 /*
1481 * Install GPE handler 971 * Install GPE handler
1482 */ 972 */
1483 status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit, 973 status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
1484 ACPI_GPE_EDGE_TRIGGERED, 974 ACPI_GPE_EDGE_TRIGGERED,
1485 &acpi_ec_gpe_handler, ec_ecdt); 975 &acpi_ec_gpe_handler, ec_ecdt);
1486 if (ACPI_FAILURE(status)) { 976 if (ACPI_FAILURE(status)) {
1487 goto error; 977 goto error;
1488 } 978 }
1489 acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); 979 acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
1490 acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR); 980 acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
1491 981
1492 status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, 982 status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
1493 ACPI_ADR_SPACE_EC, 983 ACPI_ADR_SPACE_EC,
@@ -1495,7 +985,7 @@ int __init acpi_ec_ecdt_probe(void)
1495 &acpi_ec_space_setup, 985 &acpi_ec_space_setup,
1496 ec_ecdt); 986 ec_ecdt);
1497 if (ACPI_FAILURE(status)) { 987 if (ACPI_FAILURE(status)) {
1498 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, 988 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
1499 &acpi_ec_gpe_handler); 989 &acpi_ec_gpe_handler);
1500 goto error; 990 goto error;
1501 } 991 }
@@ -1503,7 +993,7 @@ int __init acpi_ec_ecdt_probe(void)
1503 return 0; 993 return 0;
1504 994
1505 error: 995 error:
1506 printk(KERN_ERR PREFIX "Could not use ECDT\n"); 996 ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
1507 kfree(ec_ecdt); 997 kfree(ec_ecdt);
1508 ec_ecdt = NULL; 998 ec_ecdt = NULL;
1509 999
@@ -1562,13 +1052,13 @@ static int __init acpi_ec_set_intr_mode(char *str)
1562 return 0; 1052 return 0;
1563 1053
1564 if (intr) { 1054 if (intr) {
1565 acpi_ec_poll_mode = EC_INTR; 1055 acpi_ec_mode = EC_INTR;
1566 acpi_ec_driver.ops.add = acpi_ec_intr_add;
1567 } else { 1056 } else {
1568 acpi_ec_poll_mode = EC_POLL; 1057 acpi_ec_mode = EC_POLL;
1569 acpi_ec_driver.ops.add = acpi_ec_poll_add;
1570 } 1058 }
1571 printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); 1059 acpi_ec_driver.ops.add = acpi_ec_add;
1060 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling"));
1061
1572 return 1; 1062 return 1;
1573} 1063}
1574 1064
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 6eef4efddcf6..ee2a10bf9077 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -342,20 +342,8 @@ static u32 acpi_ev_global_lock_handler(void *context)
342 if (acquired) { 342 if (acquired) {
343 343
344 /* Got the lock, now wake all threads waiting for it */ 344 /* Got the lock, now wake all threads waiting for it */
345
346 acpi_gbl_global_lock_acquired = TRUE; 345 acpi_gbl_global_lock_acquired = TRUE;
347 346 acpi_ev_global_lock_thread(context);
348 /* Run the Global Lock thread which will signal all waiting threads */
349
350 status =
351 acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER,
352 acpi_ev_global_lock_thread, context);
353 if (ACPI_FAILURE(status)) {
354 ACPI_EXCEPTION((AE_INFO, status,
355 "Could not queue Global Lock thread"));
356
357 return (ACPI_INTERRUPT_NOT_HANDLED);
358 }
359 } 347 }
360 348
361 return (ACPI_INTERRUPT_HANDLED); 349 return (ACPI_INTERRUPT_HANDLED);
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,
225 if (! 225 if (!
226 (ACPI_STRNCMP 226 (ACPI_STRNCMP
227 (object_hID.value, PCI_ROOT_HID_STRING, 227 (object_hID.value, PCI_ROOT_HID_STRING,
228 sizeof(PCI_ROOT_HID_STRING)) 228 sizeof(PCI_ROOT_HID_STRING)))
229 || 229 ||
230 !(ACPI_STRNCMP 230 !(ACPI_STRNCMP
231 (object_hID.value, 231 (object_hID.value,
232 PCI_EXPRESS_ROOT_HID_STRING, 232 PCI_EXPRESS_ROOT_HID_STRING,
233 sizeof(PCI_EXPRESS_ROOT_HID_STRING))))) 233 sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
234 {
235 234
236 /* Install a handler for this PCI root bridge */ 235 /* Install a handler for this PCI root bridge */
237 236
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[] = {
1702 .name = "brightness", 1702 .name = "brightness",
1703 .read = brightness_read, 1703 .read = brightness_read,
1704 .write = brightness_write, 1704 .write = brightness_write,
1705 .experimental = 1,
1706 }, 1705 },
1707 { 1706 {
1708 .name = "volume", 1707 .name = "volume",
1709 .read = volume_read, 1708 .read = volume_read,
1710 .write = volume_write, 1709 .write = volume_write,
1711 .experimental = 1,
1712 }, 1710 },
1713 { 1711 {
1714 .name = "fan", 1712 .name = "fan",
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
index ec6b7f9ede34..2e17ec75af03 100644
--- a/drivers/acpi/motherboard.c
+++ b/drivers/acpi/motherboard.c
@@ -48,6 +48,12 @@ ACPI_MODULE_NAME("acpi_motherboard")
48 * the io ports if they really know they can use it, while 48 * the io ports if they really know they can use it, while
49 * still preventing hotplug PCI devices from using it. 49 * still preventing hotplug PCI devices from using it.
50 */ 50 */
51
52/*
53 * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01
54 * and PNP0C02, redundant with acpi_reserve_io_ranges().
55 * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP.
56 */
51static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) 57static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data)
52{ 58{
53 struct resource *requested_res = NULL; 59 struct resource *requested_res = NULL;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 068fe4f100b0..c84286cbbe25 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -73,6 +73,7 @@ static unsigned int acpi_irq_irq;
73static acpi_osd_handler acpi_irq_handler; 73static acpi_osd_handler acpi_irq_handler;
74static void *acpi_irq_context; 74static void *acpi_irq_context;
75static struct workqueue_struct *kacpid_wq; 75static struct workqueue_struct *kacpid_wq;
76static struct workqueue_struct *kacpi_notify_wq;
76 77
77acpi_status acpi_os_initialize(void) 78acpi_status acpi_os_initialize(void)
78{ 79{
@@ -91,8 +92,9 @@ acpi_status acpi_os_initialize1(void)
91 return AE_NULL_ENTRY; 92 return AE_NULL_ENTRY;
92 } 93 }
93 kacpid_wq = create_singlethread_workqueue("kacpid"); 94 kacpid_wq = create_singlethread_workqueue("kacpid");
95 kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
94 BUG_ON(!kacpid_wq); 96 BUG_ON(!kacpid_wq);
95 97 BUG_ON(!kacpi_notify_wq);
96 return AE_OK; 98 return AE_OK;
97} 99}
98 100
@@ -104,6 +106,7 @@ acpi_status acpi_os_terminate(void)
104 } 106 }
105 107
106 destroy_workqueue(kacpid_wq); 108 destroy_workqueue(kacpid_wq);
109 destroy_workqueue(kacpi_notify_wq);
107 110
108 return AE_OK; 111 return AE_OK;
109} 112}
@@ -566,10 +569,7 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
566 569
567static void acpi_os_execute_deferred(void *context) 570static void acpi_os_execute_deferred(void *context)
568{ 571{
569 struct acpi_os_dpc *dpc = NULL; 572 struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context;
570
571
572 dpc = (struct acpi_os_dpc *)context;
573 if (!dpc) { 573 if (!dpc) {
574 printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); 574 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
575 return; 575 return;
@@ -604,14 +604,12 @@ acpi_status acpi_os_execute(acpi_execute_type type,
604 struct acpi_os_dpc *dpc; 604 struct acpi_os_dpc *dpc;
605 struct work_struct *task; 605 struct work_struct *task;
606 606
607 ACPI_FUNCTION_TRACE("os_queue_for_execution");
608
609 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 607 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
610 "Scheduling function [%p(%p)] for deferred execution.\n", 608 "Scheduling function [%p(%p)] for deferred execution.\n",
611 function, context)); 609 function, context));
612 610
613 if (!function) 611 if (!function)
614 return_ACPI_STATUS(AE_BAD_PARAMETER); 612 return AE_BAD_PARAMETER;
615 613
616 /* 614 /*
617 * Allocate/initialize DPC structure. Note that this memory will be 615 * Allocate/initialize DPC structure. Note that this memory will be
@@ -624,26 +622,20 @@ acpi_status acpi_os_execute(acpi_execute_type type,
624 * from the same memory. 622 * from the same memory.
625 */ 623 */
626 624
627 dpc = 625 dpc = kmalloc(sizeof(struct acpi_os_dpc) +
628 kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct), 626 sizeof(struct work_struct), GFP_ATOMIC);
629 GFP_ATOMIC);
630 if (!dpc) 627 if (!dpc)
631 return_ACPI_STATUS(AE_NO_MEMORY); 628 return AE_NO_MEMORY;
632
633 dpc->function = function; 629 dpc->function = function;
634 dpc->context = context; 630 dpc->context = context;
635
636 task = (void *)(dpc + 1); 631 task = (void *)(dpc + 1);
637 INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); 632 INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc);
638 633 if (!queue_work((type == OSL_NOTIFY_HANDLER)?
639 if (!queue_work(kacpid_wq, task)) { 634 kacpi_notify_wq : kacpid_wq, task)) {
640 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
641 "Call to queue_work() failed.\n"));
642 kfree(dpc);
643 status = AE_ERROR; 635 status = AE_ERROR;
636 kfree(dpc);
644 } 637 }
645 638 return status;
646 return_ACPI_STATUS(status);
647} 639}
648 640
649EXPORT_SYMBOL(acpi_os_execute); 641EXPORT_SYMBOL(acpi_os_execute);
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 7f3e7e77e794..d53bd9878ca2 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -307,7 +307,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
307 if (!link || !irq) 307 if (!link || !irq)
308 return -EINVAL; 308 return -EINVAL;
309 309
310 resource = kmalloc(sizeof(*resource) + 1, GFP_ATOMIC); 310 resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
311 if (!resource) 311 if (!resource)
312 return -ENOMEM; 312 return -ENOMEM;
313 313
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index fec225d1b6b7..fe67a8af520e 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -216,10 +216,8 @@ static int acpi_power_off_device(acpi_handle handle)
216{ 216{
217 int result = 0; 217 int result = 0;
218 acpi_status status = AE_OK; 218 acpi_status status = AE_OK;
219 struct acpi_device *device = NULL;
220 struct acpi_power_resource *resource = NULL; 219 struct acpi_power_resource *resource = NULL;
221 220
222
223 result = acpi_power_get_context(handle, &resource); 221 result = acpi_power_get_context(handle, &resource);
224 if (result) 222 if (result)
225 return result; 223 return result;
@@ -230,13 +228,13 @@ static int acpi_power_off_device(acpi_handle handle)
230 if (resource->references) { 228 if (resource->references) {
231 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 229 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
232 "Resource [%s] is still in use, dereferencing\n", 230 "Resource [%s] is still in use, dereferencing\n",
233 device->pnp.bus_id)); 231 resource->device->pnp.bus_id));
234 return 0; 232 return 0;
235 } 233 }
236 234
237 if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { 235 if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
238 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", 236 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
239 device->pnp.bus_id)); 237 resource->device->pnp.bus_id));
240 return 0; 238 return 0;
241 } 239 }
242 240
@@ -251,8 +249,7 @@ static int acpi_power_off_device(acpi_handle handle)
251 return -ENOEXEC; 249 return -ENOEXEC;
252 250
253 /* Update the power resource's _device_ power state */ 251 /* Update the power resource's _device_ power state */
254 device = resource->device; 252 resource->device->power.state = ACPI_STATE_D3;
255 device->power.state = ACPI_STATE_D3;
256 253
257 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", 254 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n",
258 resource->name)); 255 resource->name));
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index b13d64415b7a..1908e0d20222 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -519,7 +519,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
519 519
520static void *processor_device_array[NR_CPUS]; 520static void *processor_device_array[NR_CPUS];
521 521
522static int acpi_processor_start(struct acpi_device *device) 522static int __cpuinit acpi_processor_start(struct acpi_device *device)
523{ 523{
524 int result = 0; 524 int result = 0;
525 acpi_status status = AE_OK; 525 acpi_status status = AE_OK;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 0a395fca843b..526387dc3799 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -219,6 +219,23 @@ static void acpi_safe_halt(void)
219 219
220static atomic_t c3_cpu_count; 220static atomic_t c3_cpu_count;
221 221
222/* Common C-state entry for C2, C3, .. */
223static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
224{
225 if (cstate->space_id == ACPI_CSTATE_FFH) {
226 /* Call into architectural FFH based C-state */
227 acpi_processor_ffh_cstate_enter(cstate);
228 } else {
229 int unused;
230 /* IO port based C-state */
231 inb(cstate->address);
232 /* Dummy wait op - must do something useless after P_LVL2 read
233 because chipsets cannot guarantee that STPCLK# signal
234 gets asserted in time to freeze execution properly. */
235 unused = inl(acpi_fadt.xpm_tmr_blk.address);
236 }
237}
238
222static void acpi_processor_idle(void) 239static void acpi_processor_idle(void)
223{ 240{
224 struct acpi_processor *pr = NULL; 241 struct acpi_processor *pr = NULL;
@@ -361,11 +378,7 @@ static void acpi_processor_idle(void)
361 /* Get start time (ticks) */ 378 /* Get start time (ticks) */
362 t1 = inl(acpi_fadt.xpm_tmr_blk.address); 379 t1 = inl(acpi_fadt.xpm_tmr_blk.address);
363 /* Invoke C2 */ 380 /* Invoke C2 */
364 inb(cx->address); 381 acpi_cstate_enter(cx);
365 /* Dummy wait op - must do something useless after P_LVL2 read
366 because chipsets cannot guarantee that STPCLK# signal
367 gets asserted in time to freeze execution properly. */
368 t2 = inl(acpi_fadt.xpm_tmr_blk.address);
369 /* Get end time (ticks) */ 382 /* Get end time (ticks) */
370 t2 = inl(acpi_fadt.xpm_tmr_blk.address); 383 t2 = inl(acpi_fadt.xpm_tmr_blk.address);
371 384
@@ -401,9 +414,7 @@ static void acpi_processor_idle(void)
401 /* Get start time (ticks) */ 414 /* Get start time (ticks) */
402 t1 = inl(acpi_fadt.xpm_tmr_blk.address); 415 t1 = inl(acpi_fadt.xpm_tmr_blk.address);
403 /* Invoke C3 */ 416 /* Invoke C3 */
404 inb(cx->address); 417 acpi_cstate_enter(cx);
405 /* Dummy wait op (see above) */
406 t2 = inl(acpi_fadt.xpm_tmr_blk.address);
407 /* Get end time (ticks) */ 418 /* Get end time (ticks) */
408 t2 = inl(acpi_fadt.xpm_tmr_blk.address); 419 t2 = inl(acpi_fadt.xpm_tmr_blk.address);
409 if (pr->flags.bm_check) { 420 if (pr->flags.bm_check) {
@@ -628,20 +639,16 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
628 return 0; 639 return 0;
629} 640}
630 641
631static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) 642static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
632{ 643{
633 644 if (!pr->power.states[ACPI_STATE_C1].valid) {
634 /* Zero initialize all the C-states info. */ 645 /* set the first C-State to C1 */
635 memset(pr->power.states, 0, sizeof(pr->power.states)); 646 /* all processors need to support C1 */
636 647 pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
637 /* set the first C-State to C1 */ 648 pr->power.states[ACPI_STATE_C1].valid = 1;
638 pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; 649 }
639 650 /* the C0 state only exists as a filler in our array */
640 /* the C0 state only exists as a filler in our array,
641 * and all processors need to support C1 */
642 pr->power.states[ACPI_STATE_C0].valid = 1; 651 pr->power.states[ACPI_STATE_C0].valid = 1;
643 pr->power.states[ACPI_STATE_C1].valid = 1;
644
645 return 0; 652 return 0;
646} 653}
647 654
@@ -658,12 +665,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
658 if (nocst) 665 if (nocst)
659 return -ENODEV; 666 return -ENODEV;
660 667
661 current_count = 1; 668 current_count = 0;
662
663 /* Zero initialize C2 onwards and prepare for fresh CST lookup */
664 for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++)
665 memset(&(pr->power.states[i]), 0,
666 sizeof(struct acpi_processor_cx));
667 669
668 status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); 670 status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
669 if (ACPI_FAILURE(status)) { 671 if (ACPI_FAILURE(status)) {
@@ -718,22 +720,39 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
718 (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) 720 (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
719 continue; 721 continue;
720 722
721 cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
722 0 : reg->address;
723
724 /* There should be an easy way to extract an integer... */ 723 /* There should be an easy way to extract an integer... */
725 obj = (union acpi_object *)&(element->package.elements[1]); 724 obj = (union acpi_object *)&(element->package.elements[1]);
726 if (obj->type != ACPI_TYPE_INTEGER) 725 if (obj->type != ACPI_TYPE_INTEGER)
727 continue; 726 continue;
728 727
729 cx.type = obj->integer.value; 728 cx.type = obj->integer.value;
730 729 /*
731 if ((cx.type != ACPI_STATE_C1) && 730 * Some buggy BIOSes won't list C1 in _CST -
732 (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) 731 * Let acpi_processor_get_power_info_default() handle them later
733 continue; 732 */
734 733 if (i == 1 && cx.type != ACPI_STATE_C1)
735 if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3)) 734 current_count++;
736 continue; 735
736 cx.address = reg->address;
737 cx.index = current_count + 1;
738
739 cx.space_id = ACPI_CSTATE_SYSTEMIO;
740 if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
741 if (acpi_processor_ffh_cstate_probe
742 (pr->id, &cx, reg) == 0) {
743 cx.space_id = ACPI_CSTATE_FFH;
744 } else if (cx.type != ACPI_STATE_C1) {
745 /*
746 * C1 is a special case where FIXED_HARDWARE
747 * can be handled in non-MWAIT way as well.
748 * In that case, save this _CST entry info.
749 * That is, we retain space_id of SYSTEM_IO for
750 * halt based C1.
751 * Otherwise, ignore this info and continue.
752 */
753 continue;
754 }
755 }
737 756
738 obj = (union acpi_object *)&(element->package.elements[2]); 757 obj = (union acpi_object *)&(element->package.elements[2]);
739 if (obj->type != ACPI_TYPE_INTEGER) 758 if (obj->type != ACPI_TYPE_INTEGER)
@@ -938,12 +957,18 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
938 /* NOTE: the idle thread may not be running while calling 957 /* NOTE: the idle thread may not be running while calling
939 * this function */ 958 * this function */
940 959
941 /* Adding C1 state */ 960 /* Zero initialize all the C-states info. */
942 acpi_processor_get_power_info_default_c1(pr); 961 memset(pr->power.states, 0, sizeof(pr->power.states));
962
943 result = acpi_processor_get_power_info_cst(pr); 963 result = acpi_processor_get_power_info_cst(pr);
944 if (result == -ENODEV) 964 if (result == -ENODEV)
945 acpi_processor_get_power_info_fadt(pr); 965 acpi_processor_get_power_info_fadt(pr);
946 966
967 if (result)
968 return result;
969
970 acpi_processor_get_power_info_default(pr);
971
947 pr->power.count = acpi_processor_power_verify(pr); 972 pr->power.count = acpi_processor_power_verify(pr);
948 973
949 /* 974 /*
@@ -1105,7 +1130,7 @@ static struct notifier_block acpi_processor_latency_notifier = {
1105 .notifier_call = acpi_processor_latency_notify, 1130 .notifier_call = acpi_processor_latency_notify,
1106}; 1131};
1107 1132
1108int acpi_processor_power_init(struct acpi_processor *pr, 1133int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1109 struct acpi_device *device) 1134 struct acpi_device *device)
1110{ 1135{
1111 acpi_status status = 0; 1136 acpi_status status = 0;
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;
98static int update_time = UPDATE_TIME; 98static int update_time = UPDATE_TIME;
99static int update_time2 = UPDATE_TIME2; 99static int update_time2 = UPDATE_TIME2;
100 100
101module_param(capacity_mode, int, CAPACITY_UNIT); 101module_param(capacity_mode, int, 0);
102module_param(update_mode, int, UPDATE_MODE); 102module_param(update_mode, int, 0);
103module_param(update_info_mode, int, UPDATE_INFO_MODE); 103module_param(update_info_mode, int, 0);
104module_param(update_time, int, UPDATE_TIME); 104module_param(update_time, int, 0);
105module_param(update_time2, int, UPDATE_TIME2); 105module_param(update_time2, int, 0);
106 106
107static int acpi_sbs_add(struct acpi_device *device); 107static int acpi_sbs_add(struct acpi_device *device);
108static int acpi_sbs_remove(struct acpi_device *device, int type); 108static int acpi_sbs_remove(struct acpi_device *device, int type);
@@ -1685,10 +1685,16 @@ static int acpi_sbs_add(struct acpi_device *device)
1685 1685
1686int acpi_sbs_remove(struct acpi_device *device, int type) 1686int acpi_sbs_remove(struct acpi_device *device, int type)
1687{ 1687{
1688 struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device); 1688 struct acpi_sbs *sbs = NULL;
1689 int id; 1689 int id;
1690 1690
1691 if (!device || !sbs) { 1691 if (!device) {
1692 return -EINVAL;
1693 }
1694
1695 sbs = (struct acpi_sbs *)acpi_driver_data(device);
1696
1697 if (!sbs) {
1692 return -EINVAL; 1698 return -EINVAL;
1693 } 1699 }
1694 1700
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 7856db759af0..11e2d4454e05 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -324,7 +324,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
324 324
325 if (header->length < sizeof(struct acpi_table_header)) { 325 if (header->length < sizeof(struct acpi_table_header)) {
326 ACPI_ERROR((AE_INFO, 326 ACPI_ERROR((AE_INFO,
327 "Table length (%X) is smaller than minimum (%X)", 327 "Table length (%X) is smaller than minimum (%zX)",
328 header->length, sizeof(struct acpi_table_header))); 328 header->length, sizeof(struct acpi_table_header)));
329 329
330 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); 330 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
index 0ad3dbb9ebca..86a5fca9b739 100644
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -187,7 +187,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
187 187
188 if (table_ptr->length < sizeof(struct acpi_table_header)) { 188 if (table_ptr->length < sizeof(struct acpi_table_header)) {
189 ACPI_ERROR((AE_INFO, 189 ACPI_ERROR((AE_INFO,
190 "RSDT/XSDT length (%X) is smaller than minimum (%X)", 190 "RSDT/XSDT length (%X) is smaller than minimum (%zX)",
191 table_ptr->length, 191 table_ptr->length,
192 sizeof(struct acpi_table_header))); 192 sizeof(struct acpi_table_header)));
193 193
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 3df0e7a07c46..fa7acc2c5c6d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -57,4 +57,23 @@ config TIFM_7XX1
57 To compile this driver as a module, choose M here: the module will 57 To compile this driver as a module, choose M here: the module will
58 be called tifm_7xx1. 58 be called tifm_7xx1.
59 59
60config MSI_LAPTOP
61 tristate "MSI Laptop Extras"
62 depends on X86
63 depends on ACPI_EC
64 depends on BACKLIGHT_CLASS_DEVICE
65 ---help---
66 This is a driver for laptops built by MSI (MICRO-STAR
67 INTERNATIONAL):
68
69 MSI MegaBook S270 (MS-1013)
70 Cytron/TCM/Medion/Tchibo MD96100/SAM2000
71
72 It adds support for Bluetooth, WLAN and LCD brightness control.
73
74 More information about this driver is available at
75 <http://0pointer.de/lennart/tchibo.html>.
76
77 If you have an MSI S270 laptop, say Y or M here.
78
60endmenu 79endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d65ece76095a..9a91c1ee8497 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -5,6 +5,7 @@ obj- := misc.o # Dummy rule to force built-in.o to be made
5 5
6obj-$(CONFIG_IBM_ASM) += ibmasm/ 6obj-$(CONFIG_IBM_ASM) += ibmasm/
7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ 7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
8obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
8obj-$(CONFIG_LKDTM) += lkdtm.o 9obj-$(CONFIG_LKDTM) += lkdtm.o
9obj-$(CONFIG_TIFM_CORE) += tifm_core.o 10obj-$(CONFIG_TIFM_CORE) += tifm_core.o
10obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 11obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
new file mode 100644
index 000000000000..fdb7153f4426
--- /dev/null
+++ b/drivers/misc/msi-laptop.c
@@ -0,0 +1,395 @@
1/*-*-linux-c-*-*/
2
3/*
4 Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.
20 */
21
22/*
23 * msi-laptop.c - MSI S270 laptop support. This laptop is sold under
24 * various brands, including "Cytron/TCM/Medion/Tchibo MD96100".
25 *
26 * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/:
27 *
28 * lcd_level - Screen brightness: contains a single integer in the
29 * range 0..8. (rw)
30 *
31 * auto_brightness - Enable automatic brightness control: contains
32 * either 0 or 1. If set to 1 the hardware adjusts the screen
33 * brightness automatically when the power cord is
34 * plugged/unplugged. (rw)
35 *
36 * wlan - WLAN subsystem enabled: contains either 0 or 1. (ro)
37 *
38 * bluetooth - Bluetooth subsystem enabled: contains either 0 or 1
39 * Please note that this file is constantly 0 if no Bluetooth
40 * hardware is available. (ro)
41 *
42 * In addition to these platform device attributes the driver
43 * registers itself in the Linux backlight control subsystem and is
44 * available to userspace under /sys/class/backlight/msi-laptop-bl/.
45 *
46 * This driver might work on other laptops produced by MSI. If you
47 * want to try it you can pass force=1 as argument to the module which
48 * will force it to load even when the DMI data doesn't identify the
49 * laptop as MSI S270. YMMV.
50 */
51
52#include <linux/module.h>
53#include <linux/kernel.h>
54#include <linux/init.h>
55#include <linux/acpi.h>
56#include <linux/dmi.h>
57#include <linux/backlight.h>
58#include <linux/platform_device.h>
59#include <linux/autoconf.h>
60
61#define MSI_DRIVER_VERSION "0.5"
62
63#define MSI_LCD_LEVEL_MAX 9
64
65#define MSI_EC_COMMAND_WIRELESS 0x10
66#define MSI_EC_COMMAND_LCD_LEVEL 0x11
67
68static int force;
69module_param(force, bool, 0);
70MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
71
72static int auto_brightness;
73module_param(auto_brightness, int, 0);
74MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)");
75
76/* Hardware access */
77
78static int set_lcd_level(int level)
79{
80 u8 buf[2];
81
82 if (level < 0 || level >= MSI_LCD_LEVEL_MAX)
83 return -EINVAL;
84
85 buf[0] = 0x80;
86 buf[1] = (u8) (level*31);
87
88 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0);
89}
90
91static int get_lcd_level(void)
92{
93 u8 wdata = 0, rdata;
94 int result;
95
96 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1);
97 if (result < 0)
98 return result;
99
100 return (int) rdata / 31;
101}
102
103static int get_auto_brightness(void)
104{
105 u8 wdata = 4, rdata;
106 int result;
107
108 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1);
109 if (result < 0)
110 return result;
111
112 return !!(rdata & 8);
113}
114
115static int set_auto_brightness(int enable)
116{
117 u8 wdata[2], rdata;
118 int result;
119
120 wdata[0] = 4;
121
122 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1);
123 if (result < 0)
124 return result;
125
126 wdata[0] = 0x84;
127 wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0);
128
129 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0);
130}
131
132static int get_wireless_state(int *wlan, int *bluetooth)
133{
134 u8 wdata = 0, rdata;
135 int result;
136
137 result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1);
138 if (result < 0)
139 return -1;
140
141 if (wlan)
142 *wlan = !!(rdata & 8);
143
144 if (bluetooth)
145 *bluetooth = !!(rdata & 128);
146
147 return 0;
148}
149
150/* Backlight device stuff */
151
152static int bl_get_brightness(struct backlight_device *b)
153{
154 return get_lcd_level();
155}
156
157
158static int bl_update_status(struct backlight_device *b)
159{
160 return set_lcd_level(b->props->brightness);
161}
162
163static struct backlight_properties msibl_props = {
164 .owner = THIS_MODULE,
165 .get_brightness = bl_get_brightness,
166 .update_status = bl_update_status,
167 .max_brightness = MSI_LCD_LEVEL_MAX-1,
168};
169
170static struct backlight_device *msibl_device;
171
172/* Platform device */
173
174static ssize_t show_wlan(struct device *dev,
175 struct device_attribute *attr, char *buf)
176{
177
178 int ret, enabled;
179
180 ret = get_wireless_state(&enabled, NULL);
181 if (ret < 0)
182 return ret;
183
184 return sprintf(buf, "%i\n", enabled);
185}
186
187static ssize_t show_bluetooth(struct device *dev,
188 struct device_attribute *attr, char *buf)
189{
190
191 int ret, enabled;
192
193 ret = get_wireless_state(NULL, &enabled);
194 if (ret < 0)
195 return ret;
196
197 return sprintf(buf, "%i\n", enabled);
198}
199
200static ssize_t show_lcd_level(struct device *dev,
201 struct device_attribute *attr, char *buf)
202{
203
204 int ret;
205
206 ret = get_lcd_level();
207 if (ret < 0)
208 return ret;
209
210 return sprintf(buf, "%i\n", ret);
211}
212
213static ssize_t store_lcd_level(struct device *dev,
214 struct device_attribute *attr, const char *buf, size_t count)
215{
216
217 int level, ret;
218
219 if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX))
220 return -EINVAL;
221
222 ret = set_lcd_level(level);
223 if (ret < 0)
224 return ret;
225
226 return count;
227}
228
229static ssize_t show_auto_brightness(struct device *dev,
230 struct device_attribute *attr, char *buf)
231{
232
233 int ret;
234
235 ret = get_auto_brightness();
236 if (ret < 0)
237 return ret;
238
239 return sprintf(buf, "%i\n", ret);
240}
241
242static ssize_t store_auto_brightness(struct device *dev,
243 struct device_attribute *attr, const char *buf, size_t count)
244{
245
246 int enable, ret;
247
248 if (sscanf(buf, "%i", &enable) != 1 || (enable != (enable & 1)))
249 return -EINVAL;
250
251 ret = set_auto_brightness(enable);
252 if (ret < 0)
253 return ret;
254
255 return count;
256}
257
258static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
259static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness);
260static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL);
261static DEVICE_ATTR(wlan, 0444, show_wlan, NULL);
262
263static struct attribute *msipf_attributes[] = {
264 &dev_attr_lcd_level.attr,
265 &dev_attr_auto_brightness.attr,
266 &dev_attr_bluetooth.attr,
267 &dev_attr_wlan.attr,
268 NULL
269};
270
271static struct attribute_group msipf_attribute_group = {
272 .attrs = msipf_attributes
273};
274
275static struct platform_driver msipf_driver = {
276 .driver = {
277 .name = "msi-laptop-pf",
278 .owner = THIS_MODULE,
279 }
280};
281
282static struct platform_device *msipf_device;
283
284/* Initialization */
285
286static struct dmi_system_id __initdata msi_dmi_table[] = {
287 {
288 .ident = "MSI S270",
289 .matches = {
290 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
291 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
292 }
293 },
294 {
295 .ident = "Medion MD96100",
296 .matches = {
297 DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
298 DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
299 }
300 },
301 { }
302};
303
304
305static int __init msi_init(void)
306{
307 int ret;
308
309 if (acpi_disabled)
310 return -ENODEV;
311
312 if (!force && !dmi_check_system(msi_dmi_table))
313 return -ENODEV;
314
315 if (auto_brightness < 0 || auto_brightness > 2)
316 return -EINVAL;
317
318 /* Register backlight stuff */
319
320 msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props);
321 if (IS_ERR(msibl_device))
322 return PTR_ERR(msibl_device);
323
324 ret = platform_driver_register(&msipf_driver);
325 if (ret)
326 goto fail_backlight;
327
328 /* Register platform stuff */
329
330 msipf_device = platform_device_alloc("msi-laptop-pf", -1);
331 if (!msipf_device) {
332 ret = -ENOMEM;
333 goto fail_platform_driver;
334 }
335
336 ret = platform_device_add(msipf_device);
337 if (ret)
338 goto fail_platform_device1;
339
340 ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group);
341 if (ret)
342 goto fail_platform_device2;
343
344 /* Disable automatic brightness control by default because
345 * this module was probably loaded to do brightness control in
346 * software. */
347
348 if (auto_brightness != 2)
349 set_auto_brightness(auto_brightness);
350
351 printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n");
352
353 return 0;
354
355fail_platform_device2:
356
357 platform_device_del(msipf_device);
358
359fail_platform_device1:
360
361 platform_device_put(msipf_device);
362
363fail_platform_driver:
364
365 platform_driver_unregister(&msipf_driver);
366
367fail_backlight:
368
369 backlight_device_unregister(msibl_device);
370
371 return ret;
372}
373
374static void __exit msi_cleanup(void)
375{
376
377 sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
378 platform_device_unregister(msipf_device);
379 platform_driver_unregister(&msipf_driver);
380 backlight_device_unregister(msibl_device);
381
382 /* Enable automatic brightness control again */
383 if (auto_brightness != 2)
384 set_auto_brightness(1);
385
386 printk(KERN_INFO "msi-laptop: driver unloaded.\n");
387}
388
389module_init(msi_init);
390module_exit(msi_cleanup);
391
392MODULE_AUTHOR("Lennart Poettering");
393MODULE_DESCRIPTION("MSI Laptop Support");
394MODULE_VERSION(MSI_DRIVER_VERSION);
395MODULE_LICENSE("GPL");