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 long 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 long 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 long in_pos,
183
				     void __iomem **mapped_regp, u32 *maskp,
184
				     unsigned long *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 long field, u32 value)
M
Magnus Damm 已提交
204
{
205
	void __iomem *mapped_reg;
206 207
	unsigned long pos;
	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 = %ld, "
212 213
		"r_width = %ld, f_width = %ld\n",
		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,
L
Laurent Pinchart 已提交
231
				 const struct pinmux_cfg_reg **crp, int *fieldp,
232
				 u32 *valuep)
M
Magnus Damm 已提交
233
{
L
Laurent Pinchart 已提交
234
	const struct pinmux_cfg_reg *config_reg;
235 236 237
	unsigned long r_width, f_width, curr_width;
	unsigned int k, m, pos, bit_pos;
	u32 ncomb, n;
M
Magnus Damm 已提交
238 239 240

	k = 0;
	while (1) {
241
		config_reg = pfc->info->cfg_regs + k;
M
Magnus Damm 已提交
242 243 244 245 246 247

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

		if (!r_width)
			break;
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264

		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 已提交
265
			}
266 267
			pos += ncomb;
			m++;
M
Magnus Damm 已提交
268 269 270 271
		}
		k++;
	}

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

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

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

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

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

298
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
M
Magnus Damm 已提交
299
{
L
Laurent Pinchart 已提交
300
	const struct pinmux_cfg_reg *cr = NULL;
301
	u16 enum_id;
L
Laurent Pinchart 已提交
302
	const struct pinmux_range *range;
303 304
	int in_range, pos, field;
	u32 value;
305
	int ret;
M
Magnus Damm 已提交
306 307

	switch (pinmux_type) {
308
	case PINMUX_TYPE_GPIO:
M
Magnus Damm 已提交
309 310 311 312 313
	case PINMUX_TYPE_FUNCTION:
		range = NULL;
		break;

	case PINMUX_TYPE_OUTPUT:
314
		range = &pfc->info->output;
M
Magnus Damm 已提交
315 316 317
		break;

	case PINMUX_TYPE_INPUT:
318
		range = &pfc->info->input;
M
Magnus Damm 已提交
319 320 321
		break;

	default:
322
		return -EINVAL;
M
Magnus Damm 已提交
323 324 325 326
	}

	pos = 0;
	enum_id = 0;
327 328
	field = 0;
	value = 0;
329 330

	/* Iterate over all the configuration fields we need to update. */
M
Magnus Damm 已提交
331
	while (1) {
332
		pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id);
333 334
		if (pos < 0)
			return pos;
M
Magnus Damm 已提交
335 336 337 338

		if (!enum_id)
			break;

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

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

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

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

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

	return 0;
}

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

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

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

	return 0;
}

L
Laurent Pinchart 已提交
441 442
#ifdef CONFIG_OF
static const struct of_device_id sh_pfc_of_table[] = {
443 444 445 446 447 448
#ifdef CONFIG_PINCTRL_PFC_EMEV2
	{
		.compatible = "renesas,pfc-emev2",
		.data = &emev2_pinmux_info,
	},
#endif
L
Laurent Pinchart 已提交
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 478
#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
479 480 481 482 483 484
#ifdef CONFIG_PINCTRL_PFC_R8A7791
	{
		.compatible = "renesas,pfc-r8a7791",
		.data = &r8a7791_pinmux_info,
	},
#endif
L
Laurent Pinchart 已提交
485 486 487 488 489 490 491 492 493 494 495
#ifdef CONFIG_PINCTRL_PFC_SH73A0
	{
		.compatible = "renesas,pfc-sh73a0",
		.data = &sh73a0_pinmux_info,
	},
#endif
	{ },
};
MODULE_DEVICE_TABLE(of, sh_pfc_of_table);
#endif

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

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

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

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

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

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

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

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

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

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

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

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

563 564
	platform_set_drvdata(pdev, pfc);

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

567
	return 0;
568
}
569

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

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

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

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