PageRenderTime 36ms CodeModel.GetById 24ms app.highlight 9ms RepoModel.GetById 0ms app.codeStats 0ms

/arch/sh/cchips/hd6446x/hd64461.c

https://bitbucket.org/cresqo/cm7-p500-kernel
C | 123 lines | 92 code | 24 blank | 7 comment | 10 complexity | 089f94fae64a7a2b642b09f59db6b8b1 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  1/*
  2 *	Copyright (C) 2000 YAEGASHI Takeshi
  3 *	Hitachi HD64461 companion chip support
  4 */
  5
  6#include <linux/sched.h>
  7#include <linux/module.h>
  8#include <linux/kernel.h>
  9#include <linux/param.h>
 10#include <linux/interrupt.h>
 11#include <linux/init.h>
 12#include <linux/irq.h>
 13#include <linux/io.h>
 14#include <asm/irq.h>
 15#include <asm/hd64461.h>
 16
 17/* This belongs in cpu specific */
 18#define INTC_ICR1 0xA4140010UL
 19
 20static void hd64461_mask_irq(unsigned int irq)
 21{
 22	unsigned short nimr;
 23	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 24
 25	nimr = __raw_readw(HD64461_NIMR);
 26	nimr |= mask;
 27	__raw_writew(nimr, HD64461_NIMR);
 28}
 29
 30static void hd64461_unmask_irq(unsigned int irq)
 31{
 32	unsigned short nimr;
 33	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 34
 35	nimr = __raw_readw(HD64461_NIMR);
 36	nimr &= ~mask;
 37	__raw_writew(nimr, HD64461_NIMR);
 38}
 39
 40static void hd64461_mask_and_ack_irq(unsigned int irq)
 41{
 42	hd64461_mask_irq(irq);
 43#ifdef CONFIG_HD64461_ENABLER
 44	if (irq == HD64461_IRQBASE + 13)
 45		__raw_writeb(0x00, HD64461_PCC1CSCR);
 46#endif
 47}
 48
 49static struct irq_chip hd64461_irq_chip = {
 50	.name		= "HD64461-IRQ",
 51	.mask		= hd64461_mask_irq,
 52	.mask_ack	= hd64461_mask_and_ack_irq,
 53	.unmask		= hd64461_unmask_irq,
 54};
 55
 56static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc)
 57{
 58	unsigned short intv = __raw_readw(HD64461_NIRR);
 59	unsigned int ext_irq = HD64461_IRQBASE;
 60
 61	intv &= (1 << HD64461_IRQ_NUM) - 1;
 62
 63	for (; intv; intv >>= 1, ext_irq++) {
 64		if (!(intv & 1))
 65			continue;
 66
 67		generic_handle_irq(ext_irq);
 68	}
 69}
 70
 71int __init setup_hd64461(void)
 72{
 73	int i, nid = cpu_to_node(boot_cpu_data);
 74
 75	if (!MACH_HD64461)
 76		return 0;
 77
 78	printk(KERN_INFO
 79	       "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n",
 80	       HD64461_IOBASE, CONFIG_HD64461_IRQ, HD64461_IRQBASE,
 81	       HD64461_IRQBASE + 15);
 82
 83/* Should be at processor specific part.. */
 84#if defined(CONFIG_CPU_SUBTYPE_SH7709)
 85	__raw_writew(0x2240, INTC_ICR1);
 86#endif
 87	__raw_writew(0xffff, HD64461_NIMR);
 88
 89	/*  IRQ 80 -> 95 belongs to HD64461  */
 90	for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) {
 91		unsigned int irq;
 92
 93		irq = create_irq_nr(i, nid);
 94		if (unlikely(irq == 0)) {
 95			pr_err("%s: failed hooking irq %d for HD64461\n",
 96			       __func__, i);
 97			return -EBUSY;
 98		}
 99
100		if (unlikely(irq != i)) {
101			pr_err("%s: got irq %d but wanted %d, bailing.\n",
102			       __func__, irq, i);
103			destroy_irq(irq);
104			return -EINVAL;
105		}
106
107		set_irq_chip_and_handler(i, &hd64461_irq_chip,
108					 handle_level_irq);
109	}
110
111	set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux);
112	set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW);
113
114#ifdef CONFIG_HD64461_ENABLER
115	printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
116	__raw_writeb(0x4c, HD64461_PCC1CSCIER);
117	__raw_writeb(0x00, HD64461_PCC1CSCR);
118#endif
119
120	return 0;
121}
122
123module_init(setup_hd64461);