drivers/rtc/rtc-ab8500.c: remove fix for AB8500 ED version
[deliverable/linux.git] / drivers / rtc / rtc-pl031.c
index 575fbbf966db21798e82f72e087bc60f44e22e37..08378e3cc21cf8209796d50876ee64ae5c0a4aaa 100644 (file)
 /**
  * struct pl031_vendor_data - per-vendor variations
  * @ops: the vendor-specific operations used on this silicon version
+ * @clockwatch: if this is an ST Microelectronics silicon version with a
+ *     clockwatch function
+ * @st_weekday: if this is an ST Microelectronics silicon version that need
+ *     the weekday fix
+ * @irqflags: special IRQ flags per variant
  */
 struct pl031_vendor_data {
        struct rtc_class_ops ops;
+       bool clockwatch;
+       bool st_weekday;
+       unsigned long irqflags;
 };
 
 struct pl031_local {
        struct pl031_vendor_data *vendor;
        struct rtc_device *rtc;
        void __iomem *base;
-       u8 hw_designer;
-       u8 hw_revision:4;
 };
 
 static int pl031_alarm_irq_enable(struct device *dev,
@@ -336,14 +342,11 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
 
        amba_set_drvdata(adev, ldata);
 
-       ldata->hw_designer = amba_manf(adev);
-       ldata->hw_revision = amba_rev(adev);
-
-       dev_dbg(&adev->dev, "designer ID = 0x%02x\n", ldata->hw_designer);
-       dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision);
+       dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev));
+       dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev));
 
        /* Enable the clockwatch on ST Variants */
-       if (ldata->hw_designer == AMBA_VENDOR_ST)
+       if (vendor->clockwatch)
                writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN,
                       ldata->base + RTC_CR);
 
@@ -351,7 +354,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
         * On ST PL031 variants, the RTC reset value does not provide correct
         * weekday for 2000-01-01. Correct the erroneous sunday to saturday.
         */
-       if (ldata->hw_designer == AMBA_VENDOR_ST) {
+       if (vendor->st_weekday) {
                if (readl(ldata->base + RTC_YDR) == 0x2000) {
                        time = readl(ldata->base + RTC_DR);
                        if ((time &
@@ -372,7 +375,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
        }
 
        if (request_irq(adev->irq[0], pl031_interrupt,
-                       0, "rtc-pl031", ldata)) {
+                       vendor->irqflags, "rtc-pl031", ldata)) {
                ret = -EIO;
                goto out_no_irq;
        }
@@ -402,6 +405,7 @@ static struct pl031_vendor_data arm_pl031 = {
                .set_alarm = pl031_set_alarm,
                .alarm_irq_enable = pl031_alarm_irq_enable,
        },
+       .irqflags = IRQF_NO_SUSPEND,
 };
 
 /* The First ST derivative */
@@ -413,6 +417,9 @@ static struct pl031_vendor_data stv1_pl031 = {
                .set_alarm = pl031_set_alarm,
                .alarm_irq_enable = pl031_alarm_irq_enable,
        },
+       .clockwatch = true,
+       .st_weekday = true,
+       .irqflags = IRQF_NO_SUSPEND,
 };
 
 /* And the second ST derivative */
@@ -424,6 +431,13 @@ static struct pl031_vendor_data stv2_pl031 = {
                .set_alarm = pl031_stv2_set_alarm,
                .alarm_irq_enable = pl031_alarm_irq_enable,
        },
+       .clockwatch = true,
+       .st_weekday = true,
+       /*
+        * This variant shares the IRQ with another block and must not
+        * suspend that IRQ line.
+        */
+       .irqflags = IRQF_SHARED | IRQF_NO_SUSPEND,
 };
 
 static struct amba_id pl031_ids[] = {
This page took 0.027073 seconds and 5 git commands to generate.