| .. | .. | 
|---|
 | 1 | +// SPDX-License-Identifier: GPL-2.0  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 | 3 |   * Alarmtimer interface | 
|---|
| 3 | 4 |   * | 
|---|
| .. | .. | 
|---|
| 10 | 11 |   * Copyright (C) 2010 IBM Corperation | 
|---|
| 11 | 12 |   * | 
|---|
| 12 | 13 |   * Author: John Stultz <john.stultz@linaro.org> | 
|---|
| 13 |  | - *  | 
|---|
| 14 |  | - * This program is free software; you can redistribute it and/or modify  | 
|---|
| 15 |  | - * it under the terms of the GNU General Public License version 2 as  | 
|---|
| 16 |  | - * published by the Free Software Foundation.  | 
|---|
| 17 | 14 |   */ | 
|---|
| 18 | 15 |  #include <linux/time.h> | 
|---|
| 19 | 16 |  #include <linux/hrtimer.h> | 
|---|
| .. | .. | 
|---|
| 29 | 26 |  #include <linux/freezer.h> | 
|---|
| 30 | 27 |  #include <linux/compat.h> | 
|---|
| 31 | 28 |  #include <linux/module.h> | 
|---|
 | 29 | +#include <linux/time_namespace.h>  | 
|---|
| 32 | 30 |   | 
|---|
| 33 | 31 |  #include "posix-timers.h" | 
|---|
| 34 | 32 |   | 
|---|
| .. | .. | 
|---|
| 39 | 37 |   * struct alarm_base - Alarm timer bases | 
|---|
| 40 | 38 |   * @lock:		Lock for syncrhonized access to the base | 
|---|
| 41 | 39 |   * @timerqueue:		Timerqueue head managing the list of events | 
|---|
| 42 |  | - * @gettime:		Function to read the time correlating to the base  | 
|---|
 | 40 | + * @get_ktime:		Function to read the time correlating to the base  | 
|---|
 | 41 | + * @get_timespec:	Function to read the namespace time correlating to the base  | 
|---|
| 43 | 42 |   * @base_clockid:	clockid for the base | 
|---|
| 44 | 43 |   */ | 
|---|
| 45 | 44 |  static struct alarm_base { | 
|---|
| 46 | 45 |  	spinlock_t		lock; | 
|---|
| 47 | 46 |  	struct timerqueue_head	timerqueue; | 
|---|
| 48 |  | -	ktime_t			(*gettime)(void);  | 
|---|
 | 47 | +	ktime_t			(*get_ktime)(void);  | 
|---|
 | 48 | +	void			(*get_timespec)(struct timespec64 *tp);  | 
|---|
| 49 | 49 |  	clockid_t		base_clockid; | 
|---|
| 50 | 50 |  } alarm_bases[ALARM_NUMTYPE]; | 
|---|
| 51 | 51 |   | 
|---|
| .. | .. | 
|---|
| 58 | 58 |  #endif | 
|---|
| 59 | 59 |   | 
|---|
| 60 | 60 |  #ifdef CONFIG_RTC_CLASS | 
|---|
| 61 |  | -static struct wakeup_source *ws;  | 
|---|
| 62 |  | -  | 
|---|
| 63 | 61 |  /* rtc timer and device for setting alarm wakeups at suspend */ | 
|---|
| 64 | 62 |  static struct rtc_timer		rtctimer; | 
|---|
| 65 | 63 |  static struct rtc_device	*rtcdev; | 
|---|
| .. | .. | 
|---|
| 69 | 67 |   * alarmtimer_get_rtcdev - Return selected rtcdevice | 
|---|
| 70 | 68 |   * | 
|---|
| 71 | 69 |   * This function returns the rtc device to use for wakealarms. | 
|---|
| 72 |  | - * If one has not already been chosen, it checks to see if a  | 
|---|
| 73 |  | - * functional rtc device is available.  | 
|---|
| 74 | 70 |   */ | 
|---|
| 75 | 71 |  struct rtc_device *alarmtimer_get_rtcdev(void) | 
|---|
| 76 | 72 |  { | 
|---|
| .. | .. | 
|---|
| 90 | 86 |  { | 
|---|
| 91 | 87 |  	unsigned long flags; | 
|---|
| 92 | 88 |  	struct rtc_device *rtc = to_rtc_device(dev); | 
|---|
| 93 |  | -	struct wakeup_source *__ws;  | 
|---|
 | 89 | +	struct platform_device *pdev;  | 
|---|
| 94 | 90 |  	int ret = 0; | 
|---|
| 95 | 91 |   | 
|---|
| 96 | 92 |  	if (rtcdev) | 
|---|
| .. | .. | 
|---|
| 101 | 97 |  	if (!device_may_wakeup(rtc->dev.parent)) | 
|---|
| 102 | 98 |  		return -1; | 
|---|
| 103 | 99 |   | 
|---|
| 104 |  | -	__ws = wakeup_source_register(dev, "alarmtimer");  | 
|---|
 | 100 | +	pdev = platform_device_register_data(dev, "alarmtimer",  | 
|---|
 | 101 | +					     PLATFORM_DEVID_AUTO, NULL, 0);  | 
|---|
 | 102 | +	if (!IS_ERR(pdev))  | 
|---|
 | 103 | +		device_init_wakeup(&pdev->dev, true);  | 
|---|
| 105 | 104 |   | 
|---|
| 106 | 105 |  	spin_lock_irqsave(&rtcdev_lock, flags); | 
|---|
| 107 |  | -	if (!rtcdev) {  | 
|---|
 | 106 | +	if (!IS_ERR(pdev) && !rtcdev) {  | 
|---|
| 108 | 107 |  		if (!try_module_get(rtc->owner)) { | 
|---|
| 109 | 108 |  			ret = -1; | 
|---|
| 110 | 109 |  			goto unlock; | 
|---|
| .. | .. | 
|---|
| 113 | 112 |  		rtcdev = rtc; | 
|---|
| 114 | 113 |  		/* hold a reference so it doesn't go away */ | 
|---|
| 115 | 114 |  		get_device(dev); | 
|---|
| 116 |  | -		ws = __ws;  | 
|---|
| 117 |  | -		__ws = NULL;  | 
|---|
 | 115 | +		pdev = NULL;  | 
|---|
 | 116 | +	} else {  | 
|---|
 | 117 | +		ret = -1;  | 
|---|
| 118 | 118 |  	} | 
|---|
| 119 | 119 |  unlock: | 
|---|
| 120 | 120 |  	spin_unlock_irqrestore(&rtcdev_lock, flags); | 
|---|
| 121 | 121 |   | 
|---|
| 122 |  | -	wakeup_source_unregister(__ws);  | 
|---|
 | 122 | +	platform_device_unregister(pdev);  | 
|---|
| 123 | 123 |   | 
|---|
| 124 | 124 |  	return ret; | 
|---|
| 125 | 125 |  } | 
|---|
| .. | .. | 
|---|
| 143 | 143 |  	class_interface_unregister(&alarmtimer_rtc_interface); | 
|---|
| 144 | 144 |  } | 
|---|
| 145 | 145 |  #else | 
|---|
| 146 |  | -struct rtc_device *alarmtimer_get_rtcdev(void)  | 
|---|
| 147 |  | -{  | 
|---|
| 148 |  | -	return NULL;  | 
|---|
| 149 |  | -}  | 
|---|
| 150 |  | -#define rtcdev (NULL)  | 
|---|
| 151 | 146 |  static inline int alarmtimer_rtc_interface_setup(void) { return 0; } | 
|---|
| 152 | 147 |  static inline void alarmtimer_rtc_interface_remove(void) { } | 
|---|
| 153 | 148 |  static inline void alarmtimer_rtc_timer_init(void) { } | 
|---|
| .. | .. | 
|---|
| 197 | 192 |   * When a alarm timer fires, this runs through the timerqueue to | 
|---|
| 198 | 193 |   * see which alarms expired, and runs those. If there are more alarm | 
|---|
| 199 | 194 |   * timers queued for the future, we set the hrtimer to fire when | 
|---|
| 200 |  | - * when the next future alarm timer expires.  | 
|---|
 | 195 | + * the next future alarm timer expires.  | 
|---|
| 201 | 196 |   */ | 
|---|
| 202 | 197 |  static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) | 
|---|
| 203 | 198 |  { | 
|---|
| .. | .. | 
|---|
| 212 | 207 |  	spin_unlock_irqrestore(&base->lock, flags); | 
|---|
| 213 | 208 |   | 
|---|
| 214 | 209 |  	if (alarm->function) | 
|---|
| 215 |  | -		restart = alarm->function(alarm, base->gettime());  | 
|---|
 | 210 | +		restart = alarm->function(alarm, base->get_ktime());  | 
|---|
| 216 | 211 |   | 
|---|
| 217 | 212 |  	spin_lock_irqsave(&base->lock, flags); | 
|---|
| 218 | 213 |  	if (restart != ALARMTIMER_NORESTART) { | 
|---|
| .. | .. | 
|---|
| 222 | 217 |  	} | 
|---|
| 223 | 218 |  	spin_unlock_irqrestore(&base->lock, flags); | 
|---|
| 224 | 219 |   | 
|---|
| 225 |  | -	trace_alarmtimer_fired(alarm, base->gettime());  | 
|---|
 | 220 | +	trace_alarmtimer_fired(alarm, base->get_ktime());  | 
|---|
| 226 | 221 |  	return ret; | 
|---|
| 227 | 222 |   | 
|---|
| 228 | 223 |  } | 
|---|
| .. | .. | 
|---|
| 230 | 225 |  ktime_t alarm_expires_remaining(const struct alarm *alarm) | 
|---|
| 231 | 226 |  { | 
|---|
| 232 | 227 |  	struct alarm_base *base = &alarm_bases[alarm->type]; | 
|---|
| 233 |  | -	return ktime_sub(alarm->node.expires, base->gettime());  | 
|---|
 | 228 | +	return ktime_sub(alarm->node.expires, base->get_ktime());  | 
|---|
| 234 | 229 |  } | 
|---|
| 235 | 230 |  EXPORT_SYMBOL_GPL(alarm_expires_remaining); | 
|---|
| 236 | 231 |   | 
|---|
| .. | .. | 
|---|
| 238 | 233 |  /** | 
|---|
| 239 | 234 |   * alarmtimer_suspend - Suspend time callback | 
|---|
| 240 | 235 |   * @dev: unused | 
|---|
| 241 |  | - * @state: unused  | 
|---|
| 242 | 236 |   * | 
|---|
| 243 | 237 |   * When we are going into suspend, we look through the bases | 
|---|
| 244 | 238 |   * to see which is the soonest timer to expire. We then | 
|---|
| .. | .. | 
|---|
| 276 | 270 |  		spin_unlock_irqrestore(&base->lock, flags); | 
|---|
| 277 | 271 |  		if (!next) | 
|---|
| 278 | 272 |  			continue; | 
|---|
| 279 |  | -		delta = ktime_sub(next->expires, base->gettime());  | 
|---|
 | 273 | +		delta = ktime_sub(next->expires, base->get_ktime());  | 
|---|
| 280 | 274 |  		if (!min || (delta < min)) { | 
|---|
| 281 | 275 |  			expires = next->expires; | 
|---|
| 282 | 276 |  			min = delta; | 
|---|
| .. | .. | 
|---|
| 287 | 281 |  		return 0; | 
|---|
| 288 | 282 |   | 
|---|
| 289 | 283 |  	if (ktime_to_ns(min) < 2 * NSEC_PER_SEC) { | 
|---|
| 290 |  | -		__pm_wakeup_event(ws, 2 * MSEC_PER_SEC);  | 
|---|
 | 284 | +		pm_wakeup_event(dev, 2 * MSEC_PER_SEC);  | 
|---|
| 291 | 285 |  		return -EBUSY; | 
|---|
| 292 | 286 |  	} | 
|---|
| 293 | 287 |   | 
|---|
| .. | .. | 
|---|
| 302 | 296 |  	/* Set alarm, if in the past reject suspend briefly to handle */ | 
|---|
| 303 | 297 |  	ret = rtc_timer_start(rtc, &rtctimer, now, 0); | 
|---|
| 304 | 298 |  	if (ret < 0) | 
|---|
| 305 |  | -		__pm_wakeup_event(ws, MSEC_PER_SEC);  | 
|---|
 | 299 | +		pm_wakeup_event(dev, MSEC_PER_SEC);  | 
|---|
| 306 | 300 |  	return ret; | 
|---|
| 307 | 301 |  } | 
|---|
| 308 | 302 |   | 
|---|
| .. | .. | 
|---|
| 370 | 364 |  	hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS); | 
|---|
| 371 | 365 |  	spin_unlock_irqrestore(&base->lock, flags); | 
|---|
| 372 | 366 |   | 
|---|
| 373 |  | -	trace_alarmtimer_start(alarm, base->gettime());  | 
|---|
 | 367 | +	trace_alarmtimer_start(alarm, base->get_ktime());  | 
|---|
| 374 | 368 |  } | 
|---|
| 375 | 369 |  EXPORT_SYMBOL_GPL(alarm_start); | 
|---|
| 376 | 370 |   | 
|---|
| .. | .. | 
|---|
| 383 | 377 |  { | 
|---|
| 384 | 378 |  	struct alarm_base *base = &alarm_bases[alarm->type]; | 
|---|
| 385 | 379 |   | 
|---|
| 386 |  | -	start = ktime_add_safe(start, base->gettime());  | 
|---|
 | 380 | +	start = ktime_add_safe(start, base->get_ktime());  | 
|---|
| 387 | 381 |  	alarm_start(alarm, start); | 
|---|
| 388 | 382 |  } | 
|---|
| 389 | 383 |  EXPORT_SYMBOL_GPL(alarm_start_relative); | 
|---|
| .. | .. | 
|---|
| 420 | 414 |  		alarmtimer_dequeue(base, alarm); | 
|---|
| 421 | 415 |  	spin_unlock_irqrestore(&base->lock, flags); | 
|---|
| 422 | 416 |   | 
|---|
| 423 |  | -	trace_alarmtimer_cancel(alarm, base->gettime());  | 
|---|
 | 417 | +	trace_alarmtimer_cancel(alarm, base->get_ktime());  | 
|---|
| 424 | 418 |  	return ret; | 
|---|
| 425 | 419 |  } | 
|---|
| 426 | 420 |  EXPORT_SYMBOL_GPL(alarm_try_to_cancel); | 
|---|
| .. | .. | 
|---|
| 438 | 432 |  		int ret = alarm_try_to_cancel(alarm); | 
|---|
| 439 | 433 |  		if (ret >= 0) | 
|---|
| 440 | 434 |  			return ret; | 
|---|
| 441 |  | -		cpu_relax();  | 
|---|
 | 435 | +		hrtimer_cancel_wait_running(&alarm->timer);  | 
|---|
| 442 | 436 |  	} | 
|---|
| 443 | 437 |  } | 
|---|
| 444 | 438 |  EXPORT_SYMBOL_GPL(alarm_cancel); | 
|---|
| .. | .. | 
|---|
| 480 | 474 |  { | 
|---|
| 481 | 475 |  	struct alarm_base *base = &alarm_bases[alarm->type]; | 
|---|
| 482 | 476 |   | 
|---|
| 483 |  | -	return alarm_forward(alarm, base->gettime(), interval);  | 
|---|
 | 477 | +	return alarm_forward(alarm, base->get_ktime(), interval);  | 
|---|
| 484 | 478 |  } | 
|---|
| 485 | 479 |  EXPORT_SYMBOL_GPL(alarm_forward_now); | 
|---|
| 486 | 480 |   | 
|---|
| .. | .. | 
|---|
| 506 | 500 |  		return; | 
|---|
| 507 | 501 |  	} | 
|---|
| 508 | 502 |   | 
|---|
| 509 |  | -	delta = ktime_sub(absexp, base->gettime());  | 
|---|
 | 503 | +	delta = ktime_sub(absexp, base->get_ktime());  | 
|---|
| 510 | 504 |   | 
|---|
| 511 | 505 |  	spin_lock_irqsave(&freezer_delta_lock, flags); | 
|---|
| 512 | 506 |  	if (!freezer_delta || (delta < freezer_delta)) { | 
|---|
| .. | .. | 
|---|
| 612 | 606 |  } | 
|---|
| 613 | 607 |   | 
|---|
| 614 | 608 |  /** | 
|---|
 | 609 | + * alarm_timer_wait_running - Posix timer callback to wait for a timer  | 
|---|
 | 610 | + * @timr:	Pointer to the posixtimer data struct  | 
|---|
 | 611 | + *  | 
|---|
 | 612 | + * Called from the core code when timer cancel detected that the callback  | 
|---|
 | 613 | + * is running. @timr is unlocked and rcu read lock is held to prevent it  | 
|---|
 | 614 | + * from being freed.  | 
|---|
 | 615 | + */  | 
|---|
 | 616 | +static void alarm_timer_wait_running(struct k_itimer *timr)  | 
|---|
 | 617 | +{  | 
|---|
 | 618 | +	hrtimer_cancel_wait_running(&timr->it.alarm.alarmtimer.timer);  | 
|---|
 | 619 | +}  | 
|---|
 | 620 | +  | 
|---|
 | 621 | +/**  | 
|---|
| 615 | 622 |   * alarm_timer_arm - Posix timer callback to arm a timer | 
|---|
| 616 | 623 |   * @timr:	Pointer to the posixtimer data struct | 
|---|
| 617 | 624 |   * @expires:	The new expiry time | 
|---|
| .. | .. | 
|---|
| 625 | 632 |  	struct alarm_base *base = &alarm_bases[alarm->type]; | 
|---|
| 626 | 633 |   | 
|---|
| 627 | 634 |  	if (!absolute) | 
|---|
| 628 |  | -		expires = ktime_add_safe(expires, base->gettime());  | 
|---|
 | 635 | +		expires = ktime_add_safe(expires, base->get_ktime());  | 
|---|
| 629 | 636 |  	if (sigev_none) | 
|---|
| 630 | 637 |  		alarm->node.expires = expires; | 
|---|
| 631 | 638 |  	else | 
|---|
| .. | .. | 
|---|
| 650 | 657 |  } | 
|---|
| 651 | 658 |   | 
|---|
| 652 | 659 |  /** | 
|---|
| 653 |  | - * alarm_clock_get - posix clock_get interface  | 
|---|
 | 660 | + * alarm_clock_get_timespec - posix clock_get_timespec interface  | 
|---|
| 654 | 661 |   * @which_clock: clockid | 
|---|
| 655 | 662 |   * @tp: timespec to fill. | 
|---|
| 656 | 663 |   * | 
|---|
| 657 |  | - * Provides the underlying alarm base time.  | 
|---|
 | 664 | + * Provides the underlying alarm base time in a tasks time namespace.  | 
|---|
| 658 | 665 |   */ | 
|---|
| 659 |  | -static int alarm_clock_get(clockid_t which_clock, struct timespec64 *tp)  | 
|---|
 | 666 | +static int alarm_clock_get_timespec(clockid_t which_clock, struct timespec64 *tp)  | 
|---|
| 660 | 667 |  { | 
|---|
| 661 | 668 |  	struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)]; | 
|---|
| 662 | 669 |   | 
|---|
| 663 | 670 |  	if (!alarmtimer_get_rtcdev()) | 
|---|
| 664 | 671 |  		return -EINVAL; | 
|---|
| 665 | 672 |   | 
|---|
| 666 |  | -	*tp = ktime_to_timespec64(base->gettime());  | 
|---|
 | 673 | +	base->get_timespec(tp);  | 
|---|
 | 674 | +  | 
|---|
| 667 | 675 |  	return 0; | 
|---|
 | 676 | +}  | 
|---|
 | 677 | +  | 
|---|
 | 678 | +/**  | 
|---|
 | 679 | + * alarm_clock_get_ktime - posix clock_get_ktime interface  | 
|---|
 | 680 | + * @which_clock: clockid  | 
|---|
 | 681 | + *  | 
|---|
 | 682 | + * Provides the underlying alarm base time in the root namespace.  | 
|---|
 | 683 | + */  | 
|---|
 | 684 | +static ktime_t alarm_clock_get_ktime(clockid_t which_clock)  | 
|---|
 | 685 | +{  | 
|---|
 | 686 | +	struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)];  | 
|---|
 | 687 | +  | 
|---|
 | 688 | +	if (!alarmtimer_get_rtcdev())  | 
|---|
 | 689 | +		return -EINVAL;  | 
|---|
 | 690 | +  | 
|---|
 | 691 | +	return base->get_ktime();  | 
|---|
| 668 | 692 |  } | 
|---|
| 669 | 693 |   | 
|---|
| 670 | 694 |  /** | 
|---|
| .. | .. | 
|---|
| 740 | 764 |  		struct timespec64 rmt; | 
|---|
| 741 | 765 |  		ktime_t rem; | 
|---|
| 742 | 766 |   | 
|---|
| 743 |  | -		rem = ktime_sub(absexp, alarm_bases[type].gettime());  | 
|---|
 | 767 | +		rem = ktime_sub(absexp, alarm_bases[type].get_ktime());  | 
|---|
| 744 | 768 |   | 
|---|
| 745 | 769 |  		if (rem <= 0) | 
|---|
| 746 | 770 |  			return 0; | 
|---|
| .. | .. | 
|---|
| 809 | 833 |  	exp = timespec64_to_ktime(*tsreq); | 
|---|
| 810 | 834 |  	/* Convert (if necessary) to absolute time */ | 
|---|
| 811 | 835 |  	if (flags != TIMER_ABSTIME) { | 
|---|
| 812 |  | -		ktime_t now = alarm_bases[type].gettime();  | 
|---|
 | 836 | +		ktime_t now = alarm_bases[type].get_ktime();  | 
|---|
| 813 | 837 |   | 
|---|
| 814 | 838 |  		exp = ktime_add_safe(now, exp); | 
|---|
 | 839 | +	} else {  | 
|---|
 | 840 | +		exp = timens_ktime_to_host(which_clock, exp);  | 
|---|
| 815 | 841 |  	} | 
|---|
| 816 | 842 |   | 
|---|
| 817 | 843 |  	ret = alarmtimer_do_nsleep(&alarm, exp, type); | 
|---|
| .. | .. | 
|---|
| 830 | 856 |   | 
|---|
| 831 | 857 |  const struct k_clock alarm_clock = { | 
|---|
| 832 | 858 |  	.clock_getres		= alarm_clock_getres, | 
|---|
| 833 |  | -	.clock_get		= alarm_clock_get,  | 
|---|
 | 859 | +	.clock_get_ktime	= alarm_clock_get_ktime,  | 
|---|
 | 860 | +	.clock_get_timespec	= alarm_clock_get_timespec,  | 
|---|
| 834 | 861 |  	.timer_create		= alarm_timer_create, | 
|---|
| 835 | 862 |  	.timer_set		= common_timer_set, | 
|---|
| 836 | 863 |  	.timer_del		= common_timer_del, | 
|---|
| .. | .. | 
|---|
| 840 | 867 |  	.timer_forward		= alarm_timer_forward, | 
|---|
| 841 | 868 |  	.timer_remaining	= alarm_timer_remaining, | 
|---|
| 842 | 869 |  	.timer_try_to_cancel	= alarm_timer_try_to_cancel, | 
|---|
 | 870 | +	.timer_wait_running	= alarm_timer_wait_running,  | 
|---|
| 843 | 871 |  	.nsleep			= alarm_timer_nsleep, | 
|---|
| 844 | 872 |  }; | 
|---|
| 845 | 873 |  #endif /* CONFIG_POSIX_TIMERS */ | 
|---|
| .. | .. | 
|---|
| 858 | 886 |  	} | 
|---|
| 859 | 887 |  }; | 
|---|
| 860 | 888 |   | 
|---|
 | 889 | +static void get_boottime_timespec(struct timespec64 *tp)  | 
|---|
 | 890 | +{  | 
|---|
 | 891 | +	ktime_get_boottime_ts64(tp);  | 
|---|
 | 892 | +	timens_add_boottime(tp);  | 
|---|
 | 893 | +}  | 
|---|
 | 894 | +  | 
|---|
| 861 | 895 |  /** | 
|---|
| 862 | 896 |   * alarmtimer_init - Initialize alarm timer code | 
|---|
| 863 | 897 |   * | 
|---|
| .. | .. | 
|---|
| 866 | 900 |   */ | 
|---|
| 867 | 901 |  static int __init alarmtimer_init(void) | 
|---|
| 868 | 902 |  { | 
|---|
| 869 |  | -	struct platform_device *pdev;  | 
|---|
| 870 |  | -	int error = 0;  | 
|---|
 | 903 | +	int error;  | 
|---|
| 871 | 904 |  	int i; | 
|---|
| 872 | 905 |   | 
|---|
| 873 | 906 |  	alarmtimer_rtc_timer_init(); | 
|---|
| 874 | 907 |   | 
|---|
| 875 | 908 |  	/* Initialize alarm bases */ | 
|---|
| 876 | 909 |  	alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME; | 
|---|
| 877 |  | -	alarm_bases[ALARM_REALTIME].gettime = &ktime_get_real;  | 
|---|
 | 910 | +	alarm_bases[ALARM_REALTIME].get_ktime = &ktime_get_real;  | 
|---|
 | 911 | +	alarm_bases[ALARM_REALTIME].get_timespec = ktime_get_real_ts64;  | 
|---|
| 878 | 912 |  	alarm_bases[ALARM_BOOTTIME].base_clockid = CLOCK_BOOTTIME; | 
|---|
| 879 |  | -	alarm_bases[ALARM_BOOTTIME].gettime = &ktime_get_boottime;  | 
|---|
 | 913 | +	alarm_bases[ALARM_BOOTTIME].get_ktime = &ktime_get_boottime;  | 
|---|
 | 914 | +	alarm_bases[ALARM_BOOTTIME].get_timespec = get_boottime_timespec;  | 
|---|
| 880 | 915 |  	for (i = 0; i < ALARM_NUMTYPE; i++) { | 
|---|
| 881 | 916 |  		timerqueue_init_head(&alarm_bases[i].timerqueue); | 
|---|
| 882 | 917 |  		spin_lock_init(&alarm_bases[i].lock); | 
|---|
| .. | .. | 
|---|
| 890 | 925 |  	if (error) | 
|---|
| 891 | 926 |  		goto out_if; | 
|---|
| 892 | 927 |   | 
|---|
| 893 |  | -	pdev = platform_device_register_simple("alarmtimer", -1, NULL, 0);  | 
|---|
| 894 |  | -	if (IS_ERR(pdev)) {  | 
|---|
| 895 |  | -		error = PTR_ERR(pdev);  | 
|---|
| 896 |  | -		goto out_drv;  | 
|---|
| 897 |  | -	}  | 
|---|
| 898 | 928 |  	return 0; | 
|---|
| 899 |  | -  | 
|---|
| 900 |  | -out_drv:  | 
|---|
| 901 |  | -	platform_driver_unregister(&alarmtimer_driver);  | 
|---|
| 902 | 929 |  out_if: | 
|---|
| 903 | 930 |  	alarmtimer_rtc_interface_remove(); | 
|---|
| 904 | 931 |  	return error; | 
|---|