Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: bd718x7: Initial support for ROHM bd71837/bd71847 PMIC clock

ROHM bd71837 and bd71847 contain 32768Hz clock gate. Support the clock
using generic clock framework. Note, only bd71837 is tested but bd71847
should be identical what comes to clk parts.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Matti Vaittinen and committed by
Stephen Boyd
2e62246b 7265c3cb

+131
+7
drivers/clk/Kconfig
··· 283 283 ---help--- 284 284 Support for stm32h7 SoC family clocks 285 285 286 + config COMMON_CLK_BD718XX 287 + tristate "Clock driver for ROHM BD718x7 PMIC" 288 + depends on MFD_ROHM_BD718XX 289 + help 290 + This driver supports ROHM BD71837 and ROHM BD71847 291 + PMICs clock gates. 292 + 286 293 source "drivers/clk/actions/Kconfig" 287 294 source "drivers/clk/bcm/Kconfig" 288 295 source "drivers/clk/hisilicon/Kconfig"
+1
drivers/clk/Makefile
··· 21 21 obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o 22 22 obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o 23 23 obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o 24 + obj-$(CONFIG_COMMON_CLK_BD718XX) += clk-bd718x7.o 24 25 obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o 25 26 obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o 26 27 obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
+123
drivers/clk/clk-bd718x7.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (C) 2018 ROHM Semiconductors 3 + 4 + #include <linux/kernel.h> 5 + #include <linux/module.h> 6 + #include <linux/init.h> 7 + #include <linux/err.h> 8 + #include <linux/platform_device.h> 9 + #include <linux/slab.h> 10 + #include <linux/mfd/rohm-bd718x7.h> 11 + #include <linux/clk-provider.h> 12 + #include <linux/clkdev.h> 13 + #include <linux/regmap.h> 14 + 15 + struct bd718xx_clk { 16 + struct clk_hw hw; 17 + u8 reg; 18 + u8 mask; 19 + struct platform_device *pdev; 20 + struct bd718xx *mfd; 21 + }; 22 + 23 + static int bd71837_clk_set(struct clk_hw *hw, int status) 24 + { 25 + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); 26 + 27 + return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status); 28 + } 29 + 30 + static void bd71837_clk_disable(struct clk_hw *hw) 31 + { 32 + int rv; 33 + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); 34 + 35 + rv = bd71837_clk_set(hw, 0); 36 + if (rv) 37 + dev_dbg(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv); 38 + } 39 + 40 + static int bd71837_clk_enable(struct clk_hw *hw) 41 + { 42 + return bd71837_clk_set(hw, 1); 43 + } 44 + 45 + static int bd71837_clk_is_enabled(struct clk_hw *hw) 46 + { 47 + int enabled; 48 + int rval; 49 + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); 50 + 51 + rval = regmap_read(c->mfd->regmap, c->reg, &enabled); 52 + 53 + if (rval) 54 + return rval; 55 + 56 + return enabled & c->mask; 57 + } 58 + 59 + static const struct clk_ops bd71837_clk_ops = { 60 + .prepare = &bd71837_clk_enable, 61 + .unprepare = &bd71837_clk_disable, 62 + .is_prepared = &bd71837_clk_is_enabled, 63 + }; 64 + 65 + static int bd71837_clk_probe(struct platform_device *pdev) 66 + { 67 + struct bd718xx_clk *c; 68 + int rval = -ENOMEM; 69 + const char *parent_clk; 70 + struct device *parent = pdev->dev.parent; 71 + struct bd718xx *mfd = dev_get_drvdata(parent); 72 + struct clk_init_data init = { 73 + .name = "bd718xx-32k-out", 74 + .ops = &bd71837_clk_ops, 75 + }; 76 + 77 + c = devm_kzalloc(&pdev->dev, sizeof(*c), GFP_KERNEL); 78 + if (!c) 79 + return -ENOMEM; 80 + 81 + init.num_parents = 1; 82 + parent_clk = of_clk_get_parent_name(parent->of_node, 0); 83 + 84 + init.parent_names = &parent_clk; 85 + if (!parent_clk) { 86 + dev_err(&pdev->dev, "No parent clk found\n"); 87 + return -EINVAL; 88 + } 89 + 90 + c->reg = BD718XX_REG_OUT32K; 91 + c->mask = BD718XX_OUT32K_EN; 92 + c->mfd = mfd; 93 + c->pdev = pdev; 94 + c->hw.init = &init; 95 + 96 + of_property_read_string_index(parent->of_node, 97 + "clock-output-names", 0, &init.name); 98 + 99 + rval = devm_clk_hw_register(&pdev->dev, &c->hw); 100 + if (rval) { 101 + dev_err(&pdev->dev, "failed to register 32K clk"); 102 + return rval; 103 + } 104 + rval = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get, 105 + &c->hw); 106 + if (rval) 107 + dev_err(&pdev->dev, "adding clk provider failed\n"); 108 + 109 + return rval; 110 + } 111 + 112 + static struct platform_driver bd71837_clk = { 113 + .driver = { 114 + .name = "bd718xx-clk", 115 + }, 116 + .probe = bd71837_clk_probe, 117 + }; 118 + 119 + module_platform_driver(bd71837_clk); 120 + 121 + MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 122 + MODULE_DESCRIPTION("BD71837 chip clk driver"); 123 + MODULE_LICENSE("GPL");