linux/arch/sparc/kernel/ebus.c
<<
>>
Prefs
   1/*
   2 * ebus.c: PCI to EBus bridge device.
   3 *
   4 * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
   5 *
   6 * Adopted for sparc by V. Roganov and G. Raiko.
   7 * Fixes for different platforms by Pete Zaitcev.
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/types.h>
  12#include <linux/init.h>
  13#include <linux/slab.h>
  14#include <linux/string.h>
  15
  16#include <asm/system.h>
  17#include <asm/page.h>
  18#include <asm/pbm.h>
  19#include <asm/ebus.h>
  20#include <asm/io.h>
  21#include <asm/oplib.h>
  22#include <asm/prom.h>
  23#include <asm/bpp.h>
  24
  25struct linux_ebus *ebus_chain = NULL;
  26
  27/* We are together with pcic.c under CONFIG_PCI. */
  28extern unsigned int pcic_pin_to_irq(unsigned int, const char *name);
  29
  30/*
  31 * IRQ Blacklist
  32 * Here we list PROMs and systems that are known to supply crap as IRQ numbers.
  33 */
  34struct ebus_device_irq {
  35        char *name;
  36        unsigned int pin;
  37};
  38
  39struct ebus_system_entry {
  40        char *esname;
  41        struct ebus_device_irq *ipt;
  42};
  43
  44static struct ebus_device_irq je1_1[] = {
  45        { "8042",                3 },
  46        { "SUNW,CS4231",         0 },
  47        { "parallel",            0 },
  48        { "se",                  2 },
  49        { NULL, 0 }
  50};
  51
  52/*
  53 * Gleb's JE1 supplied reasonable pin numbers, but mine did not (OBP 2.32).
  54 * Blacklist the sucker... Note that Gleb's system will work.
  55 */
  56static struct ebus_system_entry ebus_blacklist[] = {
  57        { "SUNW,JavaEngine1", je1_1 },
  58        { NULL, NULL }
  59};
  60
  61static struct ebus_device_irq *ebus_blackp = NULL;
  62
  63/*
  64 */
  65static inline unsigned long ebus_alloc(size_t size)
  66{
  67        return (unsigned long)kmalloc(size, GFP_ATOMIC);
  68}
  69
  70/*
  71 */
  72int __init ebus_blacklist_irq(const char *name)
  73{
  74        struct ebus_device_irq *dp;
  75
  76        if ((dp = ebus_blackp) != NULL) {
  77                for (; dp->name != NULL; dp++) {
  78                        if (strcmp(name, dp->name) == 0) {
  79                                return pcic_pin_to_irq(dp->pin, name);
  80                        }
  81                }
  82        }
  83        return 0;
  84}
  85
  86void __init fill_ebus_child(struct device_node *dp,
  87                            struct linux_ebus_child *dev)
  88{
  89        const int *regs;
  90        const int *irqs;
  91        int i, len;
  92
  93        dev->prom_node = dp;
  94        regs = of_get_property(dp, "reg", &len);
  95        if (!regs)
  96                len = 0;
  97        dev->num_addrs = len / sizeof(regs[0]);
  98
  99        for (i = 0; i < dev->num_addrs; i++) {
 100                if (regs[i] >= dev->parent->num_addrs) {
 101                        prom_printf("UGH: property for %s was %d, need < %d\n",
 102                                    dev->prom_node->name, len,
 103                                    dev->parent->num_addrs);
 104                        panic(__func__);
 105                }
 106
 107                /* XXX resource */
 108                dev->resource[i].start =
 109                        dev->parent->resource[regs[i]].start;
 110        }
 111
 112        for (i = 0; i < PROMINTR_MAX; i++)
 113                dev->irqs[i] = PCI_IRQ_NONE;
 114
 115        if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) {
 116                dev->num_irqs = 1;
 117        } else {
 118                irqs = of_get_property(dp, "interrupts", &len);
 119                if (!irqs) {
 120                        dev->num_irqs = 0;
 121                        dev->irqs[0] = 0;
 122                        if (dev->parent->num_irqs != 0) {
 123                                dev->num_irqs = 1;
 124                                dev->irqs[0] = dev->parent->irqs[0];
 125                        }
 126                } else {
 127                        dev->num_irqs = len / sizeof(irqs[0]);
 128                        if (irqs[0] == 0 || irqs[0] >= 8) {
 129                                /*
 130                                 * XXX Zero is a valid pin number...
 131                                 * This works as long as Ebus is not wired
 132                                 * to INTA#.
 133                                 */
 134                                printk("EBUS: %s got bad irq %d from PROM\n",
 135                                       dev->prom_node->name, irqs[0]);
 136                                dev->num_irqs = 0;
 137                                dev->irqs[0] = 0;
 138                        } else {
 139                                dev->irqs[0] =
 140                                        pcic_pin_to_irq(irqs[0],
 141                                                        dev->prom_node->name);
 142                        }
 143                }
 144        }
 145}
 146
 147void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
 148{
 149        const struct linux_prom_registers *regs;
 150        struct linux_ebus_child *child;
 151        struct dev_archdata *sd;
 152        const int *irqs;
 153        int i, n, len;
 154        unsigned long baseaddr;
 155
 156        dev->prom_node = dp;
 157
 158        regs = of_get_property(dp, "reg", &len);
 159        if (!regs)
 160                len = 0;
 161        if (len % sizeof(struct linux_prom_registers)) {
 162                prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
 163                            dev->prom_node->name, len,
 164                            (int)sizeof(struct linux_prom_registers));
 165                panic(__func__);
 166        }
 167        dev->num_addrs = len / sizeof(struct linux_prom_registers);
 168
 169        for (i = 0; i < dev->num_addrs; i++) {
 170                /*
 171                 * XXX Collect JE-1 PROM
 172                 * 
 173                 * Example - JS-E with 3.11:
 174                 *  /ebus
 175                 *      regs 
 176                 *        0x00000000, 0x0, 0x00000000, 0x0, 0x00000000,
 177                 *        0x82000010, 0x0, 0xf0000000, 0x0, 0x01000000,
 178                 *        0x82000014, 0x0, 0x38800000, 0x0, 0x00800000,
 179                 *      ranges
 180                 *        0x00, 0x00000000, 0x02000010, 0x0, 0x0, 0x01000000,
 181                 *        0x01, 0x01000000, 0x02000014, 0x0, 0x0, 0x00800000,
 182                 *  /ebus/8042
 183                 *      regs
 184                 *        0x00000001, 0x00300060, 0x00000008,
 185                 *        0x00000001, 0x00300060, 0x00000008,
 186                 */
 187                n = regs[i].which_io;
 188                if (n >= 4) {
 189                        /* XXX This is copied from old JE-1 by Gleb. */
 190                        n = (regs[i].which_io - 0x10) >> 2;
 191                } else {
 192                        ;
 193                }
 194
 195/*
 196 * XXX Now as we have regions, why don't we make an on-demand allocation...
 197 */
 198                dev->resource[i].start = 0;
 199                if ((baseaddr = dev->bus->self->resource[n].start +
 200                    regs[i].phys_addr) != 0) {
 201                        /* dev->resource[i].name = dev->prom_name; */
 202                        if ((baseaddr = (unsigned long) ioremap(baseaddr,
 203                            regs[i].reg_size)) == 0) {
 204                                panic("ebus: unable to remap dev %s",
 205                                      dev->prom_node->name);
 206                        }
 207                }
 208                dev->resource[i].start = baseaddr;      /* XXX Unaligned */
 209        }
 210
 211        for (i = 0; i < PROMINTR_MAX; i++)
 212                dev->irqs[i] = PCI_IRQ_NONE;
 213
 214        if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) {
 215                dev->num_irqs = 1;
 216        } else {
 217                irqs = of_get_property(dp, "interrupts", &len);
 218                if (!irqs) {
 219                        dev->num_irqs = 0;
 220                        if ((dev->irqs[0] = dev->bus->self->irq) != 0) {
 221                                dev->num_irqs = 1;
 222/* P3 */ /* printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */
 223                        }
 224                } else {
 225                        dev->num_irqs = 1;  /* dev->num_irqs = len / sizeof(irqs[0]); */
 226                        if (irqs[0] == 0 || irqs[0] >= 8) {
 227                                /* See above for the parent. XXX */
 228                                printk("EBUS: %s got bad irq %d from PROM\n",
 229                                       dev->prom_node->name, irqs[0]);
 230                                dev->num_irqs = 0;
 231                                dev->irqs[0] = 0;
 232                        } else {
 233                                dev->irqs[0] =
 234                                        pcic_pin_to_irq(irqs[0],
 235                                                        dev->prom_node->name);
 236                        }
 237                }
 238        }
 239
 240        sd = &dev->ofdev.dev.archdata;
 241        sd->prom_node = dp;
 242        sd->op = &dev->ofdev;
 243        sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu;
 244
 245        dev->ofdev.node = dp;
 246        dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
 247        dev->ofdev.dev.bus = &ebus_bus_type;
 248        sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
 249
 250        /* Register with core */
 251        if (of_device_register(&dev->ofdev) != 0)
 252                printk(KERN_DEBUG "ebus: device registration error for %s!\n",
 253                       dp->path_component_name);
 254
 255        if ((dp = dp->child) != NULL) {
 256                dev->children = (struct linux_ebus_child *)
 257                        ebus_alloc(sizeof(struct linux_ebus_child));
 258
 259                child = dev->children;
 260                child->next = NULL;
 261                child->parent = dev;
 262                child->bus = dev->bus;
 263                fill_ebus_child(dp, child);
 264
 265                while ((dp = dp->sibling) != NULL) {
 266                        child->next = (struct linux_ebus_child *)
 267                                ebus_alloc(sizeof(struct linux_ebus_child));
 268
 269                        child = child->next;
 270                        child->next = NULL;
 271                        child->parent = dev;
 272                        child->bus = dev->bus;
 273                        fill_ebus_child(dp, child);
 274                }
 275        }
 276}
 277
 278void __init ebus_init(void)
 279{
 280        const struct linux_prom_pci_registers *regs;
 281        struct linux_pbm_info *pbm;
 282        struct linux_ebus_device *dev;
 283        struct linux_ebus *ebus;
 284        struct ebus_system_entry *sp;
 285        struct pci_dev *pdev;
 286        struct pcidev_cookie *cookie;
 287        struct device_node *dp;
 288        struct resource *p;
 289        unsigned short pci_command;
 290        int len, reg, nreg;
 291        int num_ebus = 0;
 292
 293        dp = of_find_node_by_path("/");
 294        for (sp = ebus_blacklist; sp->esname != NULL; sp++) {
 295                if (strcmp(dp->name, sp->esname) == 0) {
 296                        ebus_blackp = sp->ipt;
 297                        break;
 298                }
 299        }
 300
 301        pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL);
 302        if (!pdev)
 303                return;
 304
 305        cookie = pdev->sysdata;
 306        dp = cookie->prom_node;
 307
 308        ebus_chain = ebus = (struct linux_ebus *)
 309                        ebus_alloc(sizeof(struct linux_ebus));
 310        ebus->next = NULL;
 311
 312        while (dp) {
 313                struct device_node *nd;
 314
 315                ebus->prom_node = dp;
 316                ebus->self = pdev;
 317                ebus->parent = pbm = cookie->pbm;
 318
 319                /* Enable BUS Master. */
 320                pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
 321                pci_command |= PCI_COMMAND_MASTER;
 322                pci_write_config_word(pdev, PCI_COMMAND, pci_command);
 323
 324                regs = of_get_property(dp, "reg", &len);
 325                if (!regs) {
 326                        prom_printf("%s: can't find reg property\n",
 327                                    __func__);
 328                        prom_halt();
 329                }
 330                nreg = len / sizeof(struct linux_prom_pci_registers);
 331
 332                p = &ebus->self->resource[0];
 333                for (reg = 0; reg < nreg; reg++) {
 334                        if (!(regs[reg].which_io & 0x03000000))
 335                                continue;
 336
 337                        (p++)->start = regs[reg].phys_lo;
 338                }
 339
 340                ebus->ofdev.node = dp;
 341                ebus->ofdev.dev.parent = &pdev->dev;
 342                ebus->ofdev.dev.bus = &ebus_bus_type;
 343                sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
 344
 345                /* Register with core */
 346                if (of_device_register(&ebus->ofdev) != 0)
 347                        printk(KERN_DEBUG "ebus: device registration error for %s!\n",
 348                               dp->path_component_name);
 349
 350
 351                nd = dp->child;
 352                if (!nd)
 353                        goto next_ebus;
 354
 355                ebus->devices = (struct linux_ebus_device *)
 356                                ebus_alloc(sizeof(struct linux_ebus_device));
 357
 358                dev = ebus->devices;
 359                dev->next = NULL;
 360                dev->children = NULL;
 361                dev->bus = ebus;
 362                fill_ebus_device(nd, dev);
 363
 364                while ((nd = nd->sibling) != NULL) {
 365                        dev->next = (struct linux_ebus_device *)
 366                                ebus_alloc(sizeof(struct linux_ebus_device));
 367
 368                        dev = dev->next;
 369                        dev->next = NULL;
 370                        dev->children = NULL;
 371                        dev->bus = ebus;
 372                        fill_ebus_device(nd, dev);
 373                }
 374
 375        next_ebus:
 376                pdev = pci_get_device(PCI_VENDOR_ID_SUN,
 377                                       PCI_DEVICE_ID_SUN_EBUS, pdev);
 378                if (!pdev)
 379                        break;
 380
 381                cookie = pdev->sysdata;
 382                dp = cookie->prom_node;
 383
 384                ebus->next = (struct linux_ebus *)
 385                        ebus_alloc(sizeof(struct linux_ebus));
 386                ebus = ebus->next;
 387                ebus->next = NULL;
 388                ++num_ebus;
 389        }
 390        if (pdev)
 391                pci_dev_put(pdev);
 392}
 393
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.