root/drivers/mcb/mcb-pci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mcb_pci_get_irq
  2. mcb_pci_probe
  3. mcb_pci_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * MEN Chameleon Bus.
   4  *
   5  * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
   6  * Author: Johannes Thumshirn <johannes.thumshirn@men.de>
   7  */
   8 
   9 #include <linux/module.h>
  10 #include <linux/pci.h>
  11 #include <linux/mcb.h>
  12 
  13 #include "mcb-internal.h"
  14 
  15 struct priv {
  16         struct mcb_bus *bus;
  17         phys_addr_t mapbase;
  18         void __iomem *base;
  19 };
  20 
  21 static int mcb_pci_get_irq(struct mcb_device *mdev)
  22 {
  23         struct mcb_bus *mbus = mdev->bus;
  24         struct device *dev = mbus->carrier;
  25         struct pci_dev *pdev = to_pci_dev(dev);
  26 
  27         return pdev->irq;
  28 }
  29 
  30 static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  31 {
  32         struct resource *res;
  33         struct priv *priv;
  34         int ret;
  35         unsigned long flags;
  36 
  37         priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL);
  38         if (!priv)
  39                 return -ENOMEM;
  40 
  41         ret = pci_enable_device(pdev);
  42         if (ret) {
  43                 dev_err(&pdev->dev, "Failed to enable PCI device\n");
  44                 return -ENODEV;
  45         }
  46         pci_set_master(pdev);
  47 
  48         priv->mapbase = pci_resource_start(pdev, 0);
  49         if (!priv->mapbase) {
  50                 dev_err(&pdev->dev, "No PCI resource\n");
  51                 ret = -ENODEV;
  52                 goto out_disable;
  53         }
  54 
  55         res = devm_request_mem_region(&pdev->dev, priv->mapbase,
  56                                       CHAM_HEADER_SIZE,
  57                                       KBUILD_MODNAME);
  58         if (!res) {
  59                 dev_err(&pdev->dev, "Failed to request PCI memory\n");
  60                 ret = -EBUSY;
  61                 goto out_disable;
  62         }
  63 
  64         priv->base = devm_ioremap(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE);
  65         if (!priv->base) {
  66                 dev_err(&pdev->dev, "Cannot ioremap\n");
  67                 ret = -ENOMEM;
  68                 goto out_disable;
  69         }
  70 
  71         flags = pci_resource_flags(pdev, 0);
  72         if (flags & IORESOURCE_IO) {
  73                 ret = -ENOTSUPP;
  74                 dev_err(&pdev->dev,
  75                         "IO mapped PCI devices are not supported\n");
  76                 goto out_disable;
  77         }
  78 
  79         pci_set_drvdata(pdev, priv);
  80 
  81         priv->bus = mcb_alloc_bus(&pdev->dev);
  82         if (IS_ERR(priv->bus)) {
  83                 ret = PTR_ERR(priv->bus);
  84                 goto out_disable;
  85         }
  86 
  87         priv->bus->get_irq = mcb_pci_get_irq;
  88 
  89         ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base);
  90         if (ret < 0)
  91                 goto out_mcb_bus;
  92 
  93         dev_dbg(&pdev->dev, "Found %d cells\n", ret);
  94 
  95         mcb_bus_add_devices(priv->bus);
  96 
  97         return 0;
  98 
  99 out_mcb_bus:
 100         mcb_release_bus(priv->bus);
 101 out_disable:
 102         pci_disable_device(pdev);
 103         return ret;
 104 }
 105 
 106 static void mcb_pci_remove(struct pci_dev *pdev)
 107 {
 108         struct priv *priv = pci_get_drvdata(pdev);
 109 
 110         mcb_release_bus(priv->bus);
 111 
 112         pci_disable_device(pdev);
 113 }
 114 
 115 static const struct pci_device_id mcb_pci_tbl[] = {
 116         { PCI_DEVICE(PCI_VENDOR_ID_MEN, PCI_DEVICE_ID_MEN_CHAMELEON) },
 117         { PCI_DEVICE(PCI_VENDOR_ID_ALTERA, PCI_DEVICE_ID_MEN_CHAMELEON) },
 118         { 0 },
 119 };
 120 MODULE_DEVICE_TABLE(pci, mcb_pci_tbl);
 121 
 122 static struct pci_driver mcb_pci_driver = {
 123         .name = "mcb-pci",
 124         .id_table = mcb_pci_tbl,
 125         .probe = mcb_pci_probe,
 126         .remove = mcb_pci_remove,
 127 };
 128 
 129 module_pci_driver(mcb_pci_driver);
 130 
 131 MODULE_AUTHOR("Johannes Thumshirn <johannes.thumshirn@men.de>");
 132 MODULE_LICENSE("GPL");
 133 MODULE_DESCRIPTION("MCB over PCI support");

/* [<][>][^][v][top][bottom][index][help] */