2 * Broadcom specific AMBA
5 * Licensed under the GNU/GPL. See COPYING for details.
8 #include "bcma_private.h"
9 #include <linux/slab.h>
10 #include <linux/bcma/bcma.h>
11 #include <linux/pci.h>
13 static void bcma_host_pci_switch_core(struct bcma_device
*core
)
15 pci_write_config_dword(core
->bus
->host_pci
, BCMA_PCI_BAR0_WIN
,
17 pci_write_config_dword(core
->bus
->host_pci
, BCMA_PCI_BAR0_WIN2
,
19 core
->bus
->mapped_core
= core
;
20 pr_debug("Switched to core: 0x%X\n", core
->id
.id
);
23 static u8
bcma_host_pci_read8(struct bcma_device
*core
, u16 offset
)
25 if (core
->bus
->mapped_core
!= core
)
26 bcma_host_pci_switch_core(core
);
27 return ioread8(core
->bus
->mmio
+ offset
);
30 static u16
bcma_host_pci_read16(struct bcma_device
*core
, u16 offset
)
32 if (core
->bus
->mapped_core
!= core
)
33 bcma_host_pci_switch_core(core
);
34 return ioread16(core
->bus
->mmio
+ offset
);
37 static u32
bcma_host_pci_read32(struct bcma_device
*core
, u16 offset
)
39 if (core
->bus
->mapped_core
!= core
)
40 bcma_host_pci_switch_core(core
);
41 return ioread32(core
->bus
->mmio
+ offset
);
44 static void bcma_host_pci_write8(struct bcma_device
*core
, u16 offset
,
47 if (core
->bus
->mapped_core
!= core
)
48 bcma_host_pci_switch_core(core
);
49 iowrite8(value
, core
->bus
->mmio
+ offset
);
52 static void bcma_host_pci_write16(struct bcma_device
*core
, u16 offset
,
55 if (core
->bus
->mapped_core
!= core
)
56 bcma_host_pci_switch_core(core
);
57 iowrite16(value
, core
->bus
->mmio
+ offset
);
60 static void bcma_host_pci_write32(struct bcma_device
*core
, u16 offset
,
63 if (core
->bus
->mapped_core
!= core
)
64 bcma_host_pci_switch_core(core
);
65 iowrite32(value
, core
->bus
->mmio
+ offset
);
68 static u32
bcma_host_pci_aread32(struct bcma_device
*core
, u16 offset
)
70 if (core
->bus
->mapped_core
!= core
)
71 bcma_host_pci_switch_core(core
);
72 return ioread32(core
->bus
->mmio
+ (1 * BCMA_CORE_SIZE
) + offset
);
75 static void bcma_host_pci_awrite32(struct bcma_device
*core
, u16 offset
,
78 if (core
->bus
->mapped_core
!= core
)
79 bcma_host_pci_switch_core(core
);
80 iowrite32(value
, core
->bus
->mmio
+ (1 * BCMA_CORE_SIZE
) + offset
);
83 const struct bcma_host_ops bcma_host_pci_ops
= {
84 .read8
= bcma_host_pci_read8
,
85 .read16
= bcma_host_pci_read16
,
86 .read32
= bcma_host_pci_read32
,
87 .write8
= bcma_host_pci_write8
,
88 .write16
= bcma_host_pci_write16
,
89 .write32
= bcma_host_pci_write32
,
90 .aread32
= bcma_host_pci_aread32
,
91 .awrite32
= bcma_host_pci_awrite32
,
94 static int bcma_host_pci_probe(struct pci_dev
*dev
,
95 const struct pci_device_id
*id
)
103 bus
= kzalloc(sizeof(*bus
), GFP_KERNEL
);
107 /* Basic PCI configuration */
108 err
= pci_enable_device(dev
);
112 name
= dev_name(&dev
->dev
);
113 if (dev
->driver
&& dev
->driver
->name
)
114 name
= dev
->driver
->name
;
115 err
= pci_request_regions(dev
, name
);
117 goto err_pci_disable
;
120 /* Disable the RETRY_TIMEOUT register (0x41) to keep
121 * PCI Tx retries from interfering with C3 CPU state */
122 pci_read_config_dword(dev
, 0x40, &val
);
123 if ((val
& 0x0000ff00) != 0)
124 pci_write_config_dword(dev
, 0x40, val
& 0xffff00ff);
126 /* SSB needed additional powering up, do we have any AMBA PCI cards? */
127 if (!pci_is_pcie(dev
))
128 pr_err("PCI card detected, report problems.\n");
132 bus
->mmio
= pci_iomap(dev
, 0, ~0UL);
134 goto err_pci_release_regions
;
138 bus
->hosttype
= BCMA_HOSTTYPE_PCI
;
139 bus
->ops
= &bcma_host_pci_ops
;
142 err
= bcma_bus_register(bus
);
144 goto err_pci_unmap_mmio
;
146 pci_set_drvdata(dev
, bus
);
152 pci_iounmap(dev
, bus
->mmio
);
153 err_pci_release_regions
:
154 pci_release_regions(dev
);
156 pci_disable_device(dev
);
162 static void bcma_host_pci_remove(struct pci_dev
*dev
)
164 struct bcma_bus
*bus
= pci_get_drvdata(dev
);
166 bcma_bus_unregister(bus
);
167 pci_iounmap(dev
, bus
->mmio
);
168 pci_release_regions(dev
);
169 pci_disable_device(dev
);
171 pci_set_drvdata(dev
, NULL
);
174 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl
) = {
175 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x0576) },
176 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4331) },
177 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4353) },
178 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4727) },
181 MODULE_DEVICE_TABLE(pci
, bcma_pci_bridge_tbl
);
183 static struct pci_driver bcma_pci_bridge_driver
= {
184 .name
= "bcma-pci-bridge",
185 .id_table
= bcma_pci_bridge_tbl
,
186 .probe
= bcma_host_pci_probe
,
187 .remove
= bcma_host_pci_remove
,
190 int __init
bcma_host_pci_init(void)
192 return pci_register_driver(&bcma_pci_bridge_driver
);
195 void __exit
bcma_host_pci_exit(void)
197 pci_unregister_driver(&bcma_pci_bridge_driver
);