diff options
Diffstat (limited to 'drivers/gpu/vga/vgaarb.c')
-rw-r--r-- | drivers/gpu/vga/vgaarb.c | 51 |
1 files changed, 22 insertions, 29 deletions
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index e893f6e1937d..af0259708358 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -257,9 +257,9 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev, if (!conflict->bridge_has_one_vga) { vga_irq_set_state(conflict, false); flags |= PCI_VGA_STATE_CHANGE_DECODES; - if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) + if (match & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) pci_bits |= PCI_COMMAND_MEMORY; - if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) + if (match & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) pci_bits |= PCI_COMMAND_IO; } @@ -267,11 +267,11 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev, flags |= PCI_VGA_STATE_CHANGE_BRIDGE; pci_set_vga_state(conflict->pdev, false, pci_bits, flags); - conflict->owns &= ~lwants; + conflict->owns &= ~match; /* If he also owned non-legacy, that is no longer the case */ - if (lwants & VGA_RSRC_LEGACY_MEM) + if (match & VGA_RSRC_LEGACY_MEM) conflict->owns &= ~VGA_RSRC_NORMAL_MEM; - if (lwants & VGA_RSRC_LEGACY_IO) + if (match & VGA_RSRC_LEGACY_IO) conflict->owns &= ~VGA_RSRC_NORMAL_IO; } @@ -644,10 +644,12 @@ bail: static inline void vga_update_device_decodes(struct vga_device *vgadev, int new_decodes) { - int old_decodes; - struct vga_device *new_vgadev, *conflict; + int old_decodes, decodes_removed, decodes_unlocked; old_decodes = vgadev->decodes; + decodes_removed = ~new_decodes & old_decodes; + decodes_unlocked = vgadev->locks & decodes_removed; + vgadev->owns &= ~decodes_removed; vgadev->decodes = new_decodes; pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n", @@ -656,31 +658,22 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev, vga_iostate_to_str(vgadev->decodes), vga_iostate_to_str(vgadev->owns)); - - /* if we own the decodes we should move them along to - another card */ - if ((vgadev->owns & old_decodes) && (vga_count > 1)) { - /* set us to own nothing */ - vgadev->owns &= ~old_decodes; - list_for_each_entry(new_vgadev, &vga_list, list) { - if ((new_vgadev != vgadev) && - (new_vgadev->decodes & VGA_RSRC_LEGACY_MASK)) { - pr_info("vgaarb: transferring owner from PCI:%s to PCI:%s\n", pci_name(vgadev->pdev), pci_name(new_vgadev->pdev)); - conflict = __vga_tryget(new_vgadev, VGA_RSRC_LEGACY_MASK); - if (!conflict) - __vga_put(new_vgadev, VGA_RSRC_LEGACY_MASK); - break; - } - } + /* if we removed locked decodes, lock count goes to zero, and release */ + if (decodes_unlocked) { + if (decodes_unlocked & VGA_RSRC_LEGACY_IO) + vgadev->io_lock_cnt = 0; + if (decodes_unlocked & VGA_RSRC_LEGACY_MEM) + vgadev->mem_lock_cnt = 0; + __vga_put(vgadev, decodes_unlocked); } /* change decodes counter */ - if (old_decodes != new_decodes) { - if (new_decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) - vga_decode_count++; - else - vga_decode_count--; - } + if (old_decodes & VGA_RSRC_LEGACY_MASK && + !(new_decodes & VGA_RSRC_LEGACY_MASK)) + vga_decode_count--; + if (!(old_decodes & VGA_RSRC_LEGACY_MASK) && + new_decodes & VGA_RSRC_LEGACY_MASK) + vga_decode_count++; pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); } |