Blame view

drivers/pci/host/pcie-iproc-bcma.c 3.11 KB
4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  /*
   * Copyright (C) 2015 Broadcom Corporation
   * Copyright (C) 2015 Hauke Mehrtens <hauke@hauke-m.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.
   *
   * This program is distributed "as is" WITHOUT ANY WARRANTY of any
   * kind, whether express or implied; without even the implied warranty
   * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   */
  
  #include <linux/kernel.h>
  #include <linux/pci.h>
  #include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/phy/phy.h>
  #include <linux/bcma/bcma.h>
  #include <linux/ioport.h>
  
  #include "pcie-iproc.h"
  
  
  /* NS: CLASS field is R/O, and set to wrong 0x200 value */
  static void bcma_pcie2_fixup_class(struct pci_dev *dev)
  {
  	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
  }
  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x8011, bcma_pcie2_fixup_class);
  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x8012, bcma_pcie2_fixup_class);
  
  static int iproc_pcie_bcma_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  {
  	struct pci_sys_data *sys = dev->sysdata;
  	struct iproc_pcie *pcie = sys->private_data;
  	struct bcma_device *bdev = container_of(pcie->dev, struct bcma_device, dev);
  
  	return bcma_core_irq(bdev, 5);
  }
  
  static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
  {
786aeccb4   Bjorn Helgaas   PCI: iproc: Add l...
45
  	struct device *dev = &bdev->dev;
4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
46
  	struct iproc_pcie *pcie;
6e347b5e0   Bjorn Helgaas   PCI: iproc: Save ...
47
  	LIST_HEAD(resources);
4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
48
  	int ret;
786aeccb4   Bjorn Helgaas   PCI: iproc: Add l...
49
  	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
50
51
  	if (!pcie)
  		return -ENOMEM;
786aeccb4   Bjorn Helgaas   PCI: iproc: Add l...
52
  	pcie->dev = dev;
4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
53

404349c5c   Ray Jui   PCI: iproc: Add B...
54
  	pcie->type = IPROC_PCIE_PAXB_BCMA;
4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
55
  	pcie->base = bdev->io_addr;
f66e5b290   Bjorn Helgaas   PCI: iproc: Valid...
56
57
58
59
60
  	if (!pcie->base) {
  		dev_err(dev, "no controller registers
  ");
  		return -ENOMEM;
  	}
3bc2b2348   Ray Jui   PCI: iproc: Add i...
61
  	pcie->base_addr = bdev->addr;
4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
62

6e347b5e0   Bjorn Helgaas   PCI: iproc: Save ...
63
64
65
66
67
  	pcie->mem.start = bdev->addr_s[0];
  	pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1;
  	pcie->mem.name = "PCIe MEM space";
  	pcie->mem.flags = IORESOURCE_MEM;
  	pci_add_resource(&resources, &pcie->mem);
4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
68

4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
69
  	pcie->map_irq = iproc_pcie_bcma_map_irq;
6e347b5e0   Bjorn Helgaas   PCI: iproc: Save ...
70
71
  	ret = iproc_pcie_setup(pcie, &resources);
  	if (ret) {
786aeccb4   Bjorn Helgaas   PCI: iproc: Add l...
72
73
  		dev_err(dev, "PCIe controller setup failed
  ");
6e347b5e0   Bjorn Helgaas   PCI: iproc: Save ...
74
75
76
  		pci_free_resource_list(&resources);
  		return ret;
  	}
ef07991a9   Hauke Mehrtens   PCI: iproc: Free ...
77

556c7bb7d   Bjorn Helgaas   PCI: iproc: Set d...
78
  	bcma_set_drvdata(bdev, pcie);
6e347b5e0   Bjorn Helgaas   PCI: iproc: Save ...
79
  	return 0;
4785ffbdc   Hauke Mehrtens   PCI: iproc: Add B...
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  }
  
  static void iproc_pcie_bcma_remove(struct bcma_device *bdev)
  {
  	struct iproc_pcie *pcie = bcma_get_drvdata(bdev);
  
  	iproc_pcie_remove(pcie);
  }
  
  static const struct bcma_device_id iproc_pcie_bcma_table[] = {
  	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_PCIEG2, BCMA_ANY_REV, BCMA_ANY_CLASS),
  	{},
  };
  MODULE_DEVICE_TABLE(bcma, iproc_pcie_bcma_table);
  
  static struct bcma_driver iproc_pcie_bcma_driver = {
  	.name		= KBUILD_MODNAME,
  	.id_table	= iproc_pcie_bcma_table,
  	.probe		= iproc_pcie_bcma_probe,
  	.remove		= iproc_pcie_bcma_remove,
  };
  
  static int __init iproc_pcie_bcma_init(void)
  {
  	return bcma_driver_register(&iproc_pcie_bcma_driver);
  }
  module_init(iproc_pcie_bcma_init);
  
  static void __exit iproc_pcie_bcma_exit(void)
  {
  	bcma_driver_unregister(&iproc_pcie_bcma_driver);
  }
  module_exit(iproc_pcie_bcma_exit);
  
  MODULE_AUTHOR("Hauke Mehrtens");
  MODULE_DESCRIPTION("Broadcom iProc PCIe BCMA driver");
  MODULE_LICENSE("GPL v2");