diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-08-20 00:03:41 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-09-20 22:57:51 -0400 |
commit | 8786c952c1682a132e99b736beae4523e409b13d (patch) | |
tree | fec83f758cf197fb4515675ceb8c023ecd60dc20 /arch/sh | |
parent | 2eb0303c2cd536d7f15c7f3bafc848b850a447f0 (diff) |
sh: heartbeat driver update.
Add some flags for the heartbeat driver, and kill off some duplication
in the bit positions for the boards that don't have special cases.
This also allows for variable access widths and inversion.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/boards/renesas/r7780rp/setup.c | 16 | ||||
-rw-r--r-- | arch/sh/boards/se/7206/setup.c | 8 | ||||
-rw-r--r-- | arch/sh/boards/se/770x/setup.c | 8 | ||||
-rw-r--r-- | arch/sh/boards/se/7722/setup.c | 9 | ||||
-rw-r--r-- | arch/sh/boards/se/7751/setup.c | 8 | ||||
-rw-r--r-- | arch/sh/boards/se/7780/setup.c | 7 | ||||
-rw-r--r-- | arch/sh/drivers/heartbeat.c | 70 |
7 files changed, 87 insertions, 39 deletions
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index adb529d01bae..1062346e1d34 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/machvec.h> | 19 | #include <asm/machvec.h> |
20 | #include <asm/r7780rp.h> | 20 | #include <asm/r7780rp.h> |
21 | #include <asm/clock.h> | 21 | #include <asm/clock.h> |
22 | #include <asm/heartbeat.h> | ||
22 | #include <asm/io.h> | 23 | #include <asm/io.h> |
23 | 24 | ||
24 | static struct resource r8a66597_usb_host_resources[] = { | 25 | static struct resource r8a66597_usb_host_resources[] = { |
@@ -108,16 +109,23 @@ static struct platform_device cf_ide_device = { | |||
108 | }, | 109 | }, |
109 | }; | 110 | }; |
110 | 111 | ||
111 | static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 }; | ||
112 | |||
113 | static struct resource heartbeat_resources[] = { | 112 | static struct resource heartbeat_resources[] = { |
114 | [0] = { | 113 | [0] = { |
115 | .start = PA_OBLED, | 114 | .start = PA_OBLED, |
116 | .end = PA_OBLED + ARRAY_SIZE(heartbeat_bit_pos) - 1, | 115 | .end = PA_OBLED + 8 - 1, |
117 | .flags = IORESOURCE_MEM, | 116 | .flags = IORESOURCE_MEM, |
118 | }, | 117 | }, |
119 | }; | 118 | }; |
120 | 119 | ||
120 | #ifndef CONFIG_SH_R7785RP | ||
121 | static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 }; | ||
122 | |||
123 | static struct heartbeat_data heartbeat_data = { | ||
124 | .bit_pos = heartbeat_bit_pos, | ||
125 | .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), | ||
126 | }; | ||
127 | #endif | ||
128 | |||
121 | static struct platform_device heartbeat_device = { | 129 | static struct platform_device heartbeat_device = { |
122 | .name = "heartbeat", | 130 | .name = "heartbeat", |
123 | .id = -1, | 131 | .id = -1, |
@@ -125,7 +133,7 @@ static struct platform_device heartbeat_device = { | |||
125 | /* R7785RP has a slightly more sensible FPGA.. */ | 133 | /* R7785RP has a slightly more sensible FPGA.. */ |
126 | #ifndef CONFIG_SH_R7785RP | 134 | #ifndef CONFIG_SH_R7785RP |
127 | .dev = { | 135 | .dev = { |
128 | .platform_data = heartbeat_bit_pos, | 136 | .platform_data = heartbeat_data, |
129 | }, | 137 | }, |
130 | #endif | 138 | #endif |
131 | .num_resources = ARRAY_SIZE(heartbeat_resources), | 139 | .num_resources = ARRAY_SIZE(heartbeat_resources), |
diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c index a074b62505ef..5f041f86e3dd 100644 --- a/arch/sh/boards/se/7206/setup.c +++ b/arch/sh/boards/se/7206/setup.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/se7206.h> | 14 | #include <asm/se7206.h> |
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <asm/machvec.h> | 16 | #include <asm/machvec.h> |
17 | #include <asm/heartbeat.h> | ||
17 | 18 | ||
18 | static struct resource smc91x_resources[] = { | 19 | static struct resource smc91x_resources[] = { |
19 | [0] = { | 20 | [0] = { |
@@ -37,6 +38,11 @@ static struct platform_device smc91x_device = { | |||
37 | 38 | ||
38 | static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; | 39 | static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; |
39 | 40 | ||
41 | static struct heartbeat_data heartbeat_data = { | ||
42 | .bit_pos = heartbeat_bit_pos, | ||
43 | .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), | ||
44 | }; | ||
45 | |||
40 | static struct resource heartbeat_resources[] = { | 46 | static struct resource heartbeat_resources[] = { |
41 | [0] = { | 47 | [0] = { |
42 | .start = PA_LED, | 48 | .start = PA_LED, |
@@ -49,7 +55,7 @@ static struct platform_device heartbeat_device = { | |||
49 | .name = "heartbeat", | 55 | .name = "heartbeat", |
50 | .id = -1, | 56 | .id = -1, |
51 | .dev = { | 57 | .dev = { |
52 | .platform_data = heartbeat_bit_pos, | 58 | .platform_data = heartbeat_data, |
53 | }, | 59 | }, |
54 | .num_resources = ARRAY_SIZE(heartbeat_resources), | 60 | .num_resources = ARRAY_SIZE(heartbeat_resources), |
55 | .resource = heartbeat_resources, | 61 | .resource = heartbeat_resources, |
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c index 2962da148f3f..5172f994a1be 100644 --- a/arch/sh/boards/se/770x/setup.c +++ b/arch/sh/boards/se/770x/setup.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/se.h> | 12 | #include <asm/se.h> |
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | #include <asm/smc37c93x.h> | 14 | #include <asm/smc37c93x.h> |
15 | #include <asm/heartbeat.h> | ||
15 | 16 | ||
16 | void init_se_IRQ(void); | 17 | void init_se_IRQ(void); |
17 | 18 | ||
@@ -90,6 +91,11 @@ static struct platform_device cf_ide_device = { | |||
90 | 91 | ||
91 | static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; | 92 | static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; |
92 | 93 | ||
94 | static struct heartbeat_data heartbeat_data = { | ||
95 | .bit_pos = heartbeat_bit_pos, | ||
96 | .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), | ||
97 | }; | ||
98 | |||
93 | static struct resource heartbeat_resources[] = { | 99 | static struct resource heartbeat_resources[] = { |
94 | [0] = { | 100 | [0] = { |
95 | .start = PA_LED, | 101 | .start = PA_LED, |
@@ -102,7 +108,7 @@ static struct platform_device heartbeat_device = { | |||
102 | .name = "heartbeat", | 108 | .name = "heartbeat", |
103 | .id = -1, | 109 | .id = -1, |
104 | .dev = { | 110 | .dev = { |
105 | .platform_data = heartbeat_bit_pos, | 111 | .platform_data = heartbeat_data, |
106 | }, | 112 | }, |
107 | .num_resources = ARRAY_SIZE(heartbeat_resources), | 113 | .num_resources = ARRAY_SIZE(heartbeat_resources), |
108 | .resource = heartbeat_resources, | 114 | .resource = heartbeat_resources, |
diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c index 495fc7e2b60f..8f1c8a617bb5 100644 --- a/arch/sh/boards/se/7722/setup.c +++ b/arch/sh/boards/se/7722/setup.c | |||
@@ -18,12 +18,10 @@ | |||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | 19 | ||
20 | /* Heartbeat */ | 20 | /* Heartbeat */ |
21 | static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; | ||
22 | |||
23 | static struct resource heartbeat_resources[] = { | 21 | static struct resource heartbeat_resources[] = { |
24 | [0] = { | 22 | [0] = { |
25 | .start = PA_LED, | 23 | .start = PA_LED, |
26 | .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, | 24 | .end = PA_LED + 8 - 1, |
27 | .flags = IORESOURCE_MEM, | 25 | .flags = IORESOURCE_MEM, |
28 | }, | 26 | }, |
29 | }; | 27 | }; |
@@ -31,9 +29,6 @@ static struct resource heartbeat_resources[] = { | |||
31 | static struct platform_device heartbeat_device = { | 29 | static struct platform_device heartbeat_device = { |
32 | .name = "heartbeat", | 30 | .name = "heartbeat", |
33 | .id = -1, | 31 | .id = -1, |
34 | .dev = { | ||
35 | .platform_data = heartbeat_bit_pos, | ||
36 | }, | ||
37 | .num_resources = ARRAY_SIZE(heartbeat_resources), | 32 | .num_resources = ARRAY_SIZE(heartbeat_resources), |
38 | .resource = heartbeat_resources, | 33 | .resource = heartbeat_resources, |
39 | }; | 34 | }; |
@@ -109,7 +104,7 @@ static void __init se7722_setup(char **cmdline_p) | |||
109 | ctrl_outl(0x00051001, MSTPCR0); | 104 | ctrl_outl(0x00051001, MSTPCR0); |
110 | ctrl_outl(0x00000000, MSTPCR1); | 105 | ctrl_outl(0x00000000, MSTPCR1); |
111 | /* KEYSC, VOU, BEU, CEU, VEU, VPU, LCDC */ | 106 | /* KEYSC, VOU, BEU, CEU, VEU, VPU, LCDC */ |
112 | ctrl_outl(0xffffbfC0, MSTPCR2); | 107 | ctrl_outl(0xffffbfC0, MSTPCR2); |
113 | 108 | ||
114 | ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */ | 109 | ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */ |
115 | ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */ | 110 | ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */ |
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c index 7873d07e40c1..5ed196827b0a 100644 --- a/arch/sh/boards/se/7751/setup.c +++ b/arch/sh/boards/se/7751/setup.c | |||
@@ -13,9 +13,15 @@ | |||
13 | #include <asm/machvec.h> | 13 | #include <asm/machvec.h> |
14 | #include <asm/se7751.h> | 14 | #include <asm/se7751.h> |
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <asm/heartbeat.h> | ||
16 | 17 | ||
17 | static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; | 18 | static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; |
18 | 19 | ||
20 | static struct heartbeat_data heartbeat_data = { | ||
21 | .bit_pos = heartbeat_bit_pos, | ||
22 | .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), | ||
23 | }; | ||
24 | |||
19 | static struct resource heartbeat_resources[] = { | 25 | static struct resource heartbeat_resources[] = { |
20 | [0] = { | 26 | [0] = { |
21 | .start = PA_LED, | 27 | .start = PA_LED, |
@@ -28,7 +34,7 @@ static struct platform_device heartbeat_device = { | |||
28 | .name = "heartbeat", | 34 | .name = "heartbeat", |
29 | .id = -1, | 35 | .id = -1, |
30 | .dev = { | 36 | .dev = { |
31 | .platform_data = heartbeat_bit_pos, | 37 | .platform_data = heartbeat_data, |
32 | }, | 38 | }, |
33 | .num_resources = ARRAY_SIZE(heartbeat_resources), | 39 | .num_resources = ARRAY_SIZE(heartbeat_resources), |
34 | .resource = heartbeat_resources, | 40 | .resource = heartbeat_resources, |
diff --git a/arch/sh/boards/se/7780/setup.c b/arch/sh/boards/se/7780/setup.c index 723f2fd4d55b..15c3ea4de920 100644 --- a/arch/sh/boards/se/7780/setup.c +++ b/arch/sh/boards/se/7780/setup.c | |||
@@ -16,12 +16,10 @@ | |||
16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
17 | 17 | ||
18 | /* Heartbeat */ | 18 | /* Heartbeat */ |
19 | static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; | ||
20 | |||
21 | static struct resource heartbeat_resources[] = { | 19 | static struct resource heartbeat_resources[] = { |
22 | [0] = { | 20 | [0] = { |
23 | .start = PA_LED, | 21 | .start = PA_LED, |
24 | .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, | 22 | .end = PA_LED + 8 - 1, |
25 | .flags = IORESOURCE_MEM, | 23 | .flags = IORESOURCE_MEM, |
26 | }, | 24 | }, |
27 | }; | 25 | }; |
@@ -29,9 +27,6 @@ static struct resource heartbeat_resources[] = { | |||
29 | static struct platform_device heartbeat_device = { | 27 | static struct platform_device heartbeat_device = { |
30 | .name = "heartbeat", | 28 | .name = "heartbeat", |
31 | .id = -1, | 29 | .id = -1, |
32 | .dev = { | ||
33 | .platform_data = heartbeat_bit_pos, | ||
34 | }, | ||
35 | .num_resources = ARRAY_SIZE(heartbeat_resources), | 30 | .num_resources = ARRAY_SIZE(heartbeat_resources), |
36 | .resource = heartbeat_resources, | 31 | .resource = heartbeat_resources, |
37 | }; | 32 | }; |
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index 10c1828c9ff5..b76a14f12ce2 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c | |||
@@ -24,24 +24,44 @@ | |||
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | #include <linux/timer.h> | 25 | #include <linux/timer.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <asm/heartbeat.h> | ||
27 | 28 | ||
28 | #define DRV_NAME "heartbeat" | 29 | #define DRV_NAME "heartbeat" |
29 | #define DRV_VERSION "0.1.0" | 30 | #define DRV_VERSION "0.1.1" |
30 | 31 | ||
31 | struct heartbeat_data { | 32 | static unsigned char default_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; |
32 | void __iomem *base; | 33 | |
33 | unsigned char bit_pos[8]; | 34 | static inline void heartbeat_toggle_bit(struct heartbeat_data *hd, |
34 | struct timer_list timer; | 35 | unsigned bit, unsigned int inverted) |
35 | }; | 36 | { |
37 | unsigned int new; | ||
38 | |||
39 | new = (1 << hd->bit_pos[bit]); | ||
40 | if (inverted) | ||
41 | new = ~new; | ||
42 | |||
43 | switch (hd->regsize) { | ||
44 | case 32: | ||
45 | iowrite32(new, hd->base); | ||
46 | break; | ||
47 | case 16: | ||
48 | iowrite16(new, hd->base); | ||
49 | break; | ||
50 | default: | ||
51 | iowrite8(new, hd->base); | ||
52 | break; | ||
53 | } | ||
54 | } | ||
36 | 55 | ||
37 | static void heartbeat_timer(unsigned long data) | 56 | static void heartbeat_timer(unsigned long data) |
38 | { | 57 | { |
39 | struct heartbeat_data *hd = (struct heartbeat_data *)data; | 58 | struct heartbeat_data *hd = (struct heartbeat_data *)data; |
40 | static unsigned bit = 0, up = 1; | 59 | static unsigned bit = 0, up = 1; |
41 | 60 | ||
42 | ctrl_outw(1 << hd->bit_pos[bit], (unsigned long)hd->base); | 61 | heartbeat_toggle_bit(hd, bit, hd->flags & HEARTBEAT_INVERTED); |
62 | |||
43 | bit += up; | 63 | bit += up; |
44 | if ((bit == 0) || (bit == ARRAY_SIZE(hd->bit_pos)-1)) | 64 | if ((bit == 0) || (bit == (hd->nr_bits)-1)) |
45 | up = -up; | 65 | up = -up; |
46 | 66 | ||
47 | mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) / | 67 | mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) / |
@@ -64,21 +84,31 @@ static int heartbeat_drv_probe(struct platform_device *pdev) | |||
64 | return -EINVAL; | 84 | return -EINVAL; |
65 | } | 85 | } |
66 | 86 | ||
67 | hd = kmalloc(sizeof(struct heartbeat_data), GFP_KERNEL); | ||
68 | if (unlikely(!hd)) | ||
69 | return -ENOMEM; | ||
70 | |||
71 | if (pdev->dev.platform_data) { | 87 | if (pdev->dev.platform_data) { |
72 | memcpy(hd->bit_pos, pdev->dev.platform_data, | 88 | hd = pdev->dev.platform_data; |
73 | ARRAY_SIZE(hd->bit_pos)); | ||
74 | } else { | 89 | } else { |
75 | int i; | 90 | hd = kzalloc(sizeof(struct heartbeat_data), GFP_KERNEL); |
91 | if (unlikely(!hd)) | ||
92 | return -ENOMEM; | ||
93 | } | ||
94 | |||
95 | hd->base = ioremap_nocache(res->start, res->end - res->start + 1); | ||
96 | if (!unlikely(hd->base)) { | ||
97 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
98 | |||
99 | if (!pdev->dev.platform_data) | ||
100 | kfree(hd); | ||
101 | |||
102 | return -ENXIO; | ||
103 | } | ||
76 | 104 | ||
77 | for (i = 0; i < ARRAY_SIZE(hd->bit_pos); i++) | 105 | if (!hd->nr_bits) { |
78 | hd->bit_pos[i] = i; | 106 | hd->bit_pos = default_bit_pos; |
107 | hd->nr_bits = ARRAY_SIZE(default_bit_pos); | ||
79 | } | 108 | } |
80 | 109 | ||
81 | hd->base = (void __iomem *)(unsigned long)res->start; | 110 | if (!hd->regsize) |
111 | hd->regsize = 8; /* default access size */ | ||
82 | 112 | ||
83 | setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd); | 113 | setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd); |
84 | platform_set_drvdata(pdev, hd); | 114 | platform_set_drvdata(pdev, hd); |
@@ -91,10 +121,12 @@ static int heartbeat_drv_remove(struct platform_device *pdev) | |||
91 | struct heartbeat_data *hd = platform_get_drvdata(pdev); | 121 | struct heartbeat_data *hd = platform_get_drvdata(pdev); |
92 | 122 | ||
93 | del_timer_sync(&hd->timer); | 123 | del_timer_sync(&hd->timer); |
124 | iounmap(hd->base); | ||
94 | 125 | ||
95 | platform_set_drvdata(pdev, NULL); | 126 | platform_set_drvdata(pdev, NULL); |
96 | 127 | ||
97 | kfree(hd); | 128 | if (!pdev->dev.platform_data) |
129 | kfree(hd); | ||
98 | 130 | ||
99 | return 0; | 131 | return 0; |
100 | } | 132 | } |