12ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo/* 22ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * First-level interrupt controller model for Hexagon. 32ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * 4e1858b2a21cd84a855945a4747fb2db41b250c22Richard Kuo * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 52ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * 62ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * This program is free software; you can redistribute it and/or modify 72ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * it under the terms of the GNU General Public License version 2 and 82ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * only version 2 as published by the Free Software Foundation. 92ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * 102ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * This program is distributed in the hope that it will be useful, 112ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * but WITHOUT ANY WARRANTY; without even the implied warranty of 122ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 132ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * GNU General Public License for more details. 142ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * 152ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * You should have received a copy of the GNU General Public License 162ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * along with this program; if not, write to the Free Software 172ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 182ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * 02110-1301, USA. 192ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo */ 202ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo 212ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo#include <linux/interrupt.h> 222ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo#include <asm/irq.h> 232ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo#include <asm/hexagon_vm.h> 242ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo 252ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuostatic void mask_irq(struct irq_data *data) 262ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo{ 272ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo __vmintop_locdis((long) data->irq); 282ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo} 292ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo 302ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuostatic void mask_irq_num(unsigned int irq) 312ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo{ 322ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo __vmintop_locdis((long) irq); 332ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo} 342ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo 352ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuostatic void unmask_irq(struct irq_data *data) 362ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo{ 372ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo __vmintop_locen((long) data->irq); 382ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo} 392ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo 402ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo/* This is actually all we need for handle_fasteoi_irq */ 412ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuostatic void eoi_irq(struct irq_data *data) 422ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo{ 432ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo __vmintop_globen((long) data->irq); 442ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo} 452ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo 462ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo/* Power mamangement wake call. We don't need this, however, 472ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * if this is absent, then an -ENXIO error is returned to the 482ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * msm_serial driver, and it fails to correctly initialize. 492ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * This is a bug in the msm_serial driver, but, for now, we 502ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * work around it here, by providing this bogus handler. 512ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * XXX FIXME!!! remove this when msm_serial is fixed. 522ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo */ 532ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuostatic int set_wake(struct irq_data *data, unsigned int on) 542ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo{ 552ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo return 0; 562ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo} 572ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo 582ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuostatic struct irq_chip hexagon_irq_chip = { 592ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo .name = "HEXAGON", 602ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo .irq_mask = mask_irq, 612ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo .irq_unmask = unmask_irq, 622ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo .irq_set_wake = set_wake, 632ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo .irq_eoi = eoi_irq 642ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo}; 652ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo 662ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo/** 672ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * The hexagon core comes with a first-level interrupt controller 682ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * with 32 total possible interrupts. When the core is embedded 692ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * into different systems/platforms, it is typically wrapped by 702ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * macro cells that provide one or more second-level interrupt 712ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * controllers that are cascaded into one or more of the first-level 722ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * interrupts handled here. The precise wiring of these other 732ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * irqs varies from platform to platform, and are set up & configured 742ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * in the platform-specific files. 752ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * 762ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * The first-level interrupt controller is wrapped by the VM, which 772ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * virtualizes the interrupt controller for us. It provides a very 782ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * simple, fast & efficient API, and so the fasteoi handler is 792ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo * appropriate for this case. 802ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo */ 812ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuovoid __init init_IRQ(void) 822ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo{ 832ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo int irq; 842ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo 852ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo for (irq = 0; irq < HEXAGON_CPUINTS; irq++) { 862ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo mask_irq_num(irq); 872ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo irq_set_chip_and_handler(irq, &hexagon_irq_chip, 882ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo handle_fasteoi_irq); 892ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo } 902ac211bc423a0e62fe3ca3d78954de3174ae41f2Richard Kuo} 91