drivers/ssb/driver_chipcommon.c
Source file repositories/reference/linux-study-clean/drivers/ssb/driver_chipcommon.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/ssb/driver_chipcommon.c- Extension
.c- Size
- 18154 bytes
- Lines
- 698
- Domain
- Driver Families
- Bucket
- drivers/ssb
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
ssb_private.hlinux/ssb/ssb.hlinux/ssb/ssb_regs.hlinux/export.hlinux/pci.hlinux/bcm47xx_wdt.h
Detected Declarations
enum ssb_clksrcfunction chipco_write32_maskedfunction ssb_chipco_set_clockmodefunction chipco_pctl_get_slowclksrcfunction chipco_pctl_clockfreqlimitfunction chipco_powercontrol_initfunction pmu_fast_powerup_delayfunction calc_fast_powerup_delayfunction ssb_chipco_alp_clockfunction ssb_chipco_watchdog_get_max_timerfunction ssb_chipco_watchdog_timer_set_wdtfunction ssb_chipco_watchdog_timer_set_msfunction ssb_chipco_watchdog_ticks_per_msfunction ssb_chipcommon_initfunction ssb_chipco_suspendfunction ssb_chipco_resumefunction ssb_chipco_get_clockcpufunction ssb_chipco_get_clockcontrolfunction ssb_chipco_timing_initfunction ssb_chipco_watchdog_timer_setfunction ssb_chipco_irq_maskfunction ssb_chipco_irq_statusfunction ssb_chipco_gpio_infunction ssb_chipco_gpio_outfunction ssb_chipco_gpio_outenfunction ssb_chipco_gpio_controlfunction ssb_chipco_gpio_intmaskfunction ssb_chipco_gpio_polarityfunction ssb_chipco_gpio_pullupfunction ssb_chipco_gpio_pulldownfunction ssb_chipco_serial_initexport ssb_chipco_gpio_control
Annotated Snippet
if (ccdev->id.revision < 10) {
ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
} else {
chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
(chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |
SSB_CHIPCO_SYSCLKCTL_FORCEHT));
/* udelay(150); TODO: not available in early init */
}
break;
case SSB_CLKMODE_DYNAMIC:
if (ccdev->id.revision < 10) {
tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=
SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
/* For dynamic control, we have to release our xtal_pu
* "force on" */
if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
} else {
chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
(chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
~SSB_CHIPCO_SYSCLKCTL_FORCEHT));
}
break;
default:
WARN_ON(1);
}
}
/* Get the Slow Clock Source */
static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc)
{
struct ssb_bus *bus = cc->dev->bus;
u32 tmp;
if (cc->dev->id.revision < 6) {
if (bus->bustype == SSB_BUSTYPE_SSB ||
bus->bustype == SSB_BUSTYPE_PCMCIA)
return SSB_CHIPCO_CLKSRC_XTALOS;
if (bus->bustype == SSB_BUSTYPE_PCI) {
pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &tmp);
if (tmp & 0x10)
return SSB_CHIPCO_CLKSRC_PCI;
return SSB_CHIPCO_CLKSRC_XTALOS;
}
}
if (cc->dev->id.revision < 10) {
tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
tmp &= 0x7;
if (tmp == 0)
return SSB_CHIPCO_CLKSRC_LOPWROS;
if (tmp == 1)
return SSB_CHIPCO_CLKSRC_XTALOS;
if (tmp == 2)
return SSB_CHIPCO_CLKSRC_PCI;
}
return SSB_CHIPCO_CLKSRC_XTALOS;
}
/* Get maximum or minimum (depending on get_max flag) slowclock frequency. */
static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max)
{
int limit;
enum ssb_clksrc clocksrc;
int divisor = 1;
u32 tmp;
clocksrc = chipco_pctl_get_slowclksrc(cc);
if (cc->dev->id.revision < 6) {
switch (clocksrc) {
case SSB_CHIPCO_CLKSRC_PCI:
divisor = 64;
break;
case SSB_CHIPCO_CLKSRC_XTALOS:
divisor = 32;
break;
default:
WARN_ON(1);
}
Annotation
- Immediate include surface: `ssb_private.h`, `linux/ssb/ssb.h`, `linux/ssb/ssb_regs.h`, `linux/export.h`, `linux/pci.h`, `linux/bcm47xx_wdt.h`.
- Detected declarations: `enum ssb_clksrc`, `function chipco_write32_masked`, `function ssb_chipco_set_clockmode`, `function chipco_pctl_get_slowclksrc`, `function chipco_pctl_clockfreqlimit`, `function chipco_powercontrol_init`, `function pmu_fast_powerup_delay`, `function calc_fast_powerup_delay`, `function ssb_chipco_alp_clock`, `function ssb_chipco_watchdog_get_max_timer`.
- Atlas domain: Driver Families / drivers/ssb.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.