Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fbdev: aty128fb: use generic power management

Drivers should do only device-specific jobs. But in general, drivers using
legacy PCI PM framework for .suspend()/.resume() have to manage many PCI
PM-related tasks themselves which can be done by PCI Core itself. This
brings extra load on the driver and it directly calls PCI helper functions
to handle them.

Switch to the new generic framework by updating function signatures and
define a "struct dev_pm_ops" variable to bind PM callbacks. Also, remove
unnecessary calls to the PCI Helper functions along with the legacy
.suspend & .resume bindings.

Now,
- aty128_pci_suspend() had a "pm_message_t" type parameter as per legacy
PCI PM framework that got deprecated in generic.
- Rename the callback as aty128_pci_suspend_late() and preserve the
parameter.
- Define 3 new callbacks as:
* aty128_pci_suspend()
* aty128_pci_freeze()
* aty128_pci_hibernate()
which in turn call aty128_pci_suspend_late() by passing appropriate
value for "pm_message_t" type parameter.
- Bind the callbacks in "struct dev_pm_ops" type variable
"aty128_pci_pm_ops".

Signed-off-by: Vaibhav Gupta <vaibhavgupta40@gmail.com>
Cc: Bjorn Helgaas <helgaas@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Bjorn Helgaas <bjorn@helgaas.com>
Cc: Vaibhav Gupta <vaibhav.varodek@gmail.com>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Andres Salomon <dilinger@queued.net>
CC: Antonino Daplas <adaplas@gmail.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200819185654.151170-6-vaibhavgupta40@gmail.com

authored by

Vaibhav Gupta and committed by
Bartlomiej Zolnierkiewicz
c1a47776 348b2956

+34 -17
+34 -17
drivers/video/fbdev/aty/aty128fb.c
··· 162 162 static int aty128_probe(struct pci_dev *pdev, 163 163 const struct pci_device_id *ent); 164 164 static void aty128_remove(struct pci_dev *pdev); 165 - static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state); 166 - static int aty128_pci_resume(struct pci_dev *pdev); 165 + static int aty128_pci_suspend_late(struct device *dev, pm_message_t state); 166 + static int __maybe_unused aty128_pci_suspend(struct device *dev); 167 + static int __maybe_unused aty128_pci_hibernate(struct device *dev); 168 + static int __maybe_unused aty128_pci_freeze(struct device *dev); 169 + static int __maybe_unused aty128_pci_resume(struct device *dev); 167 170 static int aty128_do_resume(struct pci_dev *pdev); 171 + 172 + static const struct dev_pm_ops aty128_pci_pm_ops = { 173 + .suspend = aty128_pci_suspend, 174 + .resume = aty128_pci_resume, 175 + .freeze = aty128_pci_freeze, 176 + .thaw = aty128_pci_resume, 177 + .poweroff = aty128_pci_hibernate, 178 + .restore = aty128_pci_resume, 179 + }; 168 180 169 181 /* supported Rage128 chipsets */ 170 182 static const struct pci_device_id aty128_pci_tbl[] = { ··· 284 272 .id_table = aty128_pci_tbl, 285 273 .probe = aty128_probe, 286 274 .remove = aty128_remove, 287 - .suspend = aty128_pci_suspend, 288 - .resume = aty128_pci_resume, 275 + .driver.pm = &aty128_pci_pm_ops, 289 276 }; 290 277 291 278 /* packed BIOS settings */ ··· 2327 2316 static void aty128_set_suspend(struct aty128fb_par *par, int suspend) 2328 2317 { 2329 2318 u32 pmgt; 2330 - struct pci_dev *pdev = par->pdev; 2331 2319 2332 2320 if (!par->pdev->pm_cap) 2333 2321 return; ··· 2353 2343 aty_st_le32(BUS_CNTL1, 0x00000010); 2354 2344 aty_st_le32(MEM_POWER_MISC, 0x0c830000); 2355 2345 msleep(100); 2356 - 2357 - /* Switch PCI power management to D2 */ 2358 - pci_set_power_state(pdev, PCI_D2); 2359 2346 } 2360 2347 } 2361 2348 2362 - static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state) 2349 + static int aty128_pci_suspend_late(struct device *dev, pm_message_t state) 2363 2350 { 2351 + struct pci_dev *pdev = to_pci_dev(dev); 2364 2352 struct fb_info *info = pci_get_drvdata(pdev); 2365 2353 struct aty128fb_par *par = info->par; 2366 - 2367 - /* Because we may change PCI D state ourselves, we need to 2368 - * first save the config space content so the core can 2369 - * restore it properly on resume. 2370 - */ 2371 - pci_save_state(pdev); 2372 2354 2373 2355 /* We don't do anything but D2, for now we return 0, but 2374 2356 * we may want to change that. How do we know if the BIOS ··· 2420 2418 return 0; 2421 2419 } 2422 2420 2421 + static int __maybe_unused aty128_pci_suspend(struct device *dev) 2422 + { 2423 + return aty128_pci_suspend_late(dev, PMSG_SUSPEND); 2424 + } 2425 + 2426 + static int __maybe_unused aty128_pci_hibernate(struct device *dev) 2427 + { 2428 + return aty128_pci_suspend_late(dev, PMSG_HIBERNATE); 2429 + } 2430 + 2431 + static int __maybe_unused aty128_pci_freeze(struct device *dev) 2432 + { 2433 + return aty128_pci_suspend_late(dev, PMSG_FREEZE); 2434 + } 2435 + 2423 2436 static int aty128_do_resume(struct pci_dev *pdev) 2424 2437 { 2425 2438 struct fb_info *info = pci_get_drvdata(pdev); ··· 2481 2464 return 0; 2482 2465 } 2483 2466 2484 - static int aty128_pci_resume(struct pci_dev *pdev) 2467 + static int __maybe_unused aty128_pci_resume(struct device *dev) 2485 2468 { 2486 2469 int rc; 2487 2470 2488 2471 console_lock(); 2489 - rc = aty128_do_resume(pdev); 2472 + rc = aty128_do_resume(to_pci_dev(dev)); 2490 2473 console_unlock(); 2491 2474 2492 2475 return rc;