core.c 14.4 KB
Newer Older
M
Magnus Damm 已提交
1
/*
2
 * SuperH Pin Function Controller support.
M
Magnus Damm 已提交
3 4
 *
 * Copyright (C) 2008 Magnus Damm
5
 * Copyright (C) 2009 - 2012 Paul Mundt
M
Magnus Damm 已提交
6 7 8 9 10
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
11 12

#define DRV_NAME "sh-pfc"
13

14
#include <linux/bitops.h>
M
Magnus Damm 已提交
15
#include <linux/err.h>
16
#include <linux/errno.h>
M
Magnus Damm 已提交
17
#include <linux/io.h>
M
Magnus Damm 已提交
18
#include <linux/ioport.h>
19 20
#include <linux/kernel.h>
#include <linux/module.h>
L
Laurent Pinchart 已提交
21 22
#include <linux/of.h>
#include <linux/of_device.h>
23
#include <linux/pinctrl/machine.h>
24
#include <linux/platform_device.h>
25
#include <linux/slab.h>
M
Magnus Damm 已提交
26

27 28
#include "core.h"

29
static int sh_pfc_ioremap(struct sh_pfc *pfc, struct platform_device *pdev)
M
Magnus Damm 已提交
30 31
{
	struct resource *res;
32
	unsigned int k;
M
Magnus Damm 已提交
33

34 35
	if (pdev->num_resources == 0)
		return -EINVAL;
M
Magnus Damm 已提交
36

37 38 39
	pfc->windows = devm_kzalloc(pfc->dev, pdev->num_resources *
				    sizeof(*pfc->windows), GFP_NOWAIT);
	if (!pfc->windows)
L
Laurent Pinchart 已提交
40
		return -ENOMEM;
M
Magnus Damm 已提交
41

42
	pfc->num_windows = pdev->num_resources;
43

44
	for (k = 0, res = pdev->resource; k < pdev->num_resources; k++, res++) {
M
Magnus Damm 已提交
45
		WARN_ON(resource_type(res) != IORESOURCE_MEM);
46 47 48 49 50 51
		pfc->windows[k].phys = res->start;
		pfc->windows[k].size = resource_size(res);
		pfc->windows[k].virt =
			devm_ioremap_nocache(pfc->dev, res->start,
					     resource_size(res));
		if (!pfc->windows[k].virt)
L
Laurent Pinchart 已提交
52
			return -ENOMEM;
M
Magnus Damm 已提交
53 54 55 56 57
	}

	return 0;
}

58 59
static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc,
					 unsigned long address)
M
Magnus Damm 已提交
60
{
61
	struct sh_pfc_window *window;
62
	unsigned int i;
M
Magnus Damm 已提交
63 64

	/* scan through physical windows and convert address */
65
	for (i = 0; i < pfc->num_windows; i++) {
66
		window = pfc->windows + i;
M
Magnus Damm 已提交
67 68 69 70 71 72 73 74 75 76

		if (address < window->phys)
			continue;

		if (address >= (window->phys + window->size))
			continue;

		return window->virt + (address - window->phys);
	}

77
	BUG();
78
	return NULL;
M
Magnus Damm 已提交
79
}
M
Magnus Damm 已提交
80

81
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin)
82
{
83 84 85
	unsigned int offset;
	unsigned int i;

86 87
	for (i = 0, offset = 0; i < pfc->nr_ranges; ++i) {
		const struct sh_pfc_pin_range *range = &pfc->ranges[i];
88 89

		if (pin <= range->end)
90 91
			return pin >= range->start
			     ? offset + pin - range->start : -1;
92

93
		offset += range->end - range->start + 1;
94 95
	}

96
	return -EINVAL;
97 98
}

99
static int sh_pfc_enum_in_range(u16 enum_id, const struct pinmux_range *r)
M
Magnus Damm 已提交
100 101 102 103 104 105 106 107 108 109
{
	if (enum_id < r->begin)
		return 0;

	if (enum_id > r->end)
		return 0;

	return 1;
}

