diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-01-22 05:23:15 +0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-01-22 05:23:15 +0400 |
commit | 19c22c34dcbecb50c24548aa2ff2b07039c26c14 (patch) | |
tree | 15793721700c05310952fede97a2585ca1959709 /drivers/bcma | |
parent | 9e5e3097a3febbf317abc6d1b07bc6c33b20c279 (diff) | |
parent | dcd6c92267155e70a94b3927bce681ce74b80d1f (diff) | |
download | linux-19c22c34dcbecb50c24548aa2ff2b07039c26c14.tar.xz |
Merge tag 'v3.3-rc1' into staging/for_v3.3
* tag 'v3.3-rc1': (8187 commits)
Linux 3.3-rc1
x86, syscall: Need __ARCH_WANT_SYS_IPC for 32 bits
qnx4: don't leak ->BitMap on late failure exits
qnx4: reduce the insane nesting in qnx4_checkroot()
qnx4: di_fname is an array, for crying out loud...
KEYS: Permit key_serial() to be called with a const key pointer
keys: fix user_defined key sparse messages
ima: fix cred sparse warning
uml: fix compile for x86-64
MPILIB: Add a missing ENOMEM check
tpm: fix (ACPI S3) suspend regression
nvme: fix merge error due to change of 'make_request_fn' fn type
xen: using EXPORT_SYMBOL requires including export.h
gpio: tps65910: Use correct offset for gpio initialization
acpi/apei/einj: Add extensions to EINJ from rev 5.0 of acpi spec
intel_idle: Split up and provide per CPU initialization func
ACPI processor: Remove unneeded variable passed by acpi_processor_hotadd_init V2
tg3: Fix single-vector MSI-X code
openvswitch: Fix multipart datapath dumps.
ipv6: fix per device IP snmp counters
...
Diffstat (limited to 'drivers/bcma')
-rw-r--r-- | drivers/bcma/bcma_private.h | 4 | ||||
-rw-r--r-- | drivers/bcma/host_pci.c | 62 | ||||
-rw-r--r-- | drivers/bcma/main.c | 40 | ||||
-rw-r--r-- | drivers/bcma/sprom.c | 61 |
4 files changed, 156 insertions, 11 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 30a3085d3354..0def898a1d15 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h @@ -18,6 +18,10 @@ void bcma_bus_unregister(struct bcma_bus *bus); int __init bcma_bus_early_register(struct bcma_bus *bus, struct bcma_device *core_cc, struct bcma_device *core_mips); +#ifdef CONFIG_PM +int bcma_bus_suspend(struct bcma_bus *bus); +int bcma_bus_resume(struct bcma_bus *bus); +#endif /* scan.c */ int bcma_bus_scan(struct bcma_bus *bus); diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 1b51d8b7ac80..f59244e33971 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -21,48 +21,58 @@ static void bcma_host_pci_switch_core(struct bcma_device *core) pr_debug("Switched to core: 0x%X\n", core->id.id); } -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset) +/* Provides access to the requested core. Returns base offset that has to be + * used. It makes use of fixed windows when possible. */ +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core) { + switch (core->id.id) { + case BCMA_CORE_CHIPCOMMON: + return 3 * BCMA_CORE_SIZE; + case BCMA_CORE_PCIE: + return 2 * BCMA_CORE_SIZE; + } + if (core->bus->mapped_core != core) bcma_host_pci_switch_core(core); + return 0; +} + +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset) +{ + offset += bcma_host_pci_provide_access_to_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); + offset += bcma_host_pci_provide_access_to_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); + offset += bcma_host_pci_provide_access_to_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); + offset += bcma_host_pci_provide_access_to_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); + offset += bcma_host_pci_provide_access_to_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); + offset += bcma_host_pci_provide_access_to_core(core); iowrite32(value, core->bus->mmio + offset); } @@ -224,6 +234,35 @@ static void bcma_host_pci_remove(struct pci_dev *dev) pci_set_drvdata(dev, NULL); } +#ifdef CONFIG_PM +static int bcma_host_pci_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct bcma_bus *bus = pci_get_drvdata(pdev); + + bus->mapped_core = NULL; + + return bcma_bus_suspend(bus); +} + +static int bcma_host_pci_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct bcma_bus *bus = pci_get_drvdata(pdev); + + return bcma_bus_resume(bus); +} + +static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend, + bcma_host_pci_resume); +#define BCMA_PM_OPS (&bcma_pm_ops) + +#else /* CONFIG_PM */ + +#define BCMA_PM_OPS NULL + +#endif /* CONFIG_PM */ + static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, @@ -239,6 +278,7 @@ static struct pci_driver bcma_pci_bridge_driver = { .id_table = bcma_pci_bridge_tbl, .probe = bcma_host_pci_probe, .remove = bcma_host_pci_remove, + .driver.pm = BCMA_PM_OPS, }; int __init bcma_host_pci_init(void) diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 70c84b951098..febbc0a1222a 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -240,6 +240,46 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, return 0; } +#ifdef CONFIG_PM +int bcma_bus_suspend(struct bcma_bus *bus) +{ + struct bcma_device *core; + + list_for_each_entry(core, &bus->cores, list) { + struct device_driver *drv = core->dev.driver; + if (drv) { + struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv); + if (adrv->suspend) + adrv->suspend(core); + } + } + return 0; +} + +int bcma_bus_resume(struct bcma_bus *bus) +{ + struct bcma_device *core; + + /* Init CC core */ + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON); + if (core) { + bus->drv_cc.setup_done = false; + bcma_core_chipcommon_init(&bus->drv_cc); + } + + list_for_each_entry(core, &bus->cores, list) { + struct device_driver *drv = core->dev.driver; + if (drv) { + struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv); + if (adrv->resume) + adrv->resume(core); + } + } + + return 0; +} +#endif + int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) { drv->drv.name = drv->name; diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index d7292390d236..6f230fb087c5 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -129,6 +129,9 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) u16 v; int i; + bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & + SSB_SPROM_REVISION_REV; + for (i = 0; i < 3; i++) { v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i]; *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); @@ -136,12 +139,70 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)]; + bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & + SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT; + bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & + SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT; + bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & + SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT; + bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & + SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT; + + bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & + SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT; + bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & + SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT; + bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & + SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT; + bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & + SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT; + + bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & + SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT; + bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & + SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT; + bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & + SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT; + bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & + SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT; + + bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & + SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT; + bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & + SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT; + bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & + SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT; + bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & + SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT; + bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)]; bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)]; bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)]; bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)]; bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)]; + + bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & + SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; + bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & + SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; + bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & + SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; + bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & + SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; + bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & + SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; + + bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & + SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; + bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & + SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; + bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & + SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; + bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & + SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; + bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & + SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; } int bcma_sprom_get(struct bcma_bus *bus) |