mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-15 08:44:14 +08:00
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: Bjorn Helgaas <bjorn.helgaas@hp.com> Acked-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
8acd3a60bc
commit
a474aaedac
@ -260,115 +260,3 @@ static int __init init_acpi_device_notify(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
arch_initcall(init_acpi_device_notify);
|
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
|
|
||||||
|
@ -913,6 +913,92 @@ static inline int cmos_poweroff(struct device *dev)
|
|||||||
* predate even PNPBIOS should set up platform_bus devices.
|
* 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
|
#ifdef CONFIG_PNP
|
||||||
|
|
||||||
#include <linux/pnp.h>
|
#include <linux/pnp.h>
|
||||||
@ -920,6 +1006,8 @@ static inline int cmos_poweroff(struct device *dev)
|
|||||||
static int __devinit
|
static int __devinit
|
||||||
cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
|
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))
|
if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0))
|
||||||
/* Some machines contain a PNP entry for the RTC, but
|
/* Some machines contain a PNP entry for the RTC, but
|
||||||
* don't define the IRQ. It should always be safe to
|
* 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)
|
static int __init cmos_platform_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
cmos_wake_setup(&pdev->dev);
|
||||||
return cmos_do_probe(&pdev->dev,
|
return cmos_do_probe(&pdev->dev,
|
||||||
platform_get_resource(pdev, IORESOURCE_IO, 0),
|
platform_get_resource(pdev, IORESOURCE_IO, 0),
|
||||||
platform_get_irq(pdev, 0));
|
platform_get_irq(pdev, 0));
|
||||||
|
Loading…
Reference in New Issue
Block a user