]> Git Repo - linux.git/blob - drivers/soc/rockchip/io-domain.c
block: add a sanity check for non-write flush/fua bios
[linux.git] / drivers / soc / rockchip / io-domain.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Rockchip IO Voltage Domain driver
4  *
5  * Copyright 2014 MundoReader S.L.
6  * Copyright 2014 Google, Inc.
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/err.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/of.h>
14 #include <linux/platform_device.h>
15 #include <linux/regmap.h>
16 #include <linux/regulator/consumer.h>
17
18 #define MAX_SUPPLIES            16
19
20 /*
21  * The max voltage for 1.8V and 3.3V come from the Rockchip datasheet under
22  * "Recommended Operating Conditions" for "Digital GPIO".   When the typical
23  * is 3.3V the max is 3.6V.  When the typical is 1.8V the max is 1.98V.
24  *
25  * They are used like this:
26  * - If the voltage on a rail is above the "1.8" voltage (1.98V) we'll tell the
27  *   SoC we're at 3.3.
28  * - If the voltage on a rail is above the "3.3" voltage (3.6V) we'll consider
29  *   that to be an error.
30  */
31 #define MAX_VOLTAGE_1_8         1980000
32 #define MAX_VOLTAGE_3_3         3600000
33
34 #define PX30_IO_VSEL                    0x180
35 #define PX30_IO_VSEL_VCCIO6_SRC         BIT(0)
36 #define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM  1
37
38 #define RK3288_SOC_CON2                 0x24c
39 #define RK3288_SOC_CON2_FLASH0          BIT(7)
40 #define RK3288_SOC_FLASH_SUPPLY_NUM     2
41
42 #define RK3328_SOC_CON4                 0x410
43 #define RK3328_SOC_CON4_VCCIO2          BIT(7)
44 #define RK3328_SOC_VCCIO2_SUPPLY_NUM    1
45
46 #define RK3368_SOC_CON15                0x43c
47 #define RK3368_SOC_CON15_FLASH0         BIT(14)
48 #define RK3368_SOC_FLASH_SUPPLY_NUM     2
49
50 #define RK3399_PMUGRF_CON0              0x180
51 #define RK3399_PMUGRF_CON0_VSEL         BIT(8)
52 #define RK3399_PMUGRF_VSEL_SUPPLY_NUM   9
53
54 #define RK3568_PMU_GRF_IO_VSEL0         (0x0140)
55 #define RK3568_PMU_GRF_IO_VSEL1         (0x0144)
56 #define RK3568_PMU_GRF_IO_VSEL2         (0x0148)
57
58 struct rockchip_iodomain;
59
60 struct rockchip_iodomain_supply {
61         struct rockchip_iodomain *iod;
62         struct regulator *reg;
63         struct notifier_block nb;
64         int idx;
65 };
66
67 struct rockchip_iodomain_soc_data {
68         int grf_offset;
69         const char *supply_names[MAX_SUPPLIES];
70         void (*init)(struct rockchip_iodomain *iod);
71         int (*write)(struct rockchip_iodomain_supply *supply, int uV);
72 };
73
74 struct rockchip_iodomain {
75         struct device *dev;
76         struct regmap *grf;
77         const struct rockchip_iodomain_soc_data *soc_data;
78         struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
79         int (*write)(struct rockchip_iodomain_supply *supply, int uV);
80 };
81
82 static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
83 {
84         struct rockchip_iodomain *iod = supply->iod;
85         u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
86         u32 val0, val1;
87         int b;
88
89         switch (supply->idx) {
90         case 0: /* pmuio1 */
91                 break;
92         case 1: /* pmuio2 */
93                 b = supply->idx;
94                 val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
95                 b = supply->idx + 4;
96                 val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
97
98                 regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
99                 regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
100                 break;
101         case 3: /* vccio2 */
102                 break;
103         case 2: /* vccio1 */
104         case 4: /* vccio3 */
105         case 5: /* vccio4 */
106         case 6: /* vccio5 */
107         case 7: /* vccio6 */
108         case 8: /* vccio7 */
109                 b = supply->idx - 1;
110                 val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
111                 val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
112
113                 regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
114                 regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
115                 break;
116         default:
117                 return -EINVAL;
118         }
119
120         return 0;
121 }
122
123 static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
124                                    int uV)
125 {
126         struct rockchip_iodomain *iod = supply->iod;
127         u32 val;
128         int ret;
129
130         /* set value bit */
131         val = (uV > MAX_VOLTAGE_1_8) ? 0 : 1;
132         val <<= supply->idx;
133
134         /* apply hiword-mask */
135         val |= (BIT(supply->idx) << 16);
136
137         ret = regmap_write(iod->grf, iod->soc_data->grf_offset, val);
138         if (ret)
139                 dev_err(iod->dev, "Couldn't write to GRF\n");
140
141         return ret;
142 }
143
144 static int rockchip_iodomain_notify(struct notifier_block *nb,
145                                     unsigned long event,
146                                     void *data)
147 {
148         struct rockchip_iodomain_supply *supply =
149                         container_of(nb, struct rockchip_iodomain_supply, nb);
150         int uV;
151         int ret;
152
153         /*
154          * According to Rockchip it's important to keep the SoC IO domain
155          * higher than (or equal to) the external voltage.  That means we need
156          * to change it before external voltage changes happen in the case
157          * of an increase.
158          *
159          * Note that in the "pre" change we pick the max possible voltage that
160          * the regulator might end up at (the client requests a range and we
161          * don't know for certain the exact voltage).  Right now we rely on the
162          * slop in MAX_VOLTAGE_1_8 and MAX_VOLTAGE_3_3 to save us if clients
163          * request something like a max of 3.6V when they really want 3.3V.
164          * We could attempt to come up with better rules if this fails.
165          */
166         if (event & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) {
167                 struct pre_voltage_change_data *pvc_data = data;
168
169                 uV = max_t(unsigned long, pvc_data->old_uV, pvc_data->max_uV);
170         } else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE |
171                             REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) {
172                 uV = (unsigned long)data;
173         } else {
174                 return NOTIFY_OK;
175         }
176
177         dev_dbg(supply->iod->dev, "Setting to %d\n", uV);
178
179         if (uV > MAX_VOLTAGE_3_3) {
180                 dev_err(supply->iod->dev, "Voltage too high: %d\n", uV);
181
182                 if (event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
183                         return NOTIFY_BAD;
184         }
185
186         ret = supply->iod->write(supply, uV);
187         if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
188                 return NOTIFY_BAD;
189
190         dev_dbg(supply->iod->dev, "Setting to %d done\n", uV);
191         return NOTIFY_OK;
192 }
193
194 static void px30_iodomain_init(struct rockchip_iodomain *iod)
195 {
196         int ret;
197         u32 val;
198
199         /* if no VCCIO6 supply we should leave things alone */
200         if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg)
201                 return;
202
203         /*
204          * set vccio6 iodomain to also use this framework
205          * instead of a special gpio.
206          */
207         val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16);
208         ret = regmap_write(iod->grf, PX30_IO_VSEL, val);
209         if (ret < 0)
210                 dev_warn(iod->dev, "couldn't update vccio6 ctrl\n");
211 }
212
213 static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
214 {
215         int ret;
216         u32 val;
217
218         /* if no flash supply we should leave things alone */
219         if (!iod->supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg)
220                 return;
221
222         /*
223          * set flash0 iodomain to also use this framework
224          * instead of a special gpio.
225          */
226         val = RK3288_SOC_CON2_FLASH0 | (RK3288_SOC_CON2_FLASH0 << 16);
227         ret = regmap_write(iod->grf, RK3288_SOC_CON2, val);
228         if (ret < 0)
229                 dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
230 }
231
232 static void rk3328_iodomain_init(struct rockchip_iodomain *iod)
233 {
234         int ret;
235         u32 val;
236
237         /* if no vccio2 supply we should leave things alone */
238         if (!iod->supplies[RK3328_SOC_VCCIO2_SUPPLY_NUM].reg)
239                 return;
240
241         /*
242          * set vccio2 iodomain to also use this framework
243          * instead of a special gpio.
244          */
245         val = RK3328_SOC_CON4_VCCIO2 | (RK3328_SOC_CON4_VCCIO2 << 16);
246         ret = regmap_write(iod->grf, RK3328_SOC_CON4, val);
247         if (ret < 0)
248                 dev_warn(iod->dev, "couldn't update vccio2 vsel ctrl\n");
249 }
250
251 static void rk3368_iodomain_init(struct rockchip_iodomain *iod)
252 {
253         int ret;
254         u32 val;
255
256         /* if no flash supply we should leave things alone */
257         if (!iod->supplies[RK3368_SOC_FLASH_SUPPLY_NUM].reg)
258                 return;
259
260         /*
261          * set flash0 iodomain to also use this framework
262          * instead of a special gpio.
263          */
264         val = RK3368_SOC_CON15_FLASH0 | (RK3368_SOC_CON15_FLASH0 << 16);
265         ret = regmap_write(iod->grf, RK3368_SOC_CON15, val);
266         if (ret < 0)
267                 dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
268 }
269
270 static void rk3399_pmu_iodomain_init(struct rockchip_iodomain *iod)
271 {
272         int ret;
273         u32 val;
274
275         /* if no pmu io supply we should leave things alone */
276         if (!iod->supplies[RK3399_PMUGRF_VSEL_SUPPLY_NUM].reg)
277                 return;
278
279         /*
280          * set pmu io iodomain to also use this framework
281          * instead of a special gpio.
282          */
283         val = RK3399_PMUGRF_CON0_VSEL | (RK3399_PMUGRF_CON0_VSEL << 16);
284         ret = regmap_write(iod->grf, RK3399_PMUGRF_CON0, val);
285         if (ret < 0)
286                 dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n");
287 }
288
289 static const struct rockchip_iodomain_soc_data soc_data_px30 = {
290         .grf_offset = 0x180,
291         .supply_names = {
292                 NULL,
293                 "vccio6",
294                 "vccio1",
295                 "vccio2",
296                 "vccio3",
297                 "vccio4",
298                 "vccio5",
299                 "vccio-oscgpi",
300         },
301         .init = px30_iodomain_init,
302 };
303
304 static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = {
305         .grf_offset = 0x100,
306         .supply_names = {
307                 NULL,
308                 NULL,
309                 NULL,
310                 NULL,
311                 NULL,
312                 NULL,
313                 NULL,
314                 NULL,
315                 NULL,
316                 NULL,
317                 NULL,
318                 NULL,
319                 NULL,
320                 NULL,
321                 "pmuio1",
322                 "pmuio2",
323         },
324 };
325
326 /*
327  * On the rk3188 the io-domains are handled by a shared register with the
328  * lower 8 bits being still being continuing drive-strength settings.
329  */
330 static const struct rockchip_iodomain_soc_data soc_data_rk3188 = {
331         .grf_offset = 0x104,
332         .supply_names = {
333                 NULL,
334                 NULL,
335                 NULL,
336                 NULL,
337                 NULL,
338                 NULL,
339                 NULL,
340                 NULL,
341                 "ap0",
342                 "ap1",
343                 "cif",
344                 "flash",
345                 "vccio0",
346                 "vccio1",
347                 "lcdc0",
348                 "lcdc1",
349         },
350 };
351
352 static const struct rockchip_iodomain_soc_data soc_data_rk3228 = {
353         .grf_offset = 0x418,
354         .supply_names = {
355                 "vccio1",
356                 "vccio2",
357                 "vccio3",
358                 "vccio4",
359         },
360 };
361
362 static const struct rockchip_iodomain_soc_data soc_data_rk3288 = {
363         .grf_offset = 0x380,
364         .supply_names = {
365                 "lcdc",         /* LCDC_VDD */
366                 "dvp",          /* DVPIO_VDD */
367                 "flash0",       /* FLASH0_VDD (emmc) */
368                 "flash1",       /* FLASH1_VDD (sdio1) */
369                 "wifi",         /* APIO3_VDD  (sdio0) */
370                 "bb",           /* APIO5_VDD */
371                 "audio",        /* APIO4_VDD */
372                 "sdcard",       /* SDMMC0_VDD (sdmmc) */
373                 "gpio30",       /* APIO1_VDD */
374                 "gpio1830",     /* APIO2_VDD */
375         },
376         .init = rk3288_iodomain_init,
377 };
378
379 static const struct rockchip_iodomain_soc_data soc_data_rk3328 = {
380         .grf_offset = 0x410,
381         .supply_names = {
382                 "vccio1",
383                 "vccio2",
384                 "vccio3",
385                 "vccio4",
386                 "vccio5",
387                 "vccio6",
388                 "pmuio",
389         },
390         .init = rk3328_iodomain_init,
391 };
392
393 static const struct rockchip_iodomain_soc_data soc_data_rk3368 = {
394         .grf_offset = 0x900,
395         .supply_names = {
396                 NULL,           /* reserved */
397                 "dvp",          /* DVPIO_VDD */
398                 "flash0",       /* FLASH0_VDD (emmc) */
399                 "wifi",         /* APIO2_VDD (sdio0) */
400                 NULL,
401                 "audio",        /* APIO3_VDD */
402                 "sdcard",       /* SDMMC0_VDD (sdmmc) */
403                 "gpio30",       /* APIO1_VDD */
404                 "gpio1830",     /* APIO4_VDD (gpujtag) */
405         },
406         .init = rk3368_iodomain_init,
407 };
408
409 static const struct rockchip_iodomain_soc_data soc_data_rk3368_pmu = {
410         .grf_offset = 0x100,
411         .supply_names = {
412                 NULL,
413                 NULL,
414                 NULL,
415                 NULL,
416                 "pmu",          /*PMU IO domain*/
417                 "vop",          /*LCDC IO domain*/
418         },
419 };
420
421 static const struct rockchip_iodomain_soc_data soc_data_rk3399 = {
422         .grf_offset = 0xe640,
423         .supply_names = {
424                 "bt656",                /* APIO2_VDD */
425                 "audio",                /* APIO5_VDD */
426                 "sdmmc",                /* SDMMC0_VDD */
427                 "gpio1830",             /* APIO4_VDD */
428         },
429 };
430
431 static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
432         .grf_offset = 0x180,
433         .supply_names = {
434                 NULL,
435                 NULL,
436                 NULL,
437                 NULL,
438                 NULL,
439                 NULL,
440                 NULL,
441                 NULL,
442                 NULL,
443                 "pmu1830",              /* PMUIO2_VDD */
444         },
445         .init = rk3399_pmu_iodomain_init,
446 };
447
448 static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
449         .grf_offset = 0x140,
450         .supply_names = {
451                 "pmuio1",
452                 "pmuio2",
453                 "vccio1",
454                 "vccio2",
455                 "vccio3",
456                 "vccio4",
457                 "vccio5",
458                 "vccio6",
459                 "vccio7",
460         },
461         .write = rk3568_iodomain_write,
462 };
463
464 static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
465         .grf_offset = 0x404,
466         .supply_names = {
467                 NULL,
468                 NULL,
469                 NULL,
470                 NULL,
471                 NULL,
472                 NULL,
473                 NULL,
474                 NULL,
475                 NULL,
476                 NULL,
477                 NULL,
478                 "vccio1",
479                 "vccio2",
480                 "vccio3",
481                 "vccio5",
482                 "vccio6",
483         },
484
485 };
486
487 static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
488         .grf_offset = 0x104,
489         .supply_names = {
490                 "pmu",
491         },
492 };
493
494 static const struct rockchip_iodomain_soc_data soc_data_rv1126_pmu = {
495         .grf_offset = 0x140,
496         .supply_names = {
497                 NULL,
498                 "vccio1",
499                 "vccio2",
500                 "vccio3",
501                 "vccio4",
502                 "vccio5",
503                 "vccio6",
504                 "vccio7",
505                 "pmuio0",
506                 "pmuio1",
507         },
508 };
509
510 static const struct of_device_id rockchip_iodomain_match[] = {
511         {
512                 .compatible = "rockchip,px30-io-voltage-domain",
513                 .data = (void *)&soc_data_px30
514         },
515         {
516                 .compatible = "rockchip,px30-pmu-io-voltage-domain",
517                 .data = (void *)&soc_data_px30_pmu
518         },
519         {
520                 .compatible = "rockchip,rk3188-io-voltage-domain",
521                 .data = &soc_data_rk3188
522         },
523         {
524                 .compatible = "rockchip,rk3228-io-voltage-domain",
525                 .data = &soc_data_rk3228
526         },
527         {
528                 .compatible = "rockchip,rk3288-io-voltage-domain",
529                 .data = &soc_data_rk3288
530         },
531         {
532                 .compatible = "rockchip,rk3328-io-voltage-domain",
533                 .data = &soc_data_rk3328
534         },
535         {
536                 .compatible = "rockchip,rk3368-io-voltage-domain",
537                 .data = &soc_data_rk3368
538         },
539         {
540                 .compatible = "rockchip,rk3368-pmu-io-voltage-domain",
541                 .data = &soc_data_rk3368_pmu
542         },
543         {
544                 .compatible = "rockchip,rk3399-io-voltage-domain",
545                 .data = &soc_data_rk3399
546         },
547         {
548                 .compatible = "rockchip,rk3399-pmu-io-voltage-domain",
549                 .data = &soc_data_rk3399_pmu
550         },
551         {
552                 .compatible = "rockchip,rk3568-pmu-io-voltage-domain",
553                 .data = &soc_data_rk3568_pmu
554         },
555         {
556                 .compatible = "rockchip,rv1108-io-voltage-domain",
557                 .data = &soc_data_rv1108
558         },
559         {
560                 .compatible = "rockchip,rv1108-pmu-io-voltage-domain",
561                 .data = &soc_data_rv1108_pmu
562         },
563         {
564                 .compatible = "rockchip,rv1126-pmu-io-voltage-domain",
565                 .data = &soc_data_rv1126_pmu
566         },
567         { /* sentinel */ },
568 };
569 MODULE_DEVICE_TABLE(of, rockchip_iodomain_match);
570
571 static int rockchip_iodomain_probe(struct platform_device *pdev)
572 {
573         struct device_node *np = pdev->dev.of_node;
574         const struct of_device_id *match;
575         struct rockchip_iodomain *iod;
576         struct device *parent;
577         int i, ret = 0;
578
579         if (!np)
580                 return -ENODEV;
581
582         iod = devm_kzalloc(&pdev->dev, sizeof(*iod), GFP_KERNEL);
583         if (!iod)
584                 return -ENOMEM;
585
586         iod->dev = &pdev->dev;
587         platform_set_drvdata(pdev, iod);
588
589         match = of_match_node(rockchip_iodomain_match, np);
590         iod->soc_data = match->data;
591
592         if (iod->soc_data->write)
593                 iod->write = iod->soc_data->write;
594         else
595                 iod->write = rockchip_iodomain_write;
596
597         parent = pdev->dev.parent;
598         if (parent && parent->of_node) {
599                 iod->grf = syscon_node_to_regmap(parent->of_node);
600         } else {
601                 dev_dbg(&pdev->dev, "falling back to old binding\n");
602                 iod->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
603         }
604
605         if (IS_ERR(iod->grf)) {
606                 dev_err(&pdev->dev, "couldn't find grf regmap\n");
607                 return PTR_ERR(iod->grf);
608         }
609
610         for (i = 0; i < MAX_SUPPLIES; i++) {
611                 const char *supply_name = iod->soc_data->supply_names[i];
612                 struct rockchip_iodomain_supply *supply = &iod->supplies[i];
613                 struct regulator *reg;
614                 int uV;
615
616                 if (!supply_name)
617                         continue;
618
619                 reg = devm_regulator_get_optional(iod->dev, supply_name);
620                 if (IS_ERR(reg)) {
621                         ret = PTR_ERR(reg);
622
623                         /* If a supply wasn't specified, that's OK */
624                         if (ret == -ENODEV)
625                                 continue;
626                         else if (ret != -EPROBE_DEFER)
627                                 dev_err(iod->dev, "couldn't get regulator %s\n",
628                                         supply_name);
629                         goto unreg_notify;
630                 }
631
632                 /* set initial correct value */
633                 uV = regulator_get_voltage(reg);
634
635                 /* must be a regulator we can get the voltage of */
636                 if (uV < 0) {
637                         dev_err(iod->dev, "Can't determine voltage: %s\n",
638                                 supply_name);
639                         ret = uV;
640                         goto unreg_notify;
641                 }
642
643                 if (uV > MAX_VOLTAGE_3_3) {
644                         dev_crit(iod->dev,
645                                  "%d uV is too high. May damage SoC!\n",
646                                  uV);
647                         ret = -EINVAL;
648                         goto unreg_notify;
649                 }
650
651                 /* setup our supply */
652                 supply->idx = i;
653                 supply->iod = iod;
654                 supply->reg = reg;
655                 supply->nb.notifier_call = rockchip_iodomain_notify;
656
657                 ret = iod->write(supply, uV);
658                 if (ret) {
659                         supply->reg = NULL;
660                         goto unreg_notify;
661                 }
662
663                 /* register regulator notifier */
664                 ret = regulator_register_notifier(reg, &supply->nb);
665                 if (ret) {
666                         dev_err(&pdev->dev,
667                                 "regulator notifier request failed\n");
668                         supply->reg = NULL;
669                         goto unreg_notify;
670                 }
671         }
672
673         if (iod->soc_data->init)
674                 iod->soc_data->init(iod);
675
676         return 0;
677
678 unreg_notify:
679         for (i = MAX_SUPPLIES - 1; i >= 0; i--) {
680                 struct rockchip_iodomain_supply *io_supply = &iod->supplies[i];
681
682                 if (io_supply->reg)
683                         regulator_unregister_notifier(io_supply->reg,
684                                                       &io_supply->nb);
685         }
686
687         return ret;
688 }
689
690 static int rockchip_iodomain_remove(struct platform_device *pdev)
691 {
692         struct rockchip_iodomain *iod = platform_get_drvdata(pdev);
693         int i;
694
695         for (i = MAX_SUPPLIES - 1; i >= 0; i--) {
696                 struct rockchip_iodomain_supply *io_supply = &iod->supplies[i];
697
698                 if (io_supply->reg)
699                         regulator_unregister_notifier(io_supply->reg,
700                                                       &io_supply->nb);
701         }
702
703         return 0;
704 }
705
706 static struct platform_driver rockchip_iodomain_driver = {
707         .probe   = rockchip_iodomain_probe,
708         .remove  = rockchip_iodomain_remove,
709         .driver  = {
710                 .name  = "rockchip-iodomain",
711                 .of_match_table = rockchip_iodomain_match,
712         },
713 };
714
715 module_platform_driver(rockchip_iodomain_driver);
716
717 MODULE_DESCRIPTION("Rockchip IO-domain driver");
718 MODULE_AUTHOR("Heiko Stuebner <[email protected]>");
719 MODULE_AUTHOR("Doug Anderson <[email protected]>");
720 MODULE_LICENSE("GPL v2");
This page took 0.111032 seconds and 4 git commands to generate.