110 111
unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg,
				  unsigned long reg_width)
M
Magnus Damm 已提交
112 113 114
{
	switch (reg_width) {
	case 8:
M
Magnus Damm 已提交
115
		return ioread8(mapped_reg);
M
Magnus Damm 已提交
116
	case 16:
M
Magnus Damm 已提交
117
		return ioread16(mapped_reg);
M
Magnus Damm 已提交
118
	case 32:
M
Magnus Damm 已提交
119
		return ioread32(mapped_reg);
M
Magnus Damm 已提交
120 121 122 123 124 125
	}

	BUG();
	return 0;
}

126 127
void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width,
			  unsigned long data)
M
Magnus Damm 已提交
128 129 130
{
	switch (reg_width) {
	case 8:
M
Magnus Damm 已提交
131
		iowrite8(data, mapped_reg);
M
Magnus Damm 已提交
132 133
		return;
	case 16:
M
Magnus Damm 已提交
134
		iowrite16(data, mapped_reg);
M
Magnus Damm 已提交
135 136
		return;
	case 32:
M
Magnus Damm 已提交
137
		iowrite32(data, mapped_reg);
M
Magnus Damm 已提交
138 139 140 141 142 143
		return;
	}

	BUG();
}

144
static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
L
Laurent Pinchart 已提交
145
				     const struct pinmux_cfg_reg *crp,
146 147 148 149
				     unsigned long in_pos,
				     void __iomem **mapped_regp,
				     unsigned long *maskp,
				     unsigned long *posp)
M
Magnus Damm 已提交
150
{
151
	unsigned int k;
152

153
	*mapped_regp = sh_pfc_phys_to_virt(pfc, crp->reg);
M
Magnus Damm 已提交
154

155 156 157 158 159 160 161 162 163
	if (crp->field_width) {
		*maskp = (1 << crp->field_width) - 1;
		*posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
	} else {
		*maskp = (1 << crp->var_field_width[in_pos]) - 1;
		*posp = crp->reg_width;
		for (k = 0; k <= in_pos; k++)
			*posp -= crp->var_field_width[k];
	}
164 165
}

166
static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
L
Laurent Pinchart 已提交
167
				    const struct pinmux_cfg_reg *crp,
168
				    unsigned long field, unsigned long value)
M
Magnus Damm 已提交
169
{
170
	void __iomem *mapped_reg;
M
Magnus Damm 已提交
171
	unsigned long mask, pos, data;
M
Magnus Damm 已提交
172

173
	sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos);
M
Magnus Damm 已提交
174

175 176 177
	dev_dbg(pfc->dev, "write_reg addr = %lx, value = %ld, field = %ld, "
		"r_width = %ld, f_width = %ld\n",
		crp->reg, value, field, crp->reg_width, crp->field_width);
M
Magnus Damm 已提交
178 179 180

	mask = ~(mask << pos);
	value = value << pos;
M
Magnus Damm 已提交
181

182
	data = sh_pfc_read_raw_reg(mapped_reg, crp->reg_width);
M
Magnus Damm 已提交
183 184 185
	data &= mask;
	data |= value;

186
	if (pfc->info->unlock_reg)
187
		sh_pfc_write_raw_reg(
188
			sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32,
189
			~data);
M
Magnus Damm 已提交
190

191
	sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data);
M
Magnus Damm 已提交
192 193
}

194
static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id,
L
Laurent Pinchart 已提交
195
				 const struct pinmux_cfg_reg **crp, int *fieldp,
196
				 int *valuep)
M
Magnus Damm 已提交
197
{
L
Laurent Pinchart 已提交
198
	const struct pinmux_cfg_reg *config_reg;
199
	unsigned long r_width, f_width, curr_width, ncomb;
200
	unsigned int k, m, n, pos, bit_pos;
M
Magnus Damm 已提交
201 202 203

	k = 0;
	while (1) {
204
		config_reg = pfc->info->cfg_regs + k;
M
Magnus Damm 已提交
205 206 207 208 209 210

		r_width = config_reg->reg_width;
		f_width = config_reg->field_width;

		if (!r_width)
			break;
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227

		pos = 0;
		m = 0;
		for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
			if (f_width)
				curr_width = f_width;
			else
				curr_width = config_reg->var_field_width[m];

			ncomb = 1 << curr_width;
			for (n = 0; n < ncomb; n++) {
				if (config_reg->enum_ids[pos + n] == enum_id) {
					*crp = config_reg;
					*fieldp = m;
					*valuep = n;
					return 0;
				}
M
Magnus Damm 已提交
228
			}
229 230
			pos += ncomb;
			m++;
M
Magnus Damm 已提交
231 232 233 234
		}
		k++;
	}

235
	return -EINVAL;
M
Magnus Damm 已提交
236 237
}

238 239
static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, u16 mark, int pos,
			      u16 *enum_idp)
M
Magnus Damm 已提交
240
{
241
	const u16 *data = pfc->info->gpio_data;
242
	unsigned int k;
M
Magnus Damm 已提交
243 244 245 246 247 248

	if (pos) {
		*enum_idp = data[pos + 1];
		return pos + 1;
	}

249
	for (k = 0; k < pfc->info->gpio_data_size; k++) {
250
		if (data[k] == mark) {
M
Magnus Damm 已提交
251 252 253 254 255
			*enum_idp = data[k + 1];
			return k + 1;
		}
	}

256 257
	dev_err(pfc->dev, "cannot locate data/mark enum_id for mark %d\n",
		mark);
258
	return -EINVAL;
M
Magnus Damm 已提交
259 260
}

261
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
M
Magnus Damm 已提交
262
{
L
Laurent Pinchart 已提交
263
	const struct pinmux_cfg_reg *cr = NULL;
264
	u16 enum_id;
L
Laurent Pinchart 已提交
265
	const struct pinmux_range *range;
266
	int in_range, pos, field, value;
267
	int ret;
M
Magnus Damm 已提交
268 269

	switch (pinmux_type) {
270
	case PINMUX_TYPE_GPIO:
M
Magnus Damm 已提交
271 272 273 274 275
	case PINMUX_TYPE_FUNCTION:
		range = NULL;
		break;

	case PINMUX_TYPE_OUTPUT:
276
		range = &pfc->info->output;
M
Magnus Damm 已提交
277 278 279
		break;

	case PINMUX_TYPE_INPUT:
280
		range = &pfc->info->input;
M
Magnus Damm 已提交
281 282 283
		break;

	default:
284
		return -EINVAL;
M
Magnus Damm 已提交
285 286 287 288
	}

	pos = 0;
	enum_id = 0;
289 290
	field = 0;
	value = 0;
291 292

	/* Iterate over all the configuration fields we need to update. */
M
Magnus Damm 已提交
293
	while (1) {
294
		pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
295 296
		if (pos < 0)
			return pos;
M
Magnus Damm 已提交
297 298 299 300

		if (!enum_id)
			break;

301 302 303 304
		/* Check if the configuration field selects a function. If it
		 * doesn't, skip the field if it's not applicable to the
		 * requested pinmux type.
		 */
305
		in_range = sh_pfc_enum_in_range(enum_id, &pfc->info->function);
306
		if (!in_range) {
307 308 309 310 311 312 313 314
			if (pinmux_type == PINMUX_TYPE_FUNCTION) {
				/* Functions are allowed to modify all
				 * fields.
				 */
				in_range = 1;
			} else if (pinmux_type != PINMUX_TYPE_GPIO) {
				/* Input/output types can only modify fields
				 * that correspond to their respective ranges.
315
				 */
316
				in_range = sh_pfc_enum_in_range(enum_id, range);
317 318 319 320 321 322 323 324 325

				/*
				 * special case pass through for fixed
				 * input-only or output-only pins without
				 * function enum register association.
				 */
				if (in_range && enum_id == range->force)
					continue;
			}
326
			/* GPIOs are only allowed to modify function fields. */
327 328
		}

M
Magnus Damm 已提交
329 330 331
		if (!in_range)
			continue;

332 333 334
		ret = sh_pfc_get_config_reg(pfc, enum_id, &cr, &field, &value);
		if (ret < 0)
			return ret;
M
Magnus Damm 已提交
335

336
		sh_pfc_write_config_reg(pfc, cr, field, value);
M
Magnus Damm 已提交
337 338 339 340 341
	}

	return 0;
}

342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
static int sh_pfc_init_ranges(struct sh_pfc *pfc)
{
	struct sh_pfc_pin_range *range;
	unsigned int nr_ranges;
	unsigned int i;

	if (pfc->info->pins[0].pin == (u16)-1) {
		/* Pin number -1 denotes that the SoC doesn't report pin numbers
		 * in its pin arrays yet. Consider the pin numbers range as
		 * continuous and allocate a single range.
		 */
		pfc->nr_ranges = 1;
		pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges),
					   GFP_KERNEL);
		if (pfc->ranges == NULL)
			return -ENOMEM;

		pfc->ranges->start = 0;
		pfc->ranges->end = pfc->info->nr_pins - 1;
		pfc->nr_gpio_pins = pfc->info->nr_pins;

		return 0;
	}

366 367 368 369
	/* Count, allocate and fill the ranges. The PFC SoC data pins array must
	 * be sorted by pin numbers, and pins without a GPIO port must come
	 * last.
	 */
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
	for (i = 1, nr_ranges = 1; i < pfc->info->nr_pins; ++i) {
		if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1)
			nr_ranges++;
	}

	pfc->nr_ranges = nr_ranges;
	pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges) * nr_ranges,
				   GFP_KERNEL);
	if (pfc->ranges == NULL)
		return -ENOMEM;

	range = pfc->ranges;
	range->start = pfc->info->pins[0].pin;

	for (i = 1; i < pfc->info->nr_pins; ++i) {
385 386 387 388 389 390 391 392 393
		if (pfc->info->pins[i-1].pin == pfc->info->pins[i].pin - 1)
			continue;

		range->end = pfc->info->pins[i-1].pin;
		if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO))
			pfc->nr_gpio_pins = range->end + 1;

		range++;
		range->start = pfc->info->pins[i].pin;
394 395 396
	}

	range->end = pfc->info->pins[i-1].pin;
397 398
	if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO))
		pfc->nr_gpio_pins = range->end + 1;
399 400 401 402

	return 0;
}

L
Laurent Pinchart 已提交
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
#ifdef CONFIG_OF
static const struct of_device_id sh_pfc_of_table[] = {
#ifdef CONFIG_PINCTRL_PFC_R8A73A4
	{
		.compatible = "renesas,pfc-r8a73a4",
		.data = &r8a73a4_pinmux_info,
	},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7740
	{
		.compatible = "renesas,pfc-r8a7740",
		.data = &r8a7740_pinmux_info,
	},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7778
	{
		.compatible = "renesas,pfc-r8a7778",
		.data = &r8a7778_pinmux_info,
	},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7779
	{
		.compatible = "renesas,pfc-r8a7779",
		.data = &r8a7779_pinmux_info,
	},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7790
	{
		.compatible = "renesas,pfc-r8a7790",
		.data = &r8a7790_pinmux_info,
	},
#endif
435 436 437 438 439 440
#ifdef CONFIG_PINCTRL_PFC_R8A7791
	{
		.compatible = "renesas,pfc-r8a7791",
		.data = &r8a7791_pinmux_info,
	},
#endif
L
Laurent Pinchart 已提交
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
#ifdef CONFIG_PINCTRL_PFC_SH7372
	{
		.compatible = "renesas,pfc-sh7372",
		.data = &sh7372_pinmux_info,
	},
#endif
#ifdef CONFIG_PINCTRL_PFC_SH73A0
	{
		.compatible = "renesas,pfc-sh73a0",
		.data = &sh73a0_pinmux_info,
	},
#endif
	{ },
};
MODULE_DEVICE_TABLE(of, sh_pfc_of_table);
#endif

458
static int sh_pfc_probe(struct platform_device *pdev)
M
Magnus Damm 已提交
459
{
L
Laurent Pinchart 已提交
460 461 462 463
	const struct platform_device_id *platid = platform_get_device_id(pdev);
#ifdef CONFIG_OF
	struct device_node *np = pdev->dev.of_node;
#endif
L
Laurent Pinchart 已提交
464
	const struct sh_pfc_soc_info *info;
465
	struct sh_pfc *pfc;
M
Magnus Damm 已提交
466
	int ret;
M
Magnus Damm 已提交
467

L
Laurent Pinchart 已提交
468 469 470 471 472 473 474
#ifdef CONFIG_OF
	if (np)
		info = of_match_device(sh_pfc_of_table, &pdev->dev)->data;
	else
#endif
		info = platid ? (const void *)platid->driver_data : NULL;

475
	if (info == NULL)
476
		return -ENODEV;
M
Magnus Damm 已提交
477

478
	pfc = devm_kzalloc(&pdev->dev, sizeof(*pfc), GFP_KERNEL);
479 480
	if (pfc == NULL)
		return -ENOMEM;
481

482
	pfc->info = info;
483 484
	pfc->dev = &pdev->dev;

485
	ret = sh_pfc_ioremap(pfc, pdev);
486
	if (unlikely(ret < 0))
M
Magnus Damm 已提交
487 488
		return ret;

489
	spin_lock_init(&pfc->lock);
M
Magnus Damm 已提交
490

491 492 493 494 495 496
	if (info->ops && info->ops->init) {
		ret = info->ops->init(pfc);
		if (ret < 0)
			return ret;
	}

497
	pinctrl_provide_dummies();
M
Magnus Damm 已提交
498

499 500 501 502
	ret = sh_pfc_init_ranges(pfc);
	if (ret < 0)
		return ret;

503 504 505
	/*
	 * Initialize pinctrl bindings first
	 */
506
	ret = sh_pfc_register_pinctrl(pfc);
507
	if (unlikely(ret != 0))
508
		goto error;
509

510
#ifdef CONFIG_GPIO_SH_PFC
511 512 513
	/*
	 * Then the GPIO chip
	 */
514
	ret = sh_pfc_register_gpiochip(pfc);
515
	if (unlikely(ret != 0)) {
516 517 518 519 520
		/*
		 * If the GPIO chip fails to come up we still leave the
		 * PFC state as it is, given that there are already
		 * extant users of it that have succeeded by this point.
		 */
521
		dev_notice(pfc->dev, "failed to init GPIO chip, ignoring...\n");
522
	}
523
#endif
524

525 526
	platform_set_drvdata(pdev, pfc);

527
	dev_info(pfc->dev, "%s support registered\n", info->name);
528

529
	return 0;
530 531 532 533 534

error:
	if (info->ops && info->ops->exit)
		info->ops->exit(pfc);
	return ret;
535
}
536

537 538 539 540 541 542 543 544 545
static int sh_pfc_remove(struct platform_device *pdev)
{
	struct sh_pfc *pfc = platform_get_drvdata(pdev);

#ifdef CONFIG_GPIO_SH_PFC
	sh_pfc_unregister_gpiochip(pfc);
#endif
	sh_pfc_unregister_pinctrl(pfc);

546 547 548
	if (pfc->info->ops && pfc->info->ops->exit)
		pfc->info->ops->exit(pfc);

549 550 551 552
	return 0;
}

static const struct platform_device_id sh_pfc_id_table[] = {
M
Magnus Damm 已提交
553 554 555
#ifdef CONFIG_PINCTRL_PFC_R8A73A4
	{ "pfc-r8a73a4", (kernel_ulong_t)&r8a73a4_pinmux_info },
#endif
556 557
#ifdef CONFIG_PINCTRL_PFC_R8A7740
	{ "pfc-r8a7740", (kernel_ulong_t)&r8a7740_pinmux_info },
558
#endif
559 560 561
#ifdef CONFIG_PINCTRL_PFC_R8A7778
	{ "pfc-r8a7778", (kernel_ulong_t)&r8a7778_pinmux_info },
#endif
562 563
#ifdef CONFIG_PINCTRL_PFC_R8A7779
	{ "pfc-r8a7779", (kernel_ulong_t)&r8a7779_pinmux_info },
564
#endif
565 566 567
#ifdef CONFIG_PINCTRL_PFC_R8A7790
	{ "pfc-r8a7790", (kernel_ulong_t)&r8a7790_pinmux_info },
#endif
568 569 570
#ifdef CONFIG_PINCTRL_PFC_R8A7791
	{ "pfc-r8a7791", (kernel_ulong_t)&r8a7791_pinmux_info },
#endif
571 572 573
#ifdef CONFIG_PINCTRL_PFC_SH7203
	{ "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info },
#endif
574 575 576
#ifdef CONFIG_PINCTRL_PFC_SH7264
	{ "pfc-sh7264", (kernel_ulong_t)&sh7264_pinmux_info },
#endif
577 578 579
#ifdef CONFIG_PINCTRL_PFC_SH7269
	{ "pfc-sh7269", (kernel_ulong_t)&sh7269_pinmux_info },
#endif
580 581
#ifdef CONFIG_PINCTRL_PFC_SH7372
	{ "pfc-sh7372", (kernel_ulong_t)&sh7372_pinmux_info },
582 583 584
#endif
#ifdef CONFIG_PINCTRL_PFC_SH73A0
	{ "pfc-sh73a0", (kernel_ulong_t)&sh73a0_pinmux_info },
585 586 587
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7720
	{ "pfc-sh7720", (kernel_ulong_t)&sh7720_pinmux_info },
588 589 590
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7722
	{ "pfc-sh7722", (kernel_ulong_t)&sh7722_pinmux_info },
591 592 593
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7723
	{ "pfc-sh7723", (kernel_ulong_t)&sh7723_pinmux_info },
594 595 596
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7724
	{ "pfc-sh7724", (kernel_ulong_t)&sh7724_pinmux_info },
597 598 599
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7734
	{ "pfc-sh7734", (kernel_ulong_t)&sh7734_pinmux_info },
600 601 602
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7757
	{ "pfc-sh7757", (kernel_ulong_t)&sh7757_pinmux_info },
603 604 605
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7785
	{ "pfc-sh7785", (kernel_ulong_t)&sh7785_pinmux_info },
606 607 608
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7786
	{ "pfc-sh7786", (kernel_ulong_t)&sh7786_pinmux_info },
609 610 611
#endif
#ifdef CONFIG_PINCTRL_PFC_SHX3
	{ "pfc-shx3", (kernel_ulong_t)&shx3_pinmux_info },
612
#endif
613 614 615 616 617 618 619 620 621 622 623 624
	{ "sh-pfc", 0 },
	{ },
};
MODULE_DEVICE_TABLE(platform, sh_pfc_id_table);

static struct platform_driver sh_pfc_driver = {
	.probe		= sh_pfc_probe,
	.remove		= sh_pfc_remove,
	.id_table	= sh_pfc_id_table,
	.driver		= {
		.name	= DRV_NAME,
		.owner	= THIS_MODULE,
L
Laurent Pinchart 已提交
625
		.of_match_table = of_match_ptr(sh_pfc_of_table),
626 627 628
	},
};

629 630 631
static int __init sh_pfc_init(void)
{
	return platform_driver_register(&sh_pfc_driver);
632
}
633
postcore_initcall(sh_pfc_init);
634 635 636 637 638 639 640

static void __exit sh_pfc_exit(void)
{
	platform_driver_unregister(&sh_pfc_driver);
}
module_exit(sh_pfc_exit);

641 642 643
MODULE_AUTHOR("Magnus Damm, Paul Mundt, Laurent Pinchart");
MODULE_DESCRIPTION("Pin Control and GPIO driver for SuperH pin function controller");
MODULE_LICENSE("GPL v2");