···1/*2- * arch/sh/kernel/cpu/irq/ipr.c3 *4 * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi5 * Copyright (C) 2000 Kazumoto Kojima6- * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>7- *8- * Interrupt handling for IPR-based IRQ.9 *10 * Supported system:11 * On-chip supporting modules (TMU, RTC, etc.).···12 * Hitachi SolutionEngine external I/O:13 * MS7709SE01, MS7709ASE01, and MS7750SE0114 *00015 */16-17#include <linux/init.h>18#include <linux/irq.h>19#include <linux/module.h>20-21#include <asm/system.h>22#include <asm/io.h>23#include <asm/machvec.h>···28 int shift; /* Shifts of the 16-bit data */29 int priority; /* The priority */30};31-static struct ipr_data ipr_data[NR_IRQS];32-33-static void enable_ipr_irq(unsigned int irq);34-static void disable_ipr_irq(unsigned int irq);35-36-/* shutdown is same as "disable" */37-#define shutdown_ipr_irq disable_ipr_irq38-39-static void mask_and_ack_ipr(unsigned int);40-static void end_ipr_irq(unsigned int irq);41-42-static unsigned int startup_ipr_irq(unsigned int irq)43-{44- enable_ipr_irq(irq);45- return 0; /* never anything pending */46-}47-48-static struct hw_interrupt_type ipr_irq_type = {49- .typename = "IPR-IRQ",50- .startup = startup_ipr_irq,51- .shutdown = shutdown_ipr_irq,52- .enable = enable_ipr_irq,53- .disable = disable_ipr_irq,54- .ack = mask_and_ack_ipr,55- .end = end_ipr_irq56-};5758static void disable_ipr_irq(unsigned int irq)59{60- unsigned long val;61- unsigned int addr = ipr_data[irq].addr;62- unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);63-64 /* Set the priority in IPR to 0 */65- val = ctrl_inw(addr);66- val &= mask;67- ctrl_outw(val, addr);68}6970static void enable_ipr_irq(unsigned int irq)71{72- unsigned long val;73- unsigned int addr = ipr_data[irq].addr;74- int priority = ipr_data[irq].priority;75- unsigned short value = (priority << ipr_data[irq].shift);76-77 /* Set priority in IPR back to original value */78- val = ctrl_inw(addr);79- val |= value;80- ctrl_outw(val, addr);81}8283-static void mask_and_ack_ipr(unsigned int irq)84-{85- disable_ipr_irq(irq);86-87-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \88- defined(CONFIG_CPU_SUBTYPE_SH7706) || \89- defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)90- /* This is needed when we use edge triggered setting */91- /* XXX: Is it really needed? */92- if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {93- /* Clear external interrupt request */94- int a = ctrl_inb(INTC_IRR0);95- a &= ~(1 << (irq - IRQ0_IRQ));96- ctrl_outb(a, INTC_IRR0);97- }98-#endif99-}100-101-static void end_ipr_irq(unsigned int irq)102-{103- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))104- enable_ipr_irq(irq);105-}106107void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)108{109- disable_irq_nosync(irq);110- ipr_data[irq].addr = addr;111- ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */112- ipr_data[irq].priority = priority;113114- irq_desc[irq].chip = &ipr_irq_type;115- disable_ipr_irq(irq);00000000116}1170118void __init init_IRQ(void)119{120#ifndef CONFIG_CPU_SUBTYPE_SH7780
···1/*2+ * Interrupt handling for IPR-based IRQ.3 *4 * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi5 * Copyright (C) 2000 Kazumoto Kojima6+ * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>7+ * Copyright (C) 2006 Paul Mundt08 *9 * Supported system:10 * On-chip supporting modules (TMU, RTC, etc.).···13 * Hitachi SolutionEngine external I/O:14 * MS7709SE01, MS7709ASE01, and MS7750SE0115 *16+ * This file is subject to the terms and conditions of the GNU General Public17+ * License. See the file "COPYING" in the main directory of this archive18+ * for more details.19 */020#include <linux/init.h>21#include <linux/irq.h>22#include <linux/module.h>023#include <asm/system.h>24#include <asm/io.h>25#include <asm/machvec.h>···28 int shift; /* Shifts of the 16-bit data */29 int priority; /* The priority */30};000000000000000000000000003132static void disable_ipr_irq(unsigned int irq)33{34+ struct ipr_data *p = get_irq_chip_data(irq);00035 /* Set the priority in IPR to 0 */36+ ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);0037}3839static void enable_ipr_irq(unsigned int irq)40{41+ struct ipr_data *p = get_irq_chip_data(irq);000042 /* Set priority in IPR back to original value */43+ ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);0044}4546+static struct irq_chip ipr_irq_chip = {47+ .name = "ipr",48+ .mask = disable_ipr_irq,49+ .unmask = enable_ipr_irq,50+ .mask_ack = disable_ipr_irq,51+};000000000000000005253void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)54{55+ struct ipr_data ipr_data;0005657+ disable_irq_nosync(irq);58+59+ ipr_data.addr = addr;60+ ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */61+ ipr_data.priority = priority;62+63+ set_irq_chip_and_handler(irq, &ipr_irq_chip, handle_level_irq);64+ set_irq_chip_data(irq, &ipr_data);65+66+ enable_ipr_irq(irq);67}6869+/* XXX: This needs to die a horrible death.. */70void __init init_IRQ(void)71{72#ifndef CONFIG_CPU_SUBTYPE_SH7780