71d083f31a9565121d238603655a73ccd9a79ca6
[openwrt/staging/dangole.git] / target / linux / mediatek / patches-5.15 / 845-v5.18-i2c-mt65xx-Simplify-with-clk-bulk.patch
1 From cc6faa5e0772296d815fd298c231277d47308a6a Mon Sep 17 00:00:00 2001
2 From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
3 Date: Thu, 3 Mar 2022 10:15:47 +0100
4 Subject: [PATCH 06/16] i2c: mt65xx: Simplify with clk-bulk
5
6 Since depending on the SoC or specific bus functionality some clocks
7 may be optional, we cannot get the benefit of using devm_clk_bulk_get()
8 but, by migrating to clk-bulk, we are able to remove the custom functions
9 mtk_i2c_clock_enable() and mtk_i2c_clock_disable(), increasing common
10 APIs usage, hence (lightly) decreasing kernel footprint.
11
12 Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
13 Reviewed-by: Qii Wang <qii.wang@mediatek.com>
14 Signed-off-by: Wolfram Sang <wsa@kernel.org>
15 ---
16 drivers/i2c/busses/i2c-mt65xx.c | 124 +++++++++++++-------------------
17 1 file changed, 51 insertions(+), 73 deletions(-)
18
19 --- a/drivers/i2c/busses/i2c-mt65xx.c
20 +++ b/drivers/i2c/busses/i2c-mt65xx.c
21 @@ -86,6 +86,27 @@
22
23 #define I2C_DRV_NAME "i2c-mt65xx"
24
25 +/**
26 + * enum i2c_mt65xx_clks - Clocks enumeration for MT65XX I2C
27 + *
28 + * @I2C_MT65XX_CLK_MAIN: main clock for i2c bus
29 + * @I2C_MT65XX_CLK_DMA: DMA clock for i2c via DMA
30 + * @I2C_MT65XX_CLK_PMIC: PMIC clock for i2c from PMIC
31 + * @I2C_MT65XX_CLK_ARB: Arbitrator clock for i2c
32 + * @I2C_MT65XX_CLK_MAX: Number of supported clocks
33 + */
34 +enum i2c_mt65xx_clks {
35 + I2C_MT65XX_CLK_MAIN = 0,
36 + I2C_MT65XX_CLK_DMA,
37 + I2C_MT65XX_CLK_PMIC,
38 + I2C_MT65XX_CLK_ARB,
39 + I2C_MT65XX_CLK_MAX
40 +};
41 +
42 +static const char * const i2c_mt65xx_clk_ids[I2C_MT65XX_CLK_MAX] = {
43 + "main", "dma", "pmic", "arb"
44 +};
45 +
46 enum DMA_REGS_OFFSET {
47 OFFSET_INT_FLAG = 0x0,
48 OFFSET_INT_EN = 0x04,
49 @@ -244,10 +265,7 @@ struct mtk_i2c {
50 /* set in i2c probe */
51 void __iomem *base; /* i2c base addr */
52 void __iomem *pdmabase; /* dma base address*/
53 - struct clk *clk_main; /* main clock for i2c bus */
54 - struct clk *clk_dma; /* DMA clock for i2c via DMA */
55 - struct clk *clk_pmic; /* PMIC clock for i2c from PMIC */
56 - struct clk *clk_arb; /* Arbitrator clock for i2c */
57 + struct clk_bulk_data clocks[I2C_MT65XX_CLK_MAX]; /* clocks for i2c */
58 bool have_pmic; /* can use i2c pins from PMIC */
59 bool use_push_pull; /* IO config push-pull mode */
60
61 @@ -449,52 +467,6 @@ static void mtk_i2c_writew(struct mtk_i2
62 writew(val, i2c->base + i2c->dev_comp->regs[reg]);
63 }
64
65 -static int mtk_i2c_clock_enable(struct mtk_i2c *i2c)
66 -{
67 - int ret;
68 -
69 - ret = clk_prepare_enable(i2c->clk_dma);
70 - if (ret)
71 - return ret;
72 -
73 - ret = clk_prepare_enable(i2c->clk_main);
74 - if (ret)
75 - goto err_main;
76 -
77 - if (i2c->have_pmic) {
78 - ret = clk_prepare_enable(i2c->clk_pmic);
79 - if (ret)
80 - goto err_pmic;
81 - }
82 -
83 - if (i2c->clk_arb) {
84 - ret = clk_prepare_enable(i2c->clk_arb);
85 - if (ret)
86 - goto err_arb;
87 - }
88 -
89 - return 0;
90 -
91 -err_arb:
92 - clk_disable_unprepare(i2c->clk_pmic);
93 -err_pmic:
94 - clk_disable_unprepare(i2c->clk_main);
95 -err_main:
96 - clk_disable_unprepare(i2c->clk_dma);
97 -
98 - return ret;
99 -}
100 -
101 -static void mtk_i2c_clock_disable(struct mtk_i2c *i2c)
102 -{
103 - clk_disable_unprepare(i2c->clk_arb);
104 -
105 - clk_disable_unprepare(i2c->clk_pmic);
106 -
107 - clk_disable_unprepare(i2c->clk_main);
108 - clk_disable_unprepare(i2c->clk_dma);
109 -}
110 -
111 static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
112 {
113 u16 control_reg;
114 @@ -1191,7 +1163,7 @@ static int mtk_i2c_transfer(struct i2c_a
115 int left_num = num;
116 struct mtk_i2c *i2c = i2c_get_adapdata(adap);
117
118 - ret = mtk_i2c_clock_enable(i2c);
119 + ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
120 if (ret)
121 return ret;
122
123 @@ -1245,7 +1217,7 @@ static int mtk_i2c_transfer(struct i2c_a
124 ret = num;
125
126 err_exit:
127 - mtk_i2c_clock_disable(i2c);
128 + clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
129 return ret;
130 }
131
132 @@ -1323,9 +1295,8 @@ static int mtk_i2c_probe(struct platform
133 {
134 int ret = 0;
135 struct mtk_i2c *i2c;
136 - struct clk *clk;
137 struct resource *res;
138 - int irq;
139 + int i, irq, speed_clk;
140
141 i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
142 if (!i2c)
143 @@ -1371,35 +1342,42 @@ static int mtk_i2c_probe(struct platform
144 if (i2c->have_pmic && !i2c->dev_comp->pmic_i2c)
145 return -EINVAL;
146
147 - i2c->clk_main = devm_clk_get(&pdev->dev, "main");
148 - if (IS_ERR(i2c->clk_main)) {
149 + /* Fill in clk-bulk IDs */
150 + for (i = 0; i < I2C_MT65XX_CLK_MAX; i++)
151 + i2c->clocks[i].id = i2c_mt65xx_clk_ids[i];
152 +
153 + /* Get clocks one by one, some may be optional */
154 + i2c->clocks[I2C_MT65XX_CLK_MAIN].clk = devm_clk_get(&pdev->dev, "main");
155 + if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk)) {
156 dev_err(&pdev->dev, "cannot get main clock\n");
157 - return PTR_ERR(i2c->clk_main);
158 + return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk);
159 }
160
161 - i2c->clk_dma = devm_clk_get(&pdev->dev, "dma");
162 - if (IS_ERR(i2c->clk_dma)) {
163 + i2c->clocks[I2C_MT65XX_CLK_DMA].clk = devm_clk_get(&pdev->dev, "dma");
164 + if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk)) {
165 dev_err(&pdev->dev, "cannot get dma clock\n");
166 - return PTR_ERR(i2c->clk_dma);
167 + return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk);
168 }
169
170 - i2c->clk_arb = devm_clk_get(&pdev->dev, "arb");
171 - if (IS_ERR(i2c->clk_arb))
172 - i2c->clk_arb = NULL;
173 + i2c->clocks[I2C_MT65XX_CLK_ARB].clk = devm_clk_get_optional(&pdev->dev, "arb");
174 + if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
175 + return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
176
177 - clk = i2c->clk_main;
178 if (i2c->have_pmic) {
179 - i2c->clk_pmic = devm_clk_get(&pdev->dev, "pmic");
180 - if (IS_ERR(i2c->clk_pmic)) {
181 + i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
182 + if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
183 dev_err(&pdev->dev, "cannot get pmic clock\n");
184 - return PTR_ERR(i2c->clk_pmic);
185 + return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
186 }
187 - clk = i2c->clk_pmic;
188 + speed_clk = I2C_MT65XX_CLK_PMIC;
189 + } else {
190 + i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL;
191 + speed_clk = I2C_MT65XX_CLK_MAIN;
192 }
193
194 strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
195
196 - ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk));
197 + ret = mtk_i2c_set_speed(i2c, clk_get_rate(i2c->clocks[speed_clk].clk));
198 if (ret) {
199 dev_err(&pdev->dev, "Failed to set the speed.\n");
200 return -EINVAL;
201 @@ -1414,13 +1392,13 @@ static int mtk_i2c_probe(struct platform
202 }
203 }
204
205 - ret = mtk_i2c_clock_enable(i2c);
206 + ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
207 if (ret) {
208 dev_err(&pdev->dev, "clock enable failed!\n");
209 return ret;
210 }
211 mtk_i2c_init_hw(i2c);
212 - mtk_i2c_clock_disable(i2c);
213 + clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
214
215 ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
216 IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
217 @@ -1465,7 +1443,7 @@ static int mtk_i2c_resume_noirq(struct d
218 int ret;
219 struct mtk_i2c *i2c = dev_get_drvdata(dev);
220
221 - ret = mtk_i2c_clock_enable(i2c);
222 + ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
223 if (ret) {
224 dev_err(dev, "clock enable failed!\n");
225 return ret;
226 @@ -1473,7 +1451,7 @@ static int mtk_i2c_resume_noirq(struct d
227
228 mtk_i2c_init_hw(i2c);
229
230 - mtk_i2c_clock_disable(i2c);
231 + clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
232
233 i2c_mark_adapter_resumed(&i2c->adap);
234