11c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil/* 21c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * cx18 interrupt handling 31c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * 41c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 56afdeaf865b729287e02aafc61d8d013b89996efAndy Walls * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> 61c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * 71c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * This program is free software; you can redistribute it and/or modify 81c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * it under the terms of the GNU General Public License as published by 91c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * the Free Software Foundation; either version 2 of the License, or 101c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * (at your option) any later version. 111c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * 121c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * This program is distributed in the hope that it will be useful, 131c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * but WITHOUT ANY WARRANTY; without even the implied warranty of 141c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 151c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * GNU General Public License for more details. 161c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * 171c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * You should have received a copy of the GNU General Public License 181c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * along with this program; if not, write to the Free Software 191c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 201c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil * 02111-1307 USA 211c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil */ 221c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil 231c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil#include "cx18-driver.h" 24b1526421eac9a912b2cda7e147f1da2aa31be278Andy Walls#include "cx18-io.h" 251c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil#include "cx18-irq.h" 261c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil#include "cx18-mailbox.h" 271c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil#include "cx18-scb.h" 28465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Walls 29465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Wallsstatic void xpu_ack(struct cx18 *cx, u32 sw2) 30465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Walls{ 31465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Walls if (sw2 & IRQ_CPU_TO_EPU_ACK) 32465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Walls wake_up(&cx->mb_cpu_waitq); 33465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Walls if (sw2 & IRQ_APU_TO_EPU_ACK) 34465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Walls wake_up(&cx->mb_apu_waitq); 351c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil} 361c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil 37ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Wallsstatic void epu_cmd(struct cx18 *cx, u32 sw1) 38ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls{ 39ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls if (sw1 & IRQ_CPU_TO_EPU) 40ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls cx18_api_epu_cmd_irq(cx, CPU); 41ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls if (sw1 & IRQ_APU_TO_EPU) 42ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls cx18_api_epu_cmd_irq(cx, APU); 43ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls} 44ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls 451c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuilirqreturn_t cx18_irq_handler(int irq, void *dev_id) 461c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil{ 471c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil struct cx18 *cx = (struct cx18 *)dev_id; 48d6c7e5f8faad080e75bace5c4f2265e3513e3510Andy Walls u32 sw1, sw2, hw2; 491c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil 50d6c7e5f8faad080e75bace5c4f2265e3513e3510Andy Walls sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & cx->sw1_irq_mask; 51d6c7e5f8faad080e75bace5c4f2265e3513e3510Andy Walls sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & cx->sw2_irq_mask; 52d6c7e5f8faad080e75bace5c4f2265e3513e3510Andy Walls hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & cx->hw2_irq_mask; 531c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil 54f056d29eebd2c8800cf42528ba0470c77a928821Andy Walls if (sw1) 55f056d29eebd2c8800cf42528ba0470c77a928821Andy Walls cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1); 56f056d29eebd2c8800cf42528ba0470c77a928821Andy Walls if (sw2) 57f056d29eebd2c8800cf42528ba0470c77a928821Andy Walls cx18_write_reg_expect(cx, sw2, SW2_INT_STATUS, ~sw2, sw2); 58f056d29eebd2c8800cf42528ba0470c77a928821Andy Walls if (hw2) 59f056d29eebd2c8800cf42528ba0470c77a928821Andy Walls cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2); 601c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil 611c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil if (sw1 || sw2 || hw2) 62ac50441720332f22a9d85ac03151d6acb7bc55d6Andy Walls CX18_DEBUG_HI_IRQ("received interrupts " 63ac50441720332f22a9d85ac03151d6acb7bc55d6Andy Walls "SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); 641c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil 65ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls /* 66ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls * SW1 responses have to happen first. The sending XPU times out the 67ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls * incoming mailboxes on us rather rapidly. 68ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls */ 69ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls if (sw1) 70ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls epu_cmd(cx, sw1); 71ee2d64f5ccc71b5c5191e92ea91a12b65f9ca060Andy Walls 721c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil /* To do: interrupt-based I2C handling 73465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Walls if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) { 741c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil } 751c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil */ 761c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil 77465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Walls if (sw2) 78465f8a805d3796fac2b2fb0c630217f6f76e667cAndy Walls xpu_ack(cx, sw2); 791c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil 80f056d29eebd2c8800cf42528ba0470c77a928821Andy Walls return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE; 811c1e45d17b663d4749af456ab7c2fc1f36405ef8Hans Verkuil} 82