aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-08-19 11:09:23 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-08 05:13:32 -0400
commit44834a67c0082e2cf74b16be91e49108b1432d65 (patch)
treeebe2c53b1a08b99a95b579942ae2d7603935709d /drivers/gpu/drm
parent3b61796785e7b0ca8846b7a709216dceb6e2f68d (diff)
drm/i915: Use the VBT from OpRegion when available (v3)
It is recommended that we use the Video BIOS tables that were copied into the OpRegion during POST when initialising the driver. This saves us from having to furtle around inside the ROM ourselves and possibly allows the vBIOS to adjust the tables prior to initialisation. On some systems, such as the Samsung N210, there is no accessible VBIOS and the only means of finding the VBT is through the OpRegion. v2: Rearrange the code so that ASLE is enabled along with ACPI v3: Enable OpRegion parsing even without ACPI Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-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 345ca52d6e8..f6e98dd416c 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 5e43d707678..16133f10ffa 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 c58ec5c0291..2dae3be9ebe 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 ba75255ec45..2879a768d65 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 980061ff5c8..f6940f1b128 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 96f75d7f663..8d7deca6983 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 97d5329079f..3cb13237ba5 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}