aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig2
-rw-r--r--drivers/acpi/glue.c123
-rw-r--r--drivers/acpi/pci_root.c13
-rw-r--r--drivers/acpi/video.c129
4 files changed, 126 insertions, 141 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f4f000abc4e9..50e295b08c94 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -107,7 +107,7 @@ config ACPI_BUTTON
107 107
108config ACPI_VIDEO 108config ACPI_VIDEO
109 tristate "Video" 109 tristate "Video"
110 depends on X86 110 depends on X86 && BACKLIGHT_CLASS_DEVICE
111 help 111 help
112 This driver implement the ACPI Extensions For Display Adapters 112 This driver implement the ACPI Extensions For Display Adapters
113 for integrated graphics devices on motherboard, as specified in 113 for integrated graphics devices on motherboard, as specified in
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 8a0324b43e53..7b6c9ff9bebe 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -86,129 +86,6 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
86 return ret; 86 return ret;
87} 87}
88 88
89/* Get PCI root bridge's handle from its segment and bus number */
90struct acpi_find_pci_root {
91 unsigned int seg;
92 unsigned int bus;
93 acpi_handle handle;
94};
95
96static acpi_status
97do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
98{
99 unsigned long *busnr = data;
100 struct acpi_resource_address64 address;
101
102 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
103 resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
104 resource->type != ACPI_RESOURCE_TYPE_ADDRESS64)
105 return AE_OK;
106
107 acpi_resource_to_address64(resource, &address);
108 if ((address.address_length > 0) &&
109 (address.resource_type == ACPI_BUS_NUMBER_RANGE))
110 *busnr = address.minimum;
111
112 return AE_OK;
113}
114
115static int get_root_bridge_busnr(acpi_handle handle)
116{
117 acpi_status status;
118 unsigned long bus, bbn;
119 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
120
121 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
122
123 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL,
124 &bbn);
125 if (status == AE_NOT_FOUND) {
126 /* Assume bus = 0 */
127 printk(KERN_INFO PREFIX
128 "Assume root bridge [%s] bus is 0\n",
129 (char *)buffer.pointer);
130 status = AE_OK;
131 bbn = 0;
132 }
133 if (ACPI_FAILURE(status)) {
134 bbn = -ENODEV;
135 goto exit;
136 }
137 if (bbn > 0)
138 goto exit;
139
140 /* _BBN in some systems return 0 for all root bridges */
141 bus = -1;
142 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
143 do_root_bridge_busnr_callback, &bus);
144 /* If _CRS failed, we just use _BBN */
145 if (ACPI_FAILURE(status) || (bus == -1))
146 goto exit;
147 /* We select _CRS */
148 if (bbn != bus) {
149 printk(KERN_INFO PREFIX
150 "_BBN and _CRS returns different value for %s. Select _CRS\n",
151 (char *)buffer.pointer);
152 bbn = bus;
153 }
154 exit:
155 kfree(buffer.pointer);
156 return (int)bbn;
157}
158
159static acpi_status
160find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv)
161{
162 struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context;
163 unsigned long seg, bus;
164 acpi_status status;
165 int tmp;
166 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
167
168 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
169
170 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg);
171 if (status == AE_NOT_FOUND) {
172 /* Assume seg = 0 */
173 status = AE_OK;
174 seg = 0;
175 }
176 if (ACPI_FAILURE(status)) {
177 status = AE_CTRL_DEPTH;
178 goto exit;
179 }
180
181 tmp = get_root_bridge_busnr(handle);
182 if (tmp < 0) {
183 printk(KERN_ERR PREFIX
184 "Find root bridge failed for %s\n",
185 (char *)buffer.pointer);
186 status = AE_CTRL_DEPTH;
187 goto exit;
188 }
189 bus = tmp;
190
191 if (seg == find->seg && bus == find->bus)
192 {
193 find->handle = handle;
194 status = AE_CTRL_TERMINATE;
195 }
196 else
197 status = AE_OK;
198 exit:
199 kfree(buffer.pointer);
200 return status;
201}
202
203acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
204{
205 struct acpi_find_pci_root find = { seg, bus, NULL };
206
207 acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
208 return find.handle;
209}
210EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
211
212/* Get device's handler per its address under its parent */ 89/* Get device's handler per its address under its parent */
213struct acpi_find_child { 90struct acpi_find_child {
214 acpi_handle handle; 91 acpi_handle handle;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index a860efa2c562..1f06229040ac 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -117,6 +117,19 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
117 117
118EXPORT_SYMBOL(acpi_pci_unregister_driver); 118EXPORT_SYMBOL(acpi_pci_unregister_driver);
119 119
120acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
121{
122 struct acpi_pci_root *tmp;
123
124 list_for_each_entry(tmp, &acpi_pci_roots, node) {
125 if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus))
126 return tmp->device->handle;
127 }
128 return NULL;
129}
130
131EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
132
120static acpi_status 133static acpi_status
121get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) 134get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
122{ 135{
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 3d54680d0333..a695aeb8b2a7 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -32,6 +32,7 @@
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34 34
35#include <linux/backlight.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36 37
37#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
@@ -56,6 +57,12 @@
56 57
57#define ACPI_VIDEO_HEAD_INVALID (~0u - 1) 58#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
58#define ACPI_VIDEO_HEAD_END (~0u) 59#define ACPI_VIDEO_HEAD_END (~0u)
60#define MAX_NAME_LEN 20
61
62#define ACPI_VIDEO_DISPLAY_CRT 1
63#define ACPI_VIDEO_DISPLAY_TV 2
64#define ACPI_VIDEO_DISPLAY_DVI 3
65#define ACPI_VIDEO_DISPLAY_LCD 4
59 66
60#define _COMPONENT ACPI_VIDEO_COMPONENT 67#define _COMPONENT ACPI_VIDEO_COMPONENT
61ACPI_MODULE_NAME("acpi_video") 68ACPI_MODULE_NAME("acpi_video")
@@ -133,20 +140,21 @@ struct acpi_video_device_flags {
133 u8 crt:1; 140 u8 crt:1;
134 u8 lcd:1; 141 u8 lcd:1;
135 u8 tvout:1; 142 u8 tvout:1;
143 u8 dvi:1;
136 u8 bios:1; 144 u8 bios:1;
137 u8 unknown:1; 145 u8 unknown:1;
138 u8 reserved:3; 146 u8 reserved:2;
139}; 147};
140 148
141struct acpi_video_device_cap { 149struct acpi_video_device_cap {
142 u8 _ADR:1; /*Return the unique ID */ 150 u8 _ADR:1; /*Return the unique ID */
143 u8 _BCL:1; /*Query list of brightness control levels supported */ 151 u8 _BCL:1; /*Query list of brightness control levels supported */
144 u8 _BCM:1; /*Set the brightness level */ 152 u8 _BCM:1; /*Set the brightness level */
153 u8 _BQC:1; /* Get current brightness level */
145 u8 _DDC:1; /*Return the EDID for this device */ 154 u8 _DDC:1; /*Return the EDID for this device */
146 u8 _DCS:1; /*Return status of output device */ 155 u8 _DCS:1; /*Return status of output device */
147 u8 _DGS:1; /*Query graphics state */ 156 u8 _DGS:1; /*Query graphics state */
148 u8 _DSS:1; /*Device state set */ 157 u8 _DSS:1; /*Device state set */
149 u8 _reserved:1;
150}; 158};
151 159
152struct acpi_video_device_brightness { 160struct acpi_video_device_brightness {
@@ -163,6 +171,8 @@ struct acpi_video_device {
163 struct acpi_video_bus *video; 171 struct acpi_video_bus *video;
164 struct acpi_device *dev; 172 struct acpi_device *dev;
165 struct acpi_video_device_brightness *brightness; 173 struct acpi_video_device_brightness *brightness;
174 struct backlight_device *backlight;
175 struct backlight_properties *data;
166}; 176};
167 177
168/* bus */ 178/* bus */
@@ -257,11 +267,35 @@ static void acpi_video_device_bind(struct acpi_video_bus *video,
257 struct acpi_video_device *device); 267 struct acpi_video_device *device);
258static int acpi_video_device_enumerate(struct acpi_video_bus *video); 268static int acpi_video_device_enumerate(struct acpi_video_bus *video);
259static int acpi_video_switch_output(struct acpi_video_bus *video, int event); 269static int acpi_video_switch_output(struct acpi_video_bus *video, int event);
270static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
271 int level);
272static int acpi_video_device_lcd_get_level_current(
273 struct acpi_video_device *device,
274 unsigned long *level);
260static int acpi_video_get_next_level(struct acpi_video_device *device, 275static int acpi_video_get_next_level(struct acpi_video_device *device,
261 u32 level_current, u32 event); 276 u32 level_current, u32 event);
262static void acpi_video_switch_brightness(struct acpi_video_device *device, 277static void acpi_video_switch_brightness(struct acpi_video_device *device,
263 int event); 278 int event);
264 279
280/*backlight device sysfs support*/
281static int acpi_video_get_brightness(struct backlight_device *bd)
282{
283 unsigned long cur_level;
284 struct acpi_video_device *vd =
285 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
286 acpi_video_device_lcd_get_level_current(vd, &cur_level);
287 return (int) cur_level;
288}
289
290static int acpi_video_set_brightness(struct backlight_device *bd)
291{
292 int request_level = bd->props->brightness;
293 struct acpi_video_device *vd =
294 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
295 acpi_video_device_lcd_set_level(vd, request_level);
296 return 0;
297}
298
265/* -------------------------------------------------------------------------- 299/* --------------------------------------------------------------------------
266 Video Management 300 Video Management
267 -------------------------------------------------------------------------- */ 301 -------------------------------------------------------------------------- */
@@ -499,6 +533,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
499 acpi_integer status; 533 acpi_integer status;
500 acpi_handle h_dummy1; 534 acpi_handle h_dummy1;
501 int i; 535 int i;
536 u32 max_level = 0;
502 union acpi_object *obj = NULL; 537 union acpi_object *obj = NULL;
503 struct acpi_video_device_brightness *br = NULL; 538 struct acpi_video_device_brightness *br = NULL;
504 539
@@ -514,6 +549,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
514 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { 549 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
515 device->cap._BCM = 1; 550 device->cap._BCM = 1;
516 } 551 }
552 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
553 device->cap._BQC = 1;
517 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { 554 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
518 device->cap._DDC = 1; 555 device->cap._DDC = 1;
519 } 556 }
@@ -550,6 +587,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
550 continue; 587 continue;
551 } 588 }
552 br->levels[count] = (u32) o->integer.value; 589 br->levels[count] = (u32) o->integer.value;
590 if (br->levels[count] > max_level)
591 max_level = br->levels[count];
553 count++; 592 count++;
554 } 593 }
555 out: 594 out:
@@ -568,6 +607,37 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
568 607
569 kfree(obj); 608 kfree(obj);
570 609
610 if (device->cap._BCL && device->cap._BCM && device->cap._BQC){
611 unsigned long tmp;
612 static int count = 0;
613 char *name;
614 struct backlight_properties *acpi_video_data;
615
616 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
617 if (!name)
618 return;
619
620 acpi_video_data = kzalloc(
621 sizeof(struct backlight_properties),
622 GFP_KERNEL);
623 if (!acpi_video_data){
624 kfree(name);
625 return;
626 }
627 acpi_video_data->owner = THIS_MODULE;
628 acpi_video_data->get_brightness =
629 acpi_video_get_brightness;
630 acpi_video_data->update_status =
631 acpi_video_set_brightness;
632 sprintf(name, "acpi_video%d", count++);
633 device->data = acpi_video_data;
634 acpi_video_data->max_brightness = max_level;
635 acpi_video_device_lcd_get_level_current(device, &tmp);
636 acpi_video_data->brightness = (int)tmp;
637 device->backlight = backlight_device_register(name,
638 NULL, device, acpi_video_data);
639 kfree(name);
640 }
571 return; 641 return;
572} 642}
573 643
@@ -668,6 +738,8 @@ static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
668 seq_printf(seq, "LCD\n"); 738 seq_printf(seq, "LCD\n");
669 else if (dev->flags.tvout) 739 else if (dev->flags.tvout)
670 seq_printf(seq, "TVOUT\n"); 740 seq_printf(seq, "TVOUT\n");
741 else if (dev->flags.dvi)
742 seq_printf(seq, "DVI\n");
671 else 743 else
672 seq_printf(seq, "UNKNOWN\n"); 744 seq_printf(seq, "UNKNOWN\n");
673 745
@@ -1242,6 +1314,16 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
1242 -------------------------------------------------------------------------- */ 1314 -------------------------------------------------------------------------- */
1243 1315
1244/* device interface */ 1316/* device interface */
1317static struct acpi_video_device_attrib*
1318acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1319{
1320 int count;
1321
1322 for(count = 0; count < video->attached_count; count++)
1323 if((video->attached_array[count].value.int_val & 0xffff) == device_id)
1324 return &(video->attached_array[count].value.attrib);
1325 return NULL;
1326}
1245 1327
1246static int 1328static int
1247acpi_video_bus_get_one_device(struct acpi_device *device, 1329acpi_video_bus_get_one_device(struct acpi_device *device,
@@ -1250,7 +1332,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1250 unsigned long device_id; 1332 unsigned long device_id;
1251 int status; 1333 int status;
1252 struct acpi_video_device *data; 1334 struct acpi_video_device *data;
1253 1335 struct acpi_video_device_attrib* attribute;
1254 1336
1255 if (!device || !video) 1337 if (!device || !video)
1256 return -EINVAL; 1338 return -EINVAL;
@@ -1271,20 +1353,30 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1271 data->video = video; 1353 data->video = video;
1272 data->dev = device; 1354 data->dev = device;
1273 1355
1274 switch (device_id & 0xffff) { 1356 attribute = acpi_video_get_device_attr(video, device_id);
1275 case 0x0100: 1357
1276 data->flags.crt = 1; 1358 if((attribute != NULL) && attribute->device_id_scheme) {
1277 break; 1359 switch (attribute->display_type) {
1278 case 0x0400: 1360 case ACPI_VIDEO_DISPLAY_CRT:
1279 data->flags.lcd = 1; 1361 data->flags.crt = 1;
1280 break; 1362 break;
1281 case 0x0200: 1363 case ACPI_VIDEO_DISPLAY_TV:
1282 data->flags.tvout = 1; 1364 data->flags.tvout = 1;
1283 break; 1365 break;
1284 default: 1366 case ACPI_VIDEO_DISPLAY_DVI:
1367 data->flags.dvi = 1;
1368 break;
1369 case ACPI_VIDEO_DISPLAY_LCD:
1370 data->flags.lcd = 1;
1371 break;
1372 default:
1373 data->flags.unknown = 1;
1374 break;
1375 }
1376 if(attribute->bios_can_detect)
1377 data->flags.bios = 1;
1378 } else
1285 data->flags.unknown = 1; 1379 data->flags.unknown = 1;
1286 break;
1287 }
1288 1380
1289 acpi_video_device_bind(video, data); 1381 acpi_video_device_bind(video, data);
1290 acpi_video_device_find_cap(data); 1382 acpi_video_device_find_cap(data);
@@ -1588,7 +1680,10 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1588 status = acpi_remove_notify_handler(device->dev->handle, 1680 status = acpi_remove_notify_handler(device->dev->handle,
1589 ACPI_DEVICE_NOTIFY, 1681 ACPI_DEVICE_NOTIFY,
1590 acpi_video_device_notify); 1682 acpi_video_device_notify);
1591 1683 if (device->backlight){
1684 backlight_device_unregister(device->backlight);
1685 kfree(device->data);
1686 }
1592 return 0; 1687 return 0;
1593} 1688}
1594 1689