sh-pfc: Simplify the sh_pfc_gpio_is_pin() logic
[deliverable/linux.git] / drivers / pinctrl / sh-pfc / core.c
CommitLineData
2967dab1 1/*
b3c185a7 2 * SuperH Pin Function Controller support.
2967dab1
MD
3 *
4 * Copyright (C) 2008 Magnus Damm
b3c185a7 5 * Copyright (C) 2009 - 2012 Paul Mundt
2967dab1
MD
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
c6193eac
LP
11
12#define DRV_NAME "sh-pfc"
f9492fda 13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
b72421d8 14
90efde22 15#include <linux/bitops.h>
2967dab1 16#include <linux/err.h>
90efde22 17#include <linux/errno.h>
2967dab1 18#include <linux/io.h>
b0e10211 19#include <linux/ioport.h>
90efde22
LP
20#include <linux/kernel.h>
21#include <linux/module.h>
ca5481c6 22#include <linux/pinctrl/machine.h>
c6193eac 23#include <linux/platform_device.h>
90efde22 24#include <linux/slab.h>
b0e10211 25
f9165132
LP
26#include "core.h"
27
973931ae 28static int sh_pfc_ioremap(struct sh_pfc *pfc, struct platform_device *pdev)
b0e10211
MD
29{
30 struct resource *res;
31 int k;
32
56dc04af 33 if (pdev->num_resources == 0) {
973931ae 34 pfc->num_windows = 0;
b0e10211 35 return 0;
973931ae 36 }
b0e10211 37
56dc04af 38 pfc->window = devm_kzalloc(pfc->dev, pdev->num_resources *
1724acfd 39 sizeof(*pfc->window), GFP_NOWAIT);
b3c185a7 40 if (!pfc->window)
1724acfd 41 return -ENOMEM;
b0e10211 42
56dc04af 43 pfc->num_windows = pdev->num_resources;
973931ae 44
56dc04af 45 for (k = 0, res = pdev->resource; k < pdev->num_resources; k++, res++) {
b0e10211 46 WARN_ON(resource_type(res) != IORESOURCE_MEM);
b3c185a7
PM
47 pfc->window[k].phys = res->start;
48 pfc->window[k].size = resource_size(res);
c9fa88e2
LP
49 pfc->window[k].virt = devm_ioremap_nocache(pfc->dev, res->start,
50 resource_size(res));
51 if (!pfc->window[k].virt)
1724acfd 52 return -ENOMEM;
b0e10211
MD
53 }
54
55 return 0;
b0e10211
MD
56}
57
4aeacd5b
LP
58static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc,
59 unsigned long address)
b0e10211 60{
4aeacd5b 61 struct sh_pfc_window *window;
b0e10211
MD
62 int k;
63
64 /* scan through physical windows and convert address */
973931ae 65 for (k = 0; k < pfc->num_windows; k++) {
b3c185a7 66 window = pfc->window + k;
b0e10211
MD
67
68 if (address < window->phys)
69 continue;
70
71 if (address >= (window->phys + window->size))
72 continue;
73
74 return window->virt + (address - window->phys);
75 }
76
77 /* no windows defined, register must be 1:1 mapped virt:phys */
78 return (void __iomem *)address;
79}
2967dab1 80
4aeacd5b 81static int sh_pfc_enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
2967dab1
MD
82{
83 if (enum_id < r->begin)
84 return 0;
85
86 if (enum_id > r->end)
87 return 0;
88
89 return 1;
90}
91
4aeacd5b
LP
92static unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg,
93 unsigned long reg_width)
3292094e
MD
94{
95 switch (reg_width) {
96 case 8:
b0e10211 97 return ioread8(mapped_reg);
3292094e 98 case 16:
b0e10211 99 return ioread16(mapped_reg);
3292094e 100 case 32:
b0e10211 101 return ioread32(mapped_reg);
3292094e
MD
102 }
103
104 BUG();
105 return 0;
106}
107
4aeacd5b
LP
108static void sh_pfc_write_raw_reg(void __iomem *mapped_reg,
109 unsigned long reg_width, unsigned long data)
3292094e
MD
110{
111 switch (reg_width) {
112 case 8:
b0e10211 113 iowrite8(data, mapped_reg);
3292094e
MD
114 return;
115 case 16:
b0e10211 116 iowrite16(data, mapped_reg);
3292094e
MD
117 return;
118 case 32:
b0e10211 119 iowrite32(data, mapped_reg);
3292094e
MD
120 return;
121 }
122
123 BUG();
124}
125
b3c185a7 126int sh_pfc_read_bit(struct pinmux_data_reg *dr, unsigned long in_pos)
92554d97
MD
127{
128 unsigned long pos;
129
130 pos = dr->reg_width - (in_pos + 1);
131
132 pr_debug("read_bit: addr = %lx, pos = %ld, "
133 "r_width = %ld\n", dr->reg, pos, dr->reg_width);
134
4aeacd5b 135 return (sh_pfc_read_raw_reg(dr->mapped_reg, dr->reg_width) >> pos) & 1;
92554d97
MD
136}
137
b3c185a7
PM
138void sh_pfc_write_bit(struct pinmux_data_reg *dr, unsigned long in_pos,
139 unsigned long value)
3292094e
MD
140{
141 unsigned long pos;
142
143 pos = dr->reg_width - (in_pos + 1);
144
ca6f2d7f 145 pr_debug("write_bit addr = %lx, value = %d, pos = %ld, "
fd2cb0ce
PM
146 "r_width = %ld\n",
147 dr->reg, !!value, pos, dr->reg_width);
3292094e
MD
148
149 if (value)
150 set_bit(pos, &dr->reg_shadow);
151 else
152 clear_bit(pos, &dr->reg_shadow);
153
4aeacd5b 154 sh_pfc_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
3292094e
MD
155}
156
4aeacd5b
LP
157static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
158 struct pinmux_cfg_reg *crp,
159 unsigned long in_pos,
160 void __iomem **mapped_regp,
161 unsigned long *maskp,
162 unsigned long *posp)
2967dab1 163{
f78a26f5
MD
164 int k;
165
4aeacd5b 166 *mapped_regp = sh_pfc_phys_to_virt(pfc, crp->reg);
2967dab1 167
f78a26f5
MD
168 if (crp->field_width) {
169 *maskp = (1 << crp->field_width) - 1;
170 *posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
171 } else {
172 *maskp = (1 << crp->var_field_width[in_pos]) - 1;
173 *posp = crp->reg_width;
174 for (k = 0; k <= in_pos; k++)
175 *posp -= crp->var_field_width[k];
176 }
18925e11
MD
177}
178
4aeacd5b
LP
179static int sh_pfc_read_config_reg(struct sh_pfc *pfc,
180 struct pinmux_cfg_reg *crp,
181 unsigned long field)
18925e11
MD
182{
183 void __iomem *mapped_reg;
184 unsigned long mask, pos;
185
4aeacd5b 186 sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos);
2967dab1 187
18925e11 188 pr_debug("read_reg: addr = %lx, field = %ld, "
fd2cb0ce 189 "r_width = %ld, f_width = %ld\n",
18925e11 190 crp->reg, field, crp->reg_width, crp->field_width);
2967dab1 191
4aeacd5b 192 return (sh_pfc_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
0fc64cc0
MD
193}
194
4aeacd5b
LP
195static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
196 struct pinmux_cfg_reg *crp,
197 unsigned long field, unsigned long value)
0fc64cc0 198{
18925e11 199 void __iomem *mapped_reg;
e499ada8 200 unsigned long mask, pos, data;
0fc64cc0 201
4aeacd5b 202 sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos);
2967dab1 203
18925e11 204 pr_debug("write_reg addr = %lx, value = %ld, field = %ld, "
fd2cb0ce 205 "r_width = %ld, f_width = %ld\n",
18925e11 206 crp->reg, value, field, crp->reg_width, crp->field_width);
0fc64cc0
MD
207
208 mask = ~(mask << pos);
209 value = value << pos;
2967dab1 210
4aeacd5b 211 data = sh_pfc_read_raw_reg(mapped_reg, crp->reg_width);
e499ada8
MD
212 data &= mask;
213 data |= value;
214
19bb7fe3 215 if (pfc->info->unlock_reg)
4aeacd5b 216 sh_pfc_write_raw_reg(
19bb7fe3 217 sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32,
4aeacd5b 218 ~data);
e499ada8 219
4aeacd5b 220 sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data);
2967dab1
MD
221}
222
0b73ee5d 223static void sh_pfc_setup_data_reg(struct sh_pfc *pfc, unsigned gpio)
2967dab1 224{
a3db40a6 225 struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio];
2967dab1
MD
226 struct pinmux_data_reg *data_reg;
227 int k, n;
228
2967dab1
MD
229 k = 0;
230 while (1) {
19bb7fe3 231 data_reg = pfc->info->data_regs + k;
2967dab1
MD
232
233 if (!data_reg->reg_width)
234 break;
235
4aeacd5b 236 data_reg->mapped_reg = sh_pfc_phys_to_virt(pfc, data_reg->reg);
b0e10211 237
2967dab1 238 for (n = 0; n < data_reg->reg_width; n++) {
18801be7
MD
239 if (data_reg->enum_ids[n] == gpiop->enum_id) {
240 gpiop->flags &= ~PINMUX_FLAG_DREG;
241 gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
242 gpiop->flags &= ~PINMUX_FLAG_DBIT;
243 gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
0b73ee5d 244 return;
2967dab1
MD
245 }
246 }
247 k++;
248 }
249
18801be7 250 BUG();
2967dab1
MD
251}
252
4aeacd5b 253static void sh_pfc_setup_data_regs(struct sh_pfc *pfc)
3292094e
MD
254{
255 struct pinmux_data_reg *drp;
256 int k;
257
0b73ee5d
LP
258 for (k = 0; k < pfc->info->nr_pins; k++) {
259 if (pfc->info->pins[k].enum_id == 0)
260 continue;
261
4aeacd5b 262 sh_pfc_setup_data_reg(pfc, k);
0b73ee5d 263 }
3292094e
MD
264
265 k = 0;
266 while (1) {
19bb7fe3 267 drp = pfc->info->data_regs + k;
3292094e
MD
268
269 if (!drp->reg_width)
270 break;
271
4aeacd5b
LP
272 drp->reg_shadow = sh_pfc_read_raw_reg(drp->mapped_reg,
273 drp->reg_width);
3292094e
MD
274 k++;
275 }
276}
277
0b73ee5d
LP
278void sh_pfc_get_data_reg(struct sh_pfc *pfc, unsigned gpio,
279 struct pinmux_data_reg **drp, int *bitp)
18801be7 280{
a3db40a6 281 struct sh_pfc_pin *gpiop = &pfc->info->pins[gpio];
18801be7
MD
282 int k, n;
283
18801be7
MD
284 k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
285 n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
19bb7fe3 286 *drp = pfc->info->data_regs + k;
18801be7 287 *bitp = n;
18801be7
MD
288}
289
4aeacd5b
LP
290static int sh_pfc_get_config_reg(struct sh_pfc *pfc, pinmux_enum_t enum_id,
291 struct pinmux_cfg_reg **crp, int *fieldp,
292 int *valuep, unsigned long **cntp)
2967dab1
MD
293{
294 struct pinmux_cfg_reg *config_reg;
f78a26f5
MD
295 unsigned long r_width, f_width, curr_width, ncomb;
296 int k, m, n, pos, bit_pos;
2967dab1
MD
297
298 k = 0;
299 while (1) {
19bb7fe3 300 config_reg = pfc->info->cfg_regs + k;
2967dab1
MD
301
302 r_width = config_reg->reg_width;
303 f_width = config_reg->field_width;
304
305 if (!r_width)
306 break;
f78a26f5
MD
307
308 pos = 0;
309 m = 0;
310 for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
311 if (f_width)
312 curr_width = f_width;
313 else
314 curr_width = config_reg->var_field_width[m];
315
316 ncomb = 1 << curr_width;
317 for (n = 0; n < ncomb; n++) {
318 if (config_reg->enum_ids[pos + n] == enum_id) {
319 *crp = config_reg;
320 *fieldp = m;
321 *valuep = n;
322 *cntp = &config_reg->cnt[m];
323 return 0;
324 }
2967dab1 325 }
f78a26f5
MD
326 pos += ncomb;
327 m++;
2967dab1
MD
328 }
329 k++;
330 }
331
332 return -1;
333}
334
a68fdca9
LP
335static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, pinmux_enum_t mark, int pos,
336 pinmux_enum_t *enum_idp)
2967dab1 337{
19bb7fe3 338 pinmux_enum_t *data = pfc->info->gpio_data;
2967dab1
MD
339 int k;
340
2967dab1
MD
341 if (pos) {
342 *enum_idp = data[pos + 1];
343 return pos + 1;
344 }
345
19bb7fe3 346 for (k = 0; k < pfc->info->gpio_data_size; k++) {
a68fdca9 347 if (data[k] == mark) {
2967dab1
MD
348 *enum_idp = data[k + 1];
349 return k + 1;
350 }
351 }
352
a68fdca9 353 pr_err("cannot locate data/mark enum_id for mark %d\n", mark);
2967dab1
MD
354 return -1;
355}
356
a68fdca9
LP
357int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type,
358 int cfg_mode)
2967dab1
MD
359{
360 struct pinmux_cfg_reg *cr = NULL;
361 pinmux_enum_t enum_id;
362 struct pinmux_range *range;
ad4a07ff 363 int in_range, pos, field, value;
2967dab1
MD
364 unsigned long *cntp;
365
366 switch (pinmux_type) {
367
368 case PINMUX_TYPE_FUNCTION:
369 range = NULL;
370 break;
371
372 case PINMUX_TYPE_OUTPUT:
19bb7fe3 373 range = &pfc->info->output;
2967dab1
MD
374 break;
375
376 case PINMUX_TYPE_INPUT:
19bb7fe3 377 range = &pfc->info->input;
2967dab1
MD
378 break;
379
380 case PINMUX_TYPE_INPUT_PULLUP:
19bb7fe3 381 range = &pfc->info->input_pu;
2967dab1
MD
382 break;
383
384 case PINMUX_TYPE_INPUT_PULLDOWN:
19bb7fe3 385 range = &pfc->info->input_pd;
2967dab1
MD
386 break;
387
388 default:
389 goto out_err;
390 }
391
392 pos = 0;
393 enum_id = 0;
ad4a07ff
MD
394 field = 0;
395 value = 0;
2967dab1 396 while (1) {
a68fdca9 397 pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
2967dab1
MD
398 if (pos <= 0)
399 goto out_err;
400
401 if (!enum_id)
402 break;
403
50dd3145 404 /* first check if this is a function enum */
19bb7fe3 405 in_range = sh_pfc_enum_in_range(enum_id, &pfc->info->function);
50dd3145
MD
406 if (!in_range) {
407 /* not a function enum */
408 if (range) {
409 /*
410 * other range exists, so this pin is
411 * a regular GPIO pin that now is being
412 * bound to a specific direction.
413 *
414 * for this case we only allow function enums
415 * and the enums that match the other range.
416 */
4aeacd5b 417 in_range = sh_pfc_enum_in_range(enum_id, range);
50dd3145
MD
418
419 /*
420 * special case pass through for fixed
421 * input-only or output-only pins without
422 * function enum register association.
423 */
424 if (in_range && enum_id == range->force)
425 continue;
426 } else {
427 /*
428 * no other range exists, so this pin
429 * must then be of the function type.
430 *
431 * allow function type pins to select
432 * any combination of function/in/out
433 * in their MARK lists.
434 */
435 in_range = 1;
436 }
42eed42b
MD
437 }
438
2967dab1
MD
439 if (!in_range)
440 continue;
441
4aeacd5b
LP
442 if (sh_pfc_get_config_reg(pfc, enum_id, &cr,
443 &field, &value, &cntp) != 0)
2967dab1
MD
444 goto out_err;
445
446 switch (cfg_mode) {
447 case GPIO_CFG_DRYRUN:
18925e11 448 if (!*cntp ||
4aeacd5b 449 (sh_pfc_read_config_reg(pfc, cr, field) != value))
2967dab1
MD
450 continue;
451 break;
452
453 case GPIO_CFG_REQ:
4aeacd5b 454 sh_pfc_write_config_reg(pfc, cr, field, value);
2967dab1
MD
455 *cntp = *cntp + 1;
456 break;
457
458 case GPIO_CFG_FREE:
459 *cntp = *cntp - 1;
460 break;
461 }
462 }
463
464 return 0;
465 out_err:
466 return -1;
467}
468
c6193eac 469static int sh_pfc_probe(struct platform_device *pdev)
2967dab1 470{
19bb7fe3 471 struct sh_pfc_soc_info *info;
c6193eac 472 struct sh_pfc *pfc;
0fc64cc0 473 int ret;
2967dab1 474
06d5631f
PM
475 /*
476 * Ensure that the type encoding fits
477 */
478 BUILD_BUG_ON(PINMUX_FLAG_TYPE > ((1 << PINMUX_FLAG_DBIT_SHIFT) - 1));
479
19bb7fe3
LP
480 info = pdev->id_entry->driver_data
481 ? (void *)pdev->id_entry->driver_data : pdev->dev.platform_data;
482 if (info == NULL)
c6193eac 483 return -ENODEV;
2967dab1 484
8c43fcc7 485 pfc = devm_kzalloc(&pdev->dev, sizeof(*pfc), GFP_KERNEL);
c6193eac
LP
486 if (pfc == NULL)
487 return -ENOMEM;
d4e62d00 488
19bb7fe3 489 pfc->info = info;
c6193eac
LP
490 pfc->dev = &pdev->dev;
491
973931ae 492 ret = sh_pfc_ioremap(pfc, pdev);
c6193eac 493 if (unlikely(ret < 0))
b0e10211
MD
494 return ret;
495
c6193eac 496 spin_lock_init(&pfc->lock);
69edbba0 497
ca5481c6 498 pinctrl_provide_dummies();
4aeacd5b 499 sh_pfc_setup_data_regs(pfc);
b0e10211 500
ca5481c6
PM
501 /*
502 * Initialize pinctrl bindings first
503 */
c6193eac 504 ret = sh_pfc_register_pinctrl(pfc);
f9492fda 505 if (unlikely(ret != 0))
c9fa88e2 506 return ret;
ca5481c6 507
6f6a4a68 508#ifdef CONFIG_GPIO_SH_PFC
ca5481c6
PM
509 /*
510 * Then the GPIO chip
511 */
c6193eac 512 ret = sh_pfc_register_gpiochip(pfc);
6f6a4a68 513 if (unlikely(ret != 0)) {
ca5481c6
PM
514 /*
515 * If the GPIO chip fails to come up we still leave the
516 * PFC state as it is, given that there are already
517 * extant users of it that have succeeded by this point.
518 */
6f6a4a68 519 pr_notice("failed to init GPIO chip, ignoring...\n");
b3c185a7 520 }
6f6a4a68 521#endif
b72421d8 522
c6193eac
LP
523 platform_set_drvdata(pdev, pfc);
524
19bb7fe3 525 pr_info("%s support registered\n", info->name);
ca5481c6 526
b3c185a7 527 return 0;
b72421d8 528}
6f6a4a68 529
c6193eac
LP
530static int sh_pfc_remove(struct platform_device *pdev)
531{
532 struct sh_pfc *pfc = platform_get_drvdata(pdev);
533
534#ifdef CONFIG_GPIO_SH_PFC
535 sh_pfc_unregister_gpiochip(pfc);
536#endif
537 sh_pfc_unregister_pinctrl(pfc);
538
c6193eac
LP
539 platform_set_drvdata(pdev, NULL);
540
541 return 0;
542}
543
544static const struct platform_device_id sh_pfc_id_table[] = {
d5b1521a
LP
545#ifdef CONFIG_PINCTRL_PFC_R8A7740
546 { "pfc-r8a7740", (kernel_ulong_t)&r8a7740_pinmux_info },
881023d2
LP
547#endif
548#ifdef CONFIG_PINCTRL_PFC_R8A7779
549 { "pfc-r8a7779", (kernel_ulong_t)&r8a7779_pinmux_info },
6e5469a6 550#endif
ccda552e
LP
551#ifdef CONFIG_PINCTRL_PFC_SH7203
552 { "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info },
553#endif
a8d42fc4
LP
554#ifdef CONFIG_PINCTRL_PFC_SH7264
555 { "pfc-sh7264", (kernel_ulong_t)&sh7264_pinmux_info },
556#endif
f5e811f2
LP
557#ifdef CONFIG_PINCTRL_PFC_SH7269
558 { "pfc-sh7269", (kernel_ulong_t)&sh7269_pinmux_info },
559#endif
6e5469a6
LP
560#ifdef CONFIG_PINCTRL_PFC_SH7372
561 { "pfc-sh7372", (kernel_ulong_t)&sh7372_pinmux_info },
5d5166dc
LP
562#endif
563#ifdef CONFIG_PINCTRL_PFC_SH73A0
564 { "pfc-sh73a0", (kernel_ulong_t)&sh73a0_pinmux_info },
74cad605
LP
565#endif
566#ifdef CONFIG_PINCTRL_PFC_SH7720
567 { "pfc-sh7720", (kernel_ulong_t)&sh7720_pinmux_info },
f5e25ae5
LP
568#endif
569#ifdef CONFIG_PINCTRL_PFC_SH7722
570 { "pfc-sh7722", (kernel_ulong_t)&sh7722_pinmux_info },
d05afa0a
LP
571#endif
572#ifdef CONFIG_PINCTRL_PFC_SH7723
573 { "pfc-sh7723", (kernel_ulong_t)&sh7723_pinmux_info },
0ff25bab
LP
574#endif
575#ifdef CONFIG_PINCTRL_PFC_SH7724
576 { "pfc-sh7724", (kernel_ulong_t)&sh7724_pinmux_info },
ac1ebc21
LP
577#endif
578#ifdef CONFIG_PINCTRL_PFC_SH7734
579 { "pfc-sh7734", (kernel_ulong_t)&sh7734_pinmux_info },
0bb92677
LP
580#endif
581#ifdef CONFIG_PINCTRL_PFC_SH7757
582 { "pfc-sh7757", (kernel_ulong_t)&sh7757_pinmux_info },
a56398e9
LP
583#endif
584#ifdef CONFIG_PINCTRL_PFC_SH7785
585 { "pfc-sh7785", (kernel_ulong_t)&sh7785_pinmux_info },
d2a31bdd
LP
586#endif
587#ifdef CONFIG_PINCTRL_PFC_SH7786
588 { "pfc-sh7786", (kernel_ulong_t)&sh7786_pinmux_info },
d5d9a818
LP
589#endif
590#ifdef CONFIG_PINCTRL_PFC_SHX3
591 { "pfc-shx3", (kernel_ulong_t)&shx3_pinmux_info },
d5b1521a 592#endif
c6193eac
LP
593 { "sh-pfc", 0 },
594 { },
595};
596MODULE_DEVICE_TABLE(platform, sh_pfc_id_table);
597
598static struct platform_driver sh_pfc_driver = {
599 .probe = sh_pfc_probe,
600 .remove = sh_pfc_remove,
601 .id_table = sh_pfc_id_table,
602 .driver = {
603 .name = DRV_NAME,
604 .owner = THIS_MODULE,
605 },
606};
607
40ee6fce
LP
608static int __init sh_pfc_init(void)
609{
610 return platform_driver_register(&sh_pfc_driver);
c6193eac 611}
40ee6fce 612postcore_initcall(sh_pfc_init);
c6193eac
LP
613
614static void __exit sh_pfc_exit(void)
615{
616 platform_driver_unregister(&sh_pfc_driver);
617}
618module_exit(sh_pfc_exit);
619
6f6a4a68
LP
620MODULE_AUTHOR("Magnus Damm, Paul Mundt, Laurent Pinchart");
621MODULE_DESCRIPTION("Pin Control and GPIO driver for SuperH pin function controller");
622MODULE_LICENSE("GPL v2");
This page took 0.283012 seconds and 5 git commands to generate.