linux/arch/sparc/kernel/leon_pci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * leon_pci.c: LEON Host PCI support
   4 *
   5 * Copyright (C) 2011 Aeroflex Gaisler AB, Daniel Hellstrom
   6 *
   7 * Code is partially derived from pcic.c
   8 */
   9
  10#include <linux/of_device.h>
  11#include <linux/kernel.h>
  12#include <linux/pci.h>
  13#include <linux/export.h>
  14#include <asm/leon.h>
  15#include <asm/leon_pci.h>
  16
  17/* The LEON architecture does not rely on a BIOS or bootloader to setup
  18 * PCI for us. The Linux generic routines are used to setup resources,
  19 * reset values of configuration-space register settings are preserved.
  20 *
  21 * PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is
  22 * accessed through a Window which is translated to low 64KB in PCI space, the
  23 * first 4KB is not used so 60KB is available.
  24 */
  25void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
  26{
  27        LIST_HEAD(resources);
  28        struct pci_bus *root_bus;
  29        struct pci_host_bridge *bridge;
  30        int ret;
  31
  32        bridge = pci_alloc_host_bridge(0);
  33        if (!bridge)
  34                return;
  35
  36        pci_add_resource_offset(&resources, &info->io_space,
  37                                info->io_space.start - 0x1000);
  38        pci_add_resource(&resources, &info->mem_space);
  39        info->busn.flags = IORESOURCE_BUS;
  40        pci_add_resource(&resources, &info->busn);
  41
  42        list_splice_init(&resources, &bridge->windows);
  43        bridge->dev.parent = &ofdev->dev;
  44        bridge->sysdata = info;
  45        bridge->busnr = 0;
  46        bridge->ops = info->ops;
  47        bridge->swizzle_irq = pci_common_swizzle;
  48        bridge->map_irq = info->map_irq;
  49
  50        ret = pci_scan_root_bus_bridge(bridge);
  51        if (ret) {
  52                pci_free_host_bridge(bridge);
  53                return;
  54        }
  55
  56        root_bus = bridge->bus;
  57
  58        /* Assign devices with resources */
  59        pci_assign_unassigned_resources();
  60        pci_bus_add_devices(root_bus);
  61}
  62
  63int pcibios_enable_device(struct pci_dev *dev, int mask)
  64{
  65        u16 cmd, oldcmd;
  66        int i;
  67
  68        pci_read_config_word(dev, PCI_COMMAND, &cmd);
  69        oldcmd = cmd;
  70
  71        for (i = 0; i < PCI_NUM_RESOURCES; i++) {
  72                struct resource *res = &dev->resource[i];
  73
  74                /* Only set up the requested stuff */
  75                if (!(mask & (1<<i)))
  76                        continue;
  77
  78                if (res->flags & IORESOURCE_IO)
  79                        cmd |= PCI_COMMAND_IO;
  80                if (res->flags & IORESOURCE_MEM)
  81                        cmd |= PCI_COMMAND_MEMORY;
  82        }
  83
  84        if (cmd != oldcmd) {
  85                pci_info(dev, "enabling device (%04x -> %04x)\n", oldcmd, cmd);
  86                pci_write_config_word(dev, PCI_COMMAND, cmd);
  87        }
  88        return 0;
  89}
  90