drivers/clk/clk-bd718x7.c

Source file repositories/reference/linux-study-clean/drivers/clk/clk-bd718x7.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-bd718x7.c
Extension
.c
Size
4175 bytes
Lines
173
Domain
Driver Families
Bucket
drivers/clk
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct bd718xx_clk {
	struct clk_hw hw;
	u8 reg;
	u8 mask;
	struct platform_device *pdev;
	struct regmap *regmap;
};

static int bd71837_clk_set(struct bd718xx_clk *c, unsigned int status)
{
	return regmap_update_bits(c->regmap, c->reg, c->mask, status);
}

static void bd71837_clk_disable(struct clk_hw *hw)
{
	int rv;
	struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);

	rv = bd71837_clk_set(c, 0);
	if (rv)
		dev_dbg(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv);
}

static int bd71837_clk_enable(struct clk_hw *hw)
{
	struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);

	return bd71837_clk_set(c, 0xffffffff);
}

static int bd71837_clk_is_enabled(struct clk_hw *hw)
{
	int enabled;
	int rval;
	struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);

	rval = regmap_read(c->regmap, c->reg, &enabled);

	if (rval)
		return rval;

	return enabled & c->mask;
}

static const struct clk_ops bd71837_clk_ops = {
	.prepare = &bd71837_clk_enable,
	.unprepare = &bd71837_clk_disable,
	.is_prepared = &bd71837_clk_is_enabled,
};

static int bd71837_clk_probe(struct platform_device *pdev)
{
	struct bd718xx_clk *c;
	int rval = -ENOMEM;
	const char *parent_clk;
	struct device *parent = pdev->dev.parent;
	struct clk_init_data init = {
		.name = "bd718xx-32k-out",
		.ops = &bd71837_clk_ops,
	};
	enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;

	c = devm_kzalloc(&pdev->dev, sizeof(*c), GFP_KERNEL);
	if (!c)
		return -ENOMEM;

	c->regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!c->regmap)
		return -ENODEV;

	init.num_parents = 1;
	parent_clk = of_clk_get_parent_name(parent->of_node, 0);

	init.parent_names = &parent_clk;
	if (!parent_clk) {
		dev_err(&pdev->dev, "No parent clk found\n");
		return -EINVAL;
	}
	switch (chip) {
	case ROHM_CHIP_TYPE_BD71837:
	case ROHM_CHIP_TYPE_BD71847:
		c->reg = BD718XX_REG_OUT32K;
		c->mask = CLK_OUT_EN_MASK;
		break;
	case ROHM_CHIP_TYPE_BD71828:
		c->reg = BD71828_REG_OUT32K;
		c->mask = CLK_OUT_EN_MASK;
		break;
	case ROHM_CHIP_TYPE_BD71815:
		c->reg = BD71815_REG_OUT32K;

Annotation

Implementation Notes