]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - drivers/staging/westbridge/astoria/api/src/cyasintr.c
Initial 2.6.37
[mcf548x/linux.git] / drivers / staging / westbridge / astoria / api / src / cyasintr.c
1 /* Cypress West Bridge API source file (cyasintr.c)
2 ## ===========================
3 ## Copyright (C) 2010  Cypress Semiconductor
4 ##
5 ## This program is free software; you can redistribute it and/or
6 ## modify it under the terms of the GNU General Public License
7 ## as published by the Free Software Foundation; either version 2
8 ## of the License, or (at your option) any later version.
9 ##
10 ## This program is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 ## GNU General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with this program; if not, write to the Free Software
17 ## Foundation, Inc., 51 Franklin Street, Fifth Floor
18 ## Boston, MA  02110-1301, USA.
19 ## ===========================
20 */
21
22 #include "../../include/linux/westbridge/cyashal.h"
23 #include "../../include/linux/westbridge/cyasdevice.h"
24 #include "../../include/linux/westbridge/cyasregs.h"
25 #include "../../include/linux/westbridge/cyaserr.h"
26
27 extern void cy_as_mail_box_interrupt_handler(cy_as_device *);
28
29 void
30 cy_as_mcu_interrupt_handler(cy_as_device *dev_p)
31 {
32         /* Read and clear the interrupt. */
33         uint16_t v;
34
35         v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_MCU_STAT);
36         v = v;
37 }
38
39 void
40 cy_as_power_management_interrupt_handler(cy_as_device *dev_p)
41 {
42         uint16_t v;
43
44         v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PWR_MAGT_STAT);
45         v = v;
46 }
47
48 void
49 cy_as_pll_lock_loss_interrupt_handler(cy_as_device *dev_p)
50 {
51         uint16_t v;
52
53         v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PLL_LOCK_LOSS_STAT);
54         v = v;
55 }
56
57 uint32_t cy_as_intr_start(cy_as_device *dev_p, cy_bool dmaintr)
58 {
59         uint16_t v;
60
61         cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);
62
63         if (cy_as_device_is_intr_running(dev_p) != 0)
64                 return CY_AS_ERROR_ALREADY_RUNNING;
65
66         v = CY_AS_MEM_P0_INT_MASK_REG_MMCUINT |
67                 CY_AS_MEM_P0_INT_MASK_REG_MMBINT |
68                 CY_AS_MEM_P0_INT_MASK_REG_MPMINT;
69
70         if (dmaintr)
71                 v |= CY_AS_MEM_P0_INT_MASK_REG_MDRQINT;
72
73         /* Enable the interrupts of interest */
74         cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, v);
75
76         /* Mark the interrupt module as initialized */
77         cy_as_device_set_intr_running(dev_p);
78
79         return CY_AS_ERROR_SUCCESS;
80 }
81
82 uint32_t cy_as_intr_stop(cy_as_device *dev_p)
83 {
84         cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);
85
86         if (cy_as_device_is_intr_running(dev_p) == 0)
87                 return CY_AS_ERROR_NOT_RUNNING;
88
89         cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, 0);
90         cy_as_device_set_intr_stopped(dev_p);
91
92         return CY_AS_ERROR_SUCCESS;
93 }
94
95 void cy_as_intr_service_interrupt(cy_as_hal_device_tag tag)
96 {
97         uint16_t v;
98         cy_as_device *dev_p;
99
100         dev_p = cy_as_device_find_from_tag(tag);
101
102         /*
103          * only power management interrupts can occur before the
104          * antioch API setup is complete. if this is a PM interrupt
105          *  handle it here; otherwise output a warning message.
106          */
107         if (dev_p == 0) {
108                 v = cy_as_hal_read_register(tag, CY_AS_MEM_P0_INTR_REG);
109                 if (v == CY_AS_MEM_P0_INTR_REG_PMINT) {
110                         /* Read the PWR_MAGT_STAT register
111                          * to clear this interrupt. */
112                         v = cy_as_hal_read_register(tag,
113                                 CY_AS_MEM_PWR_MAGT_STAT);
114                 } else
115                         cy_as_hal_print_message("stray antioch "
116                                 "interrupt detected"
117                                 ", tag not associated "
118                                 "with any created device.");
119                 return;
120         }
121
122         /* Make sure we got a valid object from CyAsDeviceFindFromTag */
123         cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);
124
125         v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG);
126
127         if (v & CY_AS_MEM_P0_INTR_REG_MCUINT)
128                 cy_as_mcu_interrupt_handler(dev_p);
129
130         if (v & CY_AS_MEM_P0_INTR_REG_PMINT)
131                 cy_as_power_management_interrupt_handler(dev_p);
132
133         if (v & CY_AS_MEM_P0_INTR_REG_PLLLOCKINT)
134                 cy_as_pll_lock_loss_interrupt_handler(dev_p);
135
136         /* If the interrupt module is not running, no mailbox
137          * interrupts are expected from the west bridge. */
138         if (cy_as_device_is_intr_running(dev_p) == 0)
139                 return;
140
141         if (v & CY_AS_MEM_P0_INTR_REG_MBINT)
142                 cy_as_mail_box_interrupt_handler(dev_p);
143 }