浏览代码

sh: Prevent heartbeat from scribbling over non-LED bits.

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>
Kuninori Morimoto 16 年之前
父节点
当前提交
e174d13010
共有 2 个文件被更改,包括 11 次插入0 次删除
  1. 10 0
      arch/sh/drivers/heartbeat.c
  2. 1 0
      arch/sh/include/asm/heartbeat.h

+ 10 - 0
arch/sh/drivers/heartbeat.c

@@ -40,14 +40,19 @@ static inline void heartbeat_toggle_bit(struct heartbeat_data *hd,
 	if (inverted)
 	if (inverted)
 		new = ~new;
 		new = ~new;
 
 
+	new &= hd->mask;
+
 	switch (hd->regsize) {
 	switch (hd->regsize) {
 	case 32:
 	case 32:
+		new |= ioread32(hd->base) & ~hd->mask;
 		iowrite32(new, hd->base);
 		iowrite32(new, hd->base);
 		break;
 		break;
 	case 16:
 	case 16:
+		new |= ioread16(hd->base) & ~hd->mask;
 		iowrite16(new, hd->base);
 		iowrite16(new, hd->base);
 		break;
 		break;
 	default:
 	default:
+		new |= ioread8(hd->base) & ~hd->mask;
 		iowrite8(new, hd->base);
 		iowrite8(new, hd->base);
 		break;
 		break;
 	}
 	}
@@ -72,6 +77,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
 {
 {
 	struct resource *res;
 	struct resource *res;
 	struct heartbeat_data *hd;
 	struct heartbeat_data *hd;
+	int i;
 
 
 	if (unlikely(pdev->num_resources != 1)) {
 	if (unlikely(pdev->num_resources != 1)) {
 		dev_err(&pdev->dev, "invalid number of resources\n");
 		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->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)
 	if (!hd->regsize)
 		hd->regsize = 8;	/* default access size */
 		hd->regsize = 8;	/* default access size */
 
 

+ 1 - 0
arch/sh/include/asm/heartbeat.h

@@ -11,6 +11,7 @@ struct heartbeat_data {
 	unsigned int nr_bits;
 	unsigned int nr_bits;
 	struct timer_list timer;
 	struct timer_list timer;
 	unsigned int regsize;
 	unsigned int regsize;
+	unsigned int mask;
 	unsigned long flags;
 	unsigned long flags;
 };
 };