aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/aty/aty128fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/aty/aty128fb.c')
-rw-r--r--drivers/video/aty/aty128fb.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index fb2b0f5b23bd..35e8eb02b9e9 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1853,13 +1853,14 @@ static void aty128_bl_exit(struct backlight_device *bd)
1853 * Initialisation 1853 * Initialisation
1854 */ 1854 */
1855 1855
1856#ifdef CONFIG_PPC_PMAC 1856#ifdef CONFIG_PPC_PMAC__disabled
1857static void aty128_early_resume(void *data) 1857static void aty128_early_resume(void *data)
1858{ 1858{
1859 struct aty128fb_par *par = data; 1859 struct aty128fb_par *par = data;
1860 1860
1861 if (try_acquire_console_sem()) 1861 if (try_acquire_console_sem())
1862 return; 1862 return;
1863 pci_restore_state(par->pdev);
1863 aty128_do_resume(par->pdev); 1864 aty128_do_resume(par->pdev);
1864 release_console_sem(); 1865 release_console_sem();
1865} 1866}
@@ -1907,7 +1908,14 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
1907 /* Indicate sleep capability */ 1908 /* Indicate sleep capability */
1908 if (par->chip_gen == rage_M3) { 1909 if (par->chip_gen == rage_M3) {
1909 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1); 1910 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1);
1911#if 0 /* Disable the early video resume hack for now as it's causing problems, among
1912 * others we now rely on the PCI core restoring the config space for us, which
1913 * isn't the case with that hack, and that code path causes various things to
1914 * be called with interrupts off while they shouldn't. I'm leaving the code in
1915 * as it can be useful for debugging purposes
1916 */
1910 pmac_set_early_video_resume(aty128_early_resume, par); 1917 pmac_set_early_video_resume(aty128_early_resume, par);
1918#endif
1911 } 1919 }
1912 1920
1913 /* Find default mode */ 1921 /* Find default mode */
@@ -2365,7 +2373,6 @@ static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx
2365static void aty128_set_suspend(struct aty128fb_par *par, int suspend) 2373static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
2366{ 2374{
2367 u32 pmgt; 2375 u32 pmgt;
2368 u16 pwr_command;
2369 struct pci_dev *pdev = par->pdev; 2376 struct pci_dev *pdev = par->pdev;
2370 2377
2371 if (!par->pm_reg) 2378 if (!par->pm_reg)
@@ -2374,6 +2381,8 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
2374 /* Set the chip into the appropriate suspend mode (we use D2, 2381 /* Set the chip into the appropriate suspend mode (we use D2,
2375 * D3 would require a complete re-initialisation of the chip, 2382 * D3 would require a complete re-initialisation of the chip,
2376 * including PCI config registers, clocks, AGP configuration, ...) 2383 * including PCI config registers, clocks, AGP configuration, ...)
2384 *
2385 * For resume, the core will have already brought us back to D0
2377 */ 2386 */
2378 if (suspend) { 2387 if (suspend) {
2379 /* Make sure CRTC2 is reset. Remove that the day we decide to 2388 /* Make sure CRTC2 is reset. Remove that the day we decide to
@@ -2391,17 +2400,9 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
2391 aty_st_le32(BUS_CNTL1, 0x00000010); 2400 aty_st_le32(BUS_CNTL1, 0x00000010);
2392 aty_st_le32(MEM_POWER_MISC, 0x0c830000); 2401 aty_st_le32(MEM_POWER_MISC, 0x0c830000);
2393 mdelay(100); 2402 mdelay(100);
2394 pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); 2403
2395 /* Switch PCI power management to D2 */ 2404 /* Switch PCI power management to D2 */
2396 pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 2405 pci_set_power_state(pdev, PCI_D2);
2397 (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
2398 pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
2399 } else {
2400 /* Switch back PCI power management to D0 */
2401 mdelay(100);
2402 pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);
2403 pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
2404 mdelay(100);
2405 } 2406 }
2406} 2407}
2407 2408
@@ -2410,6 +2411,12 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2410 struct fb_info *info = pci_get_drvdata(pdev); 2411 struct fb_info *info = pci_get_drvdata(pdev);
2411 struct aty128fb_par *par = info->par; 2412 struct aty128fb_par *par = info->par;
2412 2413
2414 /* Because we may change PCI D state ourselves, we need to
2415 * first save the config space content so the core can
2416 * restore it properly on resume.
2417 */
2418 pci_save_state(pdev);
2419
2413 /* We don't do anything but D2, for now we return 0, but 2420 /* We don't do anything but D2, for now we return 0, but
2414 * we may want to change that. How do we know if the BIOS 2421 * we may want to change that. How do we know if the BIOS
2415 * can properly take care of D3 ? Also, with swsusp, we 2422 * can properly take care of D3 ? Also, with swsusp, we
@@ -2476,6 +2483,11 @@ static int aty128_do_resume(struct pci_dev *pdev)
2476 if (pdev->dev.power.power_state.event == PM_EVENT_ON) 2483 if (pdev->dev.power.power_state.event == PM_EVENT_ON)
2477 return 0; 2484 return 0;
2478 2485
2486 /* PCI state will have been restored by the core, so
2487 * we should be in D0 now with our config space fully
2488 * restored
2489 */
2490
2479 /* Wakeup chip */ 2491 /* Wakeup chip */
2480 aty128_set_suspend(par, 0); 2492 aty128_set_suspend(par, 0);
2481 par->asleep = 0; 2493 par->asleep = 0;