aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/pmac_feature.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-04-16 18:24:19 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:24:19 -0400
commit0c541b4406a68e74d94ddb667c69d9e03bce8681 (patch)
tree869506b6c3f7c00ac13f2aa80c35fb5e229cc329 /arch/ppc64/kernel/pmac_feature.c
parent7a648b9ec09f32606fe0f27fb9d095311cf968ca (diff)
[PATCH] ppc32: Fix AGP and sleep again
My previous patch that added sleep support for uninorth-agp and some AGP "off" stuff in radeonfb and aty128fb is breaking some configs. More specifically, it has problems with rage128 setups since the DRI code for these in X doesn't properly re-enable AGP on wakeup or console switch (unlike the radeon DRM). This patch fixes the problem for pmac once for all by using a different approach. The AGP driver "registers" special suspend/resume callbacks with some arch code that the fbdev's can later on call to suspend and resume AGP, making sure it's resumed back in the same state it was when suspended. This is platform specific for now. It would be too complicated to try to do a generic implementation of this at this point due to all sort of weird things going on with AGP on other architectures. We'll re-work that whole problem cleanly once we finally merge fbdev's and DRI. In the meantime, please apply this patch which brings back some r128 based laptops into working condition as far as system sleep is concerned. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc64/kernel/pmac_feature.c')
-rw-r--r--arch/ppc64/kernel/pmac_feature.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c
index 7f1062d222c9..086abc1bcca1 100644
--- a/arch/ppc64/kernel/pmac_feature.c
+++ b/arch/ppc64/kernel/pmac_feature.c
@@ -674,3 +674,67 @@ void __init pmac_check_ht_link(void)
674 dump_HT_speeds("PCI-X HT Downlink", cfg, freq); 674 dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
675#endif 675#endif
676} 676}
677
678/*
679 * Early video resume hook
680 */
681
682static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
683static void *pmac_early_vresume_data __pmacdata;
684
685void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
686{
687 if (_machine != _MACH_Pmac)
688 return;
689 preempt_disable();
690 pmac_early_vresume_proc = proc;
691 pmac_early_vresume_data = data;
692 preempt_enable();
693}
694EXPORT_SYMBOL(pmac_set_early_video_resume);
695
696
697/*
698 * AGP related suspend/resume code
699 */
700
701static struct pci_dev *pmac_agp_bridge __pmacdata;
702static int (*pmac_agp_suspend)(struct pci_dev *bridge) __pmacdata;
703static int (*pmac_agp_resume)(struct pci_dev *bridge) __pmacdata;
704
705void __pmac pmac_register_agp_pm(struct pci_dev *bridge,
706 int (*suspend)(struct pci_dev *bridge),
707 int (*resume)(struct pci_dev *bridge))
708{
709 if (suspend || resume) {
710 pmac_agp_bridge = bridge;
711 pmac_agp_suspend = suspend;
712 pmac_agp_resume = resume;
713 return;
714 }
715 if (bridge != pmac_agp_bridge)
716 return;
717 pmac_agp_suspend = pmac_agp_resume = NULL;
718 return;
719}
720EXPORT_SYMBOL(pmac_register_agp_pm);
721
722void __pmac pmac_suspend_agp_for_card(struct pci_dev *dev)
723{
724 if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
725 return;
726 if (pmac_agp_bridge->bus != dev->bus)
727 return;
728 pmac_agp_suspend(pmac_agp_bridge);
729}
730EXPORT_SYMBOL(pmac_suspend_agp_for_card);
731
732void __pmac pmac_resume_agp_for_card(struct pci_dev *dev)
733{
734 if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
735 return;
736 if (pmac_agp_bridge->bus != dev->bus)
737 return;
738 pmac_agp_resume(pmac_agp_bridge);
739}
740EXPORT_SYMBOL(pmac_resume_agp_for_card);