Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[linux/fpc-iii.git] / drivers / isdn / hardware / eicon / s_pri.c
blobddd0e0ef8ed78e66d3d59e94c55f58fa3a848126
2 /*
4 Copyright (c) Eicon Networks, 2002.
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
9 Eicon File Revision : 2.1
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "platform.h"
27 #include "di_defs.h"
28 #include "pc.h"
29 #include "pr_pc.h"
30 #include "di.h"
31 #include "mi_pc.h"
32 #include "pc_maint.h"
33 #include "divasync.h"
34 #include "io.h"
35 #include "helpers.h"
36 #include "dsrv_pri.h"
37 #include "dsp_defs.h"
38 /*****************************************************************************/
39 #define MAX_XLOG_SIZE (64 * 1024)
40 /* -------------------------------------------------------------------------
41 Does return offset between ADAPTER->ram and real begin of memory
42 ------------------------------------------------------------------------- */
43 static dword pri_ram_offset(ADAPTER *a) {
44 return ((dword)MP_SHARED_RAM_OFFSET);
46 /* -------------------------------------------------------------------------
47 Recovery XLOG buffer from the card
48 ------------------------------------------------------------------------- */
49 static void pri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
50 byte __iomem *base;
51 word *Xlog;
52 dword regs[4], TrapID, size;
53 Xdesc xlogDesc;
55 * check for trapped MIPS 46xx CPU, dump exception frame
57 base = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
58 TrapID = READ_DWORD(&base[0x80]);
59 if ((TrapID == 0x99999999) || (TrapID == 0x99999901))
61 dump_trap_frame(IoAdapter, &base[0x90]);
62 IoAdapter->trapped = 1;
64 regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]);
65 regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]);
66 regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]);
67 regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]);
68 regs[0] &= IoAdapter->MemorySize - 1;
69 if ((regs[0] < IoAdapter->MemorySize - 1))
71 if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) {
72 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
73 return;
75 size = IoAdapter->MemorySize - regs[0];
76 if (size > MAX_XLOG_SIZE)
77 size = MAX_XLOG_SIZE;
78 memcpy_fromio(Xlog, &base[regs[0]], size);
79 xlogDesc.buf = Xlog;
80 xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]);
81 xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]);
82 dump_xlog_buffer(IoAdapter, &xlogDesc);
83 diva_os_free(0, Xlog);
84 IoAdapter->trapped = 2;
86 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
88 /* -------------------------------------------------------------------------
89 Hardware reset of PRI card
90 ------------------------------------------------------------------------- */
91 static void reset_pri_hardware(PISDN_ADAPTER IoAdapter) {
92 byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
93 WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
94 diva_os_wait(50);
95 WRITE_BYTE(p, 0x00);
96 diva_os_wait(50);
97 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
99 /* -------------------------------------------------------------------------
100 Stop Card Hardware
101 ------------------------------------------------------------------------- */
102 static void stop_pri_hardware(PISDN_ADAPTER IoAdapter) {
103 dword i;
104 byte __iomem *p;
105 dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
106 WRITE_DWORD(&cfgReg[3], 0);
107 WRITE_DWORD(&cfgReg[1], 0);
108 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
109 IoAdapter->a.ram_out(&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU);
110 i = 0;
111 while ((i < 100) && (IoAdapter->a.ram_in(&IoAdapter->a, &RAM->SWReg) != 0))
113 diva_os_wait(1);
114 i++;
116 DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
117 cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
118 WRITE_DWORD(&cfgReg[0], ((dword)(~0x03E00000)));
119 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
120 diva_os_wait(1);
121 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
122 WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
123 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
125 static int load_pri_hardware(PISDN_ADAPTER IoAdapter) {
126 return (0);
128 /* --------------------------------------------------------------------------
129 PRI Adapter interrupt Service Routine
130 -------------------------------------------------------------------------- */
131 static int pri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
132 byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
133 if (!(READ_DWORD(cfg) & 0x80000000)) {
134 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
135 return (0);
138 clear interrupt line
140 WRITE_DWORD(cfg, (dword)~0x03E00000);
141 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
142 IoAdapter->IrqCount++;
143 if (IoAdapter->Initialized)
145 diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
147 return (1);
149 /* -------------------------------------------------------------------------
150 Disable interrupt in the card hardware
151 ------------------------------------------------------------------------- */
152 static void disable_pri_interrupt(PISDN_ADAPTER IoAdapter) {
153 dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
154 WRITE_DWORD(&cfgReg[3], 0);
155 WRITE_DWORD(&cfgReg[1], 0);
156 WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000));
157 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
159 /* -------------------------------------------------------------------------
160 Install entry points for PRI Adapter
161 ------------------------------------------------------------------------- */
162 static void prepare_common_pri_functions(PISDN_ADAPTER IoAdapter) {
163 ADAPTER *a = &IoAdapter->a;
164 a->ram_in = mem_in;
165 a->ram_inw = mem_inw;
166 a->ram_in_buffer = mem_in_buffer;
167 a->ram_look_ahead = mem_look_ahead;
168 a->ram_out = mem_out;
169 a->ram_outw = mem_outw;
170 a->ram_out_buffer = mem_out_buffer;
171 a->ram_inc = mem_inc;
172 a->ram_offset = pri_ram_offset;
173 a->ram_out_dw = mem_out_dw;
174 a->ram_in_dw = mem_in_dw;
175 a->istream_wakeup = pr_stream;
176 IoAdapter->out = pr_out;
177 IoAdapter->dpc = pr_dpc;
178 IoAdapter->tst_irq = scom_test_int;
179 IoAdapter->clr_irq = scom_clear_int;
180 IoAdapter->pcm = (struct pc_maint *)(MIPS_MAINT_OFFS
181 - MP_SHARED_RAM_OFFSET);
182 IoAdapter->load = load_pri_hardware;
183 IoAdapter->disIrq = disable_pri_interrupt;
184 IoAdapter->rstFnc = reset_pri_hardware;
185 IoAdapter->stop = stop_pri_hardware;
186 IoAdapter->trapFnc = pri_cpu_trapped;
187 IoAdapter->diva_isr_handler = pri_ISR;
189 /* -------------------------------------------------------------------------
190 Install entry points for PRI Adapter
191 ------------------------------------------------------------------------- */
192 void prepare_pri_functions(PISDN_ADAPTER IoAdapter) {
193 IoAdapter->MemorySize = MP_MEMORY_SIZE;
194 prepare_common_pri_functions(IoAdapter);
195 diva_os_prepare_pri_functions(IoAdapter);
197 /* -------------------------------------------------------------------------
198 Install entry points for PRI Rev.2 Adapter
199 ------------------------------------------------------------------------- */
200 void prepare_pri2_functions(PISDN_ADAPTER IoAdapter) {
201 IoAdapter->MemorySize = MP2_MEMORY_SIZE;
202 prepare_common_pri_functions(IoAdapter);
203 diva_os_prepare_pri2_functions(IoAdapter);
205 /* ------------------------------------------------------------------------- */