Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pci-v6.14-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci

Pull pci fix from Bjorn Helgaas:

- Save the original INTX_DISABLE bit at the first pcim_intx() call and
restore that at devres cleanup instead of restoring the opposite of
the most recent enable/disable pcim_intx() argument, which was wrong
when a driver called pcim_intx() multiple times or with the already
enabled state (Takashi Iwai)

* tag 'pci-v6.14-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci:
PCI: Restore original INTX_DISABLE bit by pcim_intx()

+19 -15
+19 -15
drivers/pci/devres.c
··· 419 419 pci_intx(pdev, res->orig_intx); 420 420 } 421 421 422 - static struct pcim_intx_devres *get_or_create_intx_devres(struct device *dev) 422 + static void save_orig_intx(struct pci_dev *pdev, struct pcim_intx_devres *res) 423 423 { 424 - struct pcim_intx_devres *res; 424 + u16 pci_command; 425 425 426 - res = devres_find(dev, pcim_intx_restore, NULL, NULL); 427 - if (res) 428 - return res; 429 - 430 - res = devres_alloc(pcim_intx_restore, sizeof(*res), GFP_KERNEL); 431 - if (res) 432 - devres_add(dev, res); 433 - 434 - return res; 426 + pci_read_config_word(pdev, PCI_COMMAND, &pci_command); 427 + res->orig_intx = !(pci_command & PCI_COMMAND_INTX_DISABLE); 435 428 } 436 429 437 430 /** ··· 440 447 int pcim_intx(struct pci_dev *pdev, int enable) 441 448 { 442 449 struct pcim_intx_devres *res; 450 + struct device *dev = &pdev->dev; 443 451 444 - res = get_or_create_intx_devres(&pdev->dev); 445 - if (!res) 446 - return -ENOMEM; 452 + /* 453 + * pcim_intx() must only restore the INTx value that existed before the 454 + * driver was loaded, i.e., before it called pcim_intx() for the 455 + * first time. 456 + */ 457 + res = devres_find(dev, pcim_intx_restore, NULL, NULL); 458 + if (!res) { 459 + res = devres_alloc(pcim_intx_restore, sizeof(*res), GFP_KERNEL); 460 + if (!res) 461 + return -ENOMEM; 447 462 448 - res->orig_intx = !enable; 463 + save_orig_intx(pdev, res); 464 + devres_add(dev, res); 465 + } 466 + 449 467 pci_intx(pdev, enable); 450 468 451 469 return 0;