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