diff options
Diffstat (limited to 'drivers/rtc')
| -rw-r--r-- | drivers/rtc/rtc-at91rm9200.c | 62 | ||||
| -rw-r--r-- | drivers/rtc/rtc-at91sam9.c | 73 | ||||
| -rw-r--r-- | drivers/rtc/rtc-ds1685.c | 18 |
3 files changed, 117 insertions, 36 deletions
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 70a5d94cc766..b4f7744f6751 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
| 32 | #include <linux/of.h> | 32 | #include <linux/of.h> |
| 33 | #include <linux/of_device.h> | 33 | #include <linux/of_device.h> |
| 34 | #include <linux/suspend.h> | ||
| 34 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
| 35 | 36 | ||
| 36 | #include "rtc-at91rm9200.h" | 37 | #include "rtc-at91rm9200.h" |
| @@ -54,6 +55,10 @@ static void __iomem *at91_rtc_regs; | |||
| 54 | static int irq; | 55 | static int irq; |
| 55 | static DEFINE_SPINLOCK(at91_rtc_lock); | 56 | static DEFINE_SPINLOCK(at91_rtc_lock); |
| 56 | static u32 at91_rtc_shadow_imr; | 57 | static u32 at91_rtc_shadow_imr; |
| 58 | static bool suspended; | ||
| 59 | static DEFINE_SPINLOCK(suspended_lock); | ||
| 60 | static unsigned long cached_events; | ||
| 61 | static u32 at91_rtc_imr; | ||
| 57 | 62 | ||
| 58 | static void at91_rtc_write_ier(u32 mask) | 63 | static void at91_rtc_write_ier(u32 mask) |
| 59 | { | 64 | { |
| @@ -290,7 +295,9 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
| 290 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 295 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
| 291 | unsigned int rtsr; | 296 | unsigned int rtsr; |
| 292 | unsigned long events = 0; | 297 | unsigned long events = 0; |
| 298 | int ret = IRQ_NONE; | ||
| 293 | 299 | ||
| 300 | spin_lock(&suspended_lock); | ||
| 294 | rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read_imr(); | 301 | rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read_imr(); |
| 295 | if (rtsr) { /* this interrupt is shared! Is it ours? */ | 302 | if (rtsr) { /* this interrupt is shared! Is it ours? */ |
| 296 | if (rtsr & AT91_RTC_ALARM) | 303 | if (rtsr & AT91_RTC_ALARM) |
| @@ -304,14 +311,22 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
| 304 | 311 | ||
| 305 | at91_rtc_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ | 312 | at91_rtc_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ |
| 306 | 313 | ||
| 307 | rtc_update_irq(rtc, 1, events); | 314 | if (!suspended) { |
| 315 | rtc_update_irq(rtc, 1, events); | ||
| 308 | 316 | ||
| 309 | dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", __func__, | 317 | dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", |
| 310 | events >> 8, events & 0x000000FF); | 318 | __func__, events >> 8, events & 0x000000FF); |
| 319 | } else { | ||
| 320 | cached_events |= events; | ||
| 321 | at91_rtc_write_idr(at91_rtc_imr); | ||
| 322 | pm_system_wakeup(); | ||
| 323 | } | ||
| 311 | 324 | ||
| 312 | return IRQ_HANDLED; | 325 | ret = IRQ_HANDLED; |
| 313 | } | 326 | } |
| 314 | return IRQ_NONE; /* not handled */ | 327 | spin_lock(&suspended_lock); |
| 328 | |||
| 329 | return ret; | ||
| 315 | } | 330 | } |
| 316 | 331 | ||
| 317 | static const struct at91_rtc_config at91rm9200_config = { | 332 | static const struct at91_rtc_config at91rm9200_config = { |
| @@ -401,8 +416,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
| 401 | AT91_RTC_CALEV); | 416 | AT91_RTC_CALEV); |
| 402 | 417 | ||
| 403 | ret = devm_request_irq(&pdev->dev, irq, at91_rtc_interrupt, | 418 | ret = devm_request_irq(&pdev->dev, irq, at91_rtc_interrupt, |
| 404 | IRQF_SHARED, | 419 | IRQF_SHARED | IRQF_COND_SUSPEND, |
| 405 | "at91_rtc", pdev); | 420 | "at91_rtc", pdev); |
| 406 | if (ret) { | 421 | if (ret) { |
| 407 | dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); | 422 | dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); |
| 408 | return ret; | 423 | return ret; |
| @@ -454,8 +469,6 @@ static void at91_rtc_shutdown(struct platform_device *pdev) | |||
| 454 | 469 | ||
| 455 | /* AT91RM9200 RTC Power management control */ | 470 | /* AT91RM9200 RTC Power management control */ |
| 456 | 471 | ||
| 457 | static u32 at91_rtc_imr; | ||
| 458 | |||
| 459 | static int at91_rtc_suspend(struct device *dev) | 472 | static int at91_rtc_suspend(struct device *dev) |
| 460 | { | 473 | { |
| 461 | /* this IRQ is shared with DBGU and other hardware which isn't | 474 | /* this IRQ is shared with DBGU and other hardware which isn't |
| @@ -464,21 +477,42 @@ static int at91_rtc_suspend(struct device *dev) | |||
| 464 | at91_rtc_imr = at91_rtc_read_imr() | 477 | at91_rtc_imr = at91_rtc_read_imr() |
| 465 | & (AT91_RTC_ALARM|AT91_RTC_SECEV); | 478 | & (AT91_RTC_ALARM|AT91_RTC_SECEV); |
| 466 | if (at91_rtc_imr) { | 479 | if (at91_rtc_imr) { |
| 467 | if (device_may_wakeup(dev)) | 480 | if (device_may_wakeup(dev)) { |
| 481 | unsigned long flags; | ||
| 482 | |||
| 468 | enable_irq_wake(irq); | 483 | enable_irq_wake(irq); |
| 469 | else | 484 | |
| 485 | spin_lock_irqsave(&suspended_lock, flags); | ||
| 486 | suspended = true; | ||
| 487 | spin_unlock_irqrestore(&suspended_lock, flags); | ||
| 488 | } else { | ||
| 470 | at91_rtc_write_idr(at91_rtc_imr); | 489 | at91_rtc_write_idr(at91_rtc_imr); |
| 490 | } | ||
| 471 | } | 491 | } |
| 472 | return 0; | 492 | return 0; |
| 473 | } | 493 | } |
| 474 | 494 | ||
| 475 | static int at91_rtc_resume(struct device *dev) | 495 | static int at91_rtc_resume(struct device *dev) |
| 476 | { | 496 | { |
| 497 | struct rtc_device *rtc = dev_get_drvdata(dev); | ||
| 498 | |||
| 477 | if (at91_rtc_imr) { | 499 | if (at91_rtc_imr) { |
| 478 | if (device_may_wakeup(dev)) | 500 | if (device_may_wakeup(dev)) { |
| 501 | unsigned long flags; | ||
| 502 | |||
| 503 | spin_lock_irqsave(&suspended_lock, flags); | ||
| 504 | |||
| 505 | if (cached_events) { | ||
| 506 | rtc_update_irq(rtc, 1, cached_events); | ||
| 507 | cached_events = 0; | ||
| 508 | } | ||
| 509 | |||
| 510 | suspended = false; | ||
| 511 | spin_unlock_irqrestore(&suspended_lock, flags); | ||
| 512 | |||
| 479 | disable_irq_wake(irq); | 513 | disable_irq_wake(irq); |
| 480 | else | 514 | } |
| 481 | at91_rtc_write_ier(at91_rtc_imr); | 515 | at91_rtc_write_ier(at91_rtc_imr); |
| 482 | } | 516 | } |
| 483 | return 0; | 517 | return 0; |
| 484 | } | 518 | } |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 2183fd2750ab..5ccaee32df72 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 24 | #include <linux/mfd/syscon.h> | 24 | #include <linux/mfd/syscon.h> |
| 25 | #include <linux/regmap.h> | 25 | #include <linux/regmap.h> |
| 26 | #include <linux/suspend.h> | ||
| 26 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
| 27 | 28 | ||
| 28 | /* | 29 | /* |
| @@ -77,6 +78,9 @@ struct sam9_rtc { | |||
| 77 | unsigned int gpbr_offset; | 78 | unsigned int gpbr_offset; |
| 78 | int irq; | 79 | int irq; |
| 79 | struct clk *sclk; | 80 | struct clk *sclk; |
| 81 | bool suspended; | ||
| 82 | unsigned long events; | ||
| 83 | spinlock_t lock; | ||
| 80 | }; | 84 | }; |
| 81 | 85 | ||
| 82 | #define rtt_readl(rtc, field) \ | 86 | #define rtt_readl(rtc, field) \ |
| @@ -271,14 +275,9 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) | |||
| 271 | return 0; | 275 | return 0; |
| 272 | } | 276 | } |
| 273 | 277 | ||
| 274 | /* | 278 | static irqreturn_t at91_rtc_cache_events(struct sam9_rtc *rtc) |
| 275 | * IRQ handler for the RTC | ||
| 276 | */ | ||
| 277 | static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) | ||
| 278 | { | 279 | { |
| 279 | struct sam9_rtc *rtc = _rtc; | ||
| 280 | u32 sr, mr; | 280 | u32 sr, mr; |
| 281 | unsigned long events = 0; | ||
| 282 | 281 | ||
| 283 | /* Shared interrupt may be for another device. Note: reading | 282 | /* Shared interrupt may be for another device. Note: reading |
| 284 | * SR clears it, so we must only read it in this irq handler! | 283 | * SR clears it, so we must only read it in this irq handler! |
| @@ -290,18 +289,54 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) | |||
| 290 | 289 | ||
| 291 | /* alarm status */ | 290 | /* alarm status */ |
| 292 | if (sr & AT91_RTT_ALMS) | 291 | if (sr & AT91_RTT_ALMS) |
| 293 | events |= (RTC_AF | RTC_IRQF); | 292 | rtc->events |= (RTC_AF | RTC_IRQF); |
| 294 | 293 | ||
| 295 | /* timer update/increment */ | 294 | /* timer update/increment */ |
| 296 | if (sr & AT91_RTT_RTTINC) | 295 | if (sr & AT91_RTT_RTTINC) |
| 297 | events |= (RTC_UF | RTC_IRQF); | 296 | rtc->events |= (RTC_UF | RTC_IRQF); |
| 297 | |||
| 298 | return IRQ_HANDLED; | ||
| 299 | } | ||
| 300 | |||
| 301 | static void at91_rtc_flush_events(struct sam9_rtc *rtc) | ||
| 302 | { | ||
| 303 | if (!rtc->events) | ||
| 304 | return; | ||
| 298 | 305 | ||
| 299 | rtc_update_irq(rtc->rtcdev, 1, events); | 306 | rtc_update_irq(rtc->rtcdev, 1, rtc->events); |
| 307 | rtc->events = 0; | ||
| 300 | 308 | ||
| 301 | pr_debug("%s: num=%ld, events=0x%02lx\n", __func__, | 309 | pr_debug("%s: num=%ld, events=0x%02lx\n", __func__, |
| 302 | events >> 8, events & 0x000000FF); | 310 | rtc->events >> 8, rtc->events & 0x000000FF); |
| 311 | } | ||
| 303 | 312 | ||
| 304 | return IRQ_HANDLED; | 313 | /* |
| 314 | * IRQ handler for the RTC | ||
| 315 | */ | ||
| 316 | static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) | ||
| 317 | { | ||
| 318 | struct sam9_rtc *rtc = _rtc; | ||
| 319 | int ret; | ||
| 320 | |||
| 321 | spin_lock(&rtc->lock); | ||
| 322 | |||
| 323 | ret = at91_rtc_cache_events(rtc); | ||
| 324 | |||
| 325 | /* We're called in suspended state */ | ||
| 326 | if (rtc->suspended) { | ||
| 327 | /* Mask irqs coming from this peripheral */ | ||
| 328 | rtt_writel(rtc, MR, | ||
| 329 | rtt_readl(rtc, MR) & | ||
| 330 | ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); | ||
| 331 | /* Trigger a system wakeup */ | ||
| 332 | pm_system_wakeup(); | ||
| 333 | } else { | ||
| 334 | at91_rtc_flush_events(rtc); | ||
| 335 | } | ||
| 336 | |||
| 337 | spin_unlock(&rtc->lock); | ||
| 338 | |||
| 339 | return ret; | ||
| 305 | } | 340 | } |
| 306 | 341 | ||
| 307 | static const struct rtc_class_ops at91_rtc_ops = { | 342 | static const struct rtc_class_ops at91_rtc_ops = { |
| @@ -421,7 +456,8 @@ static int at91_rtc_probe(struct platform_device *pdev) | |||
| 421 | 456 | ||
| 422 | /* register irq handler after we know what name we'll use */ | 457 | /* register irq handler after we know what name we'll use */ |
| 423 | ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt, | 458 | ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt, |
| 424 | IRQF_SHARED, dev_name(&rtc->rtcdev->dev), rtc); | 459 | IRQF_SHARED | IRQF_COND_SUSPEND, |
| 460 | dev_name(&rtc->rtcdev->dev), rtc); | ||
| 425 | if (ret) { | 461 | if (ret) { |
| 426 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); | 462 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); |
| 427 | return ret; | 463 | return ret; |
| @@ -482,7 +518,12 @@ static int at91_rtc_suspend(struct device *dev) | |||
| 482 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | 518 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); |
| 483 | if (rtc->imr) { | 519 | if (rtc->imr) { |
| 484 | if (device_may_wakeup(dev) && (mr & AT91_RTT_ALMIEN)) { | 520 | if (device_may_wakeup(dev) && (mr & AT91_RTT_ALMIEN)) { |
| 521 | unsigned long flags; | ||
| 522 | |||
| 485 | enable_irq_wake(rtc->irq); | 523 | enable_irq_wake(rtc->irq); |
| 524 | spin_lock_irqsave(&rtc->lock, flags); | ||
| 525 | rtc->suspended = true; | ||
| 526 | spin_unlock_irqrestore(&rtc->lock, flags); | ||
| 486 | /* don't let RTTINC cause wakeups */ | 527 | /* don't let RTTINC cause wakeups */ |
| 487 | if (mr & AT91_RTT_RTTINCIEN) | 528 | if (mr & AT91_RTT_RTTINCIEN) |
| 488 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); | 529 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); |
| @@ -499,10 +540,18 @@ static int at91_rtc_resume(struct device *dev) | |||
| 499 | u32 mr; | 540 | u32 mr; |
| 500 | 541 | ||
| 501 | if (rtc->imr) { | 542 | if (rtc->imr) { |
| 543 | unsigned long flags; | ||
| 544 | |||
| 502 | if (device_may_wakeup(dev)) | 545 | if (device_may_wakeup(dev)) |
| 503 | disable_irq_wake(rtc->irq); | 546 | disable_irq_wake(rtc->irq); |
| 504 | mr = rtt_readl(rtc, MR); | 547 | mr = rtt_readl(rtc, MR); |
| 505 | rtt_writel(rtc, MR, mr | rtc->imr); | 548 | rtt_writel(rtc, MR, mr | rtc->imr); |
| 549 | |||
| 550 | spin_lock_irqsave(&rtc->lock, flags); | ||
| 551 | rtc->suspended = false; | ||
| 552 | at91_rtc_cache_events(rtc); | ||
| 553 | at91_rtc_flush_events(rtc); | ||
| 554 | spin_unlock_irqrestore(&rtc->lock, flags); | ||
| 506 | } | 555 | } |
| 507 | 556 | ||
| 508 | return 0; | 557 | return 0; |
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 8c3bfcb115b7..803869c7d7c2 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c | |||
| @@ -399,21 +399,21 @@ ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 399 | * of this RTC chip. We check for it anyways in case support is | 399 | * of this RTC chip. We check for it anyways in case support is |
| 400 | * added in the future. | 400 | * added in the future. |
| 401 | */ | 401 | */ |
| 402 | if (unlikely((seconds >= 0xc0) && (seconds <= 0xff))) | 402 | if (unlikely(seconds >= 0xc0)) |
| 403 | alrm->time.tm_sec = -1; | 403 | alrm->time.tm_sec = -1; |
| 404 | else | 404 | else |
| 405 | alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds, | 405 | alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds, |
| 406 | RTC_SECS_BCD_MASK, | 406 | RTC_SECS_BCD_MASK, |
| 407 | RTC_SECS_BIN_MASK); | 407 | RTC_SECS_BIN_MASK); |
| 408 | 408 | ||
| 409 | if (unlikely((minutes >= 0xc0) && (minutes <= 0xff))) | 409 | if (unlikely(minutes >= 0xc0)) |
| 410 | alrm->time.tm_min = -1; | 410 | alrm->time.tm_min = -1; |
| 411 | else | 411 | else |
| 412 | alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes, | 412 | alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes, |
| 413 | RTC_MINS_BCD_MASK, | 413 | RTC_MINS_BCD_MASK, |
| 414 | RTC_MINS_BIN_MASK); | 414 | RTC_MINS_BIN_MASK); |
| 415 | 415 | ||
| 416 | if (unlikely((hours >= 0xc0) && (hours <= 0xff))) | 416 | if (unlikely(hours >= 0xc0)) |
| 417 | alrm->time.tm_hour = -1; | 417 | alrm->time.tm_hour = -1; |
| 418 | else | 418 | else |
| 419 | alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours, | 419 | alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours, |
| @@ -472,13 +472,13 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 472 | * field, and we only support four fields. We put the support | 472 | * field, and we only support four fields. We put the support |
| 473 | * here anyways for the future. | 473 | * here anyways for the future. |
| 474 | */ | 474 | */ |
| 475 | if (unlikely((seconds >= 0xc0) && (seconds <= 0xff))) | 475 | if (unlikely(seconds >= 0xc0)) |
| 476 | seconds = 0xff; | 476 | seconds = 0xff; |
| 477 | 477 | ||
| 478 | if (unlikely((minutes >= 0xc0) && (minutes <= 0xff))) | 478 | if (unlikely(minutes >= 0xc0)) |
| 479 | minutes = 0xff; | 479 | minutes = 0xff; |
| 480 | 480 | ||
| 481 | if (unlikely((hours >= 0xc0) && (hours <= 0xff))) | 481 | if (unlikely(hours >= 0xc0)) |
| 482 | hours = 0xff; | 482 | hours = 0xff; |
| 483 | 483 | ||
| 484 | alrm->time.tm_mon = -1; | 484 | alrm->time.tm_mon = -1; |
| @@ -528,7 +528,6 @@ ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 528 | /* ----------------------------------------------------------------------- */ | 528 | /* ----------------------------------------------------------------------- */ |
| 529 | /* /dev/rtcX Interface functions */ | 529 | /* /dev/rtcX Interface functions */ |
| 530 | 530 | ||
| 531 | #ifdef CONFIG_RTC_INTF_DEV | ||
| 532 | /** | 531 | /** |
| 533 | * ds1685_rtc_alarm_irq_enable - replaces ioctl() RTC_AIE on/off. | 532 | * ds1685_rtc_alarm_irq_enable - replaces ioctl() RTC_AIE on/off. |
| 534 | * @dev: pointer to device structure. | 533 | * @dev: pointer to device structure. |
| @@ -557,7 +556,6 @@ ds1685_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
| 557 | 556 | ||
| 558 | return 0; | 557 | return 0; |
| 559 | } | 558 | } |
| 560 | #endif | ||
| 561 | /* ----------------------------------------------------------------------- */ | 559 | /* ----------------------------------------------------------------------- */ |
| 562 | 560 | ||
| 563 | 561 | ||
| @@ -1612,7 +1610,7 @@ ds1685_rtc_sysfs_time_regs_show(struct device *dev, | |||
| 1612 | ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, false); | 1610 | ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, false); |
| 1613 | 1611 | ||
| 1614 | /* Make sure we actually matched something. */ | 1612 | /* Make sure we actually matched something. */ |
| 1615 | if (!bcd_reg_info && !bin_reg_info) | 1613 | if (!bcd_reg_info || !bin_reg_info) |
| 1616 | return -EINVAL; | 1614 | return -EINVAL; |
| 1617 | 1615 | ||
| 1618 | /* bcd_reg_info->reg == bin_reg_info->reg. */ | 1616 | /* bcd_reg_info->reg == bin_reg_info->reg. */ |
| @@ -1650,7 +1648,7 @@ ds1685_rtc_sysfs_time_regs_store(struct device *dev, | |||
| 1650 | return -EINVAL; | 1648 | return -EINVAL; |
| 1651 | 1649 | ||
| 1652 | /* Make sure we actually matched something. */ | 1650 | /* Make sure we actually matched something. */ |
| 1653 | if (!bcd_reg_info && !bin_reg_info) | 1651 | if (!bcd_reg_info || !bin_reg_info) |
| 1654 | return -EINVAL; | 1652 | return -EINVAL; |
| 1655 | 1653 | ||
| 1656 | /* Check for a valid range. */ | 1654 | /* Check for a valid range. */ |
