diff options
Diffstat (limited to 'drivers/video/aty/aty128fb.c')
-rw-r--r-- | drivers/video/aty/aty128fb.c | 36 |
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 |
1857 | static void aty128_early_resume(void *data) | 1857 | static 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 | |||
2365 | static void aty128_set_suspend(struct aty128fb_par *par, int suspend) | 2373 | static 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; |