drivers/pwm/pwm-loongson.c
Source file repositories/reference/linux-study-clean/drivers/pwm/pwm-loongson.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pwm/pwm-loongson.c- Extension
.c- Size
- 8635 bytes
- Lines
- 291
- Domain
- Driver Families
- Bucket
- drivers/pwm
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/acpi.hlinux/clk.hlinux/device.hlinux/init.hlinux/io.hlinux/kernel.hlinux/module.hlinux/platform_device.hlinux/pwm.hlinux/units.h
Detected Declarations
struct pwm_loongson_ddatafunction pwm_loongson_readlfunction pwm_loongson_writelfunction pwm_loongson_set_polarityfunction pwm_loongson_disablefunction pwm_loongson_enablefunction pwm_loongson_configfunction pwm_loongson_applyfunction pwm_loongson_get_statefunction pwm_loongson_probefunction pwm_loongson_suspendfunction pwm_loongson_resume
Annotated Snippet
struct pwm_loongson_ddata {
struct clk *clk;
void __iomem *base;
u64 clk_rate;
};
static inline __pure struct pwm_loongson_ddata *to_pwm_loongson_ddata(struct pwm_chip *chip)
{
return pwmchip_get_drvdata(chip);
}
static inline u32 pwm_loongson_readl(struct pwm_loongson_ddata *ddata, u32 offset)
{
return readl(ddata->base + offset);
}
static inline void pwm_loongson_writel(struct pwm_loongson_ddata *ddata,
u32 val, u32 offset)
{
writel(val, ddata->base + offset);
}
static int pwm_loongson_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
enum pwm_polarity polarity)
{
u16 val;
struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL);
if (polarity == PWM_POLARITY_INVERSED)
/* Duty cycle defines LOW period of PWM */
val |= LOONGSON_PWM_CTRL_REG_INVERT;
else
/* Duty cycle defines HIGH period of PWM */
val &= ~LOONGSON_PWM_CTRL_REG_INVERT;
pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL);
return 0;
}
static void pwm_loongson_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
u32 val;
struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL);
val &= ~LOONGSON_PWM_CTRL_REG_EN;
pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL);
}
static int pwm_loongson_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
u32 val;
struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL);
val |= LOONGSON_PWM_CTRL_REG_EN;
pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL);
return 0;
}
static int pwm_loongson_config(struct pwm_chip *chip, struct pwm_device *pwm,
u64 duty_ns, u64 period_ns)
{
u64 duty, period;
struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
/* duty = duty_ns * ddata->clk_rate / NSEC_PER_SEC */
duty = mul_u64_u64_div_u64(duty_ns, ddata->clk_rate, NSEC_PER_SEC);
if (duty > U32_MAX)
duty = U32_MAX;
/* period = period_ns * ddata->clk_rate / NSEC_PER_SEC */
period = mul_u64_u64_div_u64(period_ns, ddata->clk_rate, NSEC_PER_SEC);
if (period > U32_MAX)
period = U32_MAX;
pwm_loongson_writel(ddata, duty, LOONGSON_PWM_REG_DUTY);
pwm_loongson_writel(ddata, period, LOONGSON_PWM_REG_PERIOD);
return 0;
}
static int pwm_loongson_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
int ret;
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/clk.h`, `linux/device.h`, `linux/init.h`, `linux/io.h`, `linux/kernel.h`, `linux/module.h`, `linux/platform_device.h`.
- Detected declarations: `struct pwm_loongson_ddata`, `function pwm_loongson_readl`, `function pwm_loongson_writel`, `function pwm_loongson_set_polarity`, `function pwm_loongson_disable`, `function pwm_loongson_enable`, `function pwm_loongson_config`, `function pwm_loongson_apply`, `function pwm_loongson_get_state`, `function pwm_loongson_probe`.
- Atlas domain: Driver Families / drivers/pwm.
- Implementation status: source 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.