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-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Routines for tracking a legacy ISA bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyrigh 2007 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Some bits and pieces moved over from pci_64.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyrigh 2003 Anton Blanchard <anton@au.ibm.com>, IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/string.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/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <asm/pci-bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <asm/machdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <asm/ppc-pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <asm/isa-bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) unsigned long isa_io_base;	/* NULL if no ISA bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) EXPORT_SYMBOL(isa_io_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /* Cached ISA bridge dev. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static struct device_node *isa_bridge_devnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) struct pci_dev *isa_bridge_pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) EXPORT_SYMBOL_GPL(isa_bridge_pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define ISA_SPACE_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define ISA_SPACE_IO 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static void remap_isa_base(phys_addr_t pa, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	WARN_ON_ONCE(ISA_IO_BASE & ~PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	WARN_ON_ONCE(pa & ~PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	WARN_ON_ONCE(size & ~PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	if (slab_is_available()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		if (ioremap_page_range(ISA_IO_BASE, ISA_IO_BASE + size, pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 				pgprot_noncached(PAGE_KERNEL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			unmap_kernel_range(ISA_IO_BASE, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		early_ioremap_range(ISA_IO_BASE, pa, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 				pgprot_noncached(PAGE_KERNEL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static void pci_process_ISA_OF_ranges(struct device_node *isa_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 				      unsigned long phb_io_base_phys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	/* We should get some saner parsing here and remove these structs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct pci_address {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		u32 a_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		u32 a_mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		u32 a_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	struct isa_address {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		u32 a_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		u32 a_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct isa_range {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		struct isa_address isa_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		struct pci_address pci_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	const struct isa_range *range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	unsigned long pci_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	unsigned int isa_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	int rlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	range = of_get_property(isa_node, "ranges", &rlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (range == NULL || (rlen < sizeof(struct isa_range)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		goto inval_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	/* From "ISA Binding to 1275"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	 * The ranges property is laid out as an array of elements,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	 * each of which comprises:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	 *   cells 0 - 1:	an ISA address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	 *   cells 2 - 4:	a PCI address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	 *			(size depending on dev->n_addr_cells)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	 *   cell 5:		the size of the range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if ((range->isa_addr.a_hi & ISA_SPACE_MASK) != ISA_SPACE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		range++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		rlen -= sizeof(struct isa_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		if (rlen < sizeof(struct isa_range))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			goto inval_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if ((range->isa_addr.a_hi & ISA_SPACE_MASK) != ISA_SPACE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		goto inval_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	isa_addr = range->isa_addr.a_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	pci_addr = (unsigned long) range->pci_addr.a_mid << 32 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		range->pci_addr.a_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	/* Assume these are both zero. Note: We could fix that and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	 * do a proper parsing instead ... oh well, that will do for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	 * now as nobody uses fancy mappings for ISA bridges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if ((pci_addr != 0) || (isa_addr != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		       __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	/* Align size and make sure it's cropped to 64K */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	size = PAGE_ALIGN(range->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	if (size > 0x10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		size = 0x10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	remap_isa_base(phb_io_base_phys, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) inval_range:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	printk(KERN_ERR "no ISA IO ranges or unexpected isa range, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	       "mapping 64k\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	remap_isa_base(phb_io_base_phys, 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * isa_bridge_find_early - Find and map the ISA IO space early before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  *                         main PCI discovery. This is optionally called by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  *                         the arch code when adding PCI PHBs to get early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  *                         access to ISA IO ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) void __init isa_bridge_find_early(struct pci_controller *hose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct device_node *np, *parent = NULL, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	/* If we already have an ISA bridge, bail off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (isa_bridge_devnode != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	/* For each "isa" node in the system. Note : we do a search by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	 * type and not by name. It might be better to do by name but that's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	 * what the code used to do and I don't want to break too much at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	 * once. We can look into changing that separately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	for_each_node_by_type(np, "isa") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		/* Look for our hose being a parent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		for (parent = of_get_parent(np); parent;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			if (parent == hose->dn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 				of_node_put(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			tmp = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			parent = of_get_parent(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			of_node_put(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		if (parent != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	if (np == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	isa_bridge_devnode = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	/* Now parse the "ranges" property and setup the ISA mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	pci_process_ISA_OF_ranges(np, hose->io_base_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	/* Set the global ISA io base to indicate we have an ISA bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	isa_io_base = ISA_IO_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	pr_debug("ISA bridge (early) is %pOF\n", np);
^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)  * isa_bridge_find_early - Find and map the ISA IO space early before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  *                         main PCI discovery. This is optionally called by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  *                         the arch code when adding PCI PHBs to get early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  *                         access to ISA IO ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) void __init isa_bridge_init_non_pci(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	const __be32 *ranges, *pbasep = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	int rlen, i, rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	u32 na, ns, pna;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	u64 cbase, pbase, size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	/* If we already have an ISA bridge, bail off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	if (isa_bridge_devnode != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	pna = of_n_addr_cells(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	if (of_property_read_u32(np, "#address-cells", &na) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	    of_property_read_u32(np, "#size-cells", &ns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		pr_warn("ISA: Non-PCI bridge %pOF is missing address format\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	/* Check it's a supported address format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (na != 2 || ns != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		pr_warn("ISA: Non-PCI bridge %pOF has unsupported address format\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	rs = na + ns + pna;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	/* Grab the ranges property */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	ranges = of_get_property(np, "ranges", &rlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (ranges == NULL || rlen < rs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		pr_warn("ISA: Non-PCI bridge %pOF has absent or invalid ranges\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	/* Parse it. We are only looking for IO space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	for (i = 0; (i + rs - 1) < rlen; i += rs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (be32_to_cpup(ranges + i) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		cbase = be32_to_cpup(ranges + i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		size = of_read_number(ranges + i + na + pna, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		pbasep = ranges + i + na;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	/* Got something ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	if (!size || !pbasep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		pr_warn("ISA: Non-PCI bridge %pOF has no usable IO range\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	/* Align size and make sure it's cropped to 64K */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	size = PAGE_ALIGN(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if (size > 0x10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		size = 0x10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	/* Map pbase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	pbase = of_translate_address(np, pbasep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	if (pbase == OF_BAD_ADDR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		pr_warn("ISA: Non-PCI bridge %pOF failed to translate IO base\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	/* We need page alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	if ((cbase & ~PAGE_MASK) || (pbase & ~PAGE_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		pr_warn("ISA: Non-PCI bridge %pOF has non aligned IO range\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	/* Got it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	isa_bridge_devnode = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	/* Set the global ISA io base to indicate we have an ISA bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	 * and map it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	isa_io_base = ISA_IO_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	remap_isa_base(pbase, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	pr_debug("ISA: Non-PCI bridge is %pOF\n", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  * isa_bridge_find_late - Find and map the ISA IO space upon discovery of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  *                        a new ISA bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static void isa_bridge_find_late(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 				 struct device_node *devnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	struct pci_controller *hose = pci_bus_to_host(pdev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	/* Store ISA device node and PCI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	isa_bridge_devnode = of_node_get(devnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	isa_bridge_pcidev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	/* Now parse the "ranges" property and setup the ISA mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	pci_process_ISA_OF_ranges(devnode, hose->io_base_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	/* Set the global ISA io base to indicate we have an ISA bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	isa_io_base = ISA_IO_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	pr_debug("ISA bridge (late) is %pOF on %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		 devnode, pci_name(pdev));
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * isa_bridge_remove - Remove/unmap an ISA bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static void isa_bridge_remove(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	pr_debug("ISA bridge removed !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	/* Clear the global ISA io base to indicate that we have no more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	 * ISA bridge. Note that drivers don't quite handle that, though
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	 * we should probably do something about it. But do we ever really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	 * have ISA bridges being removed on machines using legacy devices ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	isa_io_base = ISA_IO_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	/* Clear references to the bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	of_node_put(isa_bridge_devnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	isa_bridge_devnode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	isa_bridge_pcidev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	/* Unmap the ISA area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	unmap_kernel_range(ISA_IO_BASE, 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)  * isa_bridge_notify - Get notified of PCI devices addition/removal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int isa_bridge_notify(struct notifier_block *nb, unsigned long action,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			     void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	struct device *dev = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	struct device_node *devnode = pci_device_to_OF_node(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	switch(action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	case BUS_NOTIFY_ADD_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		/* Check if we have an early ISA device, without PCI dev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		if (isa_bridge_devnode && isa_bridge_devnode == devnode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		    !isa_bridge_pcidev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			pr_debug("ISA bridge PCI attached: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 				 pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			isa_bridge_pcidev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		/* Check if we have no ISA device, and this happens to be one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		 * register it as such if it has an OF device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		if (!isa_bridge_devnode && of_node_is_type(devnode, "isa"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			isa_bridge_find_late(pdev, devnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	case BUS_NOTIFY_DEL_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		/* Check if this our existing ISA device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		if (pdev == isa_bridge_pcidev ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		    (devnode && devnode == isa_bridge_devnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			isa_bridge_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		return 0;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static struct notifier_block isa_bridge_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	.notifier_call = isa_bridge_notify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * isa_bridge_init - register to be notified of ISA bridge addition/removal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static int __init isa_bridge_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	bus_register_notifier(&pci_bus_type, &isa_bridge_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) arch_initcall(isa_bridge_init);