forked from Minki/linux
ba7328b2d8
alpha allmodconfig: drivers/bcma/host_pci.c: In function 'bcma_host_pci_probe': drivers/bcma/host_pci.c:102: error: implicit declaration of function 'kzalloc' drivers/bcma/host_pci.c:102: warning: assignment makes pointer from integer without a cast Cc: <zajec5@gmail.com> Cc: John W. Linville <linville@tuxdriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
199 lines
4.8 KiB
C
199 lines
4.8 KiB
C
/*
|
|
* Broadcom specific AMBA
|
|
* PCI Host
|
|
*
|
|
* Licensed under the GNU/GPL. See COPYING for details.
|
|
*/
|
|
|
|
#include "bcma_private.h"
|
|
#include <linux/slab.h>
|
|
#include <linux/bcma/bcma.h>
|
|
#include <linux/pci.h>
|
|
|
|
static void bcma_host_pci_switch_core(struct bcma_device *core)
|
|
{
|
|
pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN,
|
|
core->addr);
|
|
pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2,
|
|
core->wrap);
|
|
core->bus->mapped_core = core;
|
|
pr_debug("Switched to core: 0x%X\n", core->id.id);
|
|
}
|
|
|
|
static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
|
|
{
|
|
if (core->bus->mapped_core != core)
|
|
bcma_host_pci_switch_core(core);
|
|
return ioread8(core->bus->mmio + offset);
|
|
}
|
|
|
|
static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
|
|
{
|
|
if (core->bus->mapped_core != core)
|
|
bcma_host_pci_switch_core(core);
|
|
return ioread16(core->bus->mmio + offset);
|
|
}
|
|
|
|
static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
|
|
{
|
|
if (core->bus->mapped_core != core)
|
|
bcma_host_pci_switch_core(core);
|
|
return ioread32(core->bus->mmio + offset);
|
|
}
|
|
|
|
static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
|
|
u8 value)
|
|
{
|
|
if (core->bus->mapped_core != core)
|
|
bcma_host_pci_switch_core(core);
|
|
iowrite8(value, core->bus->mmio + offset);
|
|
}
|
|
|
|
static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
|
|
u16 value)
|
|
{
|
|
if (core->bus->mapped_core != core)
|
|
bcma_host_pci_switch_core(core);
|
|
iowrite16(value, core->bus->mmio + offset);
|
|
}
|
|
|
|
static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
|
|
u32 value)
|
|
{
|
|
if (core->bus->mapped_core != core)
|
|
bcma_host_pci_switch_core(core);
|
|
iowrite32(value, core->bus->mmio + offset);
|
|
}
|
|
|
|
static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
|
|
{
|
|
if (core->bus->mapped_core != core)
|
|
bcma_host_pci_switch_core(core);
|
|
return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
|
|
}
|
|
|
|
static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset,
|
|
u32 value)
|
|
{
|
|
if (core->bus->mapped_core != core)
|
|
bcma_host_pci_switch_core(core);
|
|
iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
|
|
}
|
|
|
|
const struct bcma_host_ops bcma_host_pci_ops = {
|
|
.read8 = bcma_host_pci_read8,
|
|
.read16 = bcma_host_pci_read16,
|
|
.read32 = bcma_host_pci_read32,
|
|
.write8 = bcma_host_pci_write8,
|
|
.write16 = bcma_host_pci_write16,
|
|
.write32 = bcma_host_pci_write32,
|
|
.aread32 = bcma_host_pci_aread32,
|
|
.awrite32 = bcma_host_pci_awrite32,
|
|
};
|
|
|
|
static int bcma_host_pci_probe(struct pci_dev *dev,
|
|
const struct pci_device_id *id)
|
|
{
|
|
struct bcma_bus *bus;
|
|
int err = -ENOMEM;
|
|
const char *name;
|
|
u32 val;
|
|
|
|
/* Alloc */
|
|
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
|
|
if (!bus)
|
|
goto out;
|
|
|
|
/* Basic PCI configuration */
|
|
err = pci_enable_device(dev);
|
|
if (err)
|
|
goto err_kfree_bus;
|
|
|
|
name = dev_name(&dev->dev);
|
|
if (dev->driver && dev->driver->name)
|
|
name = dev->driver->name;
|
|
err = pci_request_regions(dev, name);
|
|
if (err)
|
|
goto err_pci_disable;
|
|
pci_set_master(dev);
|
|
|
|
/* Disable the RETRY_TIMEOUT register (0x41) to keep
|
|
* PCI Tx retries from interfering with C3 CPU state */
|
|
pci_read_config_dword(dev, 0x40, &val);
|
|
if ((val & 0x0000ff00) != 0)
|
|
pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
|
|
|
|
/* SSB needed additional powering up, do we have any AMBA PCI cards? */
|
|
if (!pci_is_pcie(dev))
|
|
pr_err("PCI card detected, report problems.\n");
|
|
|
|
/* Map MMIO */
|
|
err = -ENOMEM;
|
|
bus->mmio = pci_iomap(dev, 0, ~0UL);
|
|
if (!bus->mmio)
|
|
goto err_pci_release_regions;
|
|
|
|
/* Host specific */
|
|
bus->host_pci = dev;
|
|
bus->hosttype = BCMA_HOSTTYPE_PCI;
|
|
bus->ops = &bcma_host_pci_ops;
|
|
|
|
/* Register */
|
|
err = bcma_bus_register(bus);
|
|
if (err)
|
|
goto err_pci_unmap_mmio;
|
|
|
|
pci_set_drvdata(dev, bus);
|
|
|
|
out:
|
|
return err;
|
|
|
|
err_pci_unmap_mmio:
|
|
pci_iounmap(dev, bus->mmio);
|
|
err_pci_release_regions:
|
|
pci_release_regions(dev);
|
|
err_pci_disable:
|
|
pci_disable_device(dev);
|
|
err_kfree_bus:
|
|
kfree(bus);
|
|
return err;
|
|
}
|
|
|
|
static void bcma_host_pci_remove(struct pci_dev *dev)
|
|
{
|
|
struct bcma_bus *bus = pci_get_drvdata(dev);
|
|
|
|
bcma_bus_unregister(bus);
|
|
pci_iounmap(dev, bus->mmio);
|
|
pci_release_regions(dev);
|
|
pci_disable_device(dev);
|
|
kfree(bus);
|
|
pci_set_drvdata(dev, NULL);
|
|
}
|
|
|
|
static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
|
|
{ 0, },
|
|
};
|
|
MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
|
|
|
|
static struct pci_driver bcma_pci_bridge_driver = {
|
|
.name = "bcma-pci-bridge",
|
|
.id_table = bcma_pci_bridge_tbl,
|
|
.probe = bcma_host_pci_probe,
|
|
.remove = bcma_host_pci_remove,
|
|
};
|
|
|
|
int __init bcma_host_pci_init(void)
|
|
{
|
|
return pci_register_driver(&bcma_pci_bridge_driver);
|
|
}
|
|
|
|
void __exit bcma_host_pci_exit(void)
|
|
{
|
|
pci_unregister_driver(&bcma_pci_bridge_driver);
|
|
}
|