コード例 #1
0
static irqreturn_t ite_cir_isr(int irq, void *data)
{
	struct ite_dev *dev = data;
	unsigned long flags;
	irqreturn_t ret = IRQ_RETVAL(IRQ_NONE);
	u8 rx_buf[ITE_RX_FIFO_LEN];
	int rx_bytes;
	int iflags;

	ite_dbg_verbose("%s firing", __func__);

	
	spin_lock_irqsave(&dev->lock, flags);

	
	iflags = dev->params.get_irq_causes(dev);

	
	if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) {
		
		rx_bytes =
			dev->params.get_rx_bytes(dev, rx_buf,
					     ITE_RX_FIFO_LEN);

		if (rx_bytes > 0) {
			spin_unlock_irqrestore(&dev->
									 lock,
									 flags);

			
			ite_decode_bytes(dev, rx_buf,
								   rx_bytes);

			
			spin_lock_irqsave(&dev->lock,
								    flags);

			
			ret = IRQ_RETVAL(IRQ_HANDLED);
		}
	} else if (iflags & ITE_IRQ_TX_FIFO) {
		
		ite_dbg_verbose("got interrupt for TX FIFO");

		
		wake_up_interruptible(&dev->tx_queue);

		
		ret = IRQ_RETVAL(IRQ_HANDLED);
	}

	
	spin_unlock_irqrestore(&dev->lock, flags);

	ite_dbg_verbose("%s done returning %d", __func__, (int)ret);

	return ret;
}
コード例 #2
0
ファイル: ite-cir.c プロジェクト: AiWinters/linux
/* decode raw bytes as received by the hardware, and push them to the ir-core
 * layer */
static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int
			     length)
{
	u32 sample_period;
	unsigned long *ldata;
	unsigned int next_one, next_zero, size;
	DEFINE_IR_RAW_EVENT(ev);

	if (length == 0)
		return;

	sample_period = dev->params.sample_period;
	ldata = (unsigned long *)data;
	size = length << 3;
	next_one = find_next_bit_le(ldata, size, 0);
	if (next_one > 0) {
		ev.pulse = true;
		ev.duration =
		    ITE_BITS_TO_NS(next_one, sample_period);
		ir_raw_event_store_with_filter(dev->rdev, &ev);
	}

	while (next_one < size) {
		next_zero = find_next_zero_bit_le(ldata, size, next_one + 1);
		ev.pulse = false;
		ev.duration = ITE_BITS_TO_NS(next_zero - next_one, sample_period);
		ir_raw_event_store_with_filter(dev->rdev, &ev);

		if (next_zero < size) {
			next_one =
			    find_next_bit_le(ldata,
						     size,
						     next_zero + 1);
			ev.pulse = true;
			ev.duration =
			    ITE_BITS_TO_NS(next_one - next_zero,
					   sample_period);
			ir_raw_event_store_with_filter
			    (dev->rdev, &ev);
		} else
			next_one = size;
	}

	ir_raw_event_handle(dev->rdev);

	ite_dbg_verbose("decoded %d bytes.", length);
}
コード例 #3
0
ファイル: ite-cir.c プロジェクト: AiWinters/linux
/* interrupt service routine for incoming and outgoing CIR data */
static irqreturn_t ite_cir_isr(int irq, void *data)
{
	struct ite_dev *dev = data;
	unsigned long flags;
	irqreturn_t ret = IRQ_RETVAL(IRQ_NONE);
	u8 rx_buf[ITE_RX_FIFO_LEN];
	int rx_bytes;
	int iflags;

	ite_dbg_verbose("%s firing", __func__);

	/* grab the spinlock */
	spin_lock_irqsave(&dev->lock, flags);

	/* read the interrupt flags */
	iflags = dev->params.get_irq_causes(dev);

	/* check for the receive interrupt */
	if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) {
		/* read the FIFO bytes */
		rx_bytes =
			dev->params.get_rx_bytes(dev, rx_buf,
					     ITE_RX_FIFO_LEN);

		if (rx_bytes > 0) {
			/* drop the spinlock, since the ir-core layer
			 * may call us back again through
			 * ite_s_idle() */
			spin_unlock_irqrestore(&dev->
									 lock,
									 flags);

			/* decode the data we've just received */
			ite_decode_bytes(dev, rx_buf,
								   rx_bytes);

			/* reacquire the spinlock */
			spin_lock_irqsave(&dev->lock,
								    flags);

			/* mark the interrupt as serviced */
			ret = IRQ_RETVAL(IRQ_HANDLED);
		}
	} else if (iflags & ITE_IRQ_TX_FIFO) {
		/* FIFO space available interrupt */
		ite_dbg_verbose("got interrupt for TX FIFO");

		/* wake any sleeping transmitter */
		wake_up_interruptible(&dev->tx_queue);

		/* mark the interrupt as serviced */
		ret = IRQ_RETVAL(IRQ_HANDLED);
	}

	/* drop the spinlock */
	spin_unlock_irqrestore(&dev->lock, flags);

	ite_dbg_verbose("%s done returning %d", __func__, (int)ret);

	return ret;
}