Ejemplo n.º 1
0
void zion_audio_proc_event(zion_params_t *zion_params, int bit,
		      int irq, void *dev_id, u16 pci_status)
{
  u16 int_status_12;
  u16 int_status_34;

  /* Read Interrupt Status */
  int_status_12 = mbus_readw(MBUS_ADDR(zion_params, DMA12_Interrupt_Status));
  int_status_34 = mbus_readw(MBUS_ADDR(zion_params, DMA34_Interrupt_Status));

  /* Memorize it ! */
  zion_params->interrupt_bits.AUDIO_INT[0] |= int_status_12;
  zion_params->interrupt_bits.AUDIO_INT[1] |= int_status_34;

  /* Do Nothing Now... */


  /* Clear them */

  if(int_status_12)
    {
      mbus_writew(int_status_12, MBUS_ADDR(zion_params, DMA12_Interrupt_Clear));
    }

  if(int_status_34)
    {
      mbus_writew(int_status_34, MBUS_ADDR(zion_params, DMA34_Interrupt_Clear));
    }

  zion_mbus_int_clear(zion_params, AudioProc_Int);

  return;
}
Ejemplo n.º 2
0
/***************************************************************************
 * zion_dmaif_event
 * @func
 *		Interruption handler for EDMA
 * @args
 *		zion_params_t	*params	[in/out]:	parameters of ZION driver
 *		int				irq		[in]	:	IRQ number
 *		void			*dev_id	[in]	:	Device ID
 *		u16				pci_status[in]	:	PCI config interrupt status
 * @return
 * 		void
 * @comment
 * 		
 * @author
 * 		H. Hoshino
 **************************************************************************/
void
zion_dmaif_event(zion_params_t * params, int bit,
		 int irq, void *dev_id, u16 pci_status)
{
	unsigned short int_status = 0;
	unsigned short int_mask = 0;
	int ch = 0;
	zion_edma_params_t *edma_prms = NULL;
	
	/*** Check EDMA interruption for each channel ***/
	for (ch = 0; ch < ZION_EDMA_NR_CH; ++ch)
    {
		/* Get interrupt status and mask(enable) */
		int_status =
			(unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_INTSTTS(ch)) );
		int_mask =
			(unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_INTENB(ch)) );
		
		/* Memorize it ! */
		params->interrupt_bits.DMA_INT[ch] |= int_status;

		/* for DEBUG */
/* 		PDEBUG( "CH%d int_status: 0x%04X, mask: 0x%04X\n", */
/* 				ch, int_status, int_mask ); */

		/** Check interruptions (Common port) **/
		if ( int_status & int_mask ) {
			/* Get EDMA params */
			edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_CMN_PORTNO(ch)]);

			/* for DEBUG */
/* 			PDEBUG( "[CH%d port%d] Get interruptions!\n", */
/* 					ch, ZION_EDMA_CMN_PORTNO(ch) ); */

			if ( NULL == edma_prms ) {
				PERROR( "[CH%d port%d] EDMA params is NULL!!\n",
						ch, ZION_EDMA_CMN_PORTNO(ch) );

				mbus_writew( (ZION_MBUS_EDMA_DMADONEINT |
							  ZION_MBUS_EDMA_SYNCFRMINT |
							  ZION_MBUS_EDMA_BUFFINT_MASK |
							  ZION_MBUS_EDMA_ERRINT_MASK),
							 MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch)));

				/** Clear interrupt status INT B reg **/
				zion_mbus_int_clear(params, Dmaif_Int);
				
				return;
			}
			
			/* Set interrupt status */
			spin_lock( &(edma_prms->params_lock) ); /* Spin lock */
			edma_prms->int_status |= int_status;
/* 			edma_prms->int_status = int_status; */
			spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */

			/* Wake up */
			spin_lock( &(edma_prms->params_lock) ); /* Spin lock */
			edma_prms->condition = ZION_DMAIF_DISPATCH_DONE;
			spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */
			
			wake_up(&(edma_prms->zion_dmaif_wait_queue));
		}
		
		
		/** Check sync frame pulse interruption **/
		if ( int_status & int_mask & ZION_MBUS_EDMA_SYNCFRMINT )
		{
			/* Get EDMA params */
			edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_FRM_PORTNO(ch)]);

			/* for DEBUG */
