From: David Hawkins <dwh@ovro.caltech.edu>
To: linuxppc-embedded@ozlabs.org
Subject: Yosemite/440EP is there a global interrupt enable mask?
Date: Tue, 24 Jan 2006 11:07:34 -0800 [thread overview]
Message-ID: <43D67AF6.6070403@ovro.caltech.edu> (raw)
In-Reply-To: <43D66D06.9090904@ovro.caltech.edu>
Hi all,
I'm writing a simple driver to test IRQ handling on the
AMCC Yosemite board. The board has an 8x2 header with several
GPIO pins, a number of which can be configured as IRQ inputs.
I have setup GPIO46 as output, and GPIO47 as input, and
selected IRQ8 on that pin.
The simple driver sets up the IRQ handler, and then drops
into a loop where it pulses the GPIO47 output. The relevent
messages from this loop are:
- Read some GPIO1 registers
- GPIO1_OR = 0x00020000
- GPIO1_TCR = 0xC2020000
- GPIO1_ISR1L = 0x00000401
- enable IRQ8
- UIC1_SR = 0x00002800
- UIC1_ER = 0xE0801008
IRQ8 is bit 19 in the enable register, i.e., 1 << (31-19) = 1000h
So, clearly its enabled here.
- sleep for 1s
- UIC1_SR = 0x00002800
- UIC1_ER = 0xE0801008
And after a sleep for 1s its still enabled.
----- loop test -----
- generate low on GPIO46
- sleep for 10 ticks
- generate high on GPIO46
- UIC1_SR = 0x00003800
- UIC1_ER = 0xE0800008
- IRQ8 status is set, clearing it
- UIC1_SR = 0x00002800
- UIC1_ER = 0xE0800008
- sleep for 10 ticks
... repeats ...
The low pulse on the GPIO46 pin definitely set the IRQ8 status
bit, but why on earth is the enable bit cleared!
(I added the check for the status bit being set, since my
IRQ handler was not getting called)
To enable the IRQ8 line, I simply accessed the UIC1_ER register
directly via
reg = mfdcr(DCRN_UIC_ER(UIC1));
reg |= 1 << (31-19);
mtdcr(DCRN_UIC_ER(UIC1), reg);
So, is there a kernel wide interrupt enable mask that I really
should be using? Or, an interrupt enable API? I initially
thought that when I registered an interrupt using
request_irq() that the kernel would go off an enable the
requested IRQ, but this test shows that it did not.
Any ideas?
Cheers
Dave
--------------- driver code --------------------------
/* yosemite_irq.c */
#include <linux/module.h> /* kernel modules */
#include <linux/interrupt.h>/* request_irq(), etc */
#include <asm/io.h> /* ioremap64(), iounmap(), readl() */
static char *name = "yosemite_irq";
static unsigned long long base = 0x0EF600C00; // 36-bit address
static unsigned int size = 0x44;
static char *kernel;
static int irq = 8;
static irqreturn_t
simple_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
int *p = (int *)kernel;
printk("<irq %d> received!\n", irq);
/* Deassert the interrupt input; GPIO1_OR[14] = 1 */
// writel(1<<(31-14), kernel);
p[0] = 1 << (31-14);
/* Clear IRQ8 status (UIC1_SR[19] = 1 to clear it) */
mtdcr(DCRN_UIC_SR(UIC1), 1 << (31-19));
return IRQ_HANDLED;
}
static int __init simple_init(void)
{
int status;
int reg;
int *p;
int i;
printk("<init> called.\n");
/* Get the GPIO control registers */
printk(" - remap the GPIO registers\n");
kernel = ioremap64(base, size);
printk(" - remapped to address 0x%.8X\n", (int)kernel);
p = (int *)kernel;
/* Get the IRQ8 */
printk(" - request the IRQ\n");
status = request_irq(
irq,
simple_irq_handler,
SA_INTERRUPT,
name,
0);
if (status < 0) {
printk(" - request for irq %d failed\n", irq);
return status;
}
printk(" - Read some DCR registers\n");
printk(" - UIC0_SR = 0x%.8X\n", mfdcr(DCRN_UIC_SR(UIC0)));
printk(" - UIC0_ER = 0x%.8X\n", mfdcr(DCRN_UIC_ER(UIC0)));
printk(" - UIC0_PR = 0x%.8X\n", mfdcr(DCRN_UIC_PR(UIC0)));
printk(" - UIC0_TR = 0x%.8X\n", mfdcr(DCRN_UIC_TR(UIC0)));
printk(" - UIC1_SR = 0x%.8X\n", mfdcr(DCRN_UIC_SR(UIC1)));
printk(" - UIC1_ER = 0x%.8X\n", mfdcr(DCRN_UIC_ER(UIC1)));
printk(" - UIC1_PR = 0x%.8X\n", mfdcr(DCRN_UIC_PR(UIC1)));
printk(" - UIC1_TR = 0x%.8X\n", mfdcr(DCRN_UIC_TR(UIC1)));
printk(" - Read some GPIO1 registers\n");
printk(" - GPIO1_OR = 0x%.8X\n", p[0]);
printk(" - GPIO1_TCR = 0x%.8X\n", p[1]);
printk(" - GPIO1_ISR1L = 0x%.8X\n", p[12]);
/* Setup GPIO46 as output. GPIO46 drives GPIO47, and
* GPIO47 will be used as IRQ8. The default IRQ
* sensitivity is low and level sensitive.
*/
printk(" - set GPIO46 as output\n");
/* GPIO1_OR[14] = 1 */
// writel(readl(kernel) | (1 << (31-14)), kernel);
p[0] |= 1 << (31-14);
/* GPIO1_TCR[14] = 1 */
// writel(readl(kernel+0x04) | (1 << (31-14)), kernel+0x04);
p[1] |= 1 << (31-14);
/* Select GPIO47 IRQ8 input */
printk(" - set GPIO47 as IRQ8 input\n");
/* GPIO1_ISR1L[30:31] = 01b */
// writel(readl(kernel+0x30) | 1, kernel+0x30);
p[12] |= 1;
/* Clear IRQ8 status (write 1 to bit 19 to clear it) */
printk(" - clear IRQ8 status\n");
mtdcr(DCRN_UIC_SR(UIC1), 1 << (31-19));
printk(" - Read some GPIO1 registers\n");
printk(" - GPIO1_OR = 0x%.8X\n", p[0]);
printk(" - GPIO1_TCR = 0x%.8X\n", p[1]);
printk(" - GPIO1_ISR1L = 0x%.8X\n", p[12]);
/* Enable IRQ8 */
printk(" - enable IRQ8\n");
reg = mfdcr(DCRN_UIC_ER(UIC1));
reg |= 1 << (31-19);
mtdcr(DCRN_UIC_ER(UIC1), reg);
printk(" - UIC1_SR = 0x%.8X\n", mfdcr(DCRN_UIC_SR(UIC1)));
printk(" - UIC1_ER = 0x%.8X\n", mfdcr(DCRN_UIC_ER(UIC1)));
printk(" - sleep for 1s\n");
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
printk(" - UIC1_SR = 0x%.8X\n", mfdcr(DCRN_UIC_SR(UIC1)));
printk(" - UIC1_ER = 0x%.8X\n", mfdcr(DCRN_UIC_ER(UIC1)));
reg = mfdcr(DCRN_UIC_ER(UIC1));
if ((reg & (1 << (31-19))) == 0) {
printk(" - hey something cleared my enable bit!\n");
return 0;
}
printk(" ----- loop test -----\n");
for (i = 0; i < 5; i++) {
printk(" - generate low on GPIO46\n");
p[0] = 0;
printk(" - sleep for 10 ticks\n");
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(10);
printk(" - generate high on GPIO46\n");
p[0] = 1 << (31-14);
printk(" - UIC1_SR = 0x%.8X\n", mfdcr(DCRN_UIC_SR(UIC1)));
printk(" - UIC1_ER = 0x%.8X\n", mfdcr(DCRN_UIC_ER(UIC1)));
reg = mfdcr(DCRN_UIC_SR(UIC1));
if ((reg & (1 << (31-19))) == 0) {
printk(" - IRQ8 status is not set\n");
} else {
printk(" - IRQ8 status is set, clearing it\n");
mtdcr(DCRN_UIC_SR(UIC1), 1 << (31-19));
}
printk(" - UIC1_SR = 0x%.8X\n", mfdcr(DCRN_UIC_SR(UIC1)));
printk(" - UIC1_ER = 0x%.8X\n", mfdcr(DCRN_UIC_ER(UIC1)));
printk(" - sleep for 10 ticks\n");
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(10);
}
/* log load */
printk("module loaded.\n");
return 0;
}
void __exit simple_exit(void)
{
int reg;
printk("<exit> called.\n");
/* Disable IRQ8 */
reg = mfdcr(DCRN_UIC_ER(UIC1));
reg &= ~(1 << (31-19));
mtdcr(DCRN_UIC_ER(UIC1), reg);
free_irq(irq, 0);
iounmap(kernel);
printk("module unloaded\n");
}
module_init(simple_init);
module_exit(simple_exit);
next prev parent reply other threads:[~2006-01-24 19:07 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-01-17 0:45 [Patch 3/3] Add Yellowstone Platform defconfig John Otken
2006-01-24 18:08 ` Yosemite/440EP why are readl()/ioread32() setup to read little-endian? David Hawkins
2006-01-24 19:07 ` David Hawkins [this message]
2006-01-25 10:28 ` Yosemite/440EP is there a global interrupt enable mask? Stefan Roese
2006-01-25 18:30 ` David Hawkins
2006-01-25 18:55 ` Eugene Surovegin
2006-01-25 19:46 ` David Hawkins
2006-01-25 20:13 ` Eugene Surovegin
2006-01-25 20:34 ` David Hawkins
2006-01-25 9:57 ` Yosemite/440EP why are readl()/ioread32() setup to read little-endian? Stefan Roese
2006-01-25 18:26 ` David Hawkins
2006-01-25 18:51 ` Eugene Surovegin
2006-01-25 19:36 ` David Hawkins
2006-01-25 19:48 ` Eugene Surovegin
2006-01-26 10:20 ` Stefan Roese
2006-01-27 0:10 ` David Hawkins
2006-01-27 23:29 ` David Hawkins
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43D67AF6.6070403@ovro.caltech.edu \
--to=dwh@ovro.caltech.edu \
--cc=linuxppc-embedded@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).