diff options
| -rw-r--r-- | drivers/gpu/vga/vgaarb.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index af0259708358..d2077f040f3e 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c | |||
| @@ -237,12 +237,10 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev, | |||
| 237 | if (conflict->locks & lwants) | 237 | if (conflict->locks & lwants) |
| 238 | return conflict; | 238 | return conflict; |
| 239 | 239 | ||
| 240 | /* Ok, now check if he owns the resource we want. We don't need | 240 | /* Ok, now check if it owns the resource we want. We can |
| 241 | * to check "decodes" since it should be impossible to own | 241 | * lock resources that are not decoded, therefore a device |
| 242 | * own legacy resources you don't decode unless I have a bug | 242 | * can own resources it doesn't decode. |
| 243 | * in this code... | ||
| 244 | */ | 243 | */ |
| 245 | WARN_ON(conflict->owns & ~conflict->decodes); | ||
| 246 | match = lwants & conflict->owns; | 244 | match = lwants & conflict->owns; |
| 247 | if (!match) | 245 | if (!match) |
| 248 | continue; | 246 | continue; |
| @@ -254,13 +252,19 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev, | |||
| 254 | flags = 0; | 252 | flags = 0; |
| 255 | pci_bits = 0; | 253 | pci_bits = 0; |
| 256 | 254 | ||
| 255 | /* If we can't control legacy resources via the bridge, we | ||
| 256 | * also need to disable normal decoding. | ||
| 257 | */ | ||
| 257 | if (!conflict->bridge_has_one_vga) { | 258 | if (!conflict->bridge_has_one_vga) { |
| 258 | vga_irq_set_state(conflict, false); | 259 | if ((match & conflict->decodes) & VGA_RSRC_LEGACY_MEM) |
| 259 | flags |= PCI_VGA_STATE_CHANGE_DECODES; | ||
| 260 | if (match & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) | ||
| 261 | pci_bits |= PCI_COMMAND_MEMORY; | 260 | pci_bits |= PCI_COMMAND_MEMORY; |
| 262 | if (match & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) | 261 | if ((match & conflict->decodes) & VGA_RSRC_LEGACY_IO) |
| 263 | pci_bits |= PCI_COMMAND_IO; | 262 | pci_bits |= PCI_COMMAND_IO; |
| 263 | |||
| 264 | if (pci_bits) { | ||
| 265 | vga_irq_set_state(conflict, false); | ||
| 266 | flags |= PCI_VGA_STATE_CHANGE_DECODES; | ||
| 267 | } | ||
| 264 | } | 268 | } |
| 265 | 269 | ||
| 266 | if (change_bridge) | 270 | if (change_bridge) |
| @@ -268,18 +272,19 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev, | |||
| 268 | 272 | ||
| 269 | pci_set_vga_state(conflict->pdev, false, pci_bits, flags); | 273 | pci_set_vga_state(conflict->pdev, false, pci_bits, flags); |
| 270 | conflict->owns &= ~match; | 274 | conflict->owns &= ~match; |
| 271 | /* If he also owned non-legacy, that is no longer the case */ | 275 | |
| 272 | if (match & VGA_RSRC_LEGACY_MEM) | 276 | /* If we disabled normal decoding, reflect it in owns */ |
| 277 | if (pci_bits & PCI_COMMAND_MEMORY) | ||
| 273 | conflict->owns &= ~VGA_RSRC_NORMAL_MEM; | 278 | conflict->owns &= ~VGA_RSRC_NORMAL_MEM; |
| 274 | if (match & VGA_RSRC_LEGACY_IO) | 279 | if (pci_bits & PCI_COMMAND_IO) |
| 275 | conflict->owns &= ~VGA_RSRC_NORMAL_IO; | 280 | conflict->owns &= ~VGA_RSRC_NORMAL_IO; |
| 276 | } | 281 | } |
| 277 | 282 | ||
| 278 | enable_them: | 283 | enable_them: |
| 279 | /* ok dude, we got it, everybody conflicting has been disabled, let's | 284 | /* ok dude, we got it, everybody conflicting has been disabled, let's |
| 280 | * enable us. Make sure we don't mark a bit in "owns" that we don't | 285 | * enable us. Mark any bits in "owns" regardless of whether we |
| 281 | * also have in "decodes". We can lock resources we don't decode but | 286 | * decoded them. We can lock resources we don't decode, therefore |
| 282 | * not own them. | 287 | * we must track them via "owns". |
| 283 | */ | 288 | */ |
| 284 | flags = 0; | 289 | flags = 0; |
| 285 | pci_bits = 0; | 290 | pci_bits = 0; |
| @@ -291,7 +296,7 @@ enable_them: | |||
| 291 | if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) | 296 | if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) |
| 292 | pci_bits |= PCI_COMMAND_IO; | 297 | pci_bits |= PCI_COMMAND_IO; |
| 293 | } | 298 | } |
| 294 | if (!!(wants & VGA_RSRC_LEGACY_MASK)) | 299 | if (wants & VGA_RSRC_LEGACY_MASK) |
| 295 | flags |= PCI_VGA_STATE_CHANGE_BRIDGE; | 300 | flags |= PCI_VGA_STATE_CHANGE_BRIDGE; |
| 296 | 301 | ||
| 297 | pci_set_vga_state(vgadev->pdev, true, pci_bits, flags); | 302 | pci_set_vga_state(vgadev->pdev, true, pci_bits, flags); |
| @@ -299,7 +304,7 @@ enable_them: | |||
| 299 | if (!vgadev->bridge_has_one_vga) { | 304 | if (!vgadev->bridge_has_one_vga) { |
| 300 | vga_irq_set_state(vgadev, true); | 305 | vga_irq_set_state(vgadev, true); |
| 301 | } | 306 | } |
| 302 | vgadev->owns |= (wants & vgadev->decodes); | 307 | vgadev->owns |= wants; |
| 303 | lock_them: | 308 | lock_them: |
| 304 | vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK); | 309 | vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK); |
| 305 | if (rsrc & VGA_RSRC_LEGACY_IO) | 310 | if (rsrc & VGA_RSRC_LEGACY_IO) |
| @@ -649,7 +654,6 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev, | |||
| 649 | old_decodes = vgadev->decodes; | 654 | old_decodes = vgadev->decodes; |
| 650 | decodes_removed = ~new_decodes & old_decodes; | 655 | decodes_removed = ~new_decodes & old_decodes; |
| 651 | decodes_unlocked = vgadev->locks & decodes_removed; | 656 | decodes_unlocked = vgadev->locks & decodes_removed; |
| 652 | vgadev->owns &= ~decodes_removed; | ||
| 653 | vgadev->decodes = new_decodes; | 657 | vgadev->decodes = new_decodes; |
| 654 | 658 | ||
| 655 | pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n", | 659 | pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n", |
