[PATCH] xilinx_pcipr: Added Xilinx reconfigurable PCI endpoint driver.

Grant Likely grant.likely at secretlab.ca
Tue Jun 29 08:23:19 EST 2010


On Mon, Jun 28, 2010 at 10:47 AM, Stephen Neuendorffer
<stephen.neuendorffer at xilinx.com> wrote:
> This bus has an internal bus which contains some devices, which
> are described in a device tree.  This code is *very* preliminary
> and mainly exists to exercise the device tree code on an arbitrary
> architecture.
> ---
>  drivers/pci/Kconfig        |    9 ++
>  drivers/pci/Makefile       |    2 +
>  drivers/pci/xilinx_pcipr.c |  203 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 214 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/pci/xilinx_pcipr.c
>
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index 34ef70d..ec9b25d 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -65,3 +65,12 @@ config PCI_IOAPIC
>        depends on ACPI
>        depends on HOTPLUG
>        default y
> +
> +config XILINX_PCIPR
> +       tristate "Xilinx OF-based PCI endpoint"
> +       depends on PCI
> +       select OF
> +       select OF_FLATTREE
> +        select OF_DEVICE
> +       help
> +         Enable support for Xilinx PCIPR endpoint
> \ No newline at end of file
> diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
> index 0b51857..ec44c21 100644
> --- a/drivers/pci/Makefile
> +++ b/drivers/pci/Makefile
> @@ -62,6 +62,8 @@ obj-$(CONFIG_PCI_SYSCALL) += syscall.o
>
>  obj-$(CONFIG_PCI_STUB) += pci-stub.o
>
> +obj-$(CONFIG_XILINX_PCIPR) += xilinx_pcipr.o
> +
>  ifeq ($(CONFIG_PCI_DEBUG),y)
>  EXTRA_CFLAGS += -DDEBUG
>  endif
> diff --git a/drivers/pci/xilinx_pcipr.c b/drivers/pci/xilinx_pcipr.c
> new file mode 100644
> index 0000000..17fde0b
> --- /dev/null
> +++ b/drivers/pci/xilinx_pcipr.c
> @@ -0,0 +1,203 @@
> +/*
> + *  Copyright 2010 Xilinx, Inc.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/pci.h>
> +#include <linux/ide.h>
> +#include <linux/init.h>
> +#include <linux/dmi.h>
> +
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +
> +
> +#include <asm/io.h>
> +
> +#define DRV_NAME "xilinx_pcipr"
> +
> +
> +unsigned char pcipr_dtb[] = {
> +  0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x38,
> +  0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
> +  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
> +  0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
> +  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01,
> +  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x1b,
> +  0x78, 0x6c, 0x6e, 0x78, 0x2c, 0x70, 0x6c, 0x62, 0x2d, 0x76, 0x34, 0x36,
> +  0x2d, 0x31, 0x2e, 0x30, 0x33, 0x2e, 0x61, 0x00, 0x78, 0x6c, 0x6e, 0x78,
> +  0x2c, 0x70, 0x6c, 0x62, 0x2d, 0x76, 0x34, 0x36, 0x2d, 0x31, 0x2e, 0x30,
> +  0x30, 0x2e, 0x61, 0x00, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2d, 0x62,
> +  0x75, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x78, 0x70, 0x73, 0x2d,
> +  0x68, 0x77, 0x69, 0x63, 0x61, 0x70, 0x40, 0x38, 0x30, 0x30, 0x33, 0x30,
> +  0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17,
> +  0x00, 0x00, 0x00, 0x1b, 0x78, 0x6c, 0x6e, 0x78, 0x2c, 0x78, 0x70, 0x73,
> +  0x2d, 0x68, 0x77, 0x69, 0x63, 0x61, 0x70, 0x2d, 0x31, 0x2e, 0x30, 0x30,
> +  0x2e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
> +  0x00, 0x00, 0x00, 0x26, 0x80, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
> +  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2a,
> +  0x76, 0x69, 0x72, 0x74, 0x65, 0x78, 0x35, 0x00, 0x00, 0x00, 0x00, 0x03,
> +  0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x36, 0x66, 0x61, 0x6c, 0x73,
> +  0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
> +  0x00, 0x00, 0x00, 0x09, 0x23, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
> +  0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x23, 0x73, 0x69, 0x7a, 0x65,
> +  0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x63, 0x6f, 0x6d, 0x70, 0x61,
> +  0x74, 0x69, 0x62, 0x6c, 0x65, 0x00, 0x72, 0x65, 0x67, 0x00, 0x78, 0x6c,
> +  0x6e, 0x78, 0x2c, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x00, 0x78, 0x6c,
> +  0x6e, 0x78, 0x2c, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f,
> +  0x6e, 0x00
> +};
> +unsigned int pcipr_dtb_len = 362;
> +
> +
> +struct xilinx_pcipr_drvdata {
> +       unsigned long *blob;
> +       struct device_node *child_nodes;
> +};
> +
> +/**
> + *     xilinx_pcipr_probe - Setup the endpoint
> + *     @dev: PCI device to set up
> + */
> +static int __devinit xilinx_pcipr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> +{
> +  int ret;
> +  struct xilinx_pcipr_drvdata *drvdata;
> +       dev_dbg(&pdev->dev, "xilinx_pcipr_probe\n");
> +
> +       drvdata = kzalloc(sizeof(struct xilinx_pcipr_drvdata), GFP_KERNEL);
> +       if (!drvdata) {
> +               dev_err(&pdev->dev, "Couldn't allocate device private record\n");
> +               ret = -ENOMEM;
> +               goto out;
> +       }
> +
> +       dev_set_drvdata(&pdev->dev, (void *)drvdata);
> +
> +/*     /\* */
> +/*      * If we failed to assign proper bus numbers for this cardbus */
> +/*      * controller during PCI probe, its subordinate pci_bus is NULL. */
> +/*      * Bail out if so. */
> +/*      *\/ */
> +/*     if (!dev->subordinate) { */
> +/*             dev_printk(KERN_ERR, &dev->dev, "no bus associated! " */
> +/*                        "(try 'pci=assign-busses')\n"); */
> +/*             return -ENODEV; */
> +/*     } */
> +
> +       /*
> +        * Do some basic sanity checking..
> +        */
> +       if (pci_enable_device(pdev)) {
> +               ret = -EBUSY;
> +               goto free;
> +       }
> +
> +       ret = pci_request_regions(pdev, "xilinx_pcipr");
> +       if (ret)
> +               goto disable;
> +
> +       if (!pci_resource_start(pdev, 0)) {
> +               dev_printk(KERN_ERR, &pdev->dev, "No cardbus resource!\n");
> +               ret = -ENODEV;
> +               goto release;
> +       }
> +
> +       drvdata->blob = pcipr_dtb;
> +
> +/*     /\* */
> +/*      * Ok, start setup.. Map the cardbus registers, */
> +/*      * and request the IRQ. */
> +/*      *\/ */
> +/*     socket->base = ioremap(pci_resource_start(pdev, 0), 0x1000); */
> +/*     if (!socket->base) { */
> +/*             ret = -ENOMEM; */
> +/*             goto release; */
> +/*     } */
> +
> +       /*
> +        * report the subsystem vendor and device for help debugging
> +        * the irq stuff...
> +        */
> +       dev_printk(KERN_INFO, &pdev->dev, "Xilinx PCIPR bridge found [%04x:%04x]\n",
> +                  pdev->subsystem_vendor, pdev->subsystem_device);
> +
> +
> +       //      yenta_fixup_parent_bridge(dev->subordinate);
> +
> +       // initialize our sub-devices.
> +
> +
> +       unflatten_partial_device_tree(drvdata->blob, &drvdata->child_nodes);
> +       of_platform_bus_probe(drvdata->child_nodes, NULL, &pdev->dev);

This looks fairly sane.  As we talked about before, you'll probably
want to use the firmware loading mechanism to inject the dtb fragment
into the kernel.

g.


More information about the devicetree-discuss mailing list