root/arch/powerpc/kernel/isa-bridge.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pci_process_ISA_OF_ranges
  2. isa_bridge_find_early
  3. isa_bridge_init_non_pci
  4. isa_bridge_find_late
  5. isa_bridge_remove
  6. isa_bridge_notify
  7. isa_bridge_init

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

/* [<][>][^][v][top][bottom][index][help] */