diff options
author | Johannes Thumshirn <johannes.thumshirn@men.de> | 2014-02-26 11:29:06 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-28 18:47:12 -0500 |
commit | b71bb8639891827051af88d8dfb17ca608b6ae88 (patch) | |
tree | c3e5830266ce976245f8ff0f91f8e825967906a4 /drivers/mcb | |
parent | 3764e82e5150d87b205c10cd78a9c9ab86fbfa51 (diff) |
mcb: Add PCI carrier for MEN Chameleon Bus
Add support for MCB over PCI devices. Both PCI attached on-board Chameleon FPGAs
as well as CompactPCI based MCB carrier cards are supported with this driver.
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@men.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/mcb')
-rw-r--r-- | drivers/mcb/Kconfig | 14 | ||||
-rw-r--r-- | drivers/mcb/Makefile | 2 | ||||
-rw-r--r-- | drivers/mcb/mcb-internal.h | 2 | ||||
-rw-r--r-- | drivers/mcb/mcb-pci.c | 114 |
4 files changed, 132 insertions, 0 deletions
diff --git a/drivers/mcb/Kconfig b/drivers/mcb/Kconfig index 44c82d68c563..b8f5d469165c 100644 --- a/drivers/mcb/Kconfig +++ b/drivers/mcb/Kconfig | |||
@@ -13,3 +13,17 @@ menuconfig MCB | |||
13 | for these devices. | 13 | for these devices. |
14 | 14 | ||
15 | If build as a module, the module is called mcb.ko | 15 | If build as a module, the module is called mcb.ko |
16 | |||
17 | if MCB | ||
18 | config MCB_PCI | ||
19 | tristate "PCI based MCB carrier" | ||
20 | default m | ||
21 | help | ||
22 | |||
23 | This is a MCB carrier on a PCI device. Both PCI attached on-board | ||
24 | FPGAs as well as CompactPCI attached MCB FPGAs are supported with | ||
25 | this driver. | ||
26 | |||
27 | If build as a module, the module is called mcb-pci.ko | ||
28 | |||
29 | endif # MCB | ||
diff --git a/drivers/mcb/Makefile b/drivers/mcb/Makefile index 2d9a751e93bd..1ae141311def 100644 --- a/drivers/mcb/Makefile +++ b/drivers/mcb/Makefile | |||
@@ -3,3 +3,5 @@ obj-$(CONFIG_MCB) += mcb.o | |||
3 | 3 | ||
4 | mcb-y += mcb-core.o | 4 | mcb-y += mcb-core.o |
5 | mcb-y += mcb-parse.o | 5 | mcb-y += mcb-parse.o |
6 | |||
7 | obj-$(CONFIG_MCB_PCI) += mcb-pci.o | ||
diff --git a/drivers/mcb/mcb-internal.h b/drivers/mcb/mcb-internal.h index db22777d0ac8..f956ef26c0ce 100644 --- a/drivers/mcb/mcb-internal.h +++ b/drivers/mcb/mcb-internal.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | 5 | ||
6 | #define PCI_VENDOR_ID_MEN 0x1a88 | ||
7 | #define PCI_DEVICE_ID_MEN_CHAMELEON 0x4d45 | ||
6 | #define CHAMELEON_FILENAME_LEN 12 | 8 | #define CHAMELEON_FILENAME_LEN 12 |
7 | #define CHAMELEONV2_MAGIC 0xabce | 9 | #define CHAMELEONV2_MAGIC 0xabce |
8 | 10 | ||
diff --git a/drivers/mcb/mcb-pci.c b/drivers/mcb/mcb-pci.c new file mode 100644 index 000000000000..99c742cbfb5b --- /dev/null +++ b/drivers/mcb/mcb-pci.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * MEN Chameleon Bus. | ||
3 | * | ||
4 | * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de) | ||
5 | * Author: Johannes Thumshirn <johannes.thumshirn@men.de> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the Free | ||
9 | * Software Foundation; version 2 of the License. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/mcb.h> | ||
15 | |||
16 | #include "mcb-internal.h" | ||
17 | |||
18 | struct priv { | ||
19 | struct mcb_bus *bus; | ||
20 | void __iomem *base; | ||
21 | }; | ||
22 | |||
23 | static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
24 | { | ||
25 | struct priv *priv; | ||
26 | phys_addr_t mapbase; | ||
27 | int ret; | ||
28 | int num_cells; | ||
29 | unsigned long flags; | ||
30 | |||
31 | priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL); | ||
32 | if (!priv) | ||
33 | return -ENOMEM; | ||
34 | |||
35 | ret = pci_enable_device(pdev); | ||
36 | if (ret) { | ||
37 | dev_err(&pdev->dev, "Failed to enable PCI device\n"); | ||
38 | return -ENODEV; | ||
39 | } | ||
40 | |||
41 | mapbase = pci_resource_start(pdev, 0); | ||
42 | if (!mapbase) { | ||
43 | dev_err(&pdev->dev, "No PCI resource\n"); | ||
44 | goto err_start; | ||
45 | } | ||
46 | |||
47 | ret = pci_request_region(pdev, 0, KBUILD_MODNAME); | ||
48 | if (ret) { | ||
49 | dev_err(&pdev->dev, "Failed to request PCI BARs\n"); | ||
50 | goto err_start; | ||
51 | } | ||
52 | |||
53 | priv->base = pci_iomap(pdev, 0, 0); | ||
54 | if (!priv->base) { | ||
55 | dev_err(&pdev->dev, "Cannot ioremap\n"); | ||
56 | ret = -ENOMEM; | ||
57 | goto err_ioremap; | ||
58 | } | ||
59 | |||
60 | flags = pci_resource_flags(pdev, 0); | ||
61 | if (flags & IORESOURCE_IO) { | ||
62 | ret = -ENOTSUPP; | ||
63 | dev_err(&pdev->dev, | ||
64 | "IO mapped PCI devices are not supported\n"); | ||
65 | goto err_ioremap; | ||
66 | } | ||
67 | |||
68 | pci_set_drvdata(pdev, priv); | ||
69 | |||
70 | priv->bus = mcb_alloc_bus(); | ||
71 | |||
72 | ret = chameleon_parse_cells(priv->bus, mapbase, priv->base); | ||
73 | if (ret < 0) | ||
74 | goto err_drvdata; | ||
75 | num_cells = ret; | ||
76 | |||
77 | dev_dbg(&pdev->dev, "Found %d cells\n", num_cells); | ||
78 | |||
79 | mcb_bus_add_devices(priv->bus); | ||
80 | |||
81 | err_drvdata: | ||
82 | pci_iounmap(pdev, priv->base); | ||
83 | err_ioremap: | ||
84 | pci_release_region(pdev, 0); | ||
85 | err_start: | ||
86 | pci_disable_device(pdev); | ||
87 | return ret; | ||
88 | } | ||
89 | |||
90 | static void mcb_pci_remove(struct pci_dev *pdev) | ||
91 | { | ||
92 | struct priv *priv = pci_get_drvdata(pdev); | ||
93 | |||
94 | mcb_release_bus(priv->bus); | ||
95 | } | ||
96 | |||
97 | static const struct pci_device_id mcb_pci_tbl[] = { | ||
98 | { PCI_DEVICE(PCI_VENDOR_ID_MEN, PCI_DEVICE_ID_MEN_CHAMELEON) }, | ||
99 | { 0 }, | ||
100 | }; | ||
101 | MODULE_DEVICE_TABLE(pci, mcb_pci_tbl); | ||
102 | |||
103 | static struct pci_driver mcb_pci_driver = { | ||
104 | .name = "mcb-pci", | ||
105 | .id_table = mcb_pci_tbl, | ||
106 | .probe = mcb_pci_probe, | ||
107 | .remove = mcb_pci_remove, | ||
108 | }; | ||
109 | |||
110 | module_pci_driver(mcb_pci_driver); | ||
111 | |||
112 | MODULE_AUTHOR("Johannes Thumshirn <johannes.thumshirn@men.de>"); | ||
113 | MODULE_LICENSE("GPL"); | ||
114 | MODULE_DESCRIPTION("MCB over PCI support"); | ||