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

clk: meson: gxbb-aoclk: Switch to regmap for register access

Switch the aoclk driver to use the new bindings and switch all the
registers access to regmap only.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>

+95 -23
+1 -1
drivers/clk/meson/Makefile
··· 4 4 5 5 obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o 6 6 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o 7 - obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o 7 + obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-regmap.o
+46
drivers/clk/meson/gxbb-aoclk-regmap.c
··· 1 + /* 2 + * Copyright (c) 2017 BayLibre, SAS. 3 + * Author: Neil Armstrong <narmstrong@baylibre.com> 4 + * 5 + * SPDX-License-Identifier: GPL-2.0+ 6 + */ 7 + 8 + #include <linux/clk-provider.h> 9 + #include <linux/bitfield.h> 10 + #include <linux/regmap.h> 11 + #include "gxbb-aoclk.h" 12 + 13 + static int aoclk_gate_regmap_enable(struct clk_hw *hw) 14 + { 15 + struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw); 16 + 17 + return regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0, 18 + BIT(gate->bit_idx), BIT(gate->bit_idx)); 19 + } 20 + 21 + static void aoclk_gate_regmap_disable(struct clk_hw *hw) 22 + { 23 + struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw); 24 + 25 + regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0, 26 + BIT(gate->bit_idx), 0); 27 + } 28 + 29 + static int aoclk_gate_regmap_is_enabled(struct clk_hw *hw) 30 + { 31 + struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw); 32 + unsigned int val; 33 + int ret; 34 + 35 + ret = regmap_read(gate->regmap, AO_RTI_GEN_CNTL_REG0, &val); 36 + if (ret) 37 + return ret; 38 + 39 + return (val & BIT(gate->bit_idx)) != 0; 40 + } 41 + 42 + const struct clk_ops meson_aoclk_gate_regmap_ops = { 43 + .enable = aoclk_gate_regmap_enable, 44 + .disable = aoclk_gate_regmap_disable, 45 + .is_enabled = aoclk_gate_regmap_is_enabled, 46 + };
+22 -22
drivers/clk/meson/gxbb-aoclk.c
··· 56 56 #include <linux/of_address.h> 57 57 #include <linux/platform_device.h> 58 58 #include <linux/reset-controller.h> 59 + #include <linux/mfd/syscon.h> 60 + #include <linux/regmap.h> 59 61 #include <linux/init.h> 60 62 #include <dt-bindings/clock/gxbb-aoclkc.h> 61 63 #include <dt-bindings/reset/gxbb-aoclkc.h> 64 + #include "gxbb-aoclk.h" 62 65 63 66 static DEFINE_SPINLOCK(gxbb_aoclk_lock); 64 67 65 68 struct gxbb_aoclk_reset_controller { 66 69 struct reset_controller_dev reset; 67 70 unsigned int *data; 68 - void __iomem *base; 71 + struct regmap *regmap; 69 72 }; 70 73 71 74 static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, ··· 77 74 struct gxbb_aoclk_reset_controller *reset = 78 75 container_of(rcdev, struct gxbb_aoclk_reset_controller, reset); 79 76 80 - writel(BIT(reset->data[id]), reset->base); 81 - 82 - return 0; 77 + return regmap_write(reset->regmap, AO_RTI_GEN_CNTL_REG0, 78 + BIT(reset->data[id])); 83 79 } 84 80 85 81 static const struct reset_control_ops gxbb_aoclk_reset_ops = { ··· 86 84 }; 87 85 88 86 #define GXBB_AO_GATE(_name, _bit) \ 89 - static struct clk_gate _name##_ao = { \ 90 - .reg = (void __iomem *)0, \ 87 + static struct aoclk_gate_regmap _name##_ao = { \ 91 88 .bit_idx = (_bit), \ 92 89 .lock = &gxbb_aoclk_lock, \ 93 90 .hw.init = &(struct clk_init_data) { \ 94 91 .name = #_name "_ao", \ 95 - .ops = &clk_gate_ops, \ 92 + .ops = &meson_aoclk_gate_regmap_ops, \ 96 93 .parent_names = (const char *[]){ "clk81" }, \ 97 94 .num_parents = 1, \ 98 95 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ ··· 114 113 [RESET_AO_IR_BLASTER] = 23, 115 114 }; 116 115 117 - static struct clk_gate *gxbb_aoclk_gate[] = { 116 + static struct aoclk_gate_regmap *gxbb_aoclk_gate[] = { 118 117 [CLKID_AO_REMOTE] = &remote_ao, 119 118 [CLKID_AO_I2C_MASTER] = &i2c_master_ao, 120 119 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao, ··· 137 136 138 137 static int gxbb_aoclkc_probe(struct platform_device *pdev) 139 138 { 140 - struct resource *res; 141 - void __iomem *base; 142 - int ret, clkid; 143 - struct device *dev = &pdev->dev; 144 139 struct gxbb_aoclk_reset_controller *rstc; 140 + struct device *dev = &pdev->dev; 141 + struct regmap *regmap; 142 + int ret, clkid; 145 143 146 144 rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); 147 145 if (!rstc) 148 146 return -ENOMEM; 149 147 150 - /* Generic clocks */ 151 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 152 - base = devm_ioremap_resource(dev, res); 153 - if (IS_ERR(base)) 154 - return PTR_ERR(base); 148 + regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); 149 + if (IS_ERR(regmap)) { 150 + dev_err(dev, "failed to get regmap\n"); 151 + return -ENODEV; 152 + } 155 153 156 154 /* Reset Controller */ 157 - rstc->base = base; 155 + rstc->regmap = regmap; 158 156 rstc->data = gxbb_aoclk_reset; 159 157 rstc->reset.ops = &gxbb_aoclk_reset_ops; 160 158 rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); ··· 161 161 ret = devm_reset_controller_register(dev, &rstc->reset); 162 162 163 163 /* 164 - * Populate base address and register all clks 164 + * Populate regmap and register all clks 165 165 */ 166 - for (clkid = 0; clkid < gxbb_aoclk_onecell_data.num; clkid++) { 167 - gxbb_aoclk_gate[clkid]->reg = base; 166 + for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { 167 + gxbb_aoclk_gate[clkid]->regmap = regmap; 168 168 169 169 ret = devm_clk_hw_register(dev, 170 170 gxbb_aoclk_onecell_data.hws[clkid]); ··· 177 177 } 178 178 179 179 static const struct of_device_id gxbb_aoclkc_match_table[] = { 180 - { .compatible = "amlogic,gxbb-aoclkc" }, 180 + { .compatible = "amlogic,meson-gx-aoclkc" }, 181 181 { } 182 182 }; 183 183
+26
drivers/clk/meson/gxbb-aoclk.h
··· 1 + /* 2 + * Copyright (c) 2017 BayLibre, SAS 3 + * Author: Neil Armstrong <narmstrong@baylibre.com> 4 + * 5 + * SPDX-License-Identifier: GPL-2.0+ 6 + */ 7 + 8 + #ifndef __GXBB_AOCLKC_H 9 + #define __GXBB_AOCLKC_H 10 + 11 + /* AO Configuration Clock registers offsets */ 12 + #define AO_RTI_GEN_CNTL_REG0 0x40 13 + 14 + struct aoclk_gate_regmap { 15 + struct clk_hw hw; 16 + unsigned bit_idx; 17 + struct regmap *regmap; 18 + spinlock_t *lock; 19 + }; 20 + 21 + #define to_aoclk_gate_regmap(_hw) \ 22 + container_of(_hw, struct aoclk_gate_regmap, hw) 23 + 24 + extern const struct clk_ops meson_aoclk_gate_regmap_ops; 25 + 26 + #endif /* __GXBB_AOCLKC_H */