aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/Makefile2
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c21
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c9
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c7
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h14
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c73
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c113
7 files changed, 141 insertions, 98 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 345ca52d6e84..f6e98dd416c9 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -26,13 +26,13 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
26 intel_dvo.o \ 26 intel_dvo.o \
27 intel_ringbuffer.o \ 27 intel_ringbuffer.o \
28 intel_overlay.o \ 28 intel_overlay.o \
29 intel_opregion.o \
29 dvo_ch7xxx.o \ 30 dvo_ch7xxx.o \
30 dvo_ch7017.o \ 31 dvo_ch7017.o \
31 dvo_ivch.o \ 32 dvo_ivch.o \
32 dvo_tfp410.o \ 33 dvo_tfp410.o \
33 dvo_sil164.o 34 dvo_sil164.o
34 35
35i915-$(CONFIG_ACPI) += intel_opregion.o
36i915-$(CONFIG_COMPAT) += i915_ioc32.o 36i915-$(CONFIG_COMPAT) += i915_ioc32.o
37 37
38obj-$(CONFIG_DRM_I915) += i915.o 38obj-$(CONFIG_DRM_I915) += i915.o
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 5e43d7076789..16133f10ffaa 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -718,6 +718,26 @@ static int i915_gfxec(struct seq_file *m, void *unused)
718 return 0; 718 return 0;
719} 719}
720 720
721static int i915_opregion(struct seq_file *m, void *unused)
722{
723 struct drm_info_node *node = (struct drm_info_node *) m->private;
724 struct drm_device *dev = node->minor->dev;
725 drm_i915_private_t *dev_priv = dev->dev_private;
726 struct intel_opregion *opregion = &dev_priv->opregion;
727 int ret;
728
729 ret = mutex_lock_interruptible(&dev->struct_mutex);
730 if (ret)
731 return ret;
732
733 if (opregion->header)
734 seq_write(m, opregion->header, OPREGION_SIZE);
735
736 mutex_unlock(&dev->struct_mutex);
737
738 return 0;
739}
740
721static int 741static int
722i915_wedged_open(struct inode *inode, 742i915_wedged_open(struct inode *inode,
723 struct file *filp) 743 struct file *filp)
@@ -845,6 +865,7 @@ static struct drm_info_list i915_debugfs_list[] = {
845 {"i915_gfxec", i915_gfxec, 0}, 865 {"i915_gfxec", i915_gfxec, 0},
846 {"i915_fbc_status", i915_fbc_status, 0}, 866 {"i915_fbc_status", i915_fbc_status, 0},
847 {"i915_sr_status", i915_sr_status, 0}, 867 {"i915_sr_status", i915_sr_status, 0},
868 {"i915_opregion", i915_opregion, 0},
848}; 869};
849#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) 870#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
850 871
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index c58ec5c02919..2dae3be9ebef 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -40,6 +40,7 @@
40#include <linux/pnp.h> 40#include <linux/pnp.h>
41#include <linux/vga_switcheroo.h> 41#include <linux/vga_switcheroo.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <acpi/video.h>
43 44
44extern int intel_max_stolen; /* from AGP driver */ 45extern int intel_max_stolen; /* from AGP driver */
45 46
@@ -2166,6 +2167,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
2166 2167
2167 /* Try to make sure MCHBAR is enabled before poking at it */ 2168 /* Try to make sure MCHBAR is enabled before poking at it */
2168 intel_setup_mchbar(dev); 2169 intel_setup_mchbar(dev);
2170 intel_opregion_setup(dev);
2169 2171
2170 i915_gem_load(dev); 2172 i915_gem_load(dev);
2171 2173
@@ -2221,7 +2223,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
2221 } 2223 }
2222 2224
2223 /* Must be done after probing outputs */ 2225 /* Must be done after probing outputs */
2224 intel_opregion_init(dev, 0); 2226 intel_opregion_init(dev);
2227 acpi_video_register();
2225 2228
2226 setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, 2229 setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
2227 (unsigned long) dev); 2230 (unsigned long) dev);
@@ -2271,6 +2274,8 @@ int i915_driver_unload(struct drm_device *dev)
2271 dev_priv->mm.gtt_mtrr = -1; 2274 dev_priv->mm.gtt_mtrr = -1;
2272 } 2275 }
2273 2276
2277 acpi_video_unregister();
2278
2274 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 2279 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
2275 intel_modeset_cleanup(dev); 2280 intel_modeset_cleanup(dev);
2276 2281
@@ -2299,7 +2304,7 @@ int i915_driver_unload(struct drm_device *dev)
2299 if (dev_priv->regs != NULL) 2304 if (dev_priv->regs != NULL)
2300 iounmap(dev_priv->regs); 2305 iounmap(dev_priv->regs);
2301 2306
2302 intel_opregion_free(dev, 0); 2307 intel_opregion_fini(dev);
2303 2308
2304 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 2309 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
2305 /* Flush any outstanding unpin_work. */ 2310 /* Flush any outstanding unpin_work. */
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ba75255ec450..2879a768d65c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -236,7 +236,7 @@ static int i915_drm_freeze(struct drm_device *dev)
236 236
237 i915_save_state(dev); 237 i915_save_state(dev);
238 238
239 intel_opregion_free(dev, 1); 239 intel_opregion_fini(dev);
240 240
241 /* Modeset on resume, not lid events */ 241 /* Modeset on resume, not lid events */
242 dev_priv->modeset_on_lid = 0; 242 dev_priv->modeset_on_lid = 0;
@@ -276,8 +276,7 @@ static int i915_drm_thaw(struct drm_device *dev)
276 int error = 0; 276 int error = 0;
277 277
278 i915_restore_state(dev); 278 i915_restore_state(dev);
279 279 intel_opregion_setup(dev);
280 intel_opregion_init(dev, 1);
281 280
282 /* KMS EnterVT equivalent */ 281 /* KMS EnterVT equivalent */
283 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 282 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
@@ -293,6 +292,8 @@ static int i915_drm_thaw(struct drm_device *dev)
293 drm_helper_resume_force_mode(dev); 292 drm_helper_resume_force_mode(dev);
294 } 293 }
295 294
295 intel_opregion_init(dev);
296
296 dev_priv->modeset_on_lid = 0; 297 dev_priv->modeset_on_lid = 0;
297 298
298 return error; 299 return error;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 980061ff5c80..f6940f1b1286 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -110,8 +110,9 @@ struct intel_opregion {
110 struct opregion_acpi *acpi; 110 struct opregion_acpi *acpi;
111 struct opregion_swsci *swsci; 111 struct opregion_swsci *swsci;
112 struct opregion_asle *asle; 112 struct opregion_asle *asle;
113 int enabled; 113 void *vbt;
114}; 114};
115#define OPREGION_SIZE (8*1024)
115 116
116struct intel_overlay; 117struct intel_overlay;
117struct intel_overlay_error_state; 118struct intel_overlay_error_state;
@@ -1053,16 +1054,17 @@ extern int i915_restore_state(struct drm_device *dev);
1053extern int i915_save_state(struct drm_device *dev); 1054extern int i915_save_state(struct drm_device *dev);
1054extern int i915_restore_state(struct drm_device *dev); 1055extern int i915_restore_state(struct drm_device *dev);
1055 1056
1056#ifdef CONFIG_ACPI
1057/* intel_opregion.c */ 1057/* intel_opregion.c */
1058extern int intel_opregion_init(struct drm_device *dev, int resume); 1058extern int intel_opregion_setup(struct drm_device *dev);
1059extern void intel_opregion_free(struct drm_device *dev, int suspend); 1059#ifdef CONFIG_ACPI
1060extern void intel_opregion_init(struct drm_device *dev);
1061extern void intel_opregion_fini(struct drm_device *dev);
1060extern void intel_opregion_asle_intr(struct drm_device *dev); 1062extern void intel_opregion_asle_intr(struct drm_device *dev);
1061extern void intel_opregion_gse_intr(struct drm_device *dev); 1063extern void intel_opregion_gse_intr(struct drm_device *dev);
1062extern void intel_opregion_enable_asle(struct drm_device *dev); 1064extern void intel_opregion_enable_asle(struct drm_device *dev);
1063#else 1065#else
1064static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; } 1066static inline void intel_opregion_init(struct drm_device *dev) { return; }
1065static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; } 1067static inline void intel_opregion_fini(struct drm_device *dev) { return; }
1066static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } 1068static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
1067static inline void intel_opregion_gse_intr(struct drm_device *dev) { return; } 1069static inline void intel_opregion_gse_intr(struct drm_device *dev) { return; }
1068static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; } 1070static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; }
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 96f75d7f6633..8d7deca69830 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -317,7 +317,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
317 317
318static void 318static void
319parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, 319parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
320 struct bdb_header *bdb) 320 struct bdb_header *bdb)
321{ 321{
322 struct sdvo_device_mapping *p_mapping; 322 struct sdvo_device_mapping *p_mapping;
323 struct bdb_general_definitions *p_defs; 323 struct bdb_general_definitions *p_defs;
@@ -327,7 +327,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
327 327
328 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); 328 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
329 if (!p_defs) { 329 if (!p_defs) {
330 DRM_DEBUG_KMS("No general definition block is found\n"); 330 DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
331 return; 331 return;
332 } 332 }
333 /* judge whether the size of child device meets the requirements. 333 /* judge whether the size of child device meets the requirements.
@@ -460,7 +460,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
460 460
461 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); 461 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
462 if (!p_defs) { 462 if (!p_defs) {
463 DRM_DEBUG_KMS("No general definition block is found\n"); 463 DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
464 return; 464 return;
465 } 465 }
466 /* judge whether the size of child device meets the requirements. 466 /* judge whether the size of child device meets the requirements.
@@ -513,6 +513,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
513 } 513 }
514 return; 514 return;
515} 515}
516
516/** 517/**
517 * intel_init_bios - initialize VBIOS settings & find VBT 518 * intel_init_bios - initialize VBIOS settings & find VBT
518 * @dev: DRM device 519 * @dev: DRM device
@@ -520,11 +521,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
520 * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers 521 * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers
521 * to appropriate values. 522 * to appropriate values.
522 * 523 *
523 * VBT existence is a sanity check that is relied on by other i830_bios.c code.
524 * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
525 * feed an updated VBT back through that, compared to what we'll fetch using
526 * this method of groping around in the BIOS data.
527 *
528 * Returns 0 on success, nonzero on failure. 524 * Returns 0 on success, nonzero on failure.
529 */ 525 */
530bool 526bool
@@ -532,31 +528,45 @@ intel_init_bios(struct drm_device *dev)
532{ 528{
533 struct drm_i915_private *dev_priv = dev->dev_private; 529 struct drm_i915_private *dev_priv = dev->dev_private;
534 struct pci_dev *pdev = dev->pdev; 530 struct pci_dev *pdev = dev->pdev;
535 struct vbt_header *vbt = NULL; 531 struct bdb_header *bdb = NULL;
536 struct bdb_header *bdb; 532 u8 __iomem *bios = NULL;
537 u8 __iomem *bios; 533
538 size_t size; 534 /* XXX Should this validation be moved to intel_opregion.c? */
539 int i; 535 if (dev_priv->opregion.vbt) {
540 536 struct vbt_header *vbt = dev_priv->opregion.vbt;
541 bios = pci_map_rom(pdev, &size); 537 if (memcmp(vbt->signature, "$VBT", 4) == 0) {
542 if (!bios) 538 DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n",
543 return -1; 539 vbt->signature);
544 540 bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset);
545 /* Scour memory looking for the VBT signature */ 541 } else
546 for (i = 0; i + 4 < size; i++) { 542 dev_priv->opregion.vbt = NULL;
547 if (!memcmp(bios + i, "$VBT", 4)) {
548 vbt = (struct vbt_header *)(bios + i);
549 break;
550 }
551 } 543 }
552 544
553 if (!vbt) { 545 if (bdb == NULL) {
554 DRM_ERROR("VBT signature missing\n"); 546 struct vbt_header *vbt = NULL;
555 pci_unmap_rom(pdev, bios); 547 size_t size;
556 return -1; 548 int i;
557 }
558 549
559 bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); 550 bios = pci_map_rom(pdev, &size);
551 if (!bios)
552 return -1;
553
554 /* Scour memory looking for the VBT signature */
555 for (i = 0; i + 4 < size; i++) {
556 if (!memcmp(bios + i, "$VBT", 4)) {
557 vbt = (struct vbt_header *)(bios + i);
558 break;
559 }
560 }
561
562 if (!vbt) {
563 DRM_ERROR("VBT signature missing\n");
564 pci_unmap_rom(pdev, bios);
565 return -1;
566 }
567
568 bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
569 }
560 570
561 /* Grab useful general definitions */ 571 /* Grab useful general definitions */
562 parse_general_features(dev_priv, bdb); 572 parse_general_features(dev_priv, bdb);
@@ -568,7 +578,8 @@ intel_init_bios(struct drm_device *dev)
568 parse_driver_features(dev_priv, bdb); 578 parse_driver_features(dev_priv, bdb);
569 parse_edp(dev_priv, bdb); 579 parse_edp(dev_priv, bdb);
570 580
571 pci_unmap_rom(pdev, bios); 581 if (bios)
582 pci_unmap_rom(pdev, bios);
572 583
573 return 0; 584 return 0;
574} 585}
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 97d5329079fe..3cb13237ba58 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -36,12 +36,11 @@
36#define PCI_LBPC 0xf4 36#define PCI_LBPC 0xf4
37#define PCI_ASLS 0xfc 37#define PCI_ASLS 0xfc
38 38
39#define OPREGION_SZ (8*1024)
40#define OPREGION_HEADER_OFFSET 0 39#define OPREGION_HEADER_OFFSET 0
41#define OPREGION_ACPI_OFFSET 0x100 40#define OPREGION_ACPI_OFFSET 0x100
42#define OPREGION_SWSCI_OFFSET 0x200 41#define OPREGION_SWSCI_OFFSET 0x200
43#define OPREGION_ASLE_OFFSET 0x300 42#define OPREGION_ASLE_OFFSET 0x300
44#define OPREGION_VBT_OFFSET 0x1000 43#define OPREGION_VBT_OFFSET 0x400
45 44
46#define OPREGION_SIGNATURE "IntelGraphicsMem" 45#define OPREGION_SIGNATURE "IntelGraphicsMem"
47#define MBOX_ACPI (1<<0) 46#define MBOX_ACPI (1<<0)
@@ -143,6 +142,7 @@ struct opregion_asle {
143#define ACPI_DIGITAL_OUTPUT (3<<8) 142#define ACPI_DIGITAL_OUTPUT (3<<8)
144#define ACPI_LVDS_OUTPUT (4<<8) 143#define ACPI_LVDS_OUTPUT (4<<8)
145 144
145#ifdef CONFIG_ACPI
146static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) 146static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
147{ 147{
148 struct drm_i915_private *dev_priv = dev->dev_private; 148 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -465,7 +465,58 @@ blind_set:
465 goto end; 465 goto end;
466} 466}
467 467
468int intel_opregion_init(struct drm_device *dev, int resume) 468void intel_opregion_init(struct drm_device *dev)
469{
470 struct drm_i915_private *dev_priv = dev->dev_private;
471 struct intel_opregion *opregion = &dev_priv->opregion;
472
473 if (!opregion->header)
474 return;
475
476 if (opregion->acpi) {
477 if (drm_core_check_feature(dev, DRIVER_MODESET))
478 intel_didl_outputs(dev);
479
480 /* Notify BIOS we are ready to handle ACPI video ext notifs.
481 * Right now, all the events are handled by the ACPI video module.
482 * We don't actually need to do anything with them. */
483 opregion->acpi->csts = 0;
484 opregion->acpi->drdy = 1;
485
486 system_opregion = opregion;
487 register_acpi_notifier(&intel_opregion_notifier);
488 }
489
490 if (opregion->asle)
491 intel_opregion_enable_asle(dev);
492}
493
494void intel_opregion_fini(struct drm_device *dev)
495{
496 struct drm_i915_private *dev_priv = dev->dev_private;
497 struct intel_opregion *opregion = &dev_priv->opregion;
498
499 if (!opregion->header)
500 return;
501
502 if (opregion->acpi) {
503 opregion->acpi->drdy = 0;
504
505 system_opregion = NULL;
506 unregister_acpi_notifier(&intel_opregion_notifier);
507 }
508
509 /* just clear all opregion memory pointers now */
510 iounmap(opregion->header);
511 opregion->header = NULL;
512 opregion->acpi = NULL;
513 opregion->swsci = NULL;
514 opregion->asle = NULL;
515 opregion->vbt = NULL;
516}
517#endif
518
519int intel_opregion_setup(struct drm_device *dev)
469{ 520{
470 struct drm_i915_private *dev_priv = dev->dev_private; 521 struct drm_i915_private *dev_priv = dev->dev_private;
471 struct intel_opregion *opregion = &dev_priv->opregion; 522 struct intel_opregion *opregion = &dev_priv->opregion;
@@ -480,29 +531,23 @@ int intel_opregion_init(struct drm_device *dev, int resume)
480 return -ENOTSUPP; 531 return -ENOTSUPP;
481 } 532 }
482 533
483 base = ioremap(asls, OPREGION_SZ); 534 base = ioremap(asls, OPREGION_SIZE);
484 if (!base) 535 if (!base)
485 return -ENOMEM; 536 return -ENOMEM;
486 537
487 opregion->header = base; 538 if (memcmp(base, OPREGION_SIGNATURE, 16)) {
488 if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) {
489 DRM_DEBUG_DRIVER("opregion signature mismatch\n"); 539 DRM_DEBUG_DRIVER("opregion signature mismatch\n");
490 err = -EINVAL; 540 err = -EINVAL;
491 goto err_out; 541 goto err_out;
492 } 542 }
543 opregion->header = base;
544 opregion->vbt = base + OPREGION_VBT_OFFSET;
493 545
494 mboxes = opregion->header->mboxes; 546 mboxes = opregion->header->mboxes;
495 if (mboxes & MBOX_ACPI) { 547 if (mboxes & MBOX_ACPI) {
496 DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); 548 DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
497 opregion->acpi = base + OPREGION_ACPI_OFFSET; 549 opregion->acpi = base + OPREGION_ACPI_OFFSET;
498 if (drm_core_check_feature(dev, DRIVER_MODESET))
499 intel_didl_outputs(dev);
500 } else {
501 DRM_DEBUG_DRIVER("Public ACPI methods not supported\n");
502 err = -ENOTSUPP;
503 goto err_out;
504 } 550 }
505 opregion->enabled = 1;
506 551
507 if (mboxes & MBOX_SWSCI) { 552 if (mboxes & MBOX_SWSCI) {
508 DRM_DEBUG_DRIVER("SWSCI supported\n"); 553 DRM_DEBUG_DRIVER("SWSCI supported\n");
@@ -511,53 +556,11 @@ int intel_opregion_init(struct drm_device *dev, int resume)
511 if (mboxes & MBOX_ASLE) { 556 if (mboxes & MBOX_ASLE) {
512 DRM_DEBUG_DRIVER("ASLE supported\n"); 557 DRM_DEBUG_DRIVER("ASLE supported\n");
513 opregion->asle = base + OPREGION_ASLE_OFFSET; 558 opregion->asle = base + OPREGION_ASLE_OFFSET;
514 intel_opregion_enable_asle(dev);
515 } 559 }
516 560
517 if (!resume)
518 acpi_video_register();
519
520
521 /* Notify BIOS we are ready to handle ACPI video ext notifs.
522 * Right now, all the events are handled by the ACPI video module.
523 * We don't actually need to do anything with them. */
524 opregion->acpi->csts = 0;
525 opregion->acpi->drdy = 1;
526
527 system_opregion = opregion;
528 register_acpi_notifier(&intel_opregion_notifier);
529
530 return 0; 561 return 0;
531 562
532err_out: 563err_out:
533 iounmap(opregion->header); 564 iounmap(opregion->header);
534 opregion->header = NULL;
535 acpi_video_register();
536 return err; 565 return err;
537} 566}
538
539void intel_opregion_free(struct drm_device *dev, int suspend)
540{
541 struct drm_i915_private *dev_priv = dev->dev_private;
542 struct intel_opregion *opregion = &dev_priv->opregion;
543
544 if (!opregion->enabled)
545 return;
546
547 if (!suspend)
548 acpi_video_unregister();
549
550 opregion->acpi->drdy = 0;
551
552 system_opregion = NULL;
553 unregister_acpi_notifier(&intel_opregion_notifier);
554
555 /* just clear all opregion memory pointers now */
556 iounmap(opregion->header);
557 opregion->header = NULL;
558 opregion->acpi = NULL;
559 opregion->swsci = NULL;
560 opregion->asle = NULL;
561
562 opregion->enabled = 0;
563}