X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Frtc%2Frtc-cmos.c;h=5d760bb6c2cd2100e051dadc9d0bba00c0c8da33;hb=a5b4860b973bb7a306562d8715ba8538a584537d;hp=3fbfdd16191dbaf2851d1cc572ead7e011f50403;hpb=87ac84f42a7a580d0dd72ae31d6a5eb4bfe04c6d;p=linux-2.6 diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 3fbfdd1619..5d760bb6c2 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -235,7 +235,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) return 0; } -static int cmos_set_freq(struct device *dev, int freq) +static int cmos_irq_set_freq(struct device *dev, int freq) { struct cmos_rtc *cmos = dev_get_drvdata(dev); int f; @@ -259,6 +259,34 @@ static int cmos_set_freq(struct device *dev, int freq) return 0; } +static int cmos_irq_set_state(struct device *dev, int enabled) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + unsigned char rtc_control, rtc_intr; + unsigned long flags; + + if (!is_valid_irq(cmos->irq)) + return -ENXIO; + + spin_lock_irqsave(&rtc_lock, flags); + rtc_control = CMOS_READ(RTC_CONTROL); + + if (enabled) + rtc_control |= RTC_PIE; + else + rtc_control &= ~RTC_PIE; + + CMOS_WRITE(rtc_control, RTC_CONTROL); + + rtc_intr = CMOS_READ(RTC_INTR_FLAGS); + rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; + if (is_intr(rtc_intr)) + rtc_update_irq(cmos->rtc, 1, rtc_intr); + + spin_unlock_irqrestore(&rtc_lock, flags); + return 0; +} + #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) static int @@ -360,7 +388,8 @@ 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_set_freq, + .irq_set_freq = cmos_irq_set_freq, + .irq_set_state = cmos_irq_set_state, }; /*----------------------------------------------------------------*/ @@ -383,12 +412,12 @@ static irqreturn_t cmos_interrupt(int irq, void *p) return IRQ_NONE; } -#ifdef CONFIG_PNPACPI -#define is_pnpacpi() 1 +#ifdef CONFIG_PNP +#define is_pnp() 1 #define INITSECTION #else -#define is_pnpacpi() 0 +#define is_pnp() 0 #define INITSECTION __init #endif @@ -438,7 +467,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) * REVISIT for non-x86 systems we may need to handle io memory * resources: ioremap them, and request_mem_region(). */ - if (is_pnpacpi()) { + if (is_pnp()) { retval = request_resource(&ioport_resource, ports); if (retval < 0) { dev_dbg(dev, "i/o registers already in use\n"); @@ -531,7 +560,7 @@ static void __exit cmos_do_remove(struct device *dev) cmos_do_shutdown(); - if (is_pnpacpi()) + if (is_pnp()) release_resource(cmos->iomem); rename_region(cmos->iomem, NULL); @@ -630,7 +659,7 @@ static int cmos_resume(struct device *dev) * the device node will always be created as a PNPACPI device. */ -#ifdef CONFIG_PNPACPI +#ifdef CONFIG_PNP #include @@ -641,9 +670,16 @@ cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) * drivers can't provide shutdown() methods to disable IRQs. * Or better yet, fix PNP to allow those methods... */ - return cmos_do_probe(&pnp->dev, - &pnp->res.port_resource[0], - pnp->res.irq_resource[0].start); + 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 + */ + return cmos_do_probe(&pnp->dev, &pnp->res.port_resource[0], 8); + else + return cmos_do_probe(&pnp->dev, + &pnp->res.port_resource[0], + pnp->res.irq_resource[0].start); } static void __exit cmos_pnp_remove(struct pnp_dev *pnp) @@ -701,11 +737,11 @@ static void __exit cmos_exit(void) } module_exit(cmos_exit); -#else /* no PNPACPI */ +#else /* no PNP */ /*----------------------------------------------------------------*/ -/* Platform setup should have set up an RTC device, when PNPACPI is +/* Platform setup should have set up an RTC device, when PNP is * unavailable ... this could happen even on (older) PCs. */ @@ -751,7 +787,7 @@ static void __exit cmos_exit(void) module_exit(cmos_exit); -#endif /* !PNPACPI */ +#endif /* !PNP */ MODULE_AUTHOR("David Brownell"); MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs");