Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 54776
b: refs/heads/master
c: 87ac84f
h: refs/heads/master
v: v3
  • Loading branch information
David Brownell authored and Linus Torvalds committed May 8, 2007
1 parent 7b6fdac commit 17bf73e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9b5ef64a3a73757f1acdfb8565b5105115fc6e62
refs/heads/master: 87ac84f42a7a580d0dd72ae31d6a5eb4bfe04c6d
37 changes: 27 additions & 10 deletions trunk/drivers/rtc/rtc-cmos.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ struct cmos_rtc {
int irq;
struct resource *iomem;

void (*wake_on)(struct device *);
void (*wake_off)(struct device *);

u8 enabled_wake;
u8 suspend_ctrl;

/* newer hardware extends the original register set */
Expand Down Expand Up @@ -405,13 +409,20 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
cmos_rtc.irq = rtc_irq;
cmos_rtc.iomem = ports;

/* For ACPI systems the info comes from the FADT. On others,
* board specific setup provides it as appropriate.
/* For ACPI systems extension info comes from the FADT. On others,
* board specific setup provides it as appropriate. Systems where
* the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and
* some almost-clones) can provide hooks to make that behave.
*/
if (info) {
cmos_rtc.day_alrm = info->rtc_day_alarm;
cmos_rtc.mon_alrm = info->rtc_mon_alarm;
cmos_rtc.century = info->rtc_century;

if (info->wake_on && info->wake_off) {
cmos_rtc.wake_on = info->wake_on;
cmos_rtc.wake_off = info->wake_off;
}
}

cmos_rtc.rtc = rtc_device_register(driver_name, dev,
Expand Down Expand Up @@ -559,9 +570,13 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)
}
spin_unlock_irq(&rtc_lock);

/* ACPI HOOK: enable ACPI_EVENT_RTC when (tmp & RTC_AIE)
* ... it'd be best if we could do that under rtc_lock.
*/
if (tmp & RTC_AIE) {
cmos->enabled_wake = 1;
if (cmos->wake_on)
cmos->wake_on(dev);
else
enable_irq_wake(cmos->irq);
}

pr_debug("%s: suspend%s, ctrl %02x\n",
cmos_rtc.rtc->dev.bus_id,
Expand All @@ -576,14 +591,16 @@ static int cmos_resume(struct device *dev)
struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char tmp = cmos->suspend_ctrl;

/* REVISIT: a mechanism to resync the system clock (jiffies)
* on resume should be portable between platforms ...
*/

/* re-enable any irqs previously active */
if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {

/* ACPI HOOK: disable ACPI_EVENT_RTC when (tmp & RTC_AIE) */
if (cmos->enabled_wake) {
if (cmos->wake_off)
cmos->wake_off(dev);
else
disable_irq_wake(cmos->irq);
cmos->enabled_wake = 0;
}

spin_lock_irq(&rtc_lock);
CMOS_WRITE(tmp, RTC_CONTROL);
Expand Down
7 changes: 7 additions & 0 deletions trunk/include/linux/mc146818rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,15 @@ extern spinlock_t rtc_lock; /* serialize CMOS RAM access */
/* Some RTCs extend the mc146818 register set to support alarms of more
* than 24 hours in the future; or dates that include a century code.
* This platform_data structure can pass this information to the driver.
*
* Also, some platforms need suspend()/resume() hooks to kick in special
* handling of wake alarms, e.g. activating ACPI BIOS hooks or setting up
* a separate wakeup alarm used by some almost-clone chips.
*/
struct cmos_rtc_board_info {
void (*wake_on)(struct device *dev);
void (*wake_off)(struct device *dev);

u8 rtc_day_alarm; /* zero, or register index */
u8 rtc_mon_alarm; /* zero, or register index */
u8 rtc_century; /* zero, or register index */
Expand Down

0 comments on commit 17bf73e

Please sign in to comment.