| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * i740fb - framebuffer driver for Intel740 |
|---|
| 3 | 4 | * Copyright (c) 2011 Ondrej Zary |
|---|
| .. | .. |
|---|
| 399 | 400 | u32 xres, right, hslen, left, xtotal; |
|---|
| 400 | 401 | u32 yres, lower, vslen, upper, ytotal; |
|---|
| 401 | 402 | u32 vxres, xoffset, vyres, yoffset; |
|---|
| 402 | | - u32 bpp, base, dacspeed24, mem; |
|---|
| 403 | + u32 bpp, base, dacspeed24, mem, freq; |
|---|
| 403 | 404 | u8 r7; |
|---|
| 404 | 405 | int i; |
|---|
| 405 | 406 | |
|---|
| .. | .. |
|---|
| 429 | 430 | break; |
|---|
| 430 | 431 | case 9 ... 15: |
|---|
| 431 | 432 | bpp = 15; |
|---|
| 432 | | - /* fall through */ |
|---|
| 433 | + fallthrough; |
|---|
| 433 | 434 | case 16: |
|---|
| 434 | 435 | if ((1000000 / var->pixclock) > DACSPEED16) { |
|---|
| 435 | 436 | dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 15/16bpp)\n", |
|---|
| .. | .. |
|---|
| 642 | 643 | par->atc[VGA_ATC_OVERSCAN] = 0; |
|---|
| 643 | 644 | |
|---|
| 644 | 645 | /* Calculate VCLK that most closely matches the requested dot clock */ |
|---|
| 645 | | - i740_calc_vclk((((u32)1e9) / var->pixclock) * (u32)(1e3), par); |
|---|
| 646 | + freq = (((u32)1e9) / var->pixclock) * (u32)(1e3); |
|---|
| 647 | + if (freq < I740_RFREQ_FIX) { |
|---|
| 648 | + fb_dbg(info, "invalid pixclock\n"); |
|---|
| 649 | + freq = I740_RFREQ_FIX; |
|---|
| 650 | + } |
|---|
| 651 | + i740_calc_vclk(freq, par); |
|---|
| 646 | 652 | |
|---|
| 647 | 653 | /* Since we program the clocks ourselves, always use VCLK2. */ |
|---|
| 648 | 654 | par->misc |= 0x0C; |
|---|
| .. | .. |
|---|
| 656 | 662 | |
|---|
| 657 | 663 | static int i740fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
|---|
| 658 | 664 | { |
|---|
| 665 | + if (!var->pixclock) |
|---|
| 666 | + return -EINVAL; |
|---|
| 667 | + |
|---|
| 659 | 668 | switch (var->bits_per_pixel) { |
|---|
| 660 | 669 | case 8: |
|---|
| 661 | 670 | var->red.offset = var->green.offset = var->blue.offset = 0; |
|---|
| .. | .. |
|---|
| 980 | 989 | return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; |
|---|
| 981 | 990 | } |
|---|
| 982 | 991 | |
|---|
| 983 | | -static struct fb_ops i740fb_ops = { |
|---|
| 992 | +static const struct fb_ops i740fb_ops = { |
|---|
| 984 | 993 | .owner = THIS_MODULE, |
|---|
| 985 | 994 | .fb_open = i740fb_open, |
|---|
| 986 | 995 | .fb_release = i740fb_release, |
|---|
| .. | .. |
|---|
| 1005 | 1014 | u8 *edid; |
|---|
| 1006 | 1015 | |
|---|
| 1007 | 1016 | info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev)); |
|---|
| 1008 | | - if (!info) { |
|---|
| 1009 | | - dev_err(&(dev->dev), "cannot allocate framebuffer\n"); |
|---|
| 1017 | + if (!info) |
|---|
| 1010 | 1018 | return -ENOMEM; |
|---|
| 1011 | | - } |
|---|
| 1012 | 1019 | |
|---|
| 1013 | 1020 | par = info->par; |
|---|
| 1014 | 1021 | mutex_init(&par->open_lock); |
|---|
| .. | .. |
|---|
| 1176 | 1183 | } |
|---|
| 1177 | 1184 | } |
|---|
| 1178 | 1185 | |
|---|
| 1179 | | -#ifdef CONFIG_PM |
|---|
| 1180 | | -static int i740fb_suspend(struct pci_dev *dev, pm_message_t state) |
|---|
| 1186 | +static int __maybe_unused i740fb_suspend(struct device *dev) |
|---|
| 1181 | 1187 | { |
|---|
| 1182 | | - struct fb_info *info = pci_get_drvdata(dev); |
|---|
| 1188 | + struct fb_info *info = dev_get_drvdata(dev); |
|---|
| 1183 | 1189 | struct i740fb_par *par = info->par; |
|---|
| 1184 | | - |
|---|
| 1185 | | - /* don't disable console during hibernation and wakeup from it */ |
|---|
| 1186 | | - if (state.event == PM_EVENT_FREEZE || state.event == PM_EVENT_PRETHAW) |
|---|
| 1187 | | - return 0; |
|---|
| 1188 | 1190 | |
|---|
| 1189 | 1191 | console_lock(); |
|---|
| 1190 | 1192 | mutex_lock(&(par->open_lock)); |
|---|
| .. | .. |
|---|
| 1198 | 1200 | |
|---|
| 1199 | 1201 | fb_set_suspend(info, 1); |
|---|
| 1200 | 1202 | |
|---|
| 1201 | | - pci_save_state(dev); |
|---|
| 1202 | | - pci_disable_device(dev); |
|---|
| 1203 | | - pci_set_power_state(dev, pci_choose_state(dev, state)); |
|---|
| 1204 | | - |
|---|
| 1205 | 1203 | mutex_unlock(&(par->open_lock)); |
|---|
| 1206 | 1204 | console_unlock(); |
|---|
| 1207 | 1205 | |
|---|
| 1208 | 1206 | return 0; |
|---|
| 1209 | 1207 | } |
|---|
| 1210 | 1208 | |
|---|
| 1211 | | -static int i740fb_resume(struct pci_dev *dev) |
|---|
| 1209 | +static int __maybe_unused i740fb_resume(struct device *dev) |
|---|
| 1212 | 1210 | { |
|---|
| 1213 | | - struct fb_info *info = pci_get_drvdata(dev); |
|---|
| 1211 | + struct fb_info *info = dev_get_drvdata(dev); |
|---|
| 1214 | 1212 | struct i740fb_par *par = info->par; |
|---|
| 1215 | 1213 | |
|---|
| 1216 | 1214 | console_lock(); |
|---|
| 1217 | 1215 | mutex_lock(&(par->open_lock)); |
|---|
| 1218 | 1216 | |
|---|
| 1219 | 1217 | if (par->ref_count == 0) |
|---|
| 1220 | | - goto fail; |
|---|
| 1221 | | - |
|---|
| 1222 | | - pci_set_power_state(dev, PCI_D0); |
|---|
| 1223 | | - pci_restore_state(dev); |
|---|
| 1224 | | - if (pci_enable_device(dev)) |
|---|
| 1225 | 1218 | goto fail; |
|---|
| 1226 | 1219 | |
|---|
| 1227 | 1220 | i740fb_set_par(info); |
|---|
| .. | .. |
|---|
| 1232 | 1225 | console_unlock(); |
|---|
| 1233 | 1226 | return 0; |
|---|
| 1234 | 1227 | } |
|---|
| 1235 | | -#else |
|---|
| 1236 | | -#define i740fb_suspend NULL |
|---|
| 1237 | | -#define i740fb_resume NULL |
|---|
| 1238 | | -#endif /* CONFIG_PM */ |
|---|
| 1228 | + |
|---|
| 1229 | +static const struct dev_pm_ops i740fb_pm_ops = { |
|---|
| 1230 | +#ifdef CONFIG_PM_SLEEP |
|---|
| 1231 | + .suspend = i740fb_suspend, |
|---|
| 1232 | + .resume = i740fb_resume, |
|---|
| 1233 | + .freeze = NULL, |
|---|
| 1234 | + .thaw = i740fb_resume, |
|---|
| 1235 | + .poweroff = i740fb_suspend, |
|---|
| 1236 | + .restore = i740fb_resume, |
|---|
| 1237 | +#endif /* CONFIG_PM_SLEEP */ |
|---|
| 1238 | +}; |
|---|
| 1239 | 1239 | |
|---|
| 1240 | 1240 | #define I740_ID_PCI 0x00d1 |
|---|
| 1241 | 1241 | #define I740_ID_AGP 0x7800 |
|---|
| .. | .. |
|---|
| 1252 | 1252 | .id_table = i740fb_id_table, |
|---|
| 1253 | 1253 | .probe = i740fb_probe, |
|---|
| 1254 | 1254 | .remove = i740fb_remove, |
|---|
| 1255 | | - .suspend = i740fb_suspend, |
|---|
| 1256 | | - .resume = i740fb_resume, |
|---|
| 1255 | + .driver.pm = &i740fb_pm_ops, |
|---|
| 1257 | 1256 | }; |
|---|
| 1258 | 1257 | |
|---|
| 1259 | 1258 | #ifndef MODULE |
|---|