diff options
Diffstat (limited to 'drivers/pci/devres.c')
| -rw-r--r-- | drivers/pci/devres.c | 34 | 
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c index d1d97a4bb36d..3431a7df3e0d 100644 --- a/drivers/pci/devres.c +++ b/drivers/pci/devres.c @@ -419,19 +419,12 @@ static void pcim_intx_restore(struct device *dev, void *data)  	pci_intx(pdev, res->orig_intx);  } -static struct pcim_intx_devres *get_or_create_intx_devres(struct device *dev) +static void save_orig_intx(struct pci_dev *pdev, struct pcim_intx_devres *res)  { -	struct pcim_intx_devres *res; - -	res = devres_find(dev, pcim_intx_restore, NULL, NULL); -	if (res) -		return res; +	u16 pci_command; -	res = devres_alloc(pcim_intx_restore, sizeof(*res), GFP_KERNEL); -	if (res) -		devres_add(dev, res); - -	return res; +	pci_read_config_word(pdev, PCI_COMMAND, &pci_command); +	res->orig_intx = !(pci_command & PCI_COMMAND_INTX_DISABLE);  }  /** @@ -447,12 +440,23 @@ static struct pcim_intx_devres *get_or_create_intx_devres(struct device *dev)  int pcim_intx(struct pci_dev *pdev, int enable)  {  	struct pcim_intx_devres *res; +	struct device *dev = &pdev->dev; -	res = get_or_create_intx_devres(&pdev->dev); -	if (!res) -		return -ENOMEM; +	/* +	 * pcim_intx() must only restore the INTx value that existed before the +	 * driver was loaded, i.e., before it called pcim_intx() for the +	 * first time. +	 */ +	res = devres_find(dev, pcim_intx_restore, NULL, NULL); +	if (!res) { +		res = devres_alloc(pcim_intx_restore, sizeof(*res), GFP_KERNEL); +		if (!res) +			return -ENOMEM; + +		save_orig_intx(pdev, res); +		devres_add(dev, res); +	} -	res->orig_intx = !enable;  	pci_intx(pdev, enable);  	return 0;  | 
