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/] [mips/] [pmc-sierra/] [msp71xx/] [msp_hwbutton.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * Sets up interrupt handlers for various hardware switches which are
3
 * connected to interrupt lines.
4
 *
5
 * Copyright 2005-2207 PMC-Sierra, Inc.
6
 *
7
 *  This program is free software; you can redistribute  it and/or modify it
8
 *  under  the terms of  the GNU General  Public License as published by the
9
 *  Free Software Foundation;  either version 2 of the  License, or (at your
10
 *  option) any later version.
11
 *
12
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
13
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
14
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
15
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
16
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
18
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
20
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
 *
23
 *  You should have received a copy of the  GNU General Public License along
24
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
25
 *  675 Mass Ave, Cambridge, MA 02139, USA.
26
 */
27
 
28
#include <linux/kernel.h>
29
#include <linux/init.h>
30
#include <linux/interrupt.h>
31
 
32
#include <msp_int.h>
33
#include <msp_regs.h>
34
#include <msp_regops.h>
35
#ifdef CONFIG_PMCTWILED
36
#include <msp_led_macros.h>
37
#endif
38
 
39
/* For hwbutton_interrupt->initial_state */
40
#define HWBUTTON_HI     0x1
41
#define HWBUTTON_LO     0x2
42
 
43
/*
44
 * This struct describes a hardware button
45
 */
46
struct hwbutton_interrupt {
47
        char *name;                     /* Name of button */
48
        int irq;                        /* Actual LINUX IRQ */
49
        int eirq;                       /* Extended IRQ number (0-7) */
50
        int initial_state;              /* The "normal" state of the switch */
51
        void (*handle_hi)(void *);      /* Handler: switch input has gone HI */
52
        void (*handle_lo)(void *);      /* Handler: switch input has gone LO */
53
        void *data;                     /* Optional data to pass to handler */
54
};
55
 
56
#ifdef CONFIG_PMC_MSP7120_GW
57
extern void msp_restart(char *);
58
 
59
static void softreset_push(void *data)
60
{
61
        printk(KERN_WARNING "SOFTRESET switch was pushed\n");
62
 
63
        /*
64
         * In the future you could move this to the release handler,
65
         * timing the difference between the 'push' and 'release', and only
66
         * doing this ungraceful restart if the button has been down for
67
         * a certain amount of time; otherwise doing a graceful restart.
68
         */
69
 
70
        msp_restart(NULL);
71
}
72
 
73
static void softreset_release(void *data)
74
{
75
        printk(KERN_WARNING "SOFTRESET switch was released\n");
76
 
77
        /* Do nothing */
78
}
79
 
80
static void standby_on(void *data)
81
{
82
        printk(KERN_WARNING "STANDBY switch was set to ON (not implemented)\n");
83
 
84
        /* TODO: Put board in standby mode */
85
#ifdef CONFIG_PMCTWILED
86
        msp_led_turn_off(MSP_LED_PWRSTANDBY_GREEN);
87
        msp_led_turn_on(MSP_LED_PWRSTANDBY_RED);
88
#endif
89
}
90
 
91
static void standby_off(void *data)
92
{
93
        printk(KERN_WARNING
94
                "STANDBY switch was set to OFF (not implemented)\n");
95
 
96
        /* TODO: Take out of standby mode */
97
#ifdef CONFIG_PMCTWILED
98
        msp_led_turn_on(MSP_LED_PWRSTANDBY_GREEN);
99
        msp_led_turn_off(MSP_LED_PWRSTANDBY_RED);
100
#endif
101
}
102
 
103
static struct hwbutton_interrupt softreset_sw = {
104
        .name = "Softreset button",
105
        .irq = MSP_INT_EXT0,
106
        .eirq = 0,
107
        .initial_state = HWBUTTON_HI,
108
        .handle_hi = softreset_release,
109
        .handle_lo = softreset_push,
110
        .data = NULL,
111
};
112
 
113
static struct hwbutton_interrupt standby_sw = {
114
        .name = "Standby switch",
115
        .irq = MSP_INT_EXT1,
116
        .eirq = 1,
117
        .initial_state = HWBUTTON_HI,
118
        .handle_hi = standby_off,
119
        .handle_lo = standby_on,
120
        .data = NULL,
121
};
122
#endif /* CONFIG_PMC_MSP7120_GW */
123
 
124
static irqreturn_t hwbutton_handler(int irq, void *data)
125
{
126
        struct hwbutton_interrupt *hirq = data;
127
        unsigned long cic_ext = *CIC_EXT_CFG_REG;
128
 
129
        if (irq != hirq->irq)
130
                return IRQ_NONE;
131
 
132
        if (CIC_EXT_IS_ACTIVE_HI(cic_ext, hirq->eirq)) {
133
                /* Interrupt: pin is now HI */
134
                CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
135
                hirq->handle_hi(hirq->data);
136
        } else {
137
                /* Interrupt: pin is now LO */
138
                CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq);
139
                hirq->handle_lo(hirq->data);
140
        }
141
 
142
        /*
143
         * Invert the POLARITY of this level interrupt to ack the interrupt
144
         * Thus next state change will invoke the opposite message
145
         */
146
        *CIC_EXT_CFG_REG = cic_ext;
147
 
148
        return IRQ_HANDLED;
149
}
150
 
151
static int msp_hwbutton_register(struct hwbutton_interrupt *hirq)
152
{
153
        unsigned long cic_ext;
154
 
155
        if (hirq->handle_hi == NULL || hirq->handle_lo == NULL)
156
                return -EINVAL;
157
 
158
        cic_ext = *CIC_EXT_CFG_REG;
159
        CIC_EXT_SET_TRIGGER_LEVEL(cic_ext, hirq->eirq);
160
        if (hirq->initial_state == HWBUTTON_HI)
161
                CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
162
        else
163
                CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq);
164
        *CIC_EXT_CFG_REG = cic_ext;
165
 
166
        return request_irq(hirq->irq, hwbutton_handler, IRQF_DISABLED,
167
                                hirq->name, (void *)hirq);
168
}
169
 
170
static int __init msp_hwbutton_setup(void)
171
{
172
#ifdef CONFIG_PMC_MSP7120_GW
173
        msp_hwbutton_register(&softreset_sw);
174
        msp_hwbutton_register(&standby_sw);
175
#endif
176
        return 0;
177
}
178
 
179
subsys_initcall(msp_hwbutton_setup);

powered by: WebSVN 2.1.0

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