Ignore:
Timestamp:
Apr 21, 2017, 4:28:29 AM (5 weeks ago)
Author:
brainslayer
Message:

update

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/linux/universal/linux-4.9/drivers/video/fbdev/efifb.c

    r31574 r31885  
    1111#include <linux/errno.h>
    1212#include <linux/fb.h>
     13#include <linux/pci.h>
    1314#include <linux/platform_device.h>
    1415#include <linux/screen_info.h>
     
    119120}
    120121
     122static bool pci_dev_disabled;   /* FB base matches BAR of a disabled device */
     123
    121124static int efifb_probe(struct platform_device *dev)
    122125{
     
    128131        char *option = NULL;
    129132
    130         if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
     133        if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
    131134                return -ENODEV;
    132135
     
    328331
    329332builtin_platform_driver(efifb_driver);
     333
     334#if defined(CONFIG_PCI) && !defined(CONFIG_X86)
     335
     336static bool pci_bar_found;      /* did we find a BAR matching the efifb base? */
     337
     338static void claim_efifb_bar(struct pci_dev *dev, int idx)
     339{
     340        u16 word;
     341
     342        pci_bar_found = true;
     343
     344        pci_read_config_word(dev, PCI_COMMAND, &word);
     345        if (!(word & PCI_COMMAND_MEMORY)) {
     346                pci_dev_disabled = true;
     347                dev_err(&dev->dev,
     348                        "BAR %d: assigned to efifb but device is disabled!\n",
     349                        idx);
     350                return;
     351        }
     352
     353        if (pci_claim_resource(dev, idx)) {
     354                pci_dev_disabled = true;
     355                dev_err(&dev->dev,
     356                        "BAR %d: failed to claim resource for efifb!\n", idx);
     357                return;
     358        }
     359
     360        dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx);
     361}
     362
     363static void efifb_fixup_resources(struct pci_dev *dev)
     364{
     365        u64 base = screen_info.lfb_base;
     366        u64 size = screen_info.lfb_size;
     367        int i;
     368
     369        if (pci_bar_found || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
     370                return;
     371
     372        if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
     373                base |= (u64)screen_info.ext_lfb_base << 32;
     374
     375        if (!base)
     376                return;
     377
     378        for (i = 0; i < PCI_STD_RESOURCE_END; i++) {
     379                struct resource *res = &dev->resource[i];
     380
     381                if (!(res->flags & IORESOURCE_MEM))
     382                        continue;
     383
     384                if (res->start <= base && res->end >= base + size - 1) {
     385                        claim_efifb_bar(dev, i);
     386                        break;
     387                }
     388        }
     389}
     390DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY,
     391                               16, efifb_fixup_resources);
     392
     393#endif
Note: See TracChangeset for help on using the changeset viewer.