Staging: android: ram_console: Disable ECC when early init is enabled and validate...
[linux-2.6] / drivers / staging / meilhaus / me8200_do.c
1 /**
2  * @file me8200_do.c
3  *
4  * @brief ME-8200 digital output subdevice instance.
5  * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6  * @author Guenter Gebhardt
7  * @author Krzysztof Gantzke    (k.gantzke@meilhaus.de)
8  */
9
10 /*
11  * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
12  *
13  * This file is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27
28 #ifndef __KERNEL__
29 #  define __KERNEL__
30 #endif
31
32 /*
33  * Includes
34  */
35 #include <linux/module.h>
36
37 #include <linux/slab.h>
38 #include <linux/spinlock.h>
39 #include <linux/interrupt.h>
40 #include <asm/io.h>
41 #include <linux/types.h>
42 #include <linux/version.h>
43
44 #include "medefines.h"
45 #include "meinternal.h"
46 #include "meerror.h"
47
48 #include "meids.h"
49 #include "medebug.h"
50 #include "me8200_reg.h"
51 #include "me8200_do_reg.h"
52 #include "me8200_do.h"
53
54 /*
55  * Defines
56  */
57
58 /*
59  * Functions
60  */
61
62 static int me8200_do_io_irq_start(me_subdevice_t * subdevice,
63                                   struct file *filep,
64                                   int channel,
65                                   int irq_source,
66                                   int irq_edge, int irq_arg, int flags)
67 {
68         me8200_do_subdevice_t *instance;
69         int err = ME_ERRNO_SUCCESS;
70         uint8_t tmp;
71         unsigned long status;
72
73         if (flags & ~ME_IO_IRQ_START_DIO_BYTE) {
74                 PERROR("Invalid flag specified.\n");
75                 return ME_ERRNO_INVALID_FLAGS;
76         }
77
78         if (channel != 0) {
79                 PERROR("Invalid channel specified.\n");
80                 return ME_ERRNO_INVALID_CHANNEL;
81         }
82
83         if (irq_source != ME_IRQ_SOURCE_DIO_OVER_TEMP) {
84                 PERROR("Invalid interrupt source specified.\n");
85                 return ME_ERRNO_INVALID_IRQ_SOURCE;
86         }
87
88         PDEBUG("executed.\n");
89
90         instance = (me8200_do_subdevice_t *) subdevice;
91
92         ME_SUBDEVICE_ENTER;
93
94         spin_lock_irqsave(&instance->subdevice_lock, status);
95         spin_lock(instance->irq_mode_lock);
96         tmp = inb(instance->irq_ctrl_reg);
97         tmp |=
98             ME8200_IRQ_MODE_BIT_ENABLE_POWER << (ME8200_IRQ_MODE_POWER_SHIFT *
99                                                  instance->do_idx);
100         outb(tmp, instance->irq_ctrl_reg);
101         PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
102                    instance->irq_ctrl_reg - instance->reg_base, tmp);
103         spin_unlock(instance->irq_mode_lock);
104         instance->rised = 0;
105         spin_unlock_irqrestore(&instance->subdevice_lock, status);
106
107         ME_SUBDEVICE_EXIT;
108
109         return err;
110 }
111
112 static int me8200_do_io_irq_wait(me_subdevice_t * subdevice,
113                                  struct file *filep,
114                                  int channel,
115                                  int *irq_count,
116                                  int *value, int time_out, int flags)
117 {
118         me8200_do_subdevice_t *instance;
119         int err = ME_ERRNO_SUCCESS;
120         long t = 0;
121         unsigned long cpu_flags;
122
123         PDEBUG("executed.\n");
124
125         instance = (me8200_do_subdevice_t *) subdevice;
126
127         if (flags) {
128                 PERROR("Invalid flag specified.\n");
129                 return ME_ERRNO_INVALID_FLAGS;
130         }
131
132         if (time_out < 0) {
133                 PERROR("Invalid time_out specified.\n");
134                 return ME_ERRNO_INVALID_TIMEOUT;
135         }
136
137         if (time_out) {
138                 t = (time_out * HZ) / 1000;
139
140                 if (t == 0)
141                         t = 1;
142         }
143
144         ME_SUBDEVICE_ENTER;
145
146         if (instance->rised <= 0) {
147                 instance->rised = 0;
148
149                 if (time_out) {
150                         t = wait_event_interruptible_timeout(instance->
151                                                              wait_queue,
152                                                              (instance->rised !=
153                                                               0), t);
154
155                         if (t == 0) {
156                                 PERROR
157                                     ("Wait on external interrupt timed out.\n");
158                                 err = ME_ERRNO_TIMEOUT;
159                         }
160                 } else {
161                         wait_event_interruptible(instance->wait_queue,
162                                                  (instance->rised != 0));
163                 }
164
165                 if (instance->rised < 0) {
166                         PERROR("Wait on interrupt aborted by user.\n");
167                         err = ME_ERRNO_CANCELLED;
168                 }
169         }
170
171         if (signal_pending(current)) {
172                 PERROR("Wait on external interrupt aborted by signal.\n");
173                 err = ME_ERRNO_SIGNAL;
174         }
175
176         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
177         instance->rised = 0;
178         *irq_count = instance->count;
179         *value = 0;
180         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
181
182         ME_SUBDEVICE_EXIT;
183
184         return err;
185 }
186
187 static int me8200_do_io_irq_stop(me_subdevice_t * subdevice,
188                                  struct file *filep, int channel, int flags)
189 {
190         me8200_do_subdevice_t *instance;
191         uint8_t tmp;
192         unsigned long cpu_flags;
193
194         PDEBUG("executed.\n");
195
196         instance = (me8200_do_subdevice_t *) subdevice;
197
198         if (flags) {
199                 PERROR("Invalid flag specified.\n");
200                 return ME_ERRNO_INVALID_FLAGS;
201         }
202
203         ME_SUBDEVICE_ENTER;
204
205         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
206         spin_lock(instance->irq_mode_lock);
207         tmp = inb(instance->irq_ctrl_reg);
208         tmp &=
209             ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER <<
210               (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx));
211         outb(tmp, instance->irq_ctrl_reg);
212         PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
213                    instance->irq_ctrl_reg - instance->reg_base, tmp);
214         spin_unlock(instance->irq_mode_lock);
215         instance->rised = -1;
216         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
217         wake_up_interruptible_all(&instance->wait_queue);
218
219         ME_SUBDEVICE_EXIT;
220
221         return ME_ERRNO_SUCCESS;
222 }
223
224 static int me8200_do_io_reset_subdevice(struct me_subdevice *subdevice,
225                                         struct file *filep, int flags)
226 {
227         me8200_do_subdevice_t *instance;
228         unsigned long cpu_flags;
229         uint8_t tmp;
230
231         PDEBUG("executed.\n");
232
233         instance = (me8200_do_subdevice_t *) subdevice;
234
235         if (flags) {
236                 PERROR("Invalid flag specified.\n");
237                 return ME_ERRNO_INVALID_FLAGS;
238         }
239
240         ME_SUBDEVICE_ENTER;
241
242         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
243         outb(0x00, instance->port_reg);
244         PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
245                    instance->port_reg - instance->reg_base, 0x00);
246         spin_lock(instance->irq_mode_lock);
247         tmp = inb(instance->irq_ctrl_reg);
248         tmp &=
249             ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER <<
250               (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx));
251         outb(tmp, instance->irq_ctrl_reg);
252         PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
253                    instance->irq_ctrl_reg - instance->reg_base, tmp);
254         spin_unlock(instance->irq_mode_lock);
255         instance->rised = -1;
256         instance->count = 0;
257         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
258         wake_up_interruptible_all(&instance->wait_queue);
259
260         ME_SUBDEVICE_EXIT;
261
262         return ME_ERRNO_SUCCESS;
263 }
264
265 static int me8200_do_io_single_config(me_subdevice_t * subdevice,
266                                       struct file *filep,
267                                       int channel,
268                                       int single_config,
269                                       int ref,
270                                       int trig_chan,
271                                       int trig_type, int trig_edge, int flags)
272 {
273         me8200_do_subdevice_t *instance;
274         int err = ME_ERRNO_SUCCESS;
275         unsigned long status;
276
277         PDEBUG("executed.\n");
278
279         instance = (me8200_do_subdevice_t *) subdevice;
280
281         ME_SUBDEVICE_ENTER;
282
283         spin_lock_irqsave(&instance->subdevice_lock, status);
284         switch (flags) {
285         case ME_IO_SINGLE_CONFIG_NO_FLAGS:
286         case ME_IO_SINGLE_CONFIG_DIO_BYTE:
287                 if (channel == 0) {
288                         if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
289                         } else {
290                                 PERROR("Invalid byte direction specified.\n");
291                                 err = ME_ERRNO_INVALID_SINGLE_CONFIG;
292                         }
293                 } else {
294                         PERROR("Invalid byte specified.\n");
295                         err = ME_ERRNO_INVALID_CHANNEL;
296                 }
297                 break;
298
299         default:
300                 PERROR("Invalid flags specified.\n");
301                 err = ME_ERRNO_INVALID_FLAGS;
302         }
303         spin_unlock_irqrestore(&instance->subdevice_lock, status);
304
305         ME_SUBDEVICE_EXIT;
306
307         return err;
308 }
309
310 static int me8200_do_io_single_read(me_subdevice_t * subdevice,
311                                     struct file *filep,
312                                     int channel,
313                                     int *value, int time_out, int flags)
314 {
315         me8200_do_subdevice_t *instance;
316         int err = ME_ERRNO_SUCCESS;
317         unsigned long status;
318
319         PDEBUG("executed.\n");
320
321         instance = (me8200_do_subdevice_t *) subdevice;
322
323         ME_SUBDEVICE_ENTER;
324
325         spin_lock_irqsave(&instance->subdevice_lock, status);
326         switch (flags) {
327         case ME_IO_SINGLE_TYPE_DIO_BIT:
328                 if ((channel >= 0) && (channel < 8)) {
329                         *value = inb(instance->port_reg) & (0x1 << channel);
330                 } else {
331                         PERROR("Invalid bit number specified.\n");
332                         err = ME_ERRNO_INVALID_CHANNEL;
333                 }
334                 break;
335
336         case ME_IO_SINGLE_NO_FLAGS:
337         case ME_IO_SINGLE_TYPE_DIO_BYTE:
338                 if (channel == 0) {
339                         *value = inb(instance->port_reg);
340                 } else {
341                         PERROR("Invalid byte number specified.\n");
342                         err = ME_ERRNO_INVALID_CHANNEL;
343                 }
344                 break;
345
346         default:
347                 PERROR("Invalid flags specified.\n");
348                 err = ME_ERRNO_INVALID_FLAGS;
349         }
350         spin_unlock_irqrestore(&instance->subdevice_lock, status);
351
352         ME_SUBDEVICE_EXIT;
353
354         return err;
355 }
356
357 static int me8200_do_io_single_write(me_subdevice_t * subdevice,
358                                      struct file *filep,
359                                      int channel,
360                                      int value, int time_out, int flags)
361 {
362         me8200_do_subdevice_t *instance;
363         int err = ME_ERRNO_SUCCESS;
364         uint8_t state;
365         unsigned long status;
366
367         PDEBUG("executed.\n");
368
369         instance = (me8200_do_subdevice_t *) subdevice;
370
371         ME_SUBDEVICE_ENTER;
372
373         spin_lock_irqsave(&instance->subdevice_lock, status);
374         switch (flags) {
375         case ME_IO_SINGLE_TYPE_DIO_BIT:
376                 if ((channel >= 0) && (channel < 8)) {
377                         state = inb(instance->port_reg);
378                         state =
379                             value ? (state | (0x1 << channel)) : (state &
380                                                                   ~(0x1 <<
381                                                                     channel));
382                         outb(state, instance->port_reg);
383                         PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
384                                    instance->reg_base,
385                                    instance->port_reg - instance->reg_base,
386                                    state);
387                 } else {
388                         PERROR("Invalid bit number specified.\n");
389                         err = ME_ERRNO_INVALID_CHANNEL;
390                 }
391                 break;
392
393         case ME_IO_SINGLE_NO_FLAGS:
394         case ME_IO_SINGLE_TYPE_DIO_BYTE:
395                 if (channel == 0) {
396                         outb(value, instance->port_reg);
397                         PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
398                                    instance->reg_base,
399                                    instance->port_reg - instance->reg_base,
400                                    value);
401                 } else {
402                         PERROR("Invalid byte number specified.\n");
403                         err = ME_ERRNO_INVALID_CHANNEL;
404                 }
405                 break;
406
407         default:
408                 PERROR("Invalid flags specified.\n");
409                 err = ME_ERRNO_INVALID_FLAGS;
410         }
411         spin_unlock_irqrestore(&instance->subdevice_lock, status);
412
413         ME_SUBDEVICE_EXIT;
414
415         return err;
416 }
417
418 static int me8200_do_query_number_channels(me_subdevice_t * subdevice,
419                                            int *number)
420 {
421         PDEBUG("executed.\n");
422         *number = 8;
423         return ME_ERRNO_SUCCESS;
424 }
425
426 static int me8200_do_query_subdevice_type(me_subdevice_t * subdevice,
427                                           int *type, int *subtype)
428 {
429         PDEBUG("executed.\n");
430         *type = ME_TYPE_DO;
431         *subtype = ME_SUBTYPE_SINGLE;
432         return ME_ERRNO_SUCCESS;
433 }
434
435 static int me8200_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
436 {
437         PDEBUG("executed.\n");
438         *caps = ME_CAPS_DIO_OVER_TEMP_IRQ;
439         return ME_ERRNO_SUCCESS;
440 }
441
442 static void me8200_do_destructor(struct me_subdevice *subdevice)
443 {
444         me8200_do_subdevice_t *instance;
445
446         PDEBUG("executed.\n");
447
448         instance = (me8200_do_subdevice_t *) subdevice;
449
450         free_irq(instance->irq, (void *)instance);
451         me_subdevice_deinit(&instance->base);
452         kfree(instance);
453 }
454
455 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
456 static irqreturn_t me8200_do_isr(int irq, void *dev_id)
457 #else
458 static irqreturn_t me8200_do_isr(int irq, void *dev_id, struct pt_regs *regs)
459 #endif
460 {
461         me8200_do_subdevice_t *instance;
462         uint16_t ctrl;
463         uint8_t irq_status;
464
465         instance = (me8200_do_subdevice_t *) dev_id;
466
467         if (irq != instance->irq) {
468                 PERROR("Incorrect interrupt num: %d.\n", irq);
469                 return IRQ_NONE;
470         }
471
472         irq_status = inb(instance->irq_status_reg);
473         if (!
474             (irq_status &
475              (ME8200_DO_IRQ_STATUS_BIT_ACTIVE << instance->do_idx))) {
476                 PINFO
477                     ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
478                      jiffies, __func__, instance->do_idx, irq_status);
479                 return IRQ_NONE;
480         }
481
482         PDEBUG("executed.\n");
483
484         spin_lock(&instance->subdevice_lock);
485         instance->rised = 1;
486         instance->count++;
487
488         spin_lock(instance->irq_mode_lock);
489         ctrl = inw(instance->irq_ctrl_reg);
490         ctrl |= ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx;
491         outw(ctrl, instance->irq_ctrl_reg);
492         PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
493                    instance->irq_ctrl_reg - instance->reg_base, ctrl);
494         ctrl &= ~(ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx);
495         outw(ctrl, instance->irq_ctrl_reg);
496         PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
497                    instance->irq_ctrl_reg - instance->reg_base, ctrl);
498         spin_unlock(instance->irq_mode_lock);
499         spin_unlock(&instance->subdevice_lock);
500         wake_up_interruptible_all(&instance->wait_queue);
501
502         return IRQ_HANDLED;
503 }
504
505 me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
506                                              unsigned int do_idx,
507                                              int irq,
508                                              spinlock_t * irq_mode_lock)
509 {
510         me8200_do_subdevice_t *subdevice;
511         int err;
512
513         PDEBUG("executed.\n");
514
515         /* Allocate memory for subdevice instance */
516         subdevice = kmalloc(sizeof(me8200_do_subdevice_t), GFP_KERNEL);
517
518         if (!subdevice) {
519                 PERROR("Cannot get memory for subdevice instance.\n");
520                 return NULL;
521         }
522
523         memset(subdevice, 0, sizeof(me8200_do_subdevice_t));
524
525         /* Initialize subdevice base class */
526         err = me_subdevice_init(&subdevice->base);
527
528         if (err) {
529                 PERROR("Cannot initialize subdevice base class instance.\n");
530                 kfree(subdevice);
531                 return NULL;
532         }
533         // Initialize spin locks.
534         spin_lock_init(&subdevice->subdevice_lock);
535
536         subdevice->irq_mode_lock = irq_mode_lock;
537
538         /* Save the index of the digital output */
539         subdevice->do_idx = do_idx;
540         subdevice->irq = irq;
541
542         /* Initialize the registers */
543         if (do_idx == 0) {
544                 subdevice->port_reg = reg_base + ME8200_DO_PORT_0_REG;
545         } else if (do_idx == 1) {
546                 subdevice->port_reg = reg_base + ME8200_DO_PORT_1_REG;
547         } else {
548                 PERROR("Wrong subdevice idx=%d.\n", do_idx);
549                 kfree(subdevice);
550                 return NULL;
551         }
552         subdevice->irq_ctrl_reg = reg_base + ME8200_IRQ_MODE_REG;
553         subdevice->irq_status_reg = reg_base + ME8200_DO_IRQ_STATUS_REG;
554 #ifdef MEDEBUG_DEBUG_REG
555         subdevice->reg_base = reg_base;
556 #endif
557
558         /* Initialize the wait queue */
559         init_waitqueue_head(&subdevice->wait_queue);
560
561         /* Request the interrupt line */
562         err = request_irq(irq, me8200_do_isr,
563 #ifdef IRQF_DISABLED
564                           IRQF_DISABLED | IRQF_SHARED,
565 #else
566                           SA_INTERRUPT | SA_SHIRQ,
567 #endif
568                           ME8200_NAME, (void *)subdevice);
569
570         if (err) {
571                 PERROR("Cannot get interrupt line.\n");
572                 kfree(subdevice);
573                 return NULL;
574         }
575         PINFO("Registered irq=%d.\n", irq);
576
577         /* Overload base class methods. */
578         subdevice->base.me_subdevice_io_irq_start = me8200_do_io_irq_start;
579         subdevice->base.me_subdevice_io_irq_wait = me8200_do_io_irq_wait;
580         subdevice->base.me_subdevice_io_irq_stop = me8200_do_io_irq_stop;
581         subdevice->base.me_subdevice_io_reset_subdevice =
582             me8200_do_io_reset_subdevice;
583         subdevice->base.me_subdevice_io_single_config =
584             me8200_do_io_single_config;
585         subdevice->base.me_subdevice_io_single_read = me8200_do_io_single_read;
586         subdevice->base.me_subdevice_io_single_write =
587             me8200_do_io_single_write;
588         subdevice->base.me_subdevice_query_number_channels =
589             me8200_do_query_number_channels;
590         subdevice->base.me_subdevice_query_subdevice_type =
591             me8200_do_query_subdevice_type;
592         subdevice->base.me_subdevice_query_subdevice_caps =
593             me8200_do_query_subdevice_caps;
594         subdevice->base.me_subdevice_destructor = me8200_do_destructor;
595
596         subdevice->rised = 0;
597         subdevice->count = 0;
598
599         return subdevice;
600 }