drm/i915/bios: fold pci rom map/unmap into copy function
We don't need to keep the pci rom mapped during the entire intel_bios_init() anymore. Move it to the previous copy_vbt() function and rename it to oprom_get_vbt() since now it's responsible to to all operations related to get the vbt from the oprom. v2: fix double __iomem attribute detected by sparse v3: fix missing unmap on success (Ville) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191126225110.8127-3-lucas.demarchi@intel.com
This commit is contained in:
parent
fd0186ce18
commit
2cded152ad
|
@ -1925,12 +1925,17 @@ bool intel_bios_is_valid_vbt(const void *buf, size_t size)
|
||||||
return vbt;
|
return vbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct vbt_header *copy_vbt(void __iomem *oprom, size_t size)
|
static struct vbt_header *oprom_get_vbt(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
void __iomem *p = NULL;
|
struct pci_dev *pdev = dev_priv->drm.pdev;
|
||||||
|
void __iomem *p = NULL, *oprom;
|
||||||
struct vbt_header *vbt;
|
struct vbt_header *vbt;
|
||||||
u16 vbt_size;
|
u16 vbt_size;
|
||||||
size_t i;
|
size_t i, size;
|
||||||
|
|
||||||
|
oprom = pci_map_rom(pdev, &size);
|
||||||
|
if (!oprom)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* Scour memory looking for the VBT signature. */
|
/* Scour memory looking for the VBT signature. */
|
||||||
for (i = 0; i + 4 < size; i++) {
|
for (i = 0; i + 4 < size; i++) {
|
||||||
|
@ -1943,33 +1948,37 @@ static struct vbt_header *copy_vbt(void __iomem *oprom, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
goto err_unmap_oprom;
|
||||||
|
|
||||||
if (sizeof(struct vbt_header) > size) {
|
if (sizeof(struct vbt_header) > size) {
|
||||||
DRM_DEBUG_DRIVER("VBT header incomplete\n");
|
DRM_DEBUG_DRIVER("VBT header incomplete\n");
|
||||||
return NULL;
|
goto err_unmap_oprom;
|
||||||
}
|
}
|
||||||
|
|
||||||
vbt_size = ioread16(p + offsetof(struct vbt_header, vbt_size));
|
vbt_size = ioread16(p + offsetof(struct vbt_header, vbt_size));
|
||||||
if (vbt_size > size) {
|
if (vbt_size > size) {
|
||||||
DRM_DEBUG_DRIVER("VBT incomplete (vbt_size overflows)\n");
|
DRM_DEBUG_DRIVER("VBT incomplete (vbt_size overflows)\n");
|
||||||
return NULL;
|
goto err_unmap_oprom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The rest will be validated by intel_bios_is_valid_vbt() */
|
/* The rest will be validated by intel_bios_is_valid_vbt() */
|
||||||
vbt = kmalloc(vbt_size, GFP_KERNEL);
|
vbt = kmalloc(vbt_size, GFP_KERNEL);
|
||||||
if (!vbt)
|
if (!vbt)
|
||||||
return NULL;
|
goto err_unmap_oprom;
|
||||||
|
|
||||||
memcpy_fromio(vbt, p, vbt_size);
|
memcpy_fromio(vbt, p, vbt_size);
|
||||||
|
|
||||||
if (!intel_bios_is_valid_vbt(vbt, vbt_size))
|
if (!intel_bios_is_valid_vbt(vbt, vbt_size))
|
||||||
goto err_free_vbt;
|
goto err_free_vbt;
|
||||||
|
|
||||||
|
pci_unmap_rom(pdev, oprom);
|
||||||
|
|
||||||
return vbt;
|
return vbt;
|
||||||
|
|
||||||
err_free_vbt:
|
err_free_vbt:
|
||||||
kfree(vbt);
|
kfree(vbt);
|
||||||
|
err_unmap_oprom:
|
||||||
|
pci_unmap_rom(pdev, oprom);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1984,10 +1993,9 @@ err_free_vbt:
|
||||||
*/
|
*/
|
||||||
void intel_bios_init(struct drm_i915_private *dev_priv)
|
void intel_bios_init(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
struct pci_dev *pdev = dev_priv->drm.pdev;
|
|
||||||
const struct vbt_header *vbt = dev_priv->opregion.vbt;
|
const struct vbt_header *vbt = dev_priv->opregion.vbt;
|
||||||
|
struct vbt_header *oprom_vbt = NULL;
|
||||||
const struct bdb_header *bdb;
|
const struct bdb_header *bdb;
|
||||||
u8 __iomem *oprom = NULL;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&dev_priv->vbt.display_devices);
|
INIT_LIST_HEAD(&dev_priv->vbt.display_devices);
|
||||||
|
|
||||||
|
@ -2000,15 +2008,11 @@ void intel_bios_init(struct drm_i915_private *dev_priv)
|
||||||
|
|
||||||
/* If the OpRegion does not have VBT, look in PCI ROM. */
|
/* If the OpRegion does not have VBT, look in PCI ROM. */
|
||||||
if (!vbt) {
|
if (!vbt) {
|
||||||
size_t size;
|
oprom_vbt = oprom_get_vbt(dev_priv);
|
||||||
|
if (!oprom_vbt)
|
||||||
oprom = pci_map_rom(pdev, &size);
|
|
||||||
if (!oprom)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
vbt = copy_vbt(oprom, size);
|
vbt = oprom_vbt;
|
||||||
if (!vbt)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
DRM_DEBUG_KMS("Found valid VBT in PCI ROM\n");
|
DRM_DEBUG_KMS("Found valid VBT in PCI ROM\n");
|
||||||
}
|
}
|
||||||
|
@ -2042,11 +2046,7 @@ out:
|
||||||
init_vbt_missing_defaults(dev_priv);
|
init_vbt_missing_defaults(dev_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oprom)
|
kfree(oprom_vbt);
|
||||||
pci_unmap_rom(pdev, oprom);
|
|
||||||
|
|
||||||
if (vbt != dev_priv->opregion.vbt)
|
|
||||||
kfree(vbt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue