core.c 14.7 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 30
static int sh_pfc_map_resources(struct sh_pfc *pfc,
				struct platform_device *pdev)
M
Magnus Damm 已提交
31
{
32 33 34 35
	unsigned int num_windows = 0;
	unsigned int num_irqs = 0;
	struct sh_pfc_window *windows;
	unsigned int *irqs = NULL;
M
Magnus Damm 已提交
36
	struct resource *res;
37 38 39 40 41 42 43 44 45 46 47 48 49 50
	unsigned int i;

	/* Count the MEM and IRQ resources. */
	for (i = 0; i < pdev->num_resources; ++i) {
		switch (resource_type(&pdev->resource[i])) {
		case IORESOURCE_MEM:
			num_windows++;
			break;

		case IORESOURCE_IRQ:
			num_irqs++;
			break;
		}
	}
M
Magnus Damm 已提交
51

52
	if (num_windows == 0)
53
		return -EINVAL;
M
Magnus Damm 已提交
54

55 56 57 58
	/* Allocate memory windows and IRQs arrays. */
	windows = devm_kzalloc(pfc->dev, num_windows * sizeof(*windows),
			       GFP_KERNEL);
	if (windows == NULL)
L
Laurent Pinchart 已提交
59
		return -ENOMEM;
M
Magnus Damm 已提交
60

61 62
	pfc->num_windows = num_windows;
	pfc->windows = windows;
63

64 65 66 67
	if (num_irqs) {
		irqs = devm_kzalloc(pfc->dev, num_irqs * sizeof(*irqs),
				    GFP_KERNEL);
		if (irqs == NULL)
L
Laurent Pinchart 已提交
68
			return -ENOMEM;
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

		pfc->num_irqs = num_irqs;
		pfc->irqs = irqs;
	}

	/* Fill them. */
	for (i = 0, res = pdev->resource; i < pdev->num_resources; i++, res++) {
		switch (resource_type(res)) {
		case IORESOURCE_MEM:
			windows->phys = res->start;
			windows->size = resource_size(res);
			windows->virt = devm_ioremap_resource(pfc->dev, res);
			if (IS_ERR(windows->virt))
				return -ENOMEM;
			windows++;
			break;

		case IORESOURCE_IRQ:
			*irqs++ = res->start;
			break;
		}
M
Magnus Damm 已提交
90 91 92 93 94
	}

	return 0;
}

95 96
static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc,
					 unsigned long address)
M
Magnus Damm 已提交
97
{
98
	struct sh_pfc_window *window;
99
	unsigned int i;
M
Magnus Damm 已提交
100 101

	/* scan through physical windows and convert address */
102
	for (i = 0; i < pfc->num_windows; i++) {
103
		window = pfc->windows + i;
M
Magnus Damm 已提交
104 105 106 107 108 109 110 111 112 113

		if (address < window->phys)
			continue;

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

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

114
	BUG();
115
	return NULL;
M
Magnus Damm 已提交
116
}
M
Magnus Damm 已提交
117

118
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin)
119
{
120 121 122
	unsigned int offset;
	unsigned int i;

123 124
	for (i = 0, offset = 0; i < pfc->nr_ranges; ++i) {
		const struct sh_pfc_pin_range *range = &pfc->ranges[i];
125 126

		if (pin <= range->end)
127 128
			return pin >= range->start
			     ? offset + pin - range->start : -1;
129

130
		offset += range->end - range->start + 1;
131 132
	}

133
	return -EINVAL;
134 135
}

136
static int sh_pfc_enum_in_range(u16 enum_id, const struct pinmux_range *r)
M
Magnus Damm 已提交
137 138 139 140 141 142 143 144 145 146
{
	if (enum_id < r->begin)
		return 0;

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

	return 1;
}

147
u32 sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned int reg_width)
M
Magnus Damm 已提交
148 149 150
{
	switch (reg_width) {
	case 8:
M
Magnus Damm 已提交
151
		return ioread8(mapped_reg);
M
Magnus Damm 已提交
152
	case 16:
M
Magnus Damm 已提交
153
		return ioread16(mapped_reg);
M
Magnus Damm 已提交
154
	case 32:
M
Magnus Damm 已提交
155
		return ioread32(mapped_reg);
M
Magnus Damm 已提交
156 157 158 159 160 161
	}

	BUG();
	return 0;
}

162
void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width,
163
			  u32 data)
M
Magnus Damm 已提交
164 165 166
{
	switch (reg_width) {
	case 8:
M
Magnus Damm 已提交
167
		iowrite8(data, mapped_reg);
M
Magnus Damm 已提交
168 169
		return;
	case 16:
M
Magnus Damm 已提交
170
		iowrite16(data, mapped_reg);
M
Magnus Damm 已提交
171 172
		return;
	case 32:
M
Magnus Damm 已提交
173
		iowrite32(data, mapped_reg);
M
Magnus Damm 已提交
174 175 176 177 178 179
		return;
	}

	BUG();
}

180
static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
L
Laurent Pinchart 已提交
181
				     const struct pinmux_cfg_reg *crp,
182
				     unsigned int in_pos,
183
				     void __iomem **mapped_regp, u32 *maskp,
184
				     unsigned int *posp)
M
Magnus Damm 已提交
185
{
186
	unsigned int k;
187

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

190 191 192 193 194 195 196 197 198
	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];
	}
199 200
}

201
static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
L
Laurent Pinchart 已提交
202
				    const struct pinmux_cfg_reg *crp,
203
				    unsigned int field, u32 value)
M
Magnus Damm 已提交
204
{
205
	void __iomem *mapped_reg;
206
	unsigned int pos;
207
	u32 mask, data;
M
Magnus Damm 已提交
208

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

211
	dev_dbg(pfc->dev, "write_reg addr = %lx, value = 0x%x, field = %u, "
212
		"r_width = %u, f_width = %u\n",
213
		crp->reg, value, field, crp->reg_width, crp->field_width);
M
Magnus Damm 已提交
214 215 216

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

218
	data = sh_pfc_read_raw_reg(mapped_reg, crp->reg_width);
M
Magnus Damm 已提交
219 220 221
	data &= mask;
	data |= value;

222
	if (pfc->info->unlock_reg)
223
		sh_pfc_write_raw_reg(
224
			sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32,
225
			~data);
M
Magnus Damm 已提交
226

227
	sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data);
M
Magnus Damm 已提交
228 229
}

230
static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id,
231 232
				 const struct pinmux_cfg_reg **crp,
				 unsigned int *fieldp, u32 *valuep)
M
Magnus Damm 已提交
233
{
234
	unsigned int k = 0;
M
Magnus Damm 已提交
235 236

	while (1) {
237 238 239 240 241 242 243 244
		const struct pinmux_cfg_reg *config_reg =
			pfc->info->cfg_regs + k;
		unsigned int r_width = config_reg->reg_width;
		unsigned int f_width = config_reg->field_width;
		unsigned int curr_width;
		unsigned int bit_pos;
		unsigned int pos = 0;
		unsigned int m = 0;
M
Magnus Damm 已提交
245 246 247

		if (!r_width)
			break;
248 249

		for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
250 251 252
			u32 ncomb;
			u32 n;

253 254 255 256 257 258 259 260 261 262 263 264 265
			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 已提交
266
			}
267 268
			pos += ncomb;
			m++;
M
Magnus Damm 已提交
269 270 271 272
		}
		k++;
	}

273
	return -EINVAL;
M
Magnus Damm 已提交
274 275
}

276 277
static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, u16 mark, int pos,
			      u16 *enum_idp)
M
Magnus Damm 已提交
278
{
279
	const u16 *data = pfc->info->gpio_data;
280
	unsigned int k;
M
Magnus Damm 已提交
281 282 283 284 285 286

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

287
	for (k = 0; k < pfc->info->gpio_data_size; k++) {
288
		if (data[k] == mark) {
M
Magnus Damm 已提交
289 290 291 292 293
			*enum_idp = data[k + 1];
			return k + 1;
		}
	}

294 295
	dev_err(pfc->dev, "cannot locate data/mark enum_id for mark %d\n",
		mark);
296
	return -EINVAL;
M
Magnus Damm 已提交
297 298
}

299
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
M
Magnus Damm 已提交
300
{
L
Laurent Pinchart 已提交
301
	const struct pinmux_range *range;
302
	int pos = 0;
M
Magnus Damm 已提交
303 304

	switch (pinmux_type) {
305
	case PINMUX_TYPE_GPIO:
M
Magnus Damm 已提交
306 307 308 309 310
	case PINMUX_TYPE_FUNCTION:
		range = NULL;
		break;

	case PINMUX_TYPE_OUTPUT:
311
		range = &pfc->info->output;
M
Magnus Damm 已提交
312 313 314
		break;

	case PINMUX_TYPE_INPUT:
315
		range = &pfc->info->input;
M
Magnus Damm 已提交
316 317 318
		break;

	default:
319
		return -EINVAL;
M
Magnus Damm 已提交
320 321
	}

322
	/* Iterate over all the configuration fields we need to update. */
M
Magnus Damm 已提交
323
	while (1) {
324 325 326 327 328 329 330
		const struct pinmux_cfg_reg *cr;
		unsigned int field;
		u16 enum_id;
		u32 value;
		int in_range;
		int ret;

331
		pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
332 333
		if (pos < 0)
			return pos;
M
Magnus Damm 已提交
334 335 336 337

		if (!enum_id)
			break;

338 339 340 341
		/* 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.
		 */
342
		in_range = sh_pfc_enum_in_range(enum_id, &pfc->info->function);
343
		if (!in_range) {
344 345 346 347 348 349 350 351
			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.
352
				 */
353
				in_range = sh_pfc_enum_in_range(enum_id, range);
354 355 356 357 358 359 360 361 362

				/*
				 * 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;
			}
363
			/* GPIOs are only allowed to modify function fields. */
364 365
		}

M
Magnus Damm 已提交
366 367 368
		if (!in_range)
			continue;

369 370 371
		ret = sh_pfc_get_config_reg(pfc, enum_id, &cr, &field, &value);
		if (ret < 0)
			return ret;
M
Magnus Damm 已提交
372

373
		sh_pfc_write_config_reg(pfc, cr, field, value);
M
Magnus Damm 已提交
374 375 376 377 378
	}

	return 0;
}

379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
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;
	}

403 404 405 406
	/* 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.
	 */
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
	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) {
422 423 424 425 426 427 428 429 430
		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;
431 432 433
	}

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

	return 0;
}

L
Laurent Pinchart 已提交
440 441
#ifdef CONFIG_OF
static const struct of_device_id sh_pfc_of_table[] = {
442 443 444 445 446 447
#ifdef CONFIG_PINCTRL_PFC_EMEV2
	{
		.compatible = "renesas,pfc-emev2",
		.data = &emev2_pinmux_info,
	},
#endif
L
Laurent Pinchart 已提交
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
#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
478 479 480 481 482 483
#ifdef CONFIG_PINCTRL_PFC_R8A7791
	{
		.compatible = "renesas,pfc-r8a7791",
		.data = &r8a7791_pinmux_info,
	},
#endif
L
Laurent Pinchart 已提交
484 485 486 487 488 489 490 491 492 493 494
#ifdef CONFIG_PINCTRL_PFC_SH73A0
	{
		.compatible = "renesas,pfc-sh73a0",
		.data = &sh73a0_pinmux_info,
	},
#endif
	{ },
};
MODULE_DEVICE_TABLE(of, sh_pfc_of_table);
#endif

495
static int sh_pfc_probe(struct platform_device *pdev)
M
Magnus Damm 已提交
496
{
L
Laurent Pinchart 已提交
497 498 499 500
	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 已提交
501
	const struct sh_pfc_soc_info *info;
502
	struct sh_pfc *pfc;
M
Magnus Damm 已提交
503
	int ret;
M
Magnus Damm 已提交
504

L
Laurent Pinchart 已提交
505 506 507 508 509 510 511
#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;

512
	if (info == NULL)
513
		return -ENODEV;
M
Magnus Damm 已提交
514

515
	pfc = devm_kzalloc(&pdev->dev, sizeof(*pfc), GFP_KERNEL);
516 517
	if (pfc == NULL)
		return -ENOMEM;
518

519
	pfc->info = info;
520 521
	pfc->dev = &pdev->dev;

522
	ret = sh_pfc_map_resources(pfc, pdev);
523
	if (unlikely(ret < 0))
M
Magnus Damm 已提交
524 525
		return ret;

526
	spin_lock_init(&pfc->lock);
M
Magnus Damm 已提交
527

528 529 530 531 532 533
	if (info->ops && info->ops->init) {
		ret = info->ops->init(pfc);
		if (ret < 0)
			return ret;
	}

534
	pinctrl_provide_dummies();
M
Magnus Damm 已提交
535

536 537 538 539
	ret = sh_pfc_init_ranges(pfc);
	if (ret < 0)
		return ret;

540 541 542
	/*
	 * Initialize pinctrl bindings first
	 */
543
	ret = sh_pfc_register_pinctrl(pfc);
544
	if (unlikely(ret != 0))
545
		return ret;
546

547
#ifdef CONFIG_GPIO_SH_PFC
548 549 550
	/*
	 * Then the GPIO chip
	 */
551
	ret = sh_pfc_register_gpiochip(pfc);
552
	if (unlikely(ret != 0)) {
553 554 555 556 557
		/*
		 * 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.
		 */
558
		dev_notice(pfc->dev, "failed to init GPIO chip, ignoring...\n");
559
	}
560
#endif
561

562 563
	platform_set_drvdata(pdev, pfc);

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

566
	return 0;
567
}
568

569 570 571 572 573 574 575 576 577 578 579 580 581
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);

	return 0;
}

static const struct platform_device_id sh_pfc_id_table[] = {
582 583 584
#ifdef CONFIG_PINCTRL_PFC_EMEV2
	{ "pfc-emev2", (kernel_ulong_t)&emev2_pinmux_info },
#endif
M
Magnus Damm 已提交
585 586 587
#ifdef CONFIG_PINCTRL_PFC_R8A73A4
	{ "pfc-r8a73a4", (kernel_ulong_t)&r8a73a4_pinmux_info },
#endif
588 589
#ifdef CONFIG_PINCTRL_PFC_R8A7740
	{ "pfc-r8a7740", (kernel_ulong_t)&r8a7740_pinmux_info },
590
#endif
591 592 593
#ifdef CONFIG_PINCTRL_PFC_R8A7778
	{ "pfc-r8a7778", (kernel_ulong_t)&r8a7778_pinmux_info },
#endif
594 595
#ifdef CONFIG_PINCTRL_PFC_R8A7779
	{ "pfc-r8a7779", (kernel_ulong_t)&r8a7779_pinmux_info },
596
#endif
597 598 599
#ifdef CONFIG_PINCTRL_PFC_R8A7790
	{ "pfc-r8a7790", (kernel_ulong_t)&r8a7790_pinmux_info },
#endif
600 601 602
#ifdef CONFIG_PINCTRL_PFC_SH7203
	{ "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info },
#endif
603 604 605
#ifdef CONFIG_PINCTRL_PFC_SH7264
	{ "pfc-sh7264", (kernel_ulong_t)&sh7264_pinmux_info },
#endif
606 607 608
#ifdef CONFIG_PINCTRL_PFC_SH7269
	{ "pfc-sh7269", (kernel_ulong_t)&sh7269_pinmux_info },
#endif
609 610
#ifdef CONFIG_PINCTRL_PFC_SH73A0
	{ "pfc-sh73a0", (kernel_ulong_t)&sh73a0_pinmux_info },
611 612 613
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7720
	{ "pfc-sh7720", (kernel_ulong_t)&sh7720_pinmux_info },
614 615 616
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7722
	{ "pfc-sh7722", (kernel_ulong_t)&sh7722_pinmux_info },
617 618 619
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7723
	{ "pfc-sh7723", (kernel_ulong_t)&sh7723_pinmux_info },
620 621 622
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7724
	{ "pfc-sh7724", (kernel_ulong_t)&sh7724_pinmux_info },
623 624 625
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7734
	{ "pfc-sh7734", (kernel_ulong_t)&sh7734_pinmux_info },
626 627 628
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7757
	{ "pfc-sh7757", (kernel_ulong_t)&sh7757_pinmux_info },
629 630 631
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7785
	{ "pfc-sh7785", (kernel_ulong_t)&sh7785_pinmux_info },
632 633 634
#endif
#ifdef CONFIG_PINCTRL_PFC_SH7786
	{ "pfc-sh7786", (kernel_ulong_t)&sh7786_pinmux_info },
635 636 637
#endif
#ifdef CONFIG_PINCTRL_PFC_SHX3
	{ "pfc-shx3", (kernel_ulong_t)&shx3_pinmux_info },
638
#endif
639 640 641 642 643 644 645 646 647 648 649
	{ "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,
L
Laurent Pinchart 已提交
650
		.of_match_table = of_match_ptr(sh_pfc_of_table),
651 652 653
	},
};

654 655 656
static int __init sh_pfc_init(void)
{
	return platform_driver_register(&sh_pfc_driver);
657
}
658
postcore_initcall(sh_pfc_init);
659 660 661 662 663 664 665

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

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