]> err.no Git - linux-2.6/blobdiff - drivers/rtc/rtc-cmos.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[linux-2.6] / drivers / rtc / rtc-cmos.c
index 3fbfdd16191dbaf2851d1cc572ead7e011f50403..5d760bb6c2cd2100e051dadc9d0bba00c0c8da33 100644 (file)
@@ -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 <linux/pnp.h>
 
@@ -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");