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