mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
Merge branch 'pci/resource' into next
* pci/resource: PCI: Simplify pci_create_attr() control flow PCI: Don't leak memory if sysfs_create_bin_file() fails PCI: Simplify sysfs ROM cleanup PCI: Remove unused IORESOURCE_ROM_COPY and IORESOURCE_ROM_BIOS_COPY MIPS: Loongson 3: Keep CPU physical (not virtual) addresses in shadow ROM resource MIPS: Loongson 3: Use temporary struct resource * to avoid repetition ia64/PCI: Keep CPU physical (not virtual) addresses in shadow ROM resource ia64/PCI: Use ioremap() instead of open-coded equivalent ia64/PCI: Use temporary struct resource * to avoid repetition PCI: Clean up pci_map_rom() whitespace PCI: Remove arch-specific IORESOURCE_ROM_SHADOW size from sysfs PCI: Set ROM shadow location in arch code, not in PCI core PCI: Don't enable/disable ROM BAR if we're using a RAM shadow copy PCI: Don't assign or reassign immutable resources PCI: Mark shadow copy of VGA ROM as IORESOURCE_PCI_FIXED x86/PCI: Mark Broadwell-EP Home Agent & PCU as having non-compliant BARs PCI: Disable IO/MEM decoding for devices with non-compliant BARs
This commit is contained in:
commit
6e6f498b03
12 changed files with 162 additions and 160 deletions
|
|
@ -1138,33 +1138,36 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
|
|||
/* allocate attribute structure, piggyback attribute name */
|
||||
int name_len = write_combine ? 13 : 10;
|
||||
struct bin_attribute *res_attr;
|
||||
char *res_attr_name;
|
||||
int retval;
|
||||
|
||||
res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
|
||||
if (res_attr) {
|
||||
char *res_attr_name = (char *)(res_attr + 1);
|
||||
if (!res_attr)
|
||||
return -ENOMEM;
|
||||
|
||||
sysfs_bin_attr_init(res_attr);
|
||||
if (write_combine) {
|
||||
pdev->res_attr_wc[num] = res_attr;
|
||||
sprintf(res_attr_name, "resource%d_wc", num);
|
||||
res_attr->mmap = pci_mmap_resource_wc;
|
||||
} else {
|
||||
pdev->res_attr[num] = res_attr;
|
||||
sprintf(res_attr_name, "resource%d", num);
|
||||
res_attr->mmap = pci_mmap_resource_uc;
|
||||
}
|
||||
if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
|
||||
res_attr->read = pci_read_resource_io;
|
||||
res_attr->write = pci_write_resource_io;
|
||||
}
|
||||
res_attr->attr.name = res_attr_name;
|
||||
res_attr->attr.mode = S_IRUSR | S_IWUSR;
|
||||
res_attr->size = pci_resource_len(pdev, num);
|
||||
res_attr->private = &pdev->resource[num];
|
||||
retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
|
||||
} else
|
||||
retval = -ENOMEM;
|
||||
res_attr_name = (char *)(res_attr + 1);
|
||||
|
||||
sysfs_bin_attr_init(res_attr);
|
||||
if (write_combine) {
|
||||
pdev->res_attr_wc[num] = res_attr;
|
||||
sprintf(res_attr_name, "resource%d_wc", num);
|
||||
res_attr->mmap = pci_mmap_resource_wc;
|
||||
} else {
|
||||
pdev->res_attr[num] = res_attr;
|
||||
sprintf(res_attr_name, "resource%d", num);
|
||||
res_attr->mmap = pci_mmap_resource_uc;
|
||||
}
|
||||
if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
|
||||
res_attr->read = pci_read_resource_io;
|
||||
res_attr->write = pci_write_resource_io;
|
||||
}
|
||||
res_attr->attr.name = res_attr_name;
|
||||
res_attr->attr.mode = S_IRUSR | S_IWUSR;
|
||||
res_attr->size = pci_resource_len(pdev, num);
|
||||
res_attr->private = &pdev->resource[num];
|
||||
retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
|
||||
if (retval)
|
||||
kfree(res_attr);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -1360,7 +1363,7 @@ error:
|
|||
int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
|
||||
{
|
||||
int retval;
|
||||
int rom_size = 0;
|
||||
int rom_size;
|
||||
struct bin_attribute *attr;
|
||||
|
||||
if (!sysfs_initialized)
|
||||
|
|
@ -1377,12 +1380,8 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
|
|||
if (retval)
|
||||
goto err_config_file;
|
||||
|
||||
if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
|
||||
rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
|
||||
rom_size = 0x20000;
|
||||
|
||||
/* If the device has a ROM, try to expose it in sysfs. */
|
||||
rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
if (rom_size) {
|
||||
attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
|
||||
if (!attr) {
|
||||
|
|
@ -1413,7 +1412,7 @@ int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
|
|||
return 0;
|
||||
|
||||
err_rom_file:
|
||||
if (rom_size) {
|
||||
if (pdev->rom_attr) {
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
|
||||
kfree(pdev->rom_attr);
|
||||
pdev->rom_attr = NULL;
|
||||
|
|
@ -1451,8 +1450,6 @@ static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
|
|||
*/
|
||||
void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
|
||||
{
|
||||
int rom_size = 0;
|
||||
|
||||
if (!sysfs_initialized)
|
||||
return;
|
||||
|
||||
|
|
@ -1465,18 +1462,13 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
|
|||
|
||||
pci_remove_resource_files(pdev);
|
||||
|
||||
if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
|
||||
rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
|
||||
rom_size = 0x20000;
|
||||
|
||||
if (rom_size && pdev->rom_attr) {
|
||||
if (pdev->rom_attr) {
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
|
||||
kfree(pdev->rom_attr);
|
||||
pdev->rom_attr = NULL;
|
||||
}
|
||||
|
||||
pci_remove_firmware_label_files(pdev);
|
||||
|
||||
}
|
||||
|
||||
static int __init pci_sysfs_init(void)
|
||||
|
|
|
|||
|
|
@ -179,6 +179,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
|
|||
u16 orig_cmd;
|
||||
struct pci_bus_region region, inverted_region;
|
||||
|
||||
if (dev->non_compliant_bars)
|
||||
return 0;
|
||||
|
||||
mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
|
||||
|
||||
/* No printks while decoding is disabled! */
|
||||
|
|
@ -1191,6 +1194,7 @@ static void pci_msi_setup_pci_dev(struct pci_dev *dev)
|
|||
int pci_setup_device(struct pci_dev *dev)
|
||||
{
|
||||
u32 class;
|
||||
u16 cmd;
|
||||
u8 hdr_type;
|
||||
int pos = 0;
|
||||
struct pci_bus_region region;
|
||||
|
|
@ -1234,6 +1238,16 @@ int pci_setup_device(struct pci_dev *dev)
|
|||
/* device class may be changed after fixup */
|
||||
class = dev->class >> 8;
|
||||
|
||||
if (dev->non_compliant_bars) {
|
||||
pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
|
||||
dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
|
||||
cmd &= ~PCI_COMMAND_IO;
|
||||
cmd &= ~PCI_COMMAND_MEMORY;
|
||||
pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
switch (dev->hdr_type) { /* header type */
|
||||
case PCI_HEADER_TYPE_NORMAL: /* standard header */
|
||||
if (class == PCI_CLASS_BRIDGE_PCI)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ static void pci_free_resources(struct pci_dev *dev)
|
|||
{
|
||||
int i;
|
||||
|
||||
pci_cleanup_rom(dev);
|
||||
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
|
||||
struct resource *res = dev->resource + i;
|
||||
if (res->parent)
|
||||
|
|
|
|||
|
|
@ -24,13 +24,17 @@
|
|||
*/
|
||||
int pci_enable_rom(struct pci_dev *pdev)
|
||||
{
|
||||
struct resource *res = pdev->resource + PCI_ROM_RESOURCE;
|
||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||
struct pci_bus_region region;
|
||||
u32 rom_addr;
|
||||
|
||||
if (!res->flags)
|
||||
return -1;
|
||||
|
||||
/* Nothing to enable if we're using a shadow copy in RAM */
|
||||
if (res->flags & IORESOURCE_ROM_SHADOW)
|
||||
return 0;
|
||||
|
||||
pcibios_resource_to_bus(pdev->bus, ®ion, res);
|
||||
pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
|
||||
rom_addr &= ~PCI_ROM_ADDRESS_MASK;
|
||||
|
|
@ -49,7 +53,12 @@ EXPORT_SYMBOL_GPL(pci_enable_rom);
|
|||
*/
|
||||
void pci_disable_rom(struct pci_dev *pdev)
|
||||
{
|
||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||
u32 rom_addr;
|
||||
|
||||
if (res->flags & IORESOURCE_ROM_SHADOW)
|
||||
return;
|
||||
|
||||
pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
|
||||
rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
|
||||
pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
|
||||
|
|
@ -119,43 +128,23 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
|||
loff_t start;
|
||||
void __iomem *rom;
|
||||
|
||||
/*
|
||||
* IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
|
||||
* memory map if the VGA enable bit of the Bridge Control register is
|
||||
* set for embedded VGA.
|
||||
*/
|
||||
if (res->flags & IORESOURCE_ROM_SHADOW) {
|
||||
/* primary video rom always starts here */
|
||||
start = (loff_t)0xC0000;
|
||||
*size = 0x20000; /* cover C000:0 through E000:0 */
|
||||
} else {
|
||||
if (res->flags &
|
||||
(IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) {
|
||||
*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
return (void __iomem *)(unsigned long)
|
||||
pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||
} else {
|
||||
/* assign the ROM an address if it doesn't have one */
|
||||
if (res->parent == NULL &&
|
||||
pci_assign_resource(pdev, PCI_ROM_RESOURCE))
|
||||
return NULL;
|
||||
start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||
*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
if (*size == 0)
|
||||
return NULL;
|
||||
/* assign the ROM an address if it doesn't have one */
|
||||
if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE))
|
||||
return NULL;
|
||||
|
||||
/* Enable ROM space decodes */
|
||||
if (pci_enable_rom(pdev))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||
*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
if (*size == 0)
|
||||
return NULL;
|
||||
|
||||
/* Enable ROM space decodes */
|
||||
if (pci_enable_rom(pdev))
|
||||
return NULL;
|
||||
|
||||
rom = ioremap(start, *size);
|
||||
if (!rom) {
|
||||
/* restore enable if ioremap fails */
|
||||
if (!(res->flags & (IORESOURCE_ROM_ENABLE |
|
||||
IORESOURCE_ROM_SHADOW |
|
||||
IORESOURCE_ROM_COPY)))
|
||||
if (!(res->flags & IORESOURCE_ROM_ENABLE))
|
||||
pci_disable_rom(pdev);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -181,36 +170,14 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
|
|||
{
|
||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||
|
||||
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY))
|
||||
return;
|
||||
|
||||
iounmap(rom);
|
||||
|
||||
/* Disable again before continuing, leave enabled if pci=rom */
|
||||
if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
|
||||
/* Disable again before continuing */
|
||||
if (!(res->flags & IORESOURCE_ROM_ENABLE))
|
||||
pci_disable_rom(pdev);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_unmap_rom);
|
||||
|
||||
/**
|
||||
* pci_cleanup_rom - free the ROM copy created by pci_map_rom_copy
|
||||
* @pdev: pointer to pci device struct
|
||||
*
|
||||
* Free the copied ROM if we allocated one.
|
||||
*/
|
||||
void pci_cleanup_rom(struct pci_dev *pdev)
|
||||
{
|
||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||
|
||||
if (res->flags & IORESOURCE_ROM_COPY) {
|
||||
kfree((void *)(unsigned long)res->start);
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
res->flags &= ~IORESOURCE_ROM_COPY;
|
||||
res->start = 0;
|
||||
res->end = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_platform_rom - provides a pointer to any ROM image provided by the
|
||||
* platform
|
||||
|
|
|
|||
|
|
@ -276,6 +276,9 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
|
|||
resource_size_t align, size;
|
||||
int ret;
|
||||
|
||||
if (res->flags & IORESOURCE_PCI_FIXED)
|
||||
return 0;
|
||||
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
align = pci_resource_alignment(dev, res);
|
||||
if (!align) {
|
||||
|
|
@ -321,6 +324,9 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
|
|||
resource_size_t new_size;
|
||||
int ret;
|
||||
|
||||
if (res->flags & IORESOURCE_PCI_FIXED)
|
||||
return 0;
|
||||
|
||||
flags = res->flags;
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
if (!res->parent) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue