Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Support routines for initializing a PCI subsystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Extruded from code written by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *      Dave Rusling (david.rusling@reo.mts.dec.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *      David Mosberger (davidm@cs.arizona.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *	David Miller (davem@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Fixed for multiple PCI buses, 1999 Andrea Arcangeli <andrea@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *	     Resource sorting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "pci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static void pci_std_update_resource(struct pci_dev *dev, int resno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct pci_bus_region region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	bool disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	u16 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	u32 new, check, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	/* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	if (dev->is_virtfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	 * Ignore resources for unimplemented BARs and unused resource slots
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	 * for 64 bit BARs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (!res->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (res->flags & IORESOURCE_UNSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	 * Ignore non-moveable resources.  This might be legacy resources for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	 * which no functional BAR register exists or another important
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	 * system resource we shouldn't move around.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	if (res->flags & IORESOURCE_PCI_FIXED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	pcibios_resource_to_bus(dev->bus, &region, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	new = region.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (res->flags & IORESOURCE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	} else if (resno == PCI_ROM_RESOURCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		mask = PCI_ROM_ADDRESS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	if (resno < PCI_ROM_RESOURCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		reg = PCI_BASE_ADDRESS_0 + 4 * resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	} else if (resno == PCI_ROM_RESOURCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		 * Apparently some Matrox devices have ROM BARs that read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		 * as zero when disabled, so don't update ROM BARs unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		 * they're enabled.  See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		 * https://lore.kernel.org/r/43147B3D.1030309@vc.cvut.cz/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		if (!(res->flags & IORESOURCE_ROM_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		reg = dev->rom_base_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		new |= PCI_ROM_ADDRESS_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	 * We can't update a 64-bit BAR atomically, so when possible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	 * disable decoding so that a half-updated BAR won't conflict
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	 * with another device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		pci_read_config_word(dev, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		pci_write_config_word(dev, PCI_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 				      cmd & ~PCI_COMMAND_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	pci_write_config_dword(dev, reg, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	pci_read_config_dword(dev, reg, &check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if ((new ^ check) & mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		pci_err(dev, "BAR %d: error updating (%#08x != %#08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			resno, new, check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (res->flags & IORESOURCE_MEM_64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		new = region.start >> 16 >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		pci_write_config_dword(dev, reg + 4, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		pci_read_config_dword(dev, reg + 4, &check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		if (check != new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			pci_err(dev, "BAR %d: error updating (high %#08x != %#08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 				resno, new, check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		pci_write_config_word(dev, PCI_COMMAND, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) void pci_update_resource(struct pci_dev *dev, int resno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (resno <= PCI_ROM_RESOURCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		pci_std_update_resource(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #ifdef CONFIG_PCI_IOV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		pci_iov_update_resource(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int pci_claim_resource(struct pci_dev *dev, int resource)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	struct resource *res = &dev->resource[resource];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	struct resource *root, *conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (res->flags & IORESOURCE_UNSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		pci_info(dev, "can't claim BAR %d %pR: no address assigned\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			 resource, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 * If we have a shadow copy in RAM, the PCI device doesn't respond
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	 * to the shadow range, so we don't need to claim it, and upstream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	 * bridges don't need to route the range to the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (res->flags & IORESOURCE_ROM_SHADOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	root = pci_find_parent_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (!root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		pci_info(dev, "can't claim BAR %d %pR: no compatible bridge window\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			 resource, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	conflict = request_resource_conflict(root, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (conflict) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		pci_info(dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			 resource, res, conflict->name, conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) EXPORT_SYMBOL(pci_claim_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) void pci_disable_bridge_window(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	/* MMIO Base/Limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	/* Prefetchable MMIO Base/Limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * Generic function that returns a value indicating that the device's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * original BIOS BAR address was not saved and so is not available for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * reinstatement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  * Can be over-ridden by architecture specific code that implements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * reinstatement functionality rather than leaving it disabled when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * normal allocation attempts fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		int resno, resource_size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	struct resource *root, *conflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	resource_size_t fw_addr, start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	fw_addr = pcibios_retrieve_fw_addr(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	if (!fw_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	start = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	end = res->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	res->start = fw_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	res->end = res->start + size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	res->flags &= ~IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	root = pci_find_parent_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (!root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		if (res->flags & IORESOURCE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			root = &ioport_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			root = &iomem_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	pci_info(dev, "BAR %d: trying firmware assignment %pR\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		 resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	conflict = request_resource_conflict(root, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if (conflict) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		pci_info(dev, "BAR %d: %pR conflicts with %s %pR\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			 resno, res, conflict->name, conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		res->start = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		res->end = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  * We don't have to worry about legacy ISA devices, so nothing to do here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  * This is marked as __weak because multiple architectures define it; it should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  * eventually go away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) resource_size_t __weak pcibios_align_resource(void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 					      const struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 					      resource_size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 					      resource_size_t align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)        return res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		int resno, resource_size_t size, resource_size_t align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	resource_size_t min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	 * First, try exact prefetching match.  Even if a 64-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	 * prefetchable bridge window is below 4GB, we can't put a 32-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	 * prefetchable resource in it because pbus_size_mem() assumes a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	 * 64-bit window will contain no 32-bit resources.  If we assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	 * things differently than they were sized, not everything will fit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	ret = pci_bus_alloc_resource(bus, res, size, align, min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 				     pcibios_align_resource, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	 * If the prefetchable window is only 32 bits wide, we can put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	 * 64-bit prefetchable resources in it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		ret = pci_bus_alloc_resource(bus, res, size, align, min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 					     IORESOURCE_PREFETCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 					     pcibios_align_resource, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	 * If we didn't find a better match, we can put any memory resource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	 * in a non-prefetchable window.  If this resource is 32 bits and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	 * non-prefetchable, the first call already tried the only possibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	 * so we don't need to try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 					     pcibios_align_resource, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int _pci_assign_resource(struct pci_dev *dev, int resno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 				resource_size_t size, resource_size_t min_align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	struct pci_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	bus = dev->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		if (!bus->parent || !bus->self->transparent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		bus = bus->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int pci_assign_resource(struct pci_dev *dev, int resno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	resource_size_t align, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	if (res->flags & IORESOURCE_PCI_FIXED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	align = pci_resource_alignment(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	if (!align) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		pci_info(dev, "BAR %d: can't assign %pR (bogus alignment)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			 resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	size = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	ret = _pci_assign_resource(dev, resno, size, align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	 * If we failed to assign anything, let's try the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	 * where firmware left it.  That at least has a chance of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	 * working, which is better than just leaving it disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		pci_info(dev, "BAR %d: no space for %pR\n", resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		ret = pci_revert_fw_address(res, dev, resno, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		pci_info(dev, "BAR %d: failed to assign %pR\n", resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	res->flags &= ~IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	res->flags &= ~IORESOURCE_STARTALIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	pci_info(dev, "BAR %d: assigned %pR\n", resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	if (resno < PCI_BRIDGE_RESOURCES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		pci_update_resource(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) EXPORT_SYMBOL(pci_assign_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			resource_size_t min_align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	resource_size_t new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	if (res->flags & IORESOURCE_PCI_FIXED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	flags = res->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (!res->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		pci_info(dev, "BAR %d: can't reassign an unassigned resource %pR\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			 resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	/* already aligned with min_align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	new_size = resource_size(res) + addsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	ret = _pci_assign_resource(dev, resno, new_size, min_align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		res->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		pci_info(dev, "BAR %d: %pR (failed to expand by %#llx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			 resno, res, (unsigned long long) addsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	res->flags &= ~IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	res->flags &= ~IORESOURCE_STARTALIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	pci_info(dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		 resno, res, (unsigned long long) addsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	if (resno < PCI_BRIDGE_RESOURCES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		pci_update_resource(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) void pci_release_resource(struct pci_dev *dev, int resno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	if (!res->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	release_resource(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	res->end = resource_size(res) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	res->start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	res->flags |= IORESOURCE_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) EXPORT_SYMBOL(pci_release_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) int pci_resize_resource(struct pci_dev *dev, int resno, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	struct resource *res = dev->resource + resno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	struct pci_host_bridge *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	int old, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	u32 sizes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	u16 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	/* Check if we must preserve the firmware's resource assignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	host = pci_find_host_bridge(dev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	if (host->preserve_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	/* Make sure the resource isn't assigned before resizing it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	if (!(res->flags & IORESOURCE_UNSET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	if (cmd & PCI_COMMAND_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	sizes = pci_rebar_get_possible_sizes(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	if (!sizes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if (!(sizes & BIT(size)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	old = pci_rebar_get_current_size(dev, resno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	if (old < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		return old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	ret = pci_rebar_set_size(dev, resno, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	/* Check if the new config works by trying to assign everything. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	if (dev->bus->self) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			goto error_resize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) error_resize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	pci_rebar_set_size(dev, resno, old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	res->end = res->start + pci_rebar_size_to_bytes(old) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) EXPORT_SYMBOL(pci_resize_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int pci_enable_resources(struct pci_dev *dev, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	u16 cmd, old_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	struct resource *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	old_cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		if (!(mask & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		r = &dev->resource[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		if ((i == PCI_ROM_RESOURCE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 				(!(r->flags & IORESOURCE_ROM_ENABLE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		if (r->flags & IORESOURCE_UNSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			pci_err(dev, "can't enable device: BAR %d %pR not assigned\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 				i, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		if (!r->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			pci_err(dev, "can't enable device: BAR %d %pR not claimed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 				i, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		if (r->flags & IORESOURCE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 			cmd |= PCI_COMMAND_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		if (r->flags & IORESOURCE_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 			cmd |= PCI_COMMAND_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	if (cmd != old_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		pci_write_config_word(dev, PCI_COMMAND, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }