17cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar/* 27cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * clk-s2mps11.c - Clock driver for S2MPS11. 37cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * 4e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski * Copyright (C) 2013,2014 Samsung Electornics 57cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * 67cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * This program is free software; you can redistribute it and/or modify it 77cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * under the terms of the GNU General Public License as published by the 87cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * Free Software Foundation; either version 2 of the License, or (at your 97cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * option) any later version. 107cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * 117cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * This program is distributed in the hope that it will be useful, 127cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * but WITHOUT ANY WARRANTY; without even the implied warranty of 137cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 147cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * GNU General Public License for more details. 157cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar * 167cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar */ 177cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 187cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#include <linux/module.h> 197cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#include <linux/err.h> 207cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#include <linux/of.h> 217cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#include <linux/clkdev.h> 227cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#include <linux/regmap.h> 237cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#include <linux/clk-provider.h> 247cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#include <linux/platform_device.h> 257cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#include <linux/mfd/samsung/s2mps11.h> 26e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski#include <linux/mfd/samsung/s2mps14.h> 27e8e6b840c4b646ce5aaef27875a22251ebc4e0d6Tushar Behera#include <linux/mfd/samsung/s5m8767.h> 287cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#include <linux/mfd/samsung/core.h> 297cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 307cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar#define s2mps11_name(a) (a->hw.init->name) 317cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 327cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic struct clk **clk_table; 337cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic struct clk_onecell_data clk_data; 347cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 357cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarenum { 367cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar S2MPS11_CLK_AP = 0, 377cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar S2MPS11_CLK_CP, 387cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar S2MPS11_CLK_BT, 397cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar S2MPS11_CLKS_NUM, 407cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar}; 417cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 427cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstruct s2mps11_clk { 437cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct sec_pmic_dev *iodev; 44bf416bd457389bfe7371ba9074bcbd032d7a04ccKrzysztof Kozlowski struct device_node *clk_np; 457cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct clk_hw hw; 467cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct clk *clk; 477cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct clk_lookup *lookup; 487cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar u32 mask; 4964d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera unsigned int reg; 507cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar}; 517cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 527cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic struct s2mps11_clk *to_s2mps11_clk(struct clk_hw *hw) 537cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 547cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar return container_of(hw, struct s2mps11_clk, hw); 557cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 567cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 577cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic int s2mps11_clk_prepare(struct clk_hw *hw) 587cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 597cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw); 607cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar int ret; 617cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 621b1ccee1e821e59c2a45c95b007aeb2c9dafd9beKrzysztof Kozlowski ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, 6364d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera s2mps11->reg, 647cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar s2mps11->mask, s2mps11->mask); 657cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 667cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar return ret; 677cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 687cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 697cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic void s2mps11_clk_unprepare(struct clk_hw *hw) 707cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 717cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw); 727cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar int ret; 737cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 7464d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, s2mps11->reg, 757cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar s2mps11->mask, ~s2mps11->mask); 767cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 777cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 7889ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wronastatic int s2mps11_clk_is_prepared(struct clk_hw *hw) 797cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 8089ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona int ret; 8189ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona u32 val; 827cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw); 837cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 8489ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona ret = regmap_read(s2mps11->iodev->regmap_pmic, 8589ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona s2mps11->reg, &val); 8689ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona if (ret < 0) 8789ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona return -EINVAL; 8889ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona 8989ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona return val & s2mps11->mask; 907cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 917cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 927cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic unsigned long s2mps11_clk_recalc_rate(struct clk_hw *hw, 937cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar unsigned long parent_rate) 947cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 9589ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona return 32768; 967cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 977cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 987cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic struct clk_ops s2mps11_clk_ops = { 997cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .prepare = s2mps11_clk_prepare, 1007cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .unprepare = s2mps11_clk_unprepare, 10189ed7e6e68c176e77c7e2677551c91d4185fe0b4Karol Wrona .is_prepared = s2mps11_clk_is_prepared, 1027cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .recalc_rate = s2mps11_clk_recalc_rate, 1037cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar}; 1047cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 1057cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = { 1067cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar [S2MPS11_CLK_AP] = { 1077cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .name = "s2mps11_ap", 1087cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .ops = &s2mps11_clk_ops, 1097cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .flags = CLK_IS_ROOT, 1107cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar }, 1117cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar [S2MPS11_CLK_CP] = { 1127cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .name = "s2mps11_cp", 1137cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .ops = &s2mps11_clk_ops, 1147cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .flags = CLK_IS_ROOT, 1157cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar }, 1167cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar [S2MPS11_CLK_BT] = { 1177cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .name = "s2mps11_bt", 1187cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .ops = &s2mps11_clk_ops, 1197cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .flags = CLK_IS_ROOT, 1207cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar }, 1217cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar}; 1227cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 123e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowskistatic struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = { 124e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski [S2MPS11_CLK_AP] = { 125e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski .name = "s2mps14_ap", 126e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski .ops = &s2mps11_clk_ops, 127e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski .flags = CLK_IS_ROOT, 128e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski }, 129e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski [S2MPS11_CLK_BT] = { 130e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski .name = "s2mps14_bt", 131e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski .ops = &s2mps11_clk_ops, 132e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski .flags = CLK_IS_ROOT, 133e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski }, 134e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski}; 135e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski 136e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowskistatic struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev, 137e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski struct clk_init_data *clks_init) 1387cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 1397cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); 1407cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct device_node *clk_np; 1417cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar int i; 1427cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 1437cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar if (!iodev->dev->of_node) 144238e14055da87d0d012257788e39fe0df3a82226Krzysztof Kozlowski return ERR_PTR(-EINVAL); 1457cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 146afbd1a0c309e3d5cb581a3f7c879be97855fe72fKrzysztof Kozlowski clk_np = of_get_child_by_name(iodev->dev->of_node, "clocks"); 1477cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar if (!clk_np) { 1487cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar dev_err(&pdev->dev, "could not find clock sub-node\n"); 1497cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar return ERR_PTR(-EINVAL); 1507cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar } 1517cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 152e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski for (i = 0; i < S2MPS11_CLKS_NUM; i++) { 153e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski if (!clks_init[i].name) 154e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski continue; /* Skip clocks not present in some devices */ 1557cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar of_property_read_string_index(clk_np, "clock-output-names", i, 156e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski &clks_init[i].name); 157e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski } 1587cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 1597cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar return clk_np; 1607cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 1617cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 1627cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic int s2mps11_clk_probe(struct platform_device *pdev) 1637cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 1647cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); 1657cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; 16664d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera unsigned int s2mps11_reg; 167e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski struct clk_init_data *clks_init; 1687cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar int i, ret = 0; 1697cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 1707cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar s2mps11_clks = devm_kzalloc(&pdev->dev, sizeof(*s2mps11_clk) * 1717cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar S2MPS11_CLKS_NUM, GFP_KERNEL); 1727cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar if (!s2mps11_clks) 1737cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar return -ENOMEM; 1747cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 1757cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar s2mps11_clk = s2mps11_clks; 1767cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 1777002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski clk_table = devm_kzalloc(&pdev->dev, sizeof(struct clk *) * 1787002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski S2MPS11_CLKS_NUM, GFP_KERNEL); 1797002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski if (!clk_table) 1807002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski return -ENOMEM; 1817002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski 18264d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera switch(platform_get_device_id(pdev)->driver_data) { 18364d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera case S2MPS11X: 18464d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera s2mps11_reg = S2MPS11_REG_RTC_CTRL; 185e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski clks_init = s2mps11_clks_init; 186e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski break; 187e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski case S2MPS14X: 188e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski s2mps11_reg = S2MPS14_REG_RTCCTRL; 189e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski clks_init = s2mps14_clks_init; 19064d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera break; 191e8e6b840c4b646ce5aaef27875a22251ebc4e0d6Tushar Behera case S5M8767X: 192e8e6b840c4b646ce5aaef27875a22251ebc4e0d6Tushar Behera s2mps11_reg = S5M8767_REG_CTRL1; 193e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski clks_init = s2mps11_clks_init; 194e8e6b840c4b646ce5aaef27875a22251ebc4e0d6Tushar Behera break; 19564d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera default: 19664d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera dev_err(&pdev->dev, "Invalid device type\n"); 19764d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera return -EINVAL; 19864d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera }; 19964d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera 200e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski /* Store clocks of_node in first element of s2mps11_clks array */ 201e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init); 202e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski if (IS_ERR(s2mps11_clks->clk_np)) 203e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski return PTR_ERR(s2mps11_clks->clk_np); 204e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski 2057cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) { 206e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski if (!clks_init[i].name) 207e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski continue; /* Skip clocks not present in some devices */ 2087cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar s2mps11_clk->iodev = iodev; 209e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski s2mps11_clk->hw.init = &clks_init[i]; 2107cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar s2mps11_clk->mask = 1 << i; 21164d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera s2mps11_clk->reg = s2mps11_reg; 2127cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2137cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar s2mps11_clk->clk = devm_clk_register(&pdev->dev, 2147cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar &s2mps11_clk->hw); 2157cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar if (IS_ERR(s2mps11_clk->clk)) { 2167cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar dev_err(&pdev->dev, "Fail to register : %s\n", 2177cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar s2mps11_name(s2mps11_clk)); 2187cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar ret = PTR_ERR(s2mps11_clk->clk); 2197cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar goto err_reg; 2207cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar } 2217cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2222a96dfa49c83a2a7cbdb11382976aaa6b2636764Krzysztof Kozlowski s2mps11_clk->lookup = clkdev_alloc(s2mps11_clk->clk, 2232a96dfa49c83a2a7cbdb11382976aaa6b2636764Krzysztof Kozlowski s2mps11_name(s2mps11_clk), NULL); 2247cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar if (!s2mps11_clk->lookup) { 2257cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar ret = -ENOMEM; 2267cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar goto err_lup; 2277cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar } 2287cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2297cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar clkdev_add(s2mps11_clk->lookup); 2307cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar } 2317cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 232e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski for (i = 0; i < S2MPS11_CLKS_NUM; i++) { 233e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski /* Skip clocks not present on S2MPS14 */ 234e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski if (!clks_init[i].name) 235e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski continue; 2367002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski clk_table[i] = s2mps11_clks[i].clk; 237e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski } 2387cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2397002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski clk_data.clks = clk_table; 2407002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski clk_data.clk_num = S2MPS11_CLKS_NUM; 2417002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski of_clk_add_provider(s2mps11_clks->clk_np, of_clk_src_onecell_get, 2427002483c7b28a808d2bd4366b00c48911688c768Krzysztof Kozlowski &clk_data); 2437cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2447cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar platform_set_drvdata(pdev, s2mps11_clks); 2457cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2467cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar return ret; 2477cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarerr_lup: 2487cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar devm_clk_unregister(&pdev->dev, s2mps11_clk->clk); 2497cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarerr_reg: 2507cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar while (s2mps11_clk > s2mps11_clks) { 2517cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar if (s2mps11_clk->lookup) { 2527cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar clkdev_drop(s2mps11_clk->lookup); 2537cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar devm_clk_unregister(&pdev->dev, s2mps11_clk->clk); 2547cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar } 2557cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar s2mps11_clk--; 2567cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar } 2577cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2587cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar return ret; 2597cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 2607cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2617cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic int s2mps11_clk_remove(struct platform_device *pdev) 2627cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 2637cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar struct s2mps11_clk *s2mps11_clks = platform_get_drvdata(pdev); 2647cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar int i; 2657cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 266bf416bd457389bfe7371ba9074bcbd032d7a04ccKrzysztof Kozlowski of_clk_del_provider(s2mps11_clks[0].clk_np); 267bf416bd457389bfe7371ba9074bcbd032d7a04ccKrzysztof Kozlowski /* Drop the reference obtained in s2mps11_clk_parse_dt */ 268bf416bd457389bfe7371ba9074bcbd032d7a04ccKrzysztof Kozlowski of_node_put(s2mps11_clks[0].clk_np); 269bf416bd457389bfe7371ba9074bcbd032d7a04ccKrzysztof Kozlowski 270e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski for (i = 0; i < S2MPS11_CLKS_NUM; i++) { 271e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski /* Skip clocks not present on S2MPS14 */ 272e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski if (!s2mps11_clks[i].lookup) 273e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski continue; 2747cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar clkdev_drop(s2mps11_clks[i].lookup); 275e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski } 2767cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2777cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar return 0; 2787cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 2797cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2807cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic const struct platform_device_id s2mps11_clk_id[] = { 28164d64c3573b3b6bf2d67fbb54d80bc73a1850f13Tushar Behera { "s2mps11-clk", S2MPS11X}, 282e8b60a45a54738243d13aeba230af20a68619b1bKrzysztof Kozlowski { "s2mps14-clk", S2MPS14X}, 283e8e6b840c4b646ce5aaef27875a22251ebc4e0d6Tushar Behera { "s5m8767-clk", S5M8767X}, 2847cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar { }, 2857cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar}; 2867cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh BrarMODULE_DEVICE_TABLE(platform, s2mps11_clk_id); 2877cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2887cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic struct platform_driver s2mps11_clk_driver = { 2897cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .driver = { 2907cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .name = "s2mps11-clk", 2917cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .owner = THIS_MODULE, 2927cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar }, 2937cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .probe = s2mps11_clk_probe, 2947cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .remove = s2mps11_clk_remove, 2957cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar .id_table = s2mps11_clk_id, 2967cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar}; 2977cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 2987cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic int __init s2mps11_clk_init(void) 2997cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 3007cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar return platform_driver_register(&s2mps11_clk_driver); 3017cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 3027cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarsubsys_initcall(s2mps11_clk_init); 3037cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 3047cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarstatic void __init s2mps11_clk_cleanup(void) 3057cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar{ 3067cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar platform_driver_unregister(&s2mps11_clk_driver); 3077cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar} 3087cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brarmodule_exit(s2mps11_clk_cleanup); 3097cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh Brar 3107cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh BrarMODULE_DESCRIPTION("S2MPS11 Clock Driver"); 3117cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh BrarMODULE_AUTHOR("Yadwinder Singh Brar <yadi.brar@samsung.com>"); 3127cc560dea4152139e16bea6e56ffa9e1bc461082Yadwinder Singh BrarMODULE_LICENSE("GPL"); 313