Commit | Line | Data |
---|---|---|
042f01bb NA |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Amlogic Meson-AXG Clock Controller Driver | |
4 | * | |
5 | * Copyright (c) 2016 Baylibre SAS. | |
6 | * Author: Michael Turquette <mturquette@baylibre.com> | |
7 | * | |
8 | * Copyright (c) 2019 Baylibre SAS. | |
9 | * Author: Neil Armstrong <narmstrong@baylibre.com> | |
10 | */ | |
11 | #include <linux/clk-provider.h> | |
12 | #include <linux/platform_device.h> | |
13 | #include <linux/reset-controller.h> | |
14 | #include <linux/mfd/syscon.h> | |
20425f63 | 15 | #include <linux/module.h> |
042f01bb NA |
16 | #include "meson-aoclk.h" |
17 | #include "g12a-aoclk.h" | |
18 | ||
19 | #include "clk-regmap.h" | |
20 | #include "clk-dualdiv.h" | |
21 | ||
042f01bb NA |
22 | /* |
23 | * AO Configuration Clock registers offsets | |
24 | * Register offsets from the data sheet must be multiplied by 4. | |
25 | */ | |
26 | #define AO_RTI_STATUS_REG3 0x0C | |
27 | #define AO_RTI_PWR_CNTL_REG0 0x10 | |
28 | #define AO_RTI_GEN_CNTL_REG0 0x40 | |
29 | #define AO_CLK_GATE0 0x4c | |
30 | #define AO_CLK_GATE0_SP 0x50 | |
31 | #define AO_OSCIN_CNTL 0x58 | |
32 | #define AO_CEC_CLK_CNTL_REG0 0x74 | |
33 | #define AO_CEC_CLK_CNTL_REG1 0x78 | |
34 | #define AO_SAR_CLK 0x90 | |
35 | #define AO_RTC_ALT_CLK_CNTL0 0x94 | |
36 | #define AO_RTC_ALT_CLK_CNTL1 0x98 | |
37 | ||
38 | /* | |
39 | * Like every other peripheral clock gate in Amlogic Clock drivers, | |
40 | * we are using CLK_IGNORE_UNUSED here, so we keep the state of the | |
41 | * bootloader. The goal is to remove this flag at some point. | |
42 | * Actually removing it will require some extensive test to be done safely. | |
43 | */ | |
44 | #define AXG_AO_GATE(_name, _reg, _bit) \ | |
45 | static struct clk_regmap g12a_aoclk_##_name = { \ | |
46 | .data = &(struct clk_regmap_gate_data) { \ | |
47 | .offset = (_reg), \ | |
48 | .bit_idx = (_bit), \ | |
49 | }, \ | |
50 | .hw.init = &(struct clk_init_data) { \ | |
51 | .name = "g12a_ao_" #_name, \ | |
52 | .ops = &clk_regmap_gate_ops, \ | |
ba626081 AM |
53 | .parent_data = &(const struct clk_parent_data) { \ |
54 | .fw_name = "mpeg-clk", \ | |
55 | }, \ | |
042f01bb NA |
56 | .num_parents = 1, \ |
57 | .flags = CLK_IGNORE_UNUSED, \ | |
58 | }, \ | |
59 | } | |
60 | ||
61 | AXG_AO_GATE(ahb, AO_CLK_GATE0, 0); | |
62 | AXG_AO_GATE(ir_in, AO_CLK_GATE0, 1); | |
63 | AXG_AO_GATE(i2c_m0, AO_CLK_GATE0, 2); | |
64 | AXG_AO_GATE(i2c_s0, AO_CLK_GATE0, 3); | |
65 | AXG_AO_GATE(uart, AO_CLK_GATE0, 4); | |
66 | AXG_AO_GATE(prod_i2c, AO_CLK_GATE0, 5); | |
67 | AXG_AO_GATE(uart2, AO_CLK_GATE0, 6); | |
68 | AXG_AO_GATE(ir_out, AO_CLK_GATE0, 7); | |
69 | AXG_AO_GATE(saradc, AO_CLK_GATE0, 8); | |
70 | AXG_AO_GATE(mailbox, AO_CLK_GATE0_SP, 0); | |
71 | AXG_AO_GATE(m3, AO_CLK_GATE0_SP, 1); | |
72 | AXG_AO_GATE(ahb_sram, AO_CLK_GATE0_SP, 2); | |
73 | AXG_AO_GATE(rti, AO_CLK_GATE0_SP, 3); | |
74 | AXG_AO_GATE(m4_fclk, AO_CLK_GATE0_SP, 4); | |
75 | AXG_AO_GATE(m4_hclk, AO_CLK_GATE0_SP, 5); | |
76 | ||
77 | static struct clk_regmap g12a_aoclk_cts_oscin = { | |
78 | .data = &(struct clk_regmap_gate_data){ | |
79 | .offset = AO_RTI_PWR_CNTL_REG0, | |
80 | .bit_idx = 14, | |
81 | }, | |
82 | .hw.init = &(struct clk_init_data){ | |
83 | .name = "cts_oscin", | |
84 | .ops = &clk_regmap_gate_ro_ops, | |
ba626081 AM |
85 | .parent_data = &(const struct clk_parent_data) { |
86 | .fw_name = "xtal", | |
87 | }, | |
042f01bb NA |
88 | .num_parents = 1, |
89 | }, | |
90 | }; | |
91 | ||
92 | static const struct meson_clk_dualdiv_param g12a_32k_div_table[] = { | |
93 | { | |
94 | .dual = 1, | |
95 | .n1 = 733, | |
96 | .m1 = 8, | |
97 | .n2 = 732, | |
98 | .m2 = 11, | |
99 | }, {} | |
100 | }; | |
101 | ||
102 | /* 32k_by_oscin clock */ | |
103 | ||
104 | static struct clk_regmap g12a_aoclk_32k_by_oscin_pre = { | |
105 | .data = &(struct clk_regmap_gate_data){ | |
106 | .offset = AO_RTC_ALT_CLK_CNTL0, | |
107 | .bit_idx = 31, | |
108 | }, | |
109 | .hw.init = &(struct clk_init_data){ | |
110 | .name = "g12a_ao_32k_by_oscin_pre", | |
111 | .ops = &clk_regmap_gate_ops, | |
ba626081 AM |
112 | .parent_hws = (const struct clk_hw *[]) { |
113 | &g12a_aoclk_cts_oscin.hw | |
114 | }, | |
042f01bb NA |
115 | .num_parents = 1, |
116 | }, | |
117 | }; | |
118 | ||
119 | static struct clk_regmap g12a_aoclk_32k_by_oscin_div = { | |
120 | .data = &(struct meson_clk_dualdiv_data){ | |
121 | .n1 = { | |
122 | .reg_off = AO_RTC_ALT_CLK_CNTL0, | |
123 | .shift = 0, | |
124 | .width = 12, | |
125 | }, | |
126 | .n2 = { | |
127 | .reg_off = AO_RTC_ALT_CLK_CNTL0, | |
128 | .shift = 12, | |
129 | .width = 12, | |
130 | }, | |
131 | .m1 = { | |
132 | .reg_off = AO_RTC_ALT_CLK_CNTL1, | |
133 | .shift = 0, | |
134 | .width = 12, | |
135 | }, | |
136 | .m2 = { | |
137 | .reg_off = AO_RTC_ALT_CLK_CNTL1, | |
138 | .shift = 12, | |
139 | .width = 12, | |
140 | }, | |
141 | .dual = { | |
142 | .reg_off = AO_RTC_ALT_CLK_CNTL0, | |
143 | .shift = 28, | |
144 | .width = 1, | |
145 | }, | |
146 | .table = g12a_32k_div_table, | |
147 | }, | |
148 | .hw.init = &(struct clk_init_data){ | |
149 | .name = "g12a_ao_32k_by_oscin_div", | |
150 | .ops = &meson_clk_dualdiv_ops, | |
ba626081 AM |
151 | .parent_hws = (const struct clk_hw *[]) { |
152 | &g12a_aoclk_32k_by_oscin_pre.hw | |
153 | }, | |
042f01bb NA |
154 | .num_parents = 1, |
155 | }, | |
156 | }; | |
157 | ||
158 | static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = { | |
159 | .data = &(struct clk_regmap_mux_data) { | |
160 | .offset = AO_RTC_ALT_CLK_CNTL1, | |
161 | .mask = 0x1, | |
162 | .shift = 24, | |
163 | .flags = CLK_MUX_ROUND_CLOSEST, | |
164 | }, | |
165 | .hw.init = &(struct clk_init_data){ | |
166 | .name = "g12a_ao_32k_by_oscin_sel", | |
167 | .ops = &clk_regmap_mux_ops, | |
ba626081 AM |
168 | .parent_hws = (const struct clk_hw *[]) { |
169 | &g12a_aoclk_32k_by_oscin_div.hw, | |
170 | &g12a_aoclk_32k_by_oscin_pre.hw, | |
171 | }, | |
042f01bb NA |
172 | .num_parents = 2, |
173 | .flags = CLK_SET_RATE_PARENT, | |
174 | }, | |
175 | }; | |
176 | ||
177 | static struct clk_regmap g12a_aoclk_32k_by_oscin = { | |
178 | .data = &(struct clk_regmap_gate_data){ | |
179 | .offset = AO_RTC_ALT_CLK_CNTL0, | |
180 | .bit_idx = 30, | |
181 | }, | |
182 | .hw.init = &(struct clk_init_data){ | |
183 | .name = "g12a_ao_32k_by_oscin", | |
184 | .ops = &clk_regmap_gate_ops, | |
ba626081 AM |
185 | .parent_hws = (const struct clk_hw *[]) { |
186 | &g12a_aoclk_32k_by_oscin_sel.hw | |
187 | }, | |
042f01bb NA |
188 | .num_parents = 1, |
189 | .flags = CLK_SET_RATE_PARENT, | |
190 | }, | |
191 | }; | |
192 | ||
193 | /* cec clock */ | |
194 | ||
195 | static struct clk_regmap g12a_aoclk_cec_pre = { | |
196 | .data = &(struct clk_regmap_gate_data){ | |
197 | .offset = AO_CEC_CLK_CNTL_REG0, | |
198 | .bit_idx = 31, | |
199 | }, | |
200 | .hw.init = &(struct clk_init_data){ | |
201 | .name = "g12a_ao_cec_pre", | |
202 | .ops = &clk_regmap_gate_ops, | |
ba626081 AM |
203 | .parent_hws = (const struct clk_hw *[]) { |
204 | &g12a_aoclk_cts_oscin.hw | |
205 | }, | |
042f01bb NA |
206 | .num_parents = 1, |
207 | }, | |
208 | }; | |
209 | ||
210 | static struct clk_regmap g12a_aoclk_cec_div = { | |
211 | .data = &(struct meson_clk_dualdiv_data){ | |
212 | .n1 = { | |
213 | .reg_off = AO_CEC_CLK_CNTL_REG0, | |
214 | .shift = 0, | |
215 | .width = 12, | |
216 | }, | |
217 | .n2 = { | |
218 | .reg_off = AO_CEC_CLK_CNTL_REG0, | |
219 | .shift = 12, | |
220 | .width = 12, | |
221 | }, | |
222 | .m1 = { | |
223 | .reg_off = AO_CEC_CLK_CNTL_REG1, | |
224 | .shift = 0, | |
225 | .width = 12, | |
226 | }, | |
227 | .m2 = { | |
228 | .reg_off = AO_CEC_CLK_CNTL_REG1, | |
229 | .shift = 12, | |
230 | .width = 12, | |
231 | }, | |
232 | .dual = { | |
233 | .reg_off = AO_CEC_CLK_CNTL_REG0, | |
234 | .shift = 28, | |
235 | .width = 1, | |
236 | }, | |
237 | .table = g12a_32k_div_table, | |
238 | }, | |
239 | .hw.init = &(struct clk_init_data){ | |
240 | .name = "g12a_ao_cec_div", | |
241 | .ops = &meson_clk_dualdiv_ops, | |
ba626081 AM |
242 | .parent_hws = (const struct clk_hw *[]) { |
243 | &g12a_aoclk_cec_pre.hw | |
244 | }, | |
042f01bb NA |
245 | .num_parents = 1, |
246 | }, | |
247 | }; | |
248 | ||
249 | static struct clk_regmap g12a_aoclk_cec_sel = { | |
250 | .data = &(struct clk_regmap_mux_data) { | |
251 | .offset = AO_CEC_CLK_CNTL_REG1, | |
252 | .mask = 0x1, | |
253 | .shift = 24, | |
254 | .flags = CLK_MUX_ROUND_CLOSEST, | |
255 | }, | |
256 | .hw.init = &(struct clk_init_data){ | |
257 | .name = "g12a_ao_cec_sel", | |
258 | .ops = &clk_regmap_mux_ops, | |
ba626081 AM |
259 | .parent_hws = (const struct clk_hw *[]) { |
260 | &g12a_aoclk_cec_div.hw, | |
261 | &g12a_aoclk_cec_pre.hw, | |
262 | }, | |
042f01bb NA |
263 | .num_parents = 2, |
264 | .flags = CLK_SET_RATE_PARENT, | |
265 | }, | |
266 | }; | |
267 | ||
268 | static struct clk_regmap g12a_aoclk_cec = { | |
269 | .data = &(struct clk_regmap_gate_data){ | |
270 | .offset = AO_CEC_CLK_CNTL_REG0, | |
271 | .bit_idx = 30, | |
272 | }, | |
273 | .hw.init = &(struct clk_init_data){ | |
274 | .name = "g12a_ao_cec", | |
275 | .ops = &clk_regmap_gate_ops, | |
ba626081 AM |
276 | .parent_hws = (const struct clk_hw *[]) { |
277 | &g12a_aoclk_cec_sel.hw | |
278 | }, | |
042f01bb NA |
279 | .num_parents = 1, |
280 | .flags = CLK_SET_RATE_PARENT, | |
281 | }, | |
282 | }; | |
283 | ||
284 | static struct clk_regmap g12a_aoclk_cts_rtc_oscin = { | |
285 | .data = &(struct clk_regmap_mux_data) { | |
286 | .offset = AO_RTI_PWR_CNTL_REG0, | |
287 | .mask = 0x1, | |
288 | .shift = 10, | |
289 | .flags = CLK_MUX_ROUND_CLOSEST, | |
290 | }, | |
291 | .hw.init = &(struct clk_init_data){ | |
292 | .name = "g12a_ao_cts_rtc_oscin", | |
293 | .ops = &clk_regmap_mux_ops, | |
ba626081 AM |
294 | .parent_data = (const struct clk_parent_data []) { |
295 | { .hw = &g12a_aoclk_32k_by_oscin.hw }, | |
296 | { .fw_name = "ext-32k-0", }, | |
297 | }, | |
042f01bb NA |
298 | .num_parents = 2, |
299 | .flags = CLK_SET_RATE_PARENT, | |
300 | }, | |
301 | }; | |
302 | ||
303 | static struct clk_regmap g12a_aoclk_clk81 = { | |
304 | .data = &(struct clk_regmap_mux_data) { | |
305 | .offset = AO_RTI_PWR_CNTL_REG0, | |
306 | .mask = 0x1, | |
307 | .shift = 8, | |
308 | .flags = CLK_MUX_ROUND_CLOSEST, | |
309 | }, | |
310 | .hw.init = &(struct clk_init_data){ | |
311 | .name = "g12a_ao_clk81", | |
312 | .ops = &clk_regmap_mux_ro_ops, | |
ba626081 AM |
313 | .parent_data = (const struct clk_parent_data []) { |
314 | { .fw_name = "mpeg-clk", }, | |
315 | { .hw = &g12a_aoclk_cts_rtc_oscin.hw }, | |
316 | }, | |
042f01bb NA |
317 | .num_parents = 2, |
318 | .flags = CLK_SET_RATE_PARENT, | |
319 | }, | |
320 | }; | |
321 | ||
322 | static struct clk_regmap g12a_aoclk_saradc_mux = { | |
323 | .data = &(struct clk_regmap_mux_data) { | |
324 | .offset = AO_SAR_CLK, | |
325 | .mask = 0x3, | |
326 | .shift = 9, | |
327 | }, | |
328 | .hw.init = &(struct clk_init_data){ | |
329 | .name = "g12a_ao_saradc_mux", | |
330 | .ops = &clk_regmap_mux_ops, | |
ba626081 AM |
331 | .parent_data = (const struct clk_parent_data []) { |
332 | { .fw_name = "xtal", }, | |
333 | { .hw = &g12a_aoclk_clk81.hw }, | |
334 | }, | |
042f01bb NA |
335 | .num_parents = 2, |
336 | }, | |
337 | }; | |
338 | ||
339 | static struct clk_regmap g12a_aoclk_saradc_div = { | |
340 | .data = &(struct clk_regmap_div_data) { | |
341 | .offset = AO_SAR_CLK, | |
342 | .shift = 0, | |
343 | .width = 8, | |
344 | }, | |
345 | .hw.init = &(struct clk_init_data){ | |
346 | .name = "g12a_ao_saradc_div", | |
347 | .ops = &clk_regmap_divider_ops, | |
ba626081 AM |
348 | .parent_hws = (const struct clk_hw *[]) { |
349 | &g12a_aoclk_saradc_mux.hw | |
350 | }, | |
042f01bb NA |
351 | .num_parents = 1, |
352 | .flags = CLK_SET_RATE_PARENT, | |
353 | }, | |
354 | }; | |
355 | ||
356 | static struct clk_regmap g12a_aoclk_saradc_gate = { | |
357 | .data = &(struct clk_regmap_gate_data) { | |
358 | .offset = AO_SAR_CLK, | |
359 | .bit_idx = 8, | |
360 | }, | |
361 | .hw.init = &(struct clk_init_data){ | |
362 | .name = "g12a_ao_saradc_gate", | |
363 | .ops = &clk_regmap_gate_ops, | |
ba626081 AM |
364 | .parent_hws = (const struct clk_hw *[]) { |
365 | &g12a_aoclk_saradc_div.hw | |
366 | }, | |
042f01bb NA |
367 | .num_parents = 1, |
368 | .flags = CLK_SET_RATE_PARENT, | |
369 | }, | |
370 | }; | |
371 | ||
372 | static const unsigned int g12a_aoclk_reset[] = { | |
373 | [RESET_AO_IR_IN] = 16, | |
374 | [RESET_AO_UART] = 17, | |
375 | [RESET_AO_I2C_M] = 18, | |
376 | [RESET_AO_I2C_S] = 19, | |
377 | [RESET_AO_SAR_ADC] = 20, | |
378 | [RESET_AO_UART2] = 22, | |
379 | [RESET_AO_IR_OUT] = 23, | |
380 | }; | |
381 | ||
382 | static struct clk_regmap *g12a_aoclk_regmap[] = { | |
383 | &g12a_aoclk_ahb, | |
384 | &g12a_aoclk_ir_in, | |
385 | &g12a_aoclk_i2c_m0, | |
386 | &g12a_aoclk_i2c_s0, | |
387 | &g12a_aoclk_uart, | |
388 | &g12a_aoclk_prod_i2c, | |
389 | &g12a_aoclk_uart2, | |
390 | &g12a_aoclk_ir_out, | |
391 | &g12a_aoclk_saradc, | |
392 | &g12a_aoclk_mailbox, | |
393 | &g12a_aoclk_m3, | |
394 | &g12a_aoclk_ahb_sram, | |
395 | &g12a_aoclk_rti, | |
396 | &g12a_aoclk_m4_fclk, | |
397 | &g12a_aoclk_m4_hclk, | |
398 | &g12a_aoclk_cts_oscin, | |
399 | &g12a_aoclk_32k_by_oscin_pre, | |
400 | &g12a_aoclk_32k_by_oscin_div, | |
401 | &g12a_aoclk_32k_by_oscin_sel, | |
402 | &g12a_aoclk_32k_by_oscin, | |
403 | &g12a_aoclk_cec_pre, | |
404 | &g12a_aoclk_cec_div, | |
405 | &g12a_aoclk_cec_sel, | |
406 | &g12a_aoclk_cec, | |
407 | &g12a_aoclk_cts_rtc_oscin, | |
408 | &g12a_aoclk_clk81, | |
409 | &g12a_aoclk_saradc_mux, | |
410 | &g12a_aoclk_saradc_div, | |
411 | &g12a_aoclk_saradc_gate, | |
412 | }; | |
413 | ||
414 | static const struct clk_hw_onecell_data g12a_aoclk_onecell_data = { | |
415 | .hws = { | |
416 | [CLKID_AO_AHB] = &g12a_aoclk_ahb.hw, | |
417 | [CLKID_AO_IR_IN] = &g12a_aoclk_ir_in.hw, | |
418 | [CLKID_AO_I2C_M0] = &g12a_aoclk_i2c_m0.hw, | |
419 | [CLKID_AO_I2C_S0] = &g12a_aoclk_i2c_s0.hw, | |
420 | [CLKID_AO_UART] = &g12a_aoclk_uart.hw, | |
421 | [CLKID_AO_PROD_I2C] = &g12a_aoclk_prod_i2c.hw, | |
422 | [CLKID_AO_UART2] = &g12a_aoclk_uart2.hw, | |
423 | [CLKID_AO_IR_OUT] = &g12a_aoclk_ir_out.hw, | |
424 | [CLKID_AO_SAR_ADC] = &g12a_aoclk_saradc.hw, | |
425 | [CLKID_AO_MAILBOX] = &g12a_aoclk_mailbox.hw, | |
426 | [CLKID_AO_M3] = &g12a_aoclk_m3.hw, | |
427 | [CLKID_AO_AHB_SRAM] = &g12a_aoclk_ahb_sram.hw, | |
428 | [CLKID_AO_RTI] = &g12a_aoclk_rti.hw, | |
429 | [CLKID_AO_M4_FCLK] = &g12a_aoclk_m4_fclk.hw, | |
430 | [CLKID_AO_M4_HCLK] = &g12a_aoclk_m4_hclk.hw, | |
431 | [CLKID_AO_CLK81] = &g12a_aoclk_clk81.hw, | |
432 | [CLKID_AO_SAR_ADC_SEL] = &g12a_aoclk_saradc_mux.hw, | |
433 | [CLKID_AO_SAR_ADC_DIV] = &g12a_aoclk_saradc_div.hw, | |
434 | [CLKID_AO_SAR_ADC_CLK] = &g12a_aoclk_saradc_gate.hw, | |
435 | [CLKID_AO_CTS_OSCIN] = &g12a_aoclk_cts_oscin.hw, | |
436 | [CLKID_AO_32K_PRE] = &g12a_aoclk_32k_by_oscin_pre.hw, | |
437 | [CLKID_AO_32K_DIV] = &g12a_aoclk_32k_by_oscin_div.hw, | |
438 | [CLKID_AO_32K_SEL] = &g12a_aoclk_32k_by_oscin_sel.hw, | |
439 | [CLKID_AO_32K] = &g12a_aoclk_32k_by_oscin.hw, | |
440 | [CLKID_AO_CEC_PRE] = &g12a_aoclk_cec_pre.hw, | |
441 | [CLKID_AO_CEC_DIV] = &g12a_aoclk_cec_div.hw, | |
442 | [CLKID_AO_CEC_SEL] = &g12a_aoclk_cec_sel.hw, | |
443 | [CLKID_AO_CEC] = &g12a_aoclk_cec.hw, | |
444 | [CLKID_AO_CTS_RTC_OSCIN] = &g12a_aoclk_cts_rtc_oscin.hw, | |
445 | }, | |
446 | .num = NR_CLKS, | |
447 | }; | |
448 | ||
042f01bb NA |
449 | static const struct meson_aoclk_data g12a_aoclkc_data = { |
450 | .reset_reg = AO_RTI_GEN_CNTL_REG0, | |
451 | .num_reset = ARRAY_SIZE(g12a_aoclk_reset), | |
452 | .reset = g12a_aoclk_reset, | |
453 | .num_clks = ARRAY_SIZE(g12a_aoclk_regmap), | |
454 | .clks = g12a_aoclk_regmap, | |
455 | .hw_data = &g12a_aoclk_onecell_data, | |
042f01bb NA |
456 | }; |
457 | ||
458 | static const struct of_device_id g12a_aoclkc_match_table[] = { | |
459 | { | |
460 | .compatible = "amlogic,meson-g12a-aoclkc", | |
461 | .data = &g12a_aoclkc_data, | |
462 | }, | |
463 | { } | |
464 | }; | |
20425f63 | 465 | MODULE_DEVICE_TABLE(of, g12a_aoclkc_match_table); |
042f01bb NA |
466 | |
467 | static struct platform_driver g12a_aoclkc_driver = { | |
468 | .probe = meson_aoclkc_probe, | |
469 | .driver = { | |
470 | .name = "g12a-aoclkc", | |
471 | .of_match_table = g12a_aoclkc_match_table, | |
472 | }, | |
473 | }; | |
474 | ||
20425f63 KH |
475 | module_platform_driver(g12a_aoclkc_driver); |
476 | MODULE_LICENSE("GPL v2"); |