/* 			PDEBUG( "[CH%d port%d] Sync frame pulse!\n", */
/* 					ch, ZION_EDMA_FRM_PORTNO(ch) ); */

			/* Set interrupt status */
			spin_lock( &(edma_prms->params_lock) ); /* Spin lock */
			if ( 0 == edma_prms->int_status ) {
				edma_prms->int_status = int_status;
			} else {
/* 				PDEBUG( "[CH%d port%d] int_status is already set(0x%04X, 0x%04X)!\n", */
/* 						ch, ZION_EDMA_DMA_PORTNO(ch), edma_prms->int_status, int_status ); */
			}

			spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */
			
			/* Clear interrupt status: sync frame pulse */
			mbus_writew(ZION_MBUS_EDMA_SYNCFRMINT, MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch)));
			
			/* Wake up */
			spin_lock( &(edma_prms->params_lock) ); /* Spin lock */
			edma_prms->condition = ZION_DMAIF_DISPATCH_DONE;
			spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */
			
			wake_up(&(edma_prms->zion_dmaif_wait_queue));
		}
		
		/** Check DMA done interruption **/
		if ( int_status & int_mask & ZION_MBUS_EDMA_DMADONEINT )
		{
			/* Get EDMA params */
			edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_DMA_PORTNO(ch)]);
			
			/* for DEBUG */
			PDEBUG( "[CH%d port%d] DMA Done!\n",
					ch, ZION_EDMA_DMA_PORTNO(ch) );
/* 			PINFO( "[CH%d port%d] DMA Done!\n", */
/* 					ch, ZION_EDMA_DMA_PORTNO(ch) ); */
			
			/* Stop DMA for G1&G2 transfer mode */
			{
				unsigned char cmd = mbus_readb( MBUS_ADDR(params, (ZION_MBUS_EDMA_DMACMD(ch)+1)) );
				mbus_writeb( (cmd & (~0x02)),
							 MBUS_ADDR(params, (ZION_MBUS_EDMA_DMACMD(ch)+1)) );
			}

			/* for DEBUG XXX*/
/* 			{ */
/* 				unsigned short usPMT = mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_CURRPMT(ch)) ); */
/* 				PDEBUG( "[CH%d port%d] CurrPMT: 0x%04X\n", */
/* 						ch, ZION_EDMA_DMA_PORTNO(ch), usPMT ); */
/* 			} */
			
			
			spin_lock( &(edma_prms->params_lock) ); /* Spin lock */
			
			/* Set interrupt status */
/* 			PDEBUG( "[CH%d] int_status: 0x%04X, old: 0x%04X!\n", */
/* 					ch, int_status, edma_prms->int_status ); */
			if ( 0 == edma_prms->int_status ) {
				edma_prms->int_status = int_status;
			} else {
/* 				PDEBUG( "[CH%d port%d] int_status is already set(0x%04X, 0x%04X)!\n", */
/* 						ch, ZION_EDMA_DMA_PORTNO(ch), edma_prms->int_status, int_status ); */
			}

			
			/* Delete timer */
			del_timer_sync(&(edma_prms->timer));
			spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */
			
			/* Clear interrupt status: DMA done */
			mbus_writew(ZION_MBUS_EDMA_DMADONEINT,
						MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch)));
			
			/* Wake up */
			spin_lock( &(edma_prms->params_lock) ); /* Spin lock */
			edma_prms->condition = ZION_DMAIF_DISPATCH_DONE;
			spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */
			
			wake_up(&(edma_prms->zion_dmaif_wait_queue));
		}
		
		
		/** Check error and buffer empty/almost empty/almost full/full interruption **/
		if ( int_status & int_mask &
			 (ZION_MBUS_EDMA_BUFFINT_MASK | ZION_MBUS_EDMA_ERRINT_MASK) )
		{
			/* Get EDMA parameters */
			edma_prms = &(ZION_DMAIF_PARAM (params)->port_params[ZION_EDMA_BUF_PORTNO(ch)]);

			/* for DEBUG */
			PDEBUG( "[CH%d port%d] Error or warning!\n",
					ch, ZION_EDMA_BUF_PORTNO(ch) );

			/* Set interrupt status */
			spin_lock( &(edma_prms->params_lock) ); /* Spin lock */
			
/* 			PDEBUG( "[CH%d] int_status: 0x%04X, old: 0x%04X!\n", */
/* 					ch, int_status, edma_prms->int_status ); */
			if ( 0 == edma_prms->int_status ) {
				edma_prms->int_status = int_status;
			} else {
/* 				PDEBUG( "[CH%d port%d] int_status is already set(0x%04X, 0x%04X)!\n", */
/* 						ch, ZION_EDMA_BUF_PORTNO(ch), edma_prms->int_status, int_status ); */
			}
			
			spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */
			
			/* Clear interrupt status */
			mbus_writew((ZION_MBUS_EDMA_BUFFINT_MASK | ZION_MBUS_EDMA_ERRINT_MASK),
						MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch)));
			
			/* Wake up */
			spin_lock( &(edma_prms->params_lock) ); /* Spin lock */
			edma_prms->condition = ZION_DMAIF_DISPATCH_DONE;
			spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */
			
			wake_up(&(edma_prms->zion_dmaif_wait_queue));
		}
    }	/* The end of FOR(ch) */

	/** Clear interrupt status INT B reg **/
	zion_mbus_int_clear(params, Dmaif_Int);

/* 	PDEBUG ("exit %s\n", __FUNCTION__); */
	
  return;
}