diff options
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
| -rw-r--r-- | drivers/rtc/rtc-cmos.c | 368 | 
1 files changed, 211 insertions, 157 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 5856167a0c9..b0e4a3eb33c 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -34,8 +34,11 @@  #include <linux/interrupt.h>  #include <linux/spinlock.h>  #include <linux/platform_device.h> -#include <linux/mod_devicetable.h>  #include <linux/log2.h> +#include <linux/pm.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/dmi.h>  /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */  #include <asm-generic/rtc.h> @@ -161,7 +164,7 @@ static inline unsigned char cmos_read_bank2(unsigned char addr)  static inline void cmos_write_bank2(unsigned char val, unsigned char addr)  {  	outb(addr, RTC_PORT(2)); -	outb(val, RTC_PORT(2)); +	outb(val, RTC_PORT(3));  }  #else @@ -323,7 +326,7 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)  static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)  {  	struct cmos_rtc	*cmos = dev_get_drvdata(dev); -       unsigned char   mon, mday, hrs, min, sec, rtc_control; +	unsigned char mon, mday, hrs, min, sec, rtc_control;  	if (!is_valid_irq(cmos->irq))  		return -EIO; @@ -374,50 +377,51 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)  	return 0;  } -static int cmos_irq_set_freq(struct device *dev, int freq) -{ -	struct cmos_rtc	*cmos = dev_get_drvdata(dev); -	int		f; -	unsigned long	flags; - -	if (!is_valid_irq(cmos->irq)) -		return -ENXIO; - -	if (!is_power_of_2(freq)) -		return -EINVAL; -	/* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ -	f = ffs(freq); -	if (f-- > 16) -		return -EINVAL; -	f = 16 - f; - -	spin_lock_irqsave(&rtc_lock, flags); -	hpet_set_periodic_freq(freq); -	CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); -	spin_unlock_irqrestore(&rtc_lock, flags); - -	return 0; -} +/* + * Do not disable RTC alarm on shutdown - workaround for b0rked BIOSes. + */ +static bool alarm_disable_quirk; -static int cmos_irq_set_state(struct device *dev, int enabled) +static int __init set_alarm_disable_quirk(const struct dmi_system_id *id)  { -	struct cmos_rtc	*cmos = dev_get_drvdata(dev); -	unsigned long	flags; - -	if (!is_valid_irq(cmos->irq)) -		return -ENXIO; - -	spin_lock_irqsave(&rtc_lock, flags); - -	if (enabled) -		cmos_irq_enable(cmos, RTC_PIE); -	else -		cmos_irq_disable(cmos, RTC_PIE); - -	spin_unlock_irqrestore(&rtc_lock, flags); +	alarm_disable_quirk = true; +	pr_info("rtc-cmos: BIOS has alarm-disable quirk. "); +	pr_info("RTC alarms disabled\n");  	return 0;  } +static const struct dmi_system_id rtc_quirks[] __initconst = { +	/* https://bugzilla.novell.com/show_bug.cgi?id=805740 */ +	{ +		.callback = set_alarm_disable_quirk, +		.ident    = "IBM Truman", +		.matches  = { +			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), +			DMI_MATCH(DMI_PRODUCT_NAME, "4852570"), +		}, +	}, +	/* https://bugzilla.novell.com/show_bug.cgi?id=812592 */ +	{ +		.callback = set_alarm_disable_quirk, +		.ident    = "Gigabyte GA-990XA-UD3", +		.matches  = { +			DMI_MATCH(DMI_SYS_VENDOR, +					"Gigabyte Technology Co., Ltd."), +			DMI_MATCH(DMI_PRODUCT_NAME, "GA-990XA-UD3"), +		}, +	}, +	/* http://permalink.gmane.org/gmane.linux.kernel/1604474 */ +	{ +		.callback = set_alarm_disable_quirk, +		.ident    = "Toshiba Satellite L300", +		.matches  = { +			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), +			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), +		}, +	}, +	{} +}; +  static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)  {  	struct cmos_rtc	*cmos = dev_get_drvdata(dev); @@ -426,6 +430,9 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)  	if (!is_valid_irq(cmos->irq))  		return -EINVAL; +	if (alarm_disable_quirk) +		return 0; +  	spin_lock_irqsave(&rtc_lock, flags);  	if (enabled) @@ -437,25 +444,6 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)  	return 0;  } -static int cmos_update_irq_enable(struct device *dev, unsigned int enabled) -{ -	struct cmos_rtc	*cmos = dev_get_drvdata(dev); -	unsigned long	flags; - -	if (!is_valid_irq(cmos->irq)) -		return -EINVAL; - -	spin_lock_irqsave(&rtc_lock, flags); - -	if (enabled) -		cmos_irq_enable(cmos, RTC_UIE); -	else -		cmos_irq_disable(cmos, RTC_UIE); - -	spin_unlock_irqrestore(&rtc_lock, flags); -	return 0; -} -  #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)  static int cmos_procfs(struct device *dev, struct seq_file *seq) @@ -500,10 +488,7 @@ static const struct rtc_class_ops cmos_rtc_ops = {  	.read_alarm		= cmos_read_alarm,  	.set_alarm		= cmos_set_alarm,  	.proc			= cmos_procfs, -	.irq_set_freq		= cmos_irq_set_freq, -	.irq_set_state		= cmos_irq_set_state,  	.alarm_irq_enable	= cmos_alarm_irq_enable, -	.update_irq_enable	= cmos_update_irq_enable,  };  /*----------------------------------------------------------------*/ @@ -619,17 +604,24 @@ static irqreturn_t cmos_interrupt(int irq, void *p)  	rtc_control = CMOS_READ(RTC_CONTROL);  	if (is_hpet_enabled())  		irqstat = (unsigned long)irq & 0xF0; -	irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; + +	/* If we were suspended, RTC_CONTROL may not be accurate since the +	 * bios may have cleared it. +	 */ +	if (!cmos_rtc.suspend_ctrl) +		irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; +	else +		irqstat &= (cmos_rtc.suspend_ctrl & RTC_IRQMASK) | RTC_IRQF;  	/* All Linux RTC alarms should be treated as if they were oneshot.  	 * Similar code may be needed in system wakeup paths, in case the  	 * alarm woke the system.  	 */  	if (irqstat & RTC_AIE) { +		cmos_rtc.suspend_ctrl &= ~RTC_AIE;  		rtc_control &= ~RTC_AIE;  		CMOS_WRITE(rtc_control, RTC_CONTROL);  		hpet_mask_rtc_irq_bit(RTC_AIE); -  		CMOS_READ(RTC_INTR_FLAGS);  	}  	spin_unlock(&rtc_lock); @@ -651,10 +643,11 @@ static irqreturn_t cmos_interrupt(int irq, void *p)  static int INITSECTION  cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  { -	struct cmos_rtc_board_info	*info = dev->platform_data; +	struct cmos_rtc_board_info	*info = dev_get_platdata(dev);  	int				retval = 0;  	unsigned char			rtc_control;  	unsigned			address_space; +	u32				flags = 0;  	/* there can be only one ... */  	if (cmos_rtc.dev) @@ -668,9 +661,12 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  	 * REVISIT non-x86 systems may instead use memory space resources  	 * (needing ioremap etc), not i/o space resources like this ...  	 */ -	ports = request_region(ports->start, -			ports->end + 1 - ports->start, -			driver_name); +	if (RTC_IOMAPPED) +		ports = request_region(ports->start, resource_size(ports), +				       driver_name); +	else +		ports = request_mem_region(ports->start, resource_size(ports), +					   driver_name);  	if (!ports) {  		dev_dbg(dev, "i/o registers already in use\n");  		return -EBUSY; @@ -687,7 +683,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  #if	defined(CONFIG_ATARI)  	address_space = 64;  #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ -			|| defined(__sparc__) || defined(__mips__) +			|| defined(__sparc__) || defined(__mips__) \ +			|| defined(__powerpc__)  	address_space = 128;  #else  #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. @@ -706,6 +703,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  	 * expect CMOS_READ and friends to handle.  	 */  	if (info) { +		if (info->flags) +			flags = info->flags; +		if (info->address_space) +			address_space = info->address_space; +  		if (info->rtc_day_alarm && info->rtc_day_alarm < 128)  			cmos_rtc.day_alrm = info->rtc_day_alarm;  		if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128) @@ -733,18 +735,21 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  	spin_lock_irq(&rtc_lock); -	/* force periodic irq to CMOS reset default of 1024Hz; -	 * -	 * REVISIT it's been reported that at least one x86_64 ALI mobo -	 * doesn't use 32KHz here ... for portability we might need to -	 * do something about other clock frequencies. -	 */ -	cmos_rtc.rtc->irq_freq = 1024; -	hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); -	CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); +	if (!(flags & CMOS_RTC_FLAGS_NOFREQ)) { +		/* force periodic irq to CMOS reset default of 1024Hz; +		 * +		 * REVISIT it's been reported that at least one x86_64 ALI +		 * mobo doesn't use 32KHz here ... for portability we might +		 * need to do something about other clock frequencies. +		 */ +		cmos_rtc.rtc->irq_freq = 1024; +		hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq); +		CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); +	}  	/* disable irqs */ -	cmos_irq_disable(&cmos_rtc, RTC_PIE | RTC_AIE | RTC_UIE); +	if (is_valid_irq(rtc_irq)) +		cmos_irq_disable(&cmos_rtc, RTC_PIE | RTC_AIE | RTC_UIE);  	rtc_control = CMOS_READ(RTC_CONTROL); @@ -753,7 +758,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  	/* FIXME:  	 * <asm-generic/rtc.h> doesn't know 12-hour mode either.  	 */ -       if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) { +	if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {  		dev_warn(dev, "only 24-hr supported\n");  		retval = -ENXIO;  		goto cleanup1; @@ -763,12 +768,10 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  		irq_handler_t rtc_cmos_int_handler;  		if (is_hpet_enabled()) { -			int err; -  			rtc_cmos_int_handler = hpet_rtc_interrupt; -			err = hpet_register_irq_handler(cmos_interrupt); -			if (err != 0) { -				printk(KERN_WARNING "hpet_register_irq_handler " +			retval = hpet_register_irq_handler(cmos_interrupt); +			if (retval) { +				dev_warn(dev, "hpet_register_irq_handler "  						" failed in rtc_init().");  				goto cleanup1;  			} @@ -776,7 +779,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  			rtc_cmos_int_handler = cmos_interrupt;  		retval = request_irq(rtc_irq, rtc_cmos_int_handler, -				IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev), +				0, dev_name(&cmos_rtc.rtc->dev),  				cmos_rtc.rtc);  		if (retval < 0) {  			dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); @@ -793,8 +796,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)  		goto cleanup2;  	} -	pr_info("%s: %s%s, %zd bytes nvram%s\n", -		dev_name(&cmos_rtc.rtc->dev), +	dev_info(dev, "%s%s, %zd bytes nvram%s\n",  		!is_valid_irq(rtc_irq) ? "no alarms" :  			cmos_rtc.mon_alrm ? "alarms up to one year" :  			cmos_rtc.day_alrm ? "alarms up to one month" : @@ -812,14 +814,18 @@ cleanup1:  	cmos_rtc.dev = NULL;  	rtc_device_unregister(cmos_rtc.rtc);  cleanup0: -	release_region(ports->start, ports->end + 1 - ports->start); +	if (RTC_IOMAPPED) +		release_region(ports->start, resource_size(ports)); +	else +		release_mem_region(ports->start, resource_size(ports));  	return retval;  } -static void cmos_do_shutdown(void) +static void cmos_do_shutdown(int rtc_irq)  {  	spin_lock_irq(&rtc_lock); -	cmos_irq_disable(&cmos_rtc, RTC_IRQMASK); +	if (is_valid_irq(rtc_irq)) +		cmos_irq_disable(&cmos_rtc, RTC_IRQMASK);  	spin_unlock_irq(&rtc_lock);  } @@ -828,7 +834,7 @@ static void __exit cmos_do_remove(struct device *dev)  	struct cmos_rtc	*cmos = dev_get_drvdata(dev);  	struct resource *ports; -	cmos_do_shutdown(); +	cmos_do_shutdown(cmos->irq);  	sysfs_remove_bin_file(&dev->kobj, &nvram); @@ -841,16 +847,18 @@ static void __exit cmos_do_remove(struct device *dev)  	cmos->rtc = NULL;  	ports = cmos->iomem; -	release_region(ports->start, ports->end + 1 - ports->start); +	if (RTC_IOMAPPED) +		release_region(ports->start, resource_size(ports)); +	else +		release_mem_region(ports->start, resource_size(ports));  	cmos->iomem = NULL;  	cmos->dev = NULL; -	dev_set_drvdata(dev, NULL);  } -#ifdef	CONFIG_PM +#ifdef	CONFIG_PM_SLEEP -static int cmos_suspend(struct device *dev, pm_message_t mesg) +static int cmos_suspend(struct device *dev)  {  	struct cmos_rtc	*cmos = dev_get_drvdata(dev);  	unsigned char	tmp; @@ -867,9 +875,8 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)  			mask = RTC_IRQMASK;  		tmp &= ~mask;  		CMOS_WRITE(tmp, RTC_CONTROL); +		hpet_mask_rtc_irq_bit(mask); -		/* shut down hpet emulation - we don't need it for alarm */ -		hpet_mask_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE);  		cmos_checkintr(cmos, tmp);  	}  	spin_unlock_irq(&rtc_lock); @@ -882,8 +889,7 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)  			enable_irq_wake(cmos->irq);  	} -	pr_debug("%s: suspend%s, ctrl %02x\n", -			dev_name(&cmos_rtc.rtc->dev), +	dev_dbg(dev, "suspend%s, ctrl %02x\n",  			(tmp & RTC_AIE) ? ", alarm may wake" : "",  			tmp); @@ -898,27 +904,32 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)   */  static inline int cmos_poweroff(struct device *dev)  { -	return cmos_suspend(dev, PMSG_HIBERNATE); +	return cmos_suspend(dev);  }  static int cmos_resume(struct device *dev)  {  	struct cmos_rtc	*cmos = dev_get_drvdata(dev); -	unsigned char	tmp = cmos->suspend_ctrl; +	unsigned char tmp; +	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); +	tmp = cmos->suspend_ctrl; +	cmos->suspend_ctrl = 0;  	/* re-enable any irqs previously active */  	if (tmp & RTC_IRQMASK) {  		unsigned char	mask; -		if (cmos->enabled_wake) { -			if (cmos->wake_off) -				cmos->wake_off(dev); -			else -				disable_irq_wake(cmos->irq); -			cmos->enabled_wake = 0; -		} +		if (device_may_wakeup(dev)) +			hpet_rtc_timer_init(); -		spin_lock_irq(&rtc_lock);  		do {  			CMOS_WRITE(tmp, RTC_CONTROL);  			hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK); @@ -935,19 +946,15 @@ static int cmos_resume(struct device *dev)  			tmp &= ~RTC_AIE;  			hpet_mask_rtc_irq_bit(RTC_AIE);  		} while (mask & RTC_AIE); -		spin_unlock_irq(&rtc_lock);  	} +	spin_unlock_irq(&rtc_lock); -	pr_debug("%s: resume, ctrl %02x\n", -			dev_name(&cmos_rtc.rtc->dev), -			tmp); +	dev_dbg(dev, "resume, ctrl %02x\n", tmp);  	return 0;  }  #else -#define	cmos_suspend	NULL -#define	cmos_resume	NULL  static inline int cmos_poweroff(struct device *dev)  { @@ -956,6 +963,8 @@ static inline int cmos_poweroff(struct device *dev)  #endif +static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume); +  /*----------------------------------------------------------------*/  /* On non-x86 systems, a "CMOS" RTC lives most naturally on platform_bus. @@ -972,14 +981,17 @@ static inline int cmos_poweroff(struct device *dev)  static u32 rtc_handler(void *context)  { +	struct device *dev = context; + +	pm_wakeup_event(dev, 0);  	acpi_clear_event(ACPI_EVENT_RTC);  	acpi_disable_event(ACPI_EVENT_RTC, 0);  	return ACPI_INTERRUPT_HANDLED;  } -static inline void rtc_wake_setup(void) +static inline void rtc_wake_setup(struct device *dev)  { -	acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); +	acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);  	/*  	 * After the RTC handler is installed, the Fixed_RTC event should  	 * be disabled. Only when the RTC alarm is set will it be enabled. @@ -1006,13 +1018,12 @@ static void rtc_wake_off(struct device *dev)   */  static struct cmos_rtc_board_info acpi_rtc_info; -static void __devinit -cmos_wake_setup(struct device *dev) +static void cmos_wake_setup(struct device *dev)  {  	if (acpi_disabled)  		return; -	rtc_wake_setup(); +	rtc_wake_setup(dev);  	acpi_rtc_info.wake_on = rtc_wake_on;  	acpi_rtc_info.wake_off = rtc_wake_off; @@ -1039,8 +1050,7 @@ cmos_wake_setup(struct device *dev)  #else -static void __devinit -cmos_wake_setup(struct device *dev) +static void cmos_wake_setup(struct device *dev)  {  } @@ -1050,12 +1060,11 @@ cmos_wake_setup(struct device *dev)  #include <linux/pnp.h> -static int __devinit -cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) +static int 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  		 * don't define the IRQ. It should always be safe to  		 * hardcode it in these cases @@ -1073,29 +1082,15 @@ static void __exit cmos_pnp_remove(struct pnp_dev *pnp)  	cmos_do_remove(&pnp->dev);  } -#ifdef	CONFIG_PM - -static int cmos_pnp_suspend(struct pnp_dev *pnp, pm_message_t mesg) -{ -	return cmos_suspend(&pnp->dev, mesg); -} - -static int cmos_pnp_resume(struct pnp_dev *pnp) -{ -	return cmos_resume(&pnp->dev); -} - -#else -#define	cmos_pnp_suspend	NULL -#define	cmos_pnp_resume		NULL -#endif -  static void cmos_pnp_shutdown(struct pnp_dev *pnp)  { -	if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pnp->dev)) +	struct device *dev = &pnp->dev; +	struct cmos_rtc	*cmos = dev_get_drvdata(dev); + +	if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(dev))  		return; -	cmos_do_shutdown(); +	cmos_do_shutdown(cmos->irq);  }  static const struct pnp_device_id rtc_ids[] = { @@ -1115,12 +1110,53 @@ static struct pnp_driver cmos_pnp_driver = {  	/* flag ensures resume() gets called, and stops syslog spam */  	.flags		= PNP_DRIVER_RES_DO_NOT_CHANGE, -	.suspend	= cmos_pnp_suspend, -	.resume		= cmos_pnp_resume, +	.driver		= { +			.pm = &cmos_pm_ops, +	},  };  #endif	/* CONFIG_PNP */ +#ifdef CONFIG_OF +static const struct of_device_id of_cmos_match[] = { +	{ +		.compatible = "motorola,mc146818", +	}, +	{ }, +}; +MODULE_DEVICE_TABLE(of, of_cmos_match); + +static __init void cmos_of_init(struct platform_device *pdev) +{ +	struct device_node *node = pdev->dev.of_node; +	struct rtc_time time; +	int ret; +	const __be32 *val; + +	if (!node) +		return; + +	val = of_get_property(node, "ctrl-reg", NULL); +	if (val) +		CMOS_WRITE(be32_to_cpup(val), RTC_CONTROL); + +	val = of_get_property(node, "freq-reg", NULL); +	if (val) +		CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); + +	get_rtc_time(&time); +	ret = rtc_valid_tm(&time); +	if (ret) { +		struct rtc_time def_time = { +			.tm_year = 1, +			.tm_mday = 1, +		}; +		set_rtc_time(&def_time); +	} +} +#else +static inline void cmos_of_init(struct platform_device *pdev) {} +#endif  /*----------------------------------------------------------------*/  /* Platform setup should have set up an RTC device, when PNP is @@ -1129,10 +1165,21 @@ static struct pnp_driver cmos_pnp_driver = {  static int __init cmos_platform_probe(struct platform_device *pdev)  { +	struct resource *resource; +	int irq; + +	cmos_of_init(pdev);  	cmos_wake_setup(&pdev->dev); -	return cmos_do_probe(&pdev->dev, -			platform_get_resource(pdev, IORESOURCE_IO, 0), -			platform_get_irq(pdev, 0)); + +	if (RTC_IOMAPPED) +		resource = platform_get_resource(pdev, IORESOURCE_IO, 0); +	else +		resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) +		irq = -1; + +	return cmos_do_probe(&pdev->dev, resource, irq);  }  static int __exit cmos_platform_remove(struct platform_device *pdev) @@ -1143,10 +1190,13 @@ static int __exit cmos_platform_remove(struct platform_device *pdev)  static void cmos_platform_shutdown(struct platform_device *pdev)  { -	if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pdev->dev)) +	struct device *dev = &pdev->dev; +	struct cmos_rtc	*cmos = dev_get_drvdata(dev); + +	if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(dev))  		return; -	cmos_do_shutdown(); +	cmos_do_shutdown(cmos->irq);  }  /* work with hotplug and coldplug */ @@ -1156,9 +1206,11 @@ static struct platform_driver cmos_platform_driver = {  	.remove		= __exit_p(cmos_platform_remove),  	.shutdown	= cmos_platform_shutdown,  	.driver = { -		.name		= (char *) driver_name, -		.suspend	= cmos_suspend, -		.resume		= cmos_resume, +		.name		= driver_name, +#ifdef CONFIG_PM +		.pm		= &cmos_pm_ops, +#endif +		.of_match_table = of_match_ptr(of_cmos_match),  	}  }; @@ -1184,6 +1236,8 @@ static int __init cmos_init(void)  			platform_driver_registered = true;  	} +	dmi_check_system(rtc_quirks); +  	if (retval == 0)  		return 0;  | 
