diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-07-27 22:15:01 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-07-27 22:15:01 +0000 |
commit | 7996a3d79d55b7f879dfd62e202bbfe2963718d3 (patch) | |
tree | 8d9f6759fec4099b9be503c11c7ed174f7204980 /libdde-linux26/lib/src/arch/l4/pci.c | |
parent | 4fbe7358c7747a9165f776eb19addbb9baf7def2 (diff) |
really properly move files
Diffstat (limited to 'libdde-linux26/lib/src/arch/l4/pci.c')
-rw-r--r-- | libdde-linux26/lib/src/arch/l4/pci.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/libdde-linux26/lib/src/arch/l4/pci.c b/libdde-linux26/lib/src/arch/l4/pci.c new file mode 100644 index 00000000..b50a7353 --- /dev/null +++ b/libdde-linux26/lib/src/arch/l4/pci.c @@ -0,0 +1,205 @@ +#include "local.h" + +#include <linux/delay.h> +#include <linux/pci.h> +#include <linux/list.h> +#include <linux/init.h> + +/* will include $(CONTRIB)/drivers/pci/pci.h */ +#include "pci.h" + +DECLARE_INITVAR(dde26_pci); + +/** PCI device descriptor */ +typedef struct l4dde_pci_dev { + struct list_head next; /**< chain info */ + struct ddekit_pci_dev *ddekit_dev; /**< corresponding DDEKit descriptor */ + struct pci_dev *linux_dev; /**< Linux descriptor */ +} l4dde_pci_dev_t; + + +/******************************************************************************************* + ** PCI data ** + *******************************************************************************************/ +/** List of Linux-DDEKit PCIDev mappings */ +static LIST_HEAD(pcidev_mappings); + +static int l4dde26_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); +static int l4dde26_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); + +/** PCI operations for our virtual PCI bus */ +static struct pci_ops dde_pcibus_ops = { + .read = l4dde26_pci_read, + .write = l4dde26_pci_write, +}; + + +/******************************************************************************************* + ** Read/write PCI config space. This is simply mapped to the DDEKit functions. ** + *******************************************************************************************/ +static int l4dde26_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) +{ + return ddekit_pci_read(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val); +} + +static int l4dde26_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) +{ + return ddekit_pci_write(bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val); +} + +int pci_irq_enable(struct pci_dev *dev) +{ + int irq = dev->irq; + int pin = 0; + int ret; + + DEBUG_MSG("dev %p", dev); + if (!dev) + return -EINVAL; + + pin = (int)dev->pin; + DEBUG_MSG("irq %d, pin %d", dev->irq, dev->pin); + if (!pin) { + dev_warn(&dev->dev, + "No interrupt pin configured for device %s\n", + pci_name(dev)); + return 0; + } + pin--; + + ret = ddekit_pci_irq_enable(dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), pin, &irq); + if (ret) { + dev_warn(&dev->dev, "Interrupt enable failed for device %s (%d)\n", + pci_name(dev), ret); + return -1; + } + + dev_info(&dev->dev, "PCI INT %c -> GSI %d -> IRQ %d\n", + 'A' + pin, irq, dev->irq); + + dev->irq = irq; + return 0; +} + +int __pci_enable_device(struct pci_dev *dev) +{ + WARN_UNIMPL; + return 0; +} + + +/** + * pci_enable_device - Initialize device before it's used by a driver. + * + * Initialize device before it's used by a driver. Ask low-level code + * to enable I/O and memory. Wake up the device if it was suspended. + * Beware, this function can fail. + * + * \param dev PCI device to be initialized + * + */ +int +pci_enable_device(struct pci_dev *dev) +{ + CHECK_INITVAR(dde26_pci); +// WARN_UNIMPL; + return pci_irq_enable(dev); +} + + +/** + * pci_disable_device - Disable PCI device after use + * + * Signal to the system that the PCI device is not in use by the system + * anymore. This only involves disabling PCI bus-mastering, if active. + * + * \param dev PCI device to be disabled + */ +void pci_disable_device(struct pci_dev *dev) +{ + CHECK_INITVAR(dde26_pci); + WARN_UNIMPL; +} + + +void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) +{ + //WARN_UNIMPL; +} + +static unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + +int pci_create_sysfs_dev_files(struct pci_dev *pdev) +{ + return 0; +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} + +void +pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) +{ + WARN_UNIMPL; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ +#if 0 + int err; + + if ((err = pcibios_enable_resources(dev, mask)) < 0) + return err; + + return pcibios_enable_irq(dev); +#endif + WARN_UNIMPL; + return -1; +} + +/******************************************************************************************* + ** Initialization function ** + *******************************************************************************************/ + +/** Initialize DDELinux PCI subsystem. + */ +void __init l4dde26_init_pci(void) +{ + ddekit_pci_init(); + int nr; + char found[256] = { }; + int bus, slot, func; + + for (nr = 0; ; nr++) { + if (ddekit_pci_get_device(nr, &bus, &slot, &func) != 0) + break; + if (!found[bus]) { + struct pci_bus *pci_bus = pci_create_bus(NULL, bus, &dde_pcibus_ops, NULL); + Assert(pci_bus); + pci_do_scan_bus(pci_bus); + + found[bus] = 1; + } + } + + INITIALIZE_INITVAR(dde26_pci); +} + +arch_initcall(l4dde26_init_pci); |