Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a474aaed authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Linus Torvalds
Browse files

rtc-cmos: move wake setup from ACPI glue into RTC driver



Move rtc_wake_setup() from drivers/acpi/glue.c into the RTC driver
in drivers/rtc/rtc-cmos.c.

This removes the ordering constraint between the module_init(acpi_rtc_init)
and the cmos_do_probe() code that depends on it.

Signed-off-by: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8acd3a60
Loading
Loading
Loading
Loading
+0 −112
Original line number Diff line number Diff line
@@ -260,115 +260,3 @@ static int __init init_acpi_device_notify(void)
}

arch_initcall(init_acpi_device_notify);


#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)

#ifdef CONFIG_PM
static u32 rtc_handler(void *context)
{
	acpi_clear_event(ACPI_EVENT_RTC);
	acpi_disable_event(ACPI_EVENT_RTC, 0);
	return ACPI_INTERRUPT_HANDLED;
}

static inline void rtc_wake_setup(void)
{
	acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
	/*
	 * After the RTC handler is installed, the Fixed_RTC event should
	 * be disabled. Only when the RTC alarm is set will it be enabled.
	 */
	acpi_clear_event(ACPI_EVENT_RTC);
	acpi_disable_event(ACPI_EVENT_RTC, 0);
}

static void rtc_wake_on(struct device *dev)
{
	acpi_clear_event(ACPI_EVENT_RTC);
	acpi_enable_event(ACPI_EVENT_RTC, 0);
}

static void rtc_wake_off(struct device *dev)
{
	acpi_disable_event(ACPI_EVENT_RTC, 0);
}
#else
#define rtc_wake_setup()	do{}while(0)
#define rtc_wake_on		NULL
#define rtc_wake_off		NULL
#endif

/* Every ACPI platform has a mc146818 compatible "cmos rtc".  Here we find
 * its device node and pass extra config data.  This helps its driver use
 * capabilities that the now-obsolete mc146818 didn't have, and informs it
 * that this board's RTC is wakeup-capable (per ACPI spec).
 */
#include <linux/mc146818rtc.h>

static struct cmos_rtc_board_info rtc_info;


/* PNP devices are registered in a subsys_initcall();
 * ACPI specifies the PNP IDs to use.
 */
#include <linux/pnp.h>

static int __init pnp_match(struct device *dev, void *data)
{
	static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", };
	struct pnp_dev *pnp = to_pnp_dev(dev);
	int i;

	for (i = 0; i < ARRAY_SIZE(ids); i++) {
		if (compare_pnp_id(pnp->id, ids[i]) != 0)
			return 1;
	}
	return 0;
}

static struct device *__init get_rtc_dev(void)
{
	return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match);
}

static int __init acpi_rtc_init(void)
{
	struct device *dev = get_rtc_dev();

	if (acpi_disabled)
		return 0;

	if (dev) {
		rtc_wake_setup();
		rtc_info.wake_on = rtc_wake_on;
		rtc_info.wake_off = rtc_wake_off;

		/* workaround bug in some ACPI tables */
		if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
			DBG("bogus FADT month_alarm\n");
			acpi_gbl_FADT.month_alarm = 0;
		}

		rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
		rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
		rtc_info.rtc_century = acpi_gbl_FADT.century;

		/* NOTE:  S4_RTC_WAKE is NOT currently useful to Linux */
		if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
			printk(PREFIX "RTC can wake from S4\n");


		dev->platform_data = &rtc_info;

		/* RTC always wakes from S1/S2/S3, and often S4/STD */
		device_init_wakeup(dev, 1);

		put_device(dev);
	} else
		DBG("RTC unavailable?\n");
	return 0;
}
module_init(acpi_rtc_init);

#endif
+89 −0
Original line number Diff line number Diff line
@@ -913,6 +913,92 @@ static inline int cmos_poweroff(struct device *dev)
 * predate even PNPBIOS should set up platform_bus devices.
 */

#ifdef	CONFIG_ACPI

#include <linux/acpi.h>

#ifdef	CONFIG_PM
static u32 rtc_handler(void *context)
{
	acpi_clear_event(ACPI_EVENT_RTC);
	acpi_disable_event(ACPI_EVENT_RTC, 0);
	return ACPI_INTERRUPT_HANDLED;
}

static inline void rtc_wake_setup(void)
{
	acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
	/*
	 * After the RTC handler is installed, the Fixed_RTC event should
	 * be disabled. Only when the RTC alarm is set will it be enabled.
	 */
	acpi_clear_event(ACPI_EVENT_RTC);
	acpi_disable_event(ACPI_EVENT_RTC, 0);
}

static void rtc_wake_on(struct device *dev)
{
	acpi_clear_event(ACPI_EVENT_RTC);
	acpi_enable_event(ACPI_EVENT_RTC, 0);
}

static void rtc_wake_off(struct device *dev)
{
	acpi_disable_event(ACPI_EVENT_RTC, 0);
}
#else
#define rtc_wake_setup()	do{}while(0)
#define rtc_wake_on		NULL
#define rtc_wake_off		NULL
#endif

/* Every ACPI platform has a mc146818 compatible "cmos rtc".  Here we find
 * its device node and pass extra config data.  This helps its driver use
 * capabilities that the now-obsolete mc146818 didn't have, and informs it
 * that this board's RTC is wakeup-capable (per ACPI spec).
 */
static struct cmos_rtc_board_info acpi_rtc_info;

static void __devinit
cmos_wake_setup(struct device *dev)
{
	if (acpi_disabled)
		return;

	rtc_wake_setup();
	acpi_rtc_info.wake_on = rtc_wake_on;
	acpi_rtc_info.wake_off = rtc_wake_off;

	/* workaround bug in some ACPI tables */
	if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
		dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
			acpi_gbl_FADT.month_alarm);
		acpi_gbl_FADT.month_alarm = 0;
	}

	acpi_rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
	acpi_rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
	acpi_rtc_info.rtc_century = acpi_gbl_FADT.century;

	/* NOTE:  S4_RTC_WAKE is NOT currently useful to Linux */
	if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
		dev_info(dev, "RTC can wake from S4\n");

	dev->platform_data = &acpi_rtc_info;

	/* RTC always wakes from S1/S2/S3, and often S4/STD */
	device_init_wakeup(dev, 1);
}

#else

static void __devinit
cmos_wake_setup(struct device *dev)
{
}

#endif

#ifdef	CONFIG_PNP

#include <linux/pnp.h>
@@ -920,6 +1006,8 @@ static inline int cmos_poweroff(struct device *dev)
static int __devinit
cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
{
	cmos_wake_setup(&pnp->dev);

	if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0))
		/* Some machines contain a PNP entry for the RTC, but
		 * don't define the IRQ. It should always be safe to
@@ -997,6 +1085,7 @@ static struct pnp_driver cmos_pnp_driver = {

static int __init cmos_platform_probe(struct platform_device *pdev)
{
	cmos_wake_setup(&pdev->dev);
	return cmos_do_probe(&pdev->dev,
			platform_get_resource(pdev, IORESOURCE_IO, 0),
			platform_get_irq(pdev, 0));