OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [sh/] [drivers/] [heartbeat.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * Generic heartbeat driver for regular LED banks
3
 *
4
 * Copyright (C) 2007  Paul Mundt
5
 *
6
 * Most SH reference boards include a number of individual LEDs that can
7
 * be independently controlled (either via a pre-defined hardware
8
 * function or via the LED class, if desired -- the hardware tends to
9
 * encapsulate some of the same "triggers" that the LED class supports,
10
 * so there's not too much value in it).
11
 *
12
 * Additionally, most of these boards also have a LED bank that we've
13
 * traditionally used for strobing the load average. This use case is
14
 * handled by this driver, rather than giving each LED bit position its
15
 * own struct device.
16
 *
17
 * This file is subject to the terms and conditions of the GNU General Public
18
 * License.  See the file "COPYING" in the main directory of this archive
19
 * for more details.
20
 */
21
#include <linux/init.h>
22
#include <linux/module.h>
23
#include <linux/platform_device.h>
24
#include <linux/sched.h>
25
#include <linux/timer.h>
26
#include <linux/io.h>
27
#include <asm/heartbeat.h>
28
 
29
#define DRV_NAME "heartbeat"
30
#define DRV_VERSION "0.1.1"
31
 
32
static unsigned char default_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
33
 
34
static inline void heartbeat_toggle_bit(struct heartbeat_data *hd,
35
                                        unsigned bit, unsigned int inverted)
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
}
55
 
56
static void heartbeat_timer(unsigned long data)
57
{
58
        struct heartbeat_data *hd = (struct heartbeat_data *)data;
59
        static unsigned bit = 0, up = 1;
60
 
61
        heartbeat_toggle_bit(hd, bit, hd->flags & HEARTBEAT_INVERTED);
62
 
63
        bit += up;
64
        if ((bit == 0) || (bit == (hd->nr_bits)-1))
65
                up = -up;
66
 
67
        mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) /
68
                        ((avenrun[0] / 5) + (3 << FSHIFT)))));
69
}
70
 
71
static int heartbeat_drv_probe(struct platform_device *pdev)
72
{
73
        struct resource *res;
74
        struct heartbeat_data *hd;
75
 
76
        if (unlikely(pdev->num_resources != 1)) {
77
                dev_err(&pdev->dev, "invalid number of resources\n");
78
                return -EINVAL;
79
        }
80
 
81
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
82
        if (unlikely(res == NULL)) {
83
                dev_err(&pdev->dev, "invalid resource\n");
84
                return -EINVAL;
85
        }
86
 
87
        if (pdev->dev.platform_data) {
88
                hd = pdev->dev.platform_data;
89
        } else {
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
        }
104
 
105
        if (!hd->nr_bits) {
106
                hd->bit_pos = default_bit_pos;
107
                hd->nr_bits = ARRAY_SIZE(default_bit_pos);
108
        }
109
 
110
        if (!hd->regsize)
111
                hd->regsize = 8;        /* default access size */
112
 
113
        setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd);
114
        platform_set_drvdata(pdev, hd);
115
 
116
        return mod_timer(&hd->timer, jiffies + 1);
117
}
118
 
119
static int heartbeat_drv_remove(struct platform_device *pdev)
120
{
121
        struct heartbeat_data *hd = platform_get_drvdata(pdev);
122
 
123
        del_timer_sync(&hd->timer);
124
        iounmap(hd->base);
125
 
126
        platform_set_drvdata(pdev, NULL);
127
 
128
        if (!pdev->dev.platform_data)
129
                kfree(hd);
130
 
131
        return 0;
132
}
133
 
134
static struct platform_driver heartbeat_driver = {
135
        .probe          = heartbeat_drv_probe,
136
        .remove         = heartbeat_drv_remove,
137
        .driver         = {
138
                .name   = DRV_NAME,
139
        },
140
};
141
 
142
static int __init heartbeat_init(void)
143
{
144
        printk(KERN_NOTICE DRV_NAME ": version %s loaded\n", DRV_VERSION);
145
        return platform_driver_register(&heartbeat_driver);
146
}
147
 
148
static void __exit heartbeat_exit(void)
149
{
150
        platform_driver_unregister(&heartbeat_driver);
151
}
152
module_init(heartbeat_init);
153
module_exit(heartbeat_exit);
154
 
155
MODULE_VERSION(DRV_VERSION);
156
MODULE_AUTHOR("Paul Mundt");
157
MODULE_LICENSE("GPLv2");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.