/*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #include #include #include #include #include #if 1 /* Temporary autcomment */ //#include // #include // #include #include #if DEBUGVLYNQ #define DEBUG_VLYNQ(args...) printk(KERN_INFO "[VLYNQ-IRQ]: " args) #else #define DEBUG_VLYNQ(args...) /* args */ #endif /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ unsigned int vlynq_get_irq( void ) { if(vlynq_config == NULL) return (unsigned int)-1; if(vlynq_config->vlynq->local.Interrupt_Priority.Bits.nointpend) return (unsigned int)-2; return vlynq_config->vlynq->local.Interrupt_Priority.Bits.intstat; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ unsigned int vlynq_irq_status( void ) { if(vlynq_config == NULL) return (unsigned int)-1; return vlynq_config->vlynq->local.Interrupt_Status; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ unsigned int vlynq_irq_enable_mask( void ) { if(vlynq_config == NULL) return (unsigned int)-1; return vlynq_config->vlynq->local.Interrupt_Status; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ unsigned int vlynq_irq_ack( unsigned int irq) { if(vlynq_config == NULL) return (unsigned int)-1; vlynq_config->vlynq->local.Interrupt_Status = 1 << irq; return 0; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ unsigned int vlynq_irq_to_vector( unsigned int irq) { if ((irq < DAVINCI_INT_START_VIRTUAL) && (irq > MAX_VLYNQ_INT_VECTORS) ) return (unsigned int)-1; return irq - DAVINCI_INT_START_VIRTUAL; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ unsigned int vlynq_vector_to_irq(unsigned int vector) { if ((vector > MAX_VLYNQ_INT_VECTORS)) return (unsigned int)-1; return DAVINCI_INT_START_VIRTUAL + vector; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ /*unsigned int vlynq_irq_vector_setup(unsigned int instance, unsigned int irq, enum _vlynq_vector_typ type, enum _vlynq_vector_polarity polarity) */ unsigned int vlynq_irq_vector_setup(unsigned int irq, unsigned int map_vector, enum _vlynq_interrupt_types dev_type, enum _vlynq_vector_typ type, enum _vlynq_vector_polarity polarity) { volatile union __vlynq_Interrupt_Vector *Int_Vector; volatile struct _vlynq_registers_half* vlynq_dev_registers; unsigned int value; unsigned int vector; DEBUG_VLYNQ("%s(%d, %d, %d, %d)\n",__FUNCTION__, irq, map_vector, dev_type, type, polarity); if( (vlynq_config == NULL) || map_vector >= VLYNQ_NUM_INT_BITS) return (unsigned int)-1; if(dev_type == VLYNQ_INT_LOCAL) vector=vlynq_irq_to_vector(irq); //Der IRQ-Vector(Vlynq) muss einem Interrupt im System(Linux) zugeordnet werden. else vector=irq; // Fuer Remote handelt es sich bereits um den korrekten IRQ. if(vector >= MAX_VLYNQ_INT_VECTORS) /* Es werden momentan maximal 8 [0..7] Vectoren in Vlynq unterstuetzt. */ return (unsigned int)-2; /* Soll Remote oder Local konfiguriert werden?*/ if ( dev_type == VLYNQ_INT_LOCAL ) vlynq_dev_registers = &(vlynq_config->vlynq->local); else vlynq_dev_registers = &(vlynq_config->vlynq->remote); if (vector > 3) Int_Vector = &(vlynq_dev_registers->Interrupt_Vector_2); else Int_Vector = &(vlynq_dev_registers->Interrupt_Vector_1); value = (map_vector & 31) | (type<Interrupt_Vector_1); DEBUG_VLYNQ("Vector_Setup: Int_Vec=%08x\n",vlynq_dev_registers->Interrupt_Vector_2); Int_Vector->Register &= (~(0xff << ((vector % 4) << 3))); /*--- löschen bitfeld---*/ Int_Vector->Register |= ((value << ((vector % 4) << 3))); /*--- setzen bitfeld---*/ DEBUG_VLYNQ("Vector_Setup: Int_Vec=%08x\n",vlynq_dev_registers->Interrupt_Vector_1); DEBUG_VLYNQ("Vector_Setup: Int_Vec=%08x\n",vlynq_dev_registers->Interrupt_Vector_2); return 0; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ unsigned int vlynq_irq_enable(enum _vlynq_interrupt_types dev_type, unsigned int irq) { volatile union __vlynq_Interrupt_Vector *Int_Vector; volatile struct _vlynq_registers_half* vlynq_dev_registers; unsigned int vector; if((vlynq_config == NULL) || dev_type == VLYNQ_INT_OFF || dev_type == VLYNQ_INT_ROOT_ISR ) return (unsigned int)-1; if( dev_type == VLYNQ_INT_LOCAL ) vector = vlynq_irq_to_vector(irq); /*Handelt sich um den SystemIRQ. Muss auf den Vector abgebildet werden.*/ else vector = irq; /* Handelt sich um den ModulIRQ. Muss nicht umgewandelt werden. */ if(vector >= MAX_VLYNQ_INT_VECTORS) /* Es werden momentan maximal 8 [0..7] Vectoren in Vlynq unterstuetzt. */ return (unsigned int)-2; /* Soll Remote oder Local konfiguriert werden?*/ if ( dev_type == VLYNQ_INT_LOCAL ) vlynq_dev_registers = &vlynq_config->vlynq->local; else vlynq_dev_registers = &vlynq_config->vlynq->remote; if (vector > 3) Int_Vector = &(vlynq_dev_registers->Interrupt_Vector_2); else Int_Vector = &(vlynq_dev_registers->Interrupt_Vector_1); Int_Vector->Register = Int_Vector->Register | ((1<= MAX_VLYNQ_INT_VECTORS) /* Es werden momentan maximal 8 [0..7] Vectoren in Vlynq unterstuetzt. */ return (unsigned int)-2; /* Soll Remote oder Local konfiguriert werden?*/ if ( dev_type == VLYNQ_INT_LOCAL ) vlynq_dev_registers = &vlynq_config->vlynq->local; else vlynq_dev_registers = &vlynq_config->vlynq->remote; if (vector > 3) Int_Vector = &(vlynq_dev_registers->Interrupt_Vector_2); else Int_Vector = &(vlynq_dev_registers->Interrupt_Vector_1); Int_Vector->Register = Int_Vector->Register & ~((1<