drivers/clk/davinci/psc.c
Source file repositories/reference/linux-study-clean/drivers/clk/davinci/psc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/davinci/psc.c- Extension
.c- Size
- 13907 bytes
- Lines
- 557
- Domain
- Driver Families
- Bucket
- drivers/clk
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk-provider.hlinux/clk.hlinux/clk/davinci.hlinux/clkdev.hlinux/err.hlinux/of.hlinux/platform_device.hlinux/property.hlinux/pm_clock.hlinux/pm_domain.hlinux/regmap.hlinux/reset-controller.hlinux/slab.hlinux/types.hpsc.h
Detected Declarations
struct davinci_psc_datastruct davinci_lpsc_clkenum davinci_lpsc_statefunction dev_namefunction davinci_lpsc_configfunction davinci_lpsc_clk_enablefunction davinci_lpsc_clk_disablefunction davinci_lpsc_clk_is_enabledfunction davinci_psc_genpd_attach_devfunction davinci_psc_genpd_detach_devfunction davinci_lpsc_clk_registerfunction davinci_lpsc_clk_resetfunction davinci_psc_reset_assertfunction davinci_psc_reset_deassertfunction davinci_psc_reset_of_xlatefunction __davinci_psc_register_clocksfunction davinci_psc_register_clocksfunction of_davinci_psc_clk_initfunction davinci_psc_probefunction davinci_psc_driver_init
Annotated Snippet
struct davinci_psc_data {
struct clk_onecell_data clk_data;
struct genpd_onecell_data pm_data;
struct reset_controller_dev rcdev;
};
/**
* struct davinci_lpsc_clk - LPSC clock structure
* @dev: the device that provides this LPSC or NULL
* @hw: clk_hw for the LPSC
* @pm_domain: power domain for the LPSC
* @genpd_clk: clock reference owned by @pm_domain
* @regmap: PSC MMIO region
* @md: Module domain (LPSC module id)
* @pd: Power domain
* @flags: LPSC_* quirk flags
*/
struct davinci_lpsc_clk {
struct device *dev;
struct clk_hw hw;
struct generic_pm_domain pm_domain;
struct clk *genpd_clk;
struct regmap *regmap;
u32 md;
u32 pd;
u32 flags;
};
#define to_davinci_psc_data(x) container_of(x, struct davinci_psc_data, x)
#define to_davinci_lpsc_clk(x) container_of(x, struct davinci_lpsc_clk, x)
/**
* best_dev_name - get the "best" device name.
* @dev: the device
*
* Returns the device tree compatible name if the device has a DT node,
* otherwise return the device name. This is mainly needed because clkdev
* lookups are limited to 20 chars for dev_id and when using device tree,
* dev_name(dev) is much longer than that.
*/
static inline const char *best_dev_name(struct device *dev)
{
const char *compatible;
if (!of_property_read_string(dev->of_node, "compatible", &compatible))
return compatible;
return dev_name(dev);
}
static void davinci_lpsc_config(struct davinci_lpsc_clk *lpsc,
enum davinci_lpsc_state next_state)
{
u32 epcpr, pdstat, mdstat, ptstat;
regmap_write_bits(lpsc->regmap, MDCTL(lpsc->md), MDSTAT_STATE_MASK,
next_state);
if (lpsc->flags & LPSC_FORCE)
regmap_write_bits(lpsc->regmap, MDCTL(lpsc->md), MDCTL_FORCE,
MDCTL_FORCE);
regmap_read(lpsc->regmap, PDSTAT(lpsc->pd), &pdstat);
if ((pdstat & PDSTAT_STATE_MASK) == 0) {
regmap_write_bits(lpsc->regmap, PDCTL(lpsc->pd), PDCTL_NEXT,
PDCTL_NEXT);
regmap_write(lpsc->regmap, PTCMD, BIT(lpsc->pd));
regmap_read_poll_timeout(lpsc->regmap, EPCPR, epcpr,
epcpr & BIT(lpsc->pd), 0, 0);
regmap_write_bits(lpsc->regmap, PDCTL(lpsc->pd), PDCTL_EPCGOOD,
PDCTL_EPCGOOD);
} else {
regmap_write(lpsc->regmap, PTCMD, BIT(lpsc->pd));
}
regmap_read_poll_timeout(lpsc->regmap, PTSTAT, ptstat,
!(ptstat & BIT(lpsc->pd)), 0, 0);
regmap_read_poll_timeout(lpsc->regmap, MDSTAT(lpsc->md), mdstat,
(mdstat & MDSTAT_STATE_MASK) == next_state,
0, 0);
}
static int davinci_lpsc_clk_enable(struct clk_hw *hw)
{
struct davinci_lpsc_clk *lpsc = to_davinci_lpsc_clk(hw);
Annotation
- Immediate include surface: `linux/clk-provider.h`, `linux/clk.h`, `linux/clk/davinci.h`, `linux/clkdev.h`, `linux/err.h`, `linux/of.h`, `linux/platform_device.h`, `linux/property.h`.
- Detected declarations: `struct davinci_psc_data`, `struct davinci_lpsc_clk`, `enum davinci_lpsc_state`, `function dev_name`, `function davinci_lpsc_config`, `function davinci_lpsc_clk_enable`, `function davinci_lpsc_clk_disable`, `function davinci_lpsc_clk_is_enabled`, `function davinci_psc_genpd_attach_dev`, `function davinci_psc_genpd_detach_dev`.
- Atlas domain: Driver Families / drivers/clk.
- Implementation status: integration implementation candidate.
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.