source: rtems/c/src/lib/libbsp/sparc/shared/1553/gr1553b.c @ b787bead

4.115
Last change on this file since b787bead was b787bead, checked in by Daniel Hellstrom <daniel@…>, on 02/10/15 at 08:23:48

GR1553B: fixed build warnings

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*  GR1553B driver, used by BC, RT and/or BM driver
2 *
3 *  COPYRIGHT (c) 2010.
4 *  Cobham Gaisler AB.
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 */
10
11#include <stdlib.h>
12#include <drvmgr/ambapp_bus.h>
13
14#include <gr1553b.h>
15
16/* Driver Manager interface for BC, RT, BM, BRM, BC-BM and RT-BM */
17
18#define GR1553B_WRITE_REG(adr, val) *(volatile uint32_t *)(adr) = (val)
19#define GR1553B_READ_REG(adr) (*(volatile uint32_t *)(adr))
20
21#define FEAT_BC 0x1
22#define FEAT_RT 0x2
23#define FEAT_BM 0x4
24
25#define ALLOC_BC 0x1
26#define ALLOC_RT 0x2
27#define ALLOC_BM 0x4
28
29struct gr1553_device {
30        struct drvmgr_dev *dev;
31        int features;
32        int alloc;
33};
34
35struct gr1553_device_feature {
36        struct gr1553_device_feature *next;
37        struct gr1553_device *dev;
38        int minor;
39};
40
41/* Device lists */
42static struct gr1553_device_feature *gr1553_bm_root = NULL;
43static struct gr1553_device_feature *gr1553_rt_root = NULL;
44static struct gr1553_device_feature *gr1553_bc_root = NULL;
45
46/* Driver registered */
47static int gr1553_driver_registerd = 0;
48
49/* Add 'feat' to linked list pointed to by 'root'. A minor is also assigned. */
50static void gr1553_list_add
51        (
52        struct gr1553_device_feature **root,
53        struct gr1553_device_feature *feat
54        )
55{
56        int minor;
57        struct gr1553_device_feature *curr;
58
59        if ( *root == NULL ) {
60                *root = feat;
61                feat->next = NULL;
62                feat->minor = 0;
63                return;
64        }
65
66        minor = 0;
67retry_new_minor:
68        curr = *root;
69        while ( curr->next ) {
70                if ( curr->minor == minor ) {
71                        minor++;
72                        goto retry_new_minor;
73                }
74                curr = curr->next;
75        }
76
77        feat->next = NULL;
78        feat->minor = minor;
79        curr->next = feat;
80}
81
82static struct gr1553_device_feature *gr1553_list_find
83        (
84        struct gr1553_device_feature *root,
85        int minor
86        )
87{
88        struct gr1553_device_feature *curr = root;
89        while ( curr ) {
90                if ( curr->minor == minor ) {
91                        return curr;
92                }
93                curr = curr->next;
94        }
95        return NULL;
96}
97
98struct drvmgr_dev **gr1553_bc_open(int minor)
99{
100        struct gr1553_device_feature *feat;
101       
102        feat = gr1553_list_find(gr1553_bc_root, minor);
103        if ( feat == NULL )
104                return NULL;
105
106        /* Only possible to allocate is RT and BC is free,
107         * this is beacuse it is not possible to use the
108         * RT and the BC at the same time.
109         */
110        if ( feat->dev->alloc & (ALLOC_BC|ALLOC_RT) )
111                return NULL;
112
113        /* Alloc BC device */
114        feat->dev->alloc |= ALLOC_BC;
115
116        return &feat->dev->dev;
117}
118
119void gr1553_bc_close(struct drvmgr_dev **dev)
120{
121        struct gr1553_device *d = (struct gr1553_device *)dev;
122
123        d->alloc &= ~ALLOC_BC;
124}
125
126struct drvmgr_dev **gr1553_rt_open(int minor)
127{
128        struct gr1553_device_feature *feat;
129
130        feat = gr1553_list_find(gr1553_rt_root, minor);
131        if ( feat == NULL )
132                return NULL;
133
134        /* Only possible to allocate is RT and BC is free,
135         * this is beacuse it is not possible to use the
136         * RT and the BC at the same time.
137         */
138        if ( feat->dev->alloc & (ALLOC_BC|ALLOC_RT) )
139                return NULL;
140
141        /* Alloc RT device */
142        feat->dev->alloc |= ALLOC_RT;
143
144        return &feat->dev->dev;
145}
146
147void gr1553_rt_close(struct drvmgr_dev **dev)
148{
149        struct gr1553_device *d = (struct gr1553_device *)dev;
150
151        d->alloc &= ~ALLOC_RT;
152}
153
154struct drvmgr_dev **gr1553_bm_open(int minor)
155{
156        struct gr1553_device_feature *feat;
157       
158        feat = gr1553_list_find(gr1553_bm_root, minor);
159        if ( feat == NULL )
160                return NULL;
161
162        /* Only possible to allocate is RT and BC is free,
163         * this is beacuse it is not possible to use the
164         * RT and the BC at the same time.
165         */
166        if ( feat->dev->alloc & ALLOC_BM )
167                return NULL;
168
169        /* Alloc BM device */
170        feat->dev->alloc |= ALLOC_BM;
171
172        return &feat->dev->dev;
173}
174
175void gr1553_bm_close(struct drvmgr_dev **dev)
176{
177        struct gr1553_device *d = (struct gr1553_device *)dev;
178
179        d->alloc &= ~ALLOC_BM;
180}
181
182static int gr1553_init2(struct drvmgr_dev *dev)
183{
184        struct amba_dev_info *ambadev;
185        struct ambapp_core *pnpinfo;
186        struct gr1553b_regs *regs;
187
188        /* Get device information from AMBA PnP information */
189        ambadev = (struct amba_dev_info *)dev->businfo;
190        if ( ambadev == NULL ) {
191                return DRVMGR_FAIL;
192        }
193        pnpinfo = &ambadev->info;
194        regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
195
196        /* Stop IRQ */
197        GR1553B_WRITE_REG(&regs->imask, 0);
198        GR1553B_WRITE_REG(&regs->irq, 0xffffffff);
199        /* Stop BC if not already stopped (just in case) */
200        GR1553B_WRITE_REG(&regs->bc_ctrl, 0x15520204);
201        /* Stop RT rx (just in case) */
202        GR1553B_WRITE_REG(&regs->rt_cfg, 0x15530000);
203        /* Stop BM logging (just in case) */
204        GR1553B_WRITE_REG(&regs->bm_ctrl, 0);
205
206        return DRVMGR_OK;
207}
208
209/* Register the different functionalities that the
210 * core supports.
211 */
212static int gr1553_init3(struct drvmgr_dev *dev)
213{
214        struct amba_dev_info *ambadev;
215        struct ambapp_core *pnpinfo;
216        struct gr1553_device *priv;
217        struct gr1553_device_feature *feat;
218        struct gr1553b_regs *regs;
219
220        priv = malloc(sizeof(struct gr1553_device));
221        if ( priv == NULL )
222                return DRVMGR_NOMEM;
223        priv->dev = dev;
224        priv->alloc = 0;
225        priv->features = 0;
226        dev->priv = NULL; /* Let higher level driver handle this */
227
228        /* Get device information from AMBA PnP information */
229        ambadev = (struct amba_dev_info *)dev->businfo;
230        if ( ambadev == NULL ) {
231                return DRVMGR_FAIL;
232        }
233        pnpinfo = &ambadev->info;
234        regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
235
236        if ( GR1553B_READ_REG(&regs->bm_stat) & GR1553B_BM_STAT_BMSUP ) {
237                priv->features |= FEAT_BM;
238                feat = malloc(sizeof(struct gr1553_device_feature));
239                feat->dev = priv;
240                /* Init Minor and Next */
241                gr1553_list_add(&gr1553_bm_root, feat);
242        }
243
244        if ( GR1553B_READ_REG(&regs->bc_stat) & GR1553B_BC_STAT_BCSUP ) {
245                priv->features |= FEAT_BC;
246                feat = malloc(sizeof(struct gr1553_device_feature));
247                feat->dev = priv;
248                /* Init Minor and Next */
249                gr1553_list_add(&gr1553_bc_root, feat);
250        }
251
252        if ( GR1553B_READ_REG(&regs->rt_stat) & GR1553B_RT_STAT_RTSUP ) {
253                priv->features |= FEAT_RT;
254                feat = malloc(sizeof(struct gr1553_device_feature));
255                feat->dev = priv;
256                /* Init Minor and Next */
257                gr1553_list_add(&gr1553_rt_root, feat);
258        }
259
260        return DRVMGR_OK;
261}
262
263struct drvmgr_drv_ops gr1553_ops =
264{
265        {NULL, gr1553_init2, gr1553_init3, NULL},
266        NULL,
267        NULL
268};
269
270struct amba_dev_id gr1553_ids[] =
271{
272        {VENDOR_GAISLER, GAISLER_GR1553B},
273        {0, 0}  /* Mark end of table */
274};
275
276struct amba_drv_info gr1553_drv_info =
277{
278        {
279                DRVMGR_OBJ_DRV,                 /* Driver */
280                NULL,                           /* Next driver */
281                NULL,                           /* Device list */
282                DRIVER_AMBAPP_GAISLER_GR1553B_ID,/* Driver ID */
283                "GR1553_DRV",                   /* Driver Name */
284                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
285                &gr1553_ops,
286                NULL,                           /* Funcs */
287                0,                              /* No devices yet */
288                0,
289        },
290        &gr1553_ids[0]
291};
292
293/* Multiple drivers may call this function. The drivers that depends on
294 * this driver:
295 *  - BM driver
296 *  - BC driver
297 *  - RT driver
298 */
299void gr1553_register(void)
300{
301        if ( gr1553_driver_registerd == 0 ) {
302                gr1553_driver_registerd = 1;
303                drvmgr_drv_register(&gr1553_drv_info.general);
304        }
305}
Note: See TracBrowser for help on using the repository browser.