| .. | .. | 
|---|
|  | 1 | +// SPDX-License-Identifier: GPL-2.0 | 
|---|
| 1 | 2 | /* | 
|---|
| 2 | 3 | * SuperH Timer Support - MTU2 | 
|---|
| 3 | 4 | * | 
|---|
| 4 | 5 | *  Copyright (C) 2009 Magnus Damm | 
|---|
| 5 |  | - * | 
|---|
| 6 |  | - * This program is free software; you can redistribute it and/or modify | 
|---|
| 7 |  | - * it under the terms of the GNU General Public License as published by | 
|---|
| 8 |  | - * the Free Software Foundation; either version 2 of the License | 
|---|
| 9 |  | - * | 
|---|
| 10 |  | - * This program is distributed in the hope that it will be useful, | 
|---|
| 11 |  | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 12 |  | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 13 |  | - * GNU General Public License for more details. | 
|---|
| 14 | 6 | */ | 
|---|
| 15 | 7 |  | 
|---|
| 16 | 8 | #include <linux/clk.h> | 
|---|
| .. | .. | 
|---|
| 30 | 22 | #include <linux/sh_timer.h> | 
|---|
| 31 | 23 | #include <linux/slab.h> | 
|---|
| 32 | 24 | #include <linux/spinlock.h> | 
|---|
|  | 25 | + | 
|---|
|  | 26 | +#ifdef CONFIG_SUPERH | 
|---|
|  | 27 | +#include <asm/platform_early.h> | 
|---|
|  | 28 | +#endif | 
|---|
| 33 | 29 |  | 
|---|
| 34 | 30 | struct sh_mtu2_device; | 
|---|
| 35 | 31 |  | 
|---|
| .. | .. | 
|---|
| 301 | 297 |  | 
|---|
| 302 | 298 | static void sh_mtu2_clock_event_suspend(struct clock_event_device *ced) | 
|---|
| 303 | 299 | { | 
|---|
| 304 |  | -	pm_genpd_syscore_poweroff(&ced_to_sh_mtu2(ced)->mtu->pdev->dev); | 
|---|
|  | 300 | +	dev_pm_genpd_suspend(&ced_to_sh_mtu2(ced)->mtu->pdev->dev); | 
|---|
| 305 | 301 | } | 
|---|
| 306 | 302 |  | 
|---|
| 307 | 303 | static void sh_mtu2_clock_event_resume(struct clock_event_device *ced) | 
|---|
| 308 | 304 | { | 
|---|
| 309 |  | -	pm_genpd_syscore_poweron(&ced_to_sh_mtu2(ced)->mtu->pdev->dev); | 
|---|
|  | 305 | +	dev_pm_genpd_resume(&ced_to_sh_mtu2(ced)->mtu->pdev->dev); | 
|---|
| 310 | 306 | } | 
|---|
| 311 | 307 |  | 
|---|
| 312 | 308 | static void sh_mtu2_register_clockevent(struct sh_mtu2_channel *ch, | 
|---|
| .. | .. | 
|---|
| 336 | 332 | return 0; | 
|---|
| 337 | 333 | } | 
|---|
| 338 | 334 |  | 
|---|
|  | 335 | +static const unsigned int sh_mtu2_channel_offsets[] = { | 
|---|
|  | 336 | +	0x300, 0x380, 0x000, | 
|---|
|  | 337 | +}; | 
|---|
|  | 338 | + | 
|---|
| 339 | 339 | static int sh_mtu2_setup_channel(struct sh_mtu2_channel *ch, unsigned int index, | 
|---|
| 340 | 340 | struct sh_mtu2_device *mtu) | 
|---|
| 341 | 341 | { | 
|---|
| 342 |  | -	static const unsigned int channel_offsets[] = { | 
|---|
| 343 |  | -		0x300, 0x380, 0x000, | 
|---|
| 344 |  | -	}; | 
|---|
| 345 | 342 | char name[6]; | 
|---|
| 346 | 343 | int irq; | 
|---|
| 347 | 344 | int ret; | 
|---|
| .. | .. | 
|---|
| 364 | 361 | return ret; | 
|---|
| 365 | 362 | } | 
|---|
| 366 | 363 |  | 
|---|
| 367 |  | -	ch->base = mtu->mapbase + channel_offsets[index]; | 
|---|
|  | 364 | +	ch->base = mtu->mapbase + sh_mtu2_channel_offsets[index]; | 
|---|
| 368 | 365 | ch->index = index; | 
|---|
| 369 | 366 |  | 
|---|
| 370 | 367 | return sh_mtu2_register(ch, dev_name(&mtu->pdev->dev)); | 
|---|
| .. | .. | 
|---|
| 380 | 377 | return -ENXIO; | 
|---|
| 381 | 378 | } | 
|---|
| 382 | 379 |  | 
|---|
| 383 |  | -	mtu->mapbase = ioremap_nocache(res->start, resource_size(res)); | 
|---|
|  | 380 | +	mtu->mapbase = ioremap(res->start, resource_size(res)); | 
|---|
| 384 | 381 | if (mtu->mapbase == NULL) | 
|---|
| 385 | 382 | return -ENXIO; | 
|---|
| 386 | 383 |  | 
|---|
| .. | .. | 
|---|
| 416 | 413 | } | 
|---|
| 417 | 414 |  | 
|---|
| 418 | 415 | /* Allocate and setup the channels. */ | 
|---|
| 419 |  | -	mtu->num_channels = 3; | 
|---|
|  | 416 | +	ret = platform_irq_count(pdev); | 
|---|
|  | 417 | +	if (ret < 0) | 
|---|
|  | 418 | +		goto err_unmap; | 
|---|
|  | 419 | + | 
|---|
|  | 420 | +	mtu->num_channels = min_t(unsigned int, ret, | 
|---|
|  | 421 | +				  ARRAY_SIZE(sh_mtu2_channel_offsets)); | 
|---|
| 420 | 422 |  | 
|---|
| 421 | 423 | mtu->channels = kcalloc(mtu->num_channels, sizeof(*mtu->channels), | 
|---|
| 422 | 424 | GFP_KERNEL); | 
|---|
| .. | .. | 
|---|
| 450 | 452 | struct sh_mtu2_device *mtu = platform_get_drvdata(pdev); | 
|---|
| 451 | 453 | int ret; | 
|---|
| 452 | 454 |  | 
|---|
| 453 |  | -	if (!is_early_platform_device(pdev)) { | 
|---|
|  | 455 | +	if (!is_sh_early_platform_device(pdev)) { | 
|---|
| 454 | 456 | pm_runtime_set_active(&pdev->dev); | 
|---|
| 455 | 457 | pm_runtime_enable(&pdev->dev); | 
|---|
| 456 | 458 | } | 
|---|
| .. | .. | 
|---|
| 470 | 472 | pm_runtime_idle(&pdev->dev); | 
|---|
| 471 | 473 | return ret; | 
|---|
| 472 | 474 | } | 
|---|
| 473 |  | -	if (is_early_platform_device(pdev)) | 
|---|
|  | 475 | +	if (is_sh_early_platform_device(pdev)) | 
|---|
| 474 | 476 | return 0; | 
|---|
| 475 | 477 |  | 
|---|
| 476 | 478 | out: | 
|---|
| .. | .. | 
|---|
| 519 | 521 | platform_driver_unregister(&sh_mtu2_device_driver); | 
|---|
| 520 | 522 | } | 
|---|
| 521 | 523 |  | 
|---|
| 522 |  | -early_platform_init("earlytimer", &sh_mtu2_device_driver); | 
|---|
|  | 524 | +#ifdef CONFIG_SUPERH | 
|---|
|  | 525 | +sh_early_platform_init("earlytimer", &sh_mtu2_device_driver); | 
|---|
|  | 526 | +#endif | 
|---|
|  | 527 | + | 
|---|
| 523 | 528 | subsys_initcall(sh_mtu2_init); | 
|---|
| 524 | 529 | module_exit(sh_mtu2_exit); | 
|---|
| 525 | 530 |  | 
|---|