1/* 2 * s6000 irq crossbar 3 * 4 * Copyright (c) 2009 emlix GmbH 5 * Authors: Johannes Weiner <jw@emlix.com> 6 * Oskar Schirmer <os@emlix.com> 7 */ 8#include <linux/io.h> 9#include <asm/irq.h> 10#include <variant/hardware.h> 11 12/* S6_REG_INTC */ 13#define INTC_STATUS 0x000 14#define INTC_RAW 0x010 15#define INTC_STATUS_AG 0x100 16#define INTC_CFG(n) (0x200 + 4 * (n)) 17 18/* 19 * The s6000 has a crossbar that multiplexes interrupt output lines 20 * from the peripherals to input lines on the xtensa core. 21 * 22 * We leave the mapping decisions to the platform as it depends on the 23 * actually connected peripherals which distribution makes sense. 24 */ 25extern const signed char *platform_irq_mappings[NR_IRQS]; 26 27static unsigned long scp_to_intc_enable[] = { 28#define TO_INTC_ENABLE(n) (((n) << 1) + 1) 29 TO_INTC_ENABLE(0), 30 TO_INTC_ENABLE(1), 31 TO_INTC_ENABLE(2), 32 TO_INTC_ENABLE(3), 33 TO_INTC_ENABLE(4), 34 TO_INTC_ENABLE(5), 35 TO_INTC_ENABLE(6), 36 TO_INTC_ENABLE(7), 37 TO_INTC_ENABLE(8), 38 TO_INTC_ENABLE(9), 39 TO_INTC_ENABLE(10), 40 TO_INTC_ENABLE(11), 41 TO_INTC_ENABLE(12), 42 -1, 43 -1, 44 TO_INTC_ENABLE(13), 45 -1, 46 TO_INTC_ENABLE(14), 47 -1, 48 TO_INTC_ENABLE(15), 49#undef TO_INTC_ENABLE 50}; 51 52static void irq_set(unsigned int irq, int enable) 53{ 54 unsigned long en; 55 const signed char *m = platform_irq_mappings[irq]; 56 57 if (!m) 58 return; 59 en = enable ? scp_to_intc_enable[irq] : 0; 60 while (*m >= 0) { 61 writel(en, S6_REG_INTC + INTC_CFG(*m)); 62 m++; 63 } 64} 65 66void variant_irq_enable(unsigned int irq) 67{ 68 irq_set(irq, 1); 69} 70 71void variant_irq_disable(unsigned int irq) 72{ 73 irq_set(irq, 0); 74} 75