File Index
Files and directories
Sign in
FILE

hd64461.c

File preview with syntax highlighting.

linux-6.19.14/arch/sh/cchips/hd6446x/hd64461.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *	Copyright (C) 2000 YAEGASHI Takeshi
  4 *	Hitachi HD64461 companion chip support
  5 */
  6
  7#include <linux/sched.h>
  8#include <linux/module.h>
  9#include <linux/kernel.h>
 10#include <linux/param.h>
 11#include <linux/interrupt.h>
 12#include <linux/init.h>
 13#include <linux/irq.h>
 14#include <linux/io.h>
 15#include <asm/irq.h>
 16#include <asm/hd64461.h>
 17
 18/* This belongs in cpu specific */
 19#define INTC_ICR1 0xA4140010UL
 20
 21static void hd64461_mask_irq(struct irq_data *data)
 22{
 23	unsigned int irq = data->irq;
 24	unsigned short nimr;
 25	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 26
 27	nimr = __raw_readw(HD64461_NIMR);
 28	nimr |= mask;
 29	__raw_writew(nimr, HD64461_NIMR);
 30}
 31
 32static void hd64461_unmask_irq(struct irq_data *data)
 33{
 34	unsigned int irq = data->irq;
 35	unsigned short nimr;
 36	unsigned short mask = 1 << (irq - HD64461_IRQBASE);
 37
 38	nimr = __raw_readw(HD64461_NIMR);
 39	nimr &= ~mask;
 40	__raw_writew(nimr, HD64461_NIMR);
 41}
 42
 43static void hd64461_mask_and_ack_irq(struct irq_data *data)
 44{
 45	hd64461_mask_irq(data);
 46
 47#ifdef CONFIG_HD64461_ENABLER
 48	if (data->irq == HD64461_IRQBASE + 13)
 49		__raw_writeb(0x00, HD64461_PCC1CSCR);
 50#endif
 51}
 52
 53static struct irq_chip hd64461_irq_chip = {
 54	.name		= "HD64461-IRQ",
 55	.irq_mask	= hd64461_mask_irq,
 56	.irq_mask_ack	= hd64461_mask_and_ack_irq,
 57	.irq_unmask	= hd64461_unmask_irq,
 58};
 59
 60static void hd64461_irq_demux(struct irq_desc *desc)
 61{
 62	unsigned short intv = __raw_readw(HD64461_NIRR);
 63	unsigned int ext_irq = HD64461_IRQBASE;
 64
 65	intv &= (1 << HD64461_IRQ_NUM) - 1;
 66
 67	for (; intv; intv >>= 1, ext_irq++) {
 68		if (!(intv & 1))
 69			continue;
 70
 71		generic_handle_irq(ext_irq);
 72	}
 73}
 74
 75static int __init setup_hd64461(void)
 76{
 77	int irq_base, i;
 78
 79	printk(KERN_INFO
 80	       "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n",
 81	       HD64461_IOBASE, CONFIG_HD64461_IRQ, HD64461_IRQBASE,
 82	       HD64461_IRQBASE + 15);
 83
 84/* Should be at processor specific part.. */
 85#if defined(CONFIG_CPU_SUBTYPE_SH7709)
 86	__raw_writew(0x2240, INTC_ICR1);
 87#endif
 88	__raw_writew(0xffff, HD64461_NIMR);
 89
 90	irq_base = irq_alloc_descs(HD64461_IRQBASE, HD64461_IRQBASE, 16, -1);
 91	if (IS_ERR_VALUE(irq_base)) {
 92		pr_err("%s: failed hooking irqs for HD64461\n", __func__);
 93		return irq_base;
 94	}
 95
 96	for (i = 0; i < 16; i++)
 97		irq_set_chip_and_handler(irq_base + i, &hd64461_irq_chip,
 98					 handle_level_irq);
 99
100	irq_set_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux);
101	irq_set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW);
102
103#ifdef CONFIG_HD64461_ENABLER
104	printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
105	__raw_writeb(0x4c, HD64461_PCC1CSCIER);
106	__raw_writeb(0x00, HD64461_PCC1CSCR);
107#endif
108
109	return 0;
110}
111
112module_init(setup_hd64461);
~/ Read-only file preview.