-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 313738 b: refs/heads/master c: 5df38b9 h: refs/heads/master v: v3
- Loading branch information
Paul Mundt
committed
May 24, 2012
1 parent
22baa46
commit fe09fac
Showing
5 changed files
with
95 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: b98b35815f40f01337e25e3f0d10d57b7cec5126 | ||
refs/heads/master: 5df38b9b7676e4e46c5c13e75f023ffb82542980 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,122 @@ | ||
/* | ||
* linux/arch/sh/boards/se/7722/irq.c | ||
* Hitachi UL SolutionEngine 7722 FPGA IRQ Support. | ||
* | ||
* Copyright (C) 2007 Nobuhiro Iwamatsu | ||
* | ||
* Hitachi UL SolutionEngine 7722 Support. | ||
* Copyright (C) 2012 Paul Mundt | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
*/ | ||
#define DRV_NAME "SE7722-FPGA" | ||
#define pr_fmt(fmt) DRV_NAME ": " fmt | ||
|
||
#define irq_reg_readl ioread16 | ||
#define irq_reg_writel iowrite16 | ||
|
||
#include <linux/init.h> | ||
#include <linux/irq.h> | ||
#include <linux/interrupt.h> | ||
#include <asm/irq.h> | ||
#include <asm/io.h> | ||
#include <linux/irqdomain.h> | ||
#include <linux/io.h> | ||
#include <linux/err.h> | ||
#include <asm/sizes.h> | ||
#include <mach-se/mach/se7722.h> | ||
|
||
unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, }; | ||
#define IRQ01_BASE_ADDR 0x11800000 | ||
#define IRQ01_MODE_REG 0 | ||
#define IRQ01_STS_REG 4 | ||
#define IRQ01_MASK_REG 8 | ||
|
||
static void disable_se7722_irq(struct irq_data *data) | ||
{ | ||
unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); | ||
__raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); | ||
} | ||
static void __iomem *se7722_irq_regs; | ||
struct irq_domain *se7722_irq_domain; | ||
|
||
static void enable_se7722_irq(struct irq_data *data) | ||
static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) | ||
{ | ||
unsigned int bit = (unsigned int)irq_data_get_irq_chip_data(data); | ||
__raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); | ||
} | ||
struct irq_data *data = irq_get_irq_data(irq); | ||
struct irq_chip *chip = irq_data_get_irq_chip(data); | ||
unsigned long mask; | ||
int bit; | ||
|
||
static struct irq_chip se7722_irq_chip __read_mostly = { | ||
.name = "SE7722-FPGA", | ||
.irq_mask = disable_se7722_irq, | ||
.irq_unmask = enable_se7722_irq, | ||
}; | ||
chip->irq_mask_ack(data); | ||
|
||
static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) | ||
mask = ioread16(se7722_irq_regs + IRQ01_STS_REG); | ||
|
||
for_each_set_bit(bit, &mask, SE7722_FPGA_IRQ_NR) | ||
generic_handle_irq(irq_linear_revmap(se7722_irq_domain, bit)); | ||
|
||
chip->irq_unmask(data); | ||
} | ||
|
||
static void __init se7722_domain_init(void) | ||
{ | ||
unsigned short intv = __raw_readw(IRQ01_STS); | ||
unsigned int ext_irq = 0; | ||
int i; | ||
|
||
intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; | ||
se7722_irq_domain = irq_domain_add_linear(NULL, SE7722_FPGA_IRQ_NR, | ||
&irq_domain_simple_ops, NULL); | ||
if (unlikely(!se7722_irq_domain)) { | ||
printk("Failed to get IRQ domain\n"); | ||
return; | ||
} | ||
|
||
for (; intv; intv >>= 1, ext_irq++) { | ||
if (!(intv & 1)) | ||
continue; | ||
for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { | ||
int irq = irq_create_mapping(se7722_irq_domain, i); | ||
|
||
generic_handle_irq(se7722_fpga_irq[ext_irq]); | ||
if (unlikely(irq == 0)) { | ||
printk("Failed to allocate IRQ %d\n", i); | ||
return; | ||
} | ||
} | ||
} | ||
|
||
/* | ||
* Initialize IRQ setting | ||
*/ | ||
void __init init_se7722_IRQ(void) | ||
static void __init se7722_gc_init(void) | ||
{ | ||
int i, irq; | ||
struct irq_chip_generic *gc; | ||
struct irq_chip_type *ct; | ||
unsigned int irq_base; | ||
|
||
__raw_writew(0, IRQ01_MASK); /* disable all irqs */ | ||
__raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ | ||
irq_base = irq_linear_revmap(se7722_irq_domain, 0); | ||
|
||
for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { | ||
irq = create_irq(); | ||
if (irq < 0) | ||
return; | ||
se7722_fpga_irq[i] = irq; | ||
gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7722_irq_regs, | ||
handle_level_irq); | ||
if (unlikely(!gc)) | ||
return; | ||
|
||
irq_set_chip_and_handler_name(se7722_fpga_irq[i], | ||
&se7722_irq_chip, | ||
handle_level_irq, | ||
"level"); | ||
ct = gc->chip_types; | ||
ct->chip.irq_mask = irq_gc_mask_set_bit; | ||
ct->chip.irq_unmask = irq_gc_mask_clr_bit; | ||
|
||
irq_set_chip_data(se7722_fpga_irq[i], (void *)i); | ||
} | ||
ct->regs.mask = IRQ01_MASK_REG; | ||
|
||
irq_setup_generic_chip(gc, IRQ_MSK(SE7722_FPGA_IRQ_NR), | ||
IRQ_GC_INIT_MASK_CACHE, | ||
IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
|
||
irq_set_chained_handler(IRQ0_IRQ, se7722_irq_demux); | ||
irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); | ||
|
||
irq_set_chained_handler(IRQ1_IRQ, se7722_irq_demux); | ||
irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); | ||
} | ||
|
||
/* | ||
* Initialize FPGA IRQs | ||
*/ | ||
void __init init_se7722_IRQ(void) | ||
{ | ||
se7722_irq_regs = ioremap(IRQ01_BASE_ADDR, SZ_16); | ||
if (unlikely(!se7722_irq_regs)) { | ||
printk("Failed to remap IRQ01 regs\n"); | ||
return; | ||
} | ||
|
||
/* | ||
* All FPGA IRQs disabled by default | ||
*/ | ||
iowrite16(0, se7722_irq_regs + IRQ01_MASK_REG); | ||
|
||
__raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ | ||
|
||
se7722_domain_init(); | ||
se7722_gc_init(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters