sh: Prevent heartbeat from scribbling over non-LED bits.
authorKuninori Morimoto <morimoto.kuninori@renesas.com>
Tue, 18 Aug 2009 07:00:20 +0000 (07:00 +0000)
committerPaul Mundt <lethal@linux-sh.org>
Tue, 18 Aug 2009 12:16:29 +0000 (21:16 +0900)
While most platforms implement LED banks in sets of 8/16/32, some use
different configurations. This adds a LED mask to the heartbeat platform
data to allow platforms to constrain the bitmap, which is otherwise
derived from the register size.

Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/drivers/heartbeat.c
arch/sh/include/asm/heartbeat.h

index 938817e..a9339a6 100644 (file)
@@ -40,14 +40,19 @@ static inline void heartbeat_toggle_bit(struct heartbeat_data *hd,
        if (inverted)
                new = ~new;
 
+       new &= hd->mask;
+
        switch (hd->regsize) {
        case 32:
+               new |= ioread32(hd->base) & ~hd->mask;
                iowrite32(new, hd->base);
                break;
        case 16:
+               new |= ioread16(hd->base) & ~hd->mask;
                iowrite16(new, hd->base);
                break;
        default:
+               new |= ioread8(hd->base) & ~hd->mask;
                iowrite8(new, hd->base);
                break;
        }
@@ -72,6 +77,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
 {
        struct resource *res;
        struct heartbeat_data *hd;
+       int i;
 
        if (unlikely(pdev->num_resources != 1)) {
                dev_err(&pdev->dev, "invalid number of resources\n");
@@ -107,6 +113,10 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
                hd->nr_bits = ARRAY_SIZE(default_bit_pos);
        }
 
+       hd->mask = 0;
+       for (i = 0; i < hd->nr_bits; i++)
+               hd->mask |= (1 << hd->bit_pos[i]);
+
        if (!hd->regsize)
                hd->regsize = 8;        /* default access size */
 
index 724a43e..caaafe5 100644 (file)
@@ -11,6 +11,7 @@ struct heartbeat_data {
        unsigned int nr_bits;
        struct timer_list timer;
        unsigned int regsize;
+       unsigned int mask;
        unsigned long flags;
 };