^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // clk-s2mps11.c - Clock driver for S2MPS11.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (C) 2013,2014 Samsung Electornics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mfd/samsung/s2mps11.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mfd/samsung/s2mps13.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mfd/samsung/s2mps14.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mfd/samsung/s5m8767.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mfd/samsung/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <dt-bindings/clock/samsung,s2mps11.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct s2mps11_clk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct sec_pmic_dev *iodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct device_node *clk_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct clk_lookup *lookup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static struct s2mps11_clk *to_s2mps11_clk(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return container_of(hw, struct s2mps11_clk, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int s2mps11_clk_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return regmap_update_bits(s2mps11->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) s2mps11->reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) s2mps11->mask, s2mps11->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static void s2mps11_clk_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) regmap_update_bits(s2mps11->iodev->regmap_pmic, s2mps11->reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) s2mps11->mask, ~s2mps11->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int s2mps11_clk_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ret = regmap_read(s2mps11->iodev->regmap_pmic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) s2mps11->reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return val & s2mps11->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static unsigned long s2mps11_clk_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return 32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static const struct clk_ops s2mps11_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .prepare = s2mps11_clk_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .unprepare = s2mps11_clk_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .is_prepared = s2mps11_clk_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .recalc_rate = s2mps11_clk_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* This s2mps11_clks_init tructure is common to s2mps11, s2mps13 and s2mps14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) [S2MPS11_CLK_AP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .name = "s2mps11_ap",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .ops = &s2mps11_clk_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) [S2MPS11_CLK_CP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .name = "s2mps11_cp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .ops = &s2mps11_clk_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) [S2MPS11_CLK_BT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .name = "s2mps11_bt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .ops = &s2mps11_clk_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct clk_init_data *clks_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct device_node *clk_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!iodev->dev->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) clk_np = of_get_child_by_name(iodev->dev->of_node, "clocks");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!clk_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) dev_err(&pdev->dev, "could not find clock sub-node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) for (i = 0; i < S2MPS11_CLKS_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) of_property_read_string_index(clk_np, "clock-output-names", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) &clks_init[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return clk_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int s2mps11_clk_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct s2mps11_clk *s2mps11_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct clk_hw_onecell_data *clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int s2mps11_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) enum sec_device_type hwid = platform_get_device_id(pdev)->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) s2mps11_clks = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) sizeof(*s2mps11_clks), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (!s2mps11_clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) clk_data = devm_kzalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct_size(clk_data, hws, S2MPS11_CLKS_NUM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (!clk_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) switch (hwid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case S2MPS11X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) s2mps11_reg = S2MPS11_REG_RTC_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case S2MPS13X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) s2mps11_reg = S2MPS13_REG_RTCCTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case S2MPS14X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) s2mps11_reg = S2MPS14_REG_RTCCTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case S5M8767X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) s2mps11_reg = S5M8767_REG_CTRL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) dev_err(&pdev->dev, "Invalid device type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Store clocks of_node in first element of s2mps11_clks array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, s2mps11_clks_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (IS_ERR(s2mps11_clks->clk_np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return PTR_ERR(s2mps11_clks->clk_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) for (i = 0; i < S2MPS11_CLKS_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (i == S2MPS11_CLK_CP && hwid == S2MPS14X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) continue; /* Skip clocks not present in some devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) s2mps11_clks[i].iodev = iodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) s2mps11_clks[i].hw.init = &s2mps11_clks_init[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) s2mps11_clks[i].mask = 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) s2mps11_clks[i].reg = s2mps11_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) s2mps11_clks[i].clk = devm_clk_register(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) &s2mps11_clks[i].hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (IS_ERR(s2mps11_clks[i].clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dev_err(&pdev->dev, "Fail to register : %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) s2mps11_clks_init[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret = PTR_ERR(s2mps11_clks[i].clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) goto err_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) s2mps11_clks[i].lookup = clkdev_hw_create(&s2mps11_clks[i].hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) s2mps11_clks_init[i].name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (!s2mps11_clks[i].lookup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) goto err_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) clk_data->hws[i] = &s2mps11_clks[i].hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) clk_data->num = S2MPS11_CLKS_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) of_clk_add_hw_provider(s2mps11_clks->clk_np, of_clk_hw_onecell_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) platform_set_drvdata(pdev, s2mps11_clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) err_reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) of_node_put(s2mps11_clks[0].clk_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) while (--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) clkdev_drop(s2mps11_clks[i].lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int s2mps11_clk_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct s2mps11_clk *s2mps11_clks = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) of_clk_del_provider(s2mps11_clks[0].clk_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Drop the reference obtained in s2mps11_clk_parse_dt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) of_node_put(s2mps11_clks[0].clk_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) for (i = 0; i < S2MPS11_CLKS_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Skip clocks not present on S2MPS14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!s2mps11_clks[i].lookup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) clkdev_drop(s2mps11_clks[i].lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static const struct platform_device_id s2mps11_clk_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { "s2mps11-clk", S2MPS11X},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) { "s2mps13-clk", S2MPS13X},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) { "s2mps14-clk", S2MPS14X},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) { "s5m8767-clk", S5M8767X},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) MODULE_DEVICE_TABLE(platform, s2mps11_clk_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * Device is instantiated through parent MFD device and device matching is done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * through platform_device_id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * However if device's DT node contains proper clock compatible and driver is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * built as a module, then the *module* matching will be done trough DT aliases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * This requires of_device_id table. In the same time this will not change the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * actual *device* matching so do not add .of_match_table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static const struct of_device_id s2mps11_dt_match[] __used = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .compatible = "samsung,s2mps11-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .data = (void *)S2MPS11X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .compatible = "samsung,s2mps13-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .data = (void *)S2MPS13X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .compatible = "samsung,s2mps14-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .data = (void *)S2MPS14X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .compatible = "samsung,s5m8767-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .data = (void *)S5M8767X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) MODULE_DEVICE_TABLE(of, s2mps11_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static struct platform_driver s2mps11_clk_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .name = "s2mps11-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .probe = s2mps11_clk_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .remove = s2mps11_clk_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .id_table = s2mps11_clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) module_platform_driver(s2mps11_clk_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) MODULE_DESCRIPTION("S2MPS11 Clock Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) MODULE_AUTHOR("Yadwinder Singh Brar <yadi.brar@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) MODULE_LICENSE("GPL");