From: bennett78 <bennett78@digis.net>
To: linuxppc-embedded@ozlabs.org
Subject: mpc5200 timer3 Interrupts stopped working
Date: Fri, 24 Feb 2006 08:59:37 -0700 [thread overview]
Message-ID: <43FF2D69.3030902@digis.net> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 3303 bytes --]
Help, how do I debug timer3 Interrupts? My driver was working and then
interrupts
stopped coming (most likely blocked). I have a driver that is very
similar to
linuxppc_2_4_devel/drivers/char/pp01_ad64.c
I have attached the complete driver (et.c)
/ # insmod et
ET Display Driver v0.1 loaded ET_TIN irq 16
et_init 00 intr->per_mask 1bfffc00
et_init 10 intr->ctrl 00c01001
et_init 14 intr->main_mask 00010e00
et_init 24 intr->enc_stat 00000001
et_init 28 intr->crit_stat 00000000
et_init 2c intr->main_stat 00002000
et_init 30 intr->per_stat 00000000
et_init 38 intr->per_error 00000000
/ # cat /proc/interrupts
CPU0
16: 0 MPC5xxx Edge et Trubine
23: 1049 MPC5xxx Edge eth_xmit
24: 2468 MPC5xxx Edge eth_recv
39: 51 MPC5xxx Edge serial
40: 0 MPC5xxx Edge serial
43: 69 MPC5xxx Edge eth_err
BAD: 0
with a pulse train on timer3 input "et_interrupt" no longer gets
called.
code snippets
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#define ET_TIN 3 // Turbine PULSE IN
static void et_interrupt (int irq, void *dev_id, struct pt_regs * regs)
{
int port = ET_IRQ_TO_PORT(irq);
unsigned long stat;
printk(KERN_INFO "et_interrupt IRQ %d port %d main_stat %x gpt.sr %x
\n",
irq, port, intr->main_status, gpt[port].sr );
if( port == ET_TIN ) {
// Clear pending interrupt
stat = in_be32(&gpt[port].sr) & 0xffff;
out_be32(&gpt[port].sr, MPC5xxx_GPT_SR_CAPT);
printk(KERN_INFO "et_int irq=%d port=%d stat %0lx \n", irq,
port, stat);
// wake_up_interruptible(&et_wait);
} else {
printk(KERN_ERR ET_MSG "Unexpected IRQ %d received", irq);
}
spin_lock (&et_lock);
turbine_per = in_be32(&gpt[port].sr) >> 16;
spin_unlock (&et_lock);
}
static int __init et_init (void)
....
if (request_irq(ET_PORT_TO_IRQ(ET_TIN), et_interrupt, 0, "et Trubine",
NULL)) {
printk(KERN_ERR ET_MSG "couldn't register interrupts\n");
goto abort_remove_proc;
}
out_be32(&gpt[ET_TIN].cir, ( 66<<16) | 1 ); /* prescale(16),
period(16) */
out_be32(&gpt[ET_TIN].emsr,
MPC5xxx_GPT_EMSR_INP_CAPTURE
| MPC5xxx_GPT_EMSR_ICT_FALLING
| MPC5xxx_GPT_EMSR_INT_ENABLE);
...
printk(KERN_INFO "ET Display Driver v%s loaded ET_TIN irq %d\n",
ET_VERSION, ET_PORT_TO_IRQ(ET_TIN) );
//broke with or without the following
intr->main_mask &= ~(0x000000ff); /* enable timer ints */
printk(KERN_INFO "et_init 00 intr->per_mask %08x\n", intr->per_mask);
printk(KERN_INFO "et_init 10 intr->ctrl %08x\n", intr->ctrl);
printk(KERN_INFO "et_init 14 intr->main_mask %08x\n", intr->main_mask);
printk(KERN_INFO "et_init 24 intr->enc_stat %08x\n", intr->enc_status);
printk(KERN_INFO "et_init 28 intr->crit_stat %08x\n",
intr->crit_status);
printk(KERN_INFO "et_init 2c intr->main_stat %08x\n",
intr->main_status);
printk(KERN_INFO "et_init 30 intr->per_stat %08x\n", intr->per_status);
printk(KERN_INFO "et_init 38 intr->per_error %08x\n", intr->per_error);
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
thanks in advance for any help,
Frank Bennett
*//*
[-- Attachment #1.2: Type: text/html, Size: 5932 bytes --]
[-- Attachment #2: et.c --]
[-- Type: text/x-c, Size: 11242 bytes --]
/*
* et.c - Driver for EMCO Timers
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <asm/types.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/mpc5xxx.h>
#include <asm/emco_et.h>
#define CONFIG_PPC_5xxx_IPBFREQ 66000
#define ET_VERSION "0.1"
#define ET_NAME "et"
#define ET_MSG "et: "
#undef ET_EXCLUSIVE_OPEN
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Frank Bennett");
MODULE_DESCRIPTION("Emco Timers Driver");
#define ET_MAJOR 190
static int major = ET_MAJOR;
MODULE_PARM(major,"i");
MODULE_PARM_DESC(major, "Device major number (default=190)");
static struct mpc5xxx_gpt *gpt = (struct mpc5xxx_gpt *)MPC5xxx_GPT;
// static struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5xxx_GPIO;
static struct mpc5xxx_intr *intr = (struct mpc5xxx_intr *)MPC5xxx_INTR;
static unsigned long turbine_per;
static DECLARE_WAIT_QUEUE_HEAD(et_wait);
/*
* ET timer related definitions:
*
*/
#define ET_POUT 0 // Pulse Out
#define ET_KP_ACTIVE 1 // not KeyPad active (low) IN see gui.c
#define ET_TDIR 2 // Turbine DIR IN
#define ET_TIN 3 // Turbine PULSE IN
#define ET_52k 4 // start SAR convert
#define ET_RLY1 5 // RELAY 1 active low OUT
#define ET_RLY2 6 // RELAY 2 active low OUT
#define ET_BKL 7 // LCD Backlite OUT
#define ET_DELAY_US 10 /* in micro-seconds */
#define ET_PORT_TO_IRQ(port) (13 + port)
#define ET_IRQ_TO_PORT(irq) (irq - 13)
#ifdef ET_EXCLUSICE_OPEN
static char et_is_open = 0;
#endif
static spinlock_t et_lock = SPIN_LOCK_UNLOCKED;
static void et_interrupt (int irq, void *dev_id, struct pt_regs * regs)
{
int port = ET_IRQ_TO_PORT(irq);
unsigned long stat;
printk(KERN_INFO "et_interrupt IRQ %d port %d main_stat %x gpt.sr %x \n",
irq, port, intr->main_status, gpt[port].sr );
if( port == ET_TIN ) {
// Clear pending interrupt
stat = in_be32(&gpt[port].sr) & 0xffff;
out_be32(&gpt[port].sr, MPC5xxx_GPT_SR_CAPT);
printk(KERN_INFO "et_int irq=%d port=%d stat %0lx \n", irq, port, stat);
// wake_up_interruptible(&et_wait);
} else {
printk(KERN_ERR ET_MSG "Unexpected IRQ %d received", irq);
}
spin_lock (&et_lock);
turbine_per = in_be32(&gpt[port].sr) >> 16;
spin_unlock (&et_lock);
}
#ifdef CONFIG_PROC_FS
static int et_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
*eof = 1;
return count;
}
static int et_write_proc(struct file *file, const char *buffer,
unsigned long count, void *data)
{
if (count > 128)
return -EINVAL;
return count;
}
#endif
/*
* Device file operations
*/
static int et_open(struct inode *inode, struct file *file)
{
#ifdef ET_EXCLUSICE_OPEN
if (et_is_open != 0)
return -EBUSY;
et_is_open = 1;
#endif
spin_lock_irq (&et_lock);
turbine_per = 0L;
spin_unlock_irq (&et_lock);
return 0;
}
static int et_close(struct inode *inode, struct file *file)
{
#ifdef ET_EXCLUSICE_OPEN
et_is_open = 0;
#endif
return 0;
}
static int et_write (struct file *file, u8 *buf,
size_t count, loff_t *ppos)
{
printk(KERN_DEBUG " et_write \n" );
return 0;
}
static size_t et_read (struct file *file, char *buf,
size_t count, loff_t *ppos)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long data;
ssize_t retval;
printk(KERN_DEBUG " et_read \n" );
if (count != sizeof (unsigned int) && count != sizeof (unsigned long))
return -EINVAL;
// add_wait_queue(&et_wait, &wait);
while (1) {
__set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irq (&et_lock);
data = turbine_per;
turbine_per = 0L;
spin_unlock_irq (&et_lock);
if (data != 0)
break;
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
goto out;
}
if (signal_pending(current)) {
retval = -ERESTARTSYS;
goto out;
}
schedule();
}
if (count == sizeof(unsigned int))
retval = put_user(data, (unsigned int *)buf);
else
retval = put_user(data, (unsigned long *)buf);
if (!retval)
retval = count;
out:
current->state = TASK_RUNNING;
// remove_wait_queue(&et_wait, &wait);
return retval;
}
static int et_ioctl (struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
unsigned long data;
// printk(KERN_DEBUG "et_ioctl %04x %08lx\n", cmd, arg);
switch (cmd) {
case ET_POUT:
case ET_52k:
case ET_BKL:
case ET_RLY1:
case ET_RLY2:
out_be32(&gpt[cmd].cr, (arg & 0xffff0000) |1); /* width, update_now */
out_be32(&gpt[cmd].cir, ((CONFIG_PPC_5xxx_IPBFREQ / 1000) << 16) | (arg&0xffff) ); // prescale, period
break;
case ET_TIN:
data = turbine_per;
turbine_per = 0L;
return copy_to_user((void *)arg, &data, sizeof data) ? -EFAULT : 0;
break;
case ET_TDIR:
case ET_KP_ACTIVE:
data = (gpt[cmd].sr & MPC5xxx_GPT_SR_PIN)>>8;
return copy_to_user((void *)arg, &data, sizeof data) ? -EFAULT : 0;
//case ET_RLY1:
//case ET_RLY2:
// if( arg == 1L)
// out_be32(&gpt[cmd].emsr, MPC5xxx_GPT_EMSR_OUTPUT_1 | MPC5xxx_GPT_EMSR_INTERNAL);
// else
// out_be32(&gpt[cmd].emsr, MPC5xxx_GPT_EMSR_OUTPUT_0 | MPC5xxx_GPT_EMSR_INTERNAL);
// break;
}
return 0;
}
static struct file_operations et_fops = {
owner: THIS_MODULE,
open: et_open,
release: et_close,
read: et_read,
write: et_write,
ioctl: et_ioctl,
};
static void et_init_gpt(void)
{
unsigned int per;
/* Pulse Out - Timer 0 */
out_be32(&gpt[ET_POUT].emsr,
MPC5xxx_GPT_EMSR_PWM | MPC5xxx_GPT_EMSR_CE | MPC5xxx_GPT_EMSR_CONTINOUS);
/* Turbine in - GPIO Timer 1 */
turbine_per = 0L;
out_be32(&gpt[ET_TIN].cir, ( 66<<16) | 1 ); /* prescale(16), period(16) */
out_be32(&gpt[ET_TIN].emsr,
MPC5xxx_GPT_EMSR_INP_CAPTURE | MPC5xxx_GPT_EMSR_ICT_FALLING | MPC5xxx_GPT_EMSR_INT_ENABLE);
/* Turbine dir - GPIO Timer 2 */
out_be32(&gpt[ET_TDIR].emsr,
MPC5xxx_GPT_EMSR_INP_CAPTURE | MPC5xxx_GPT_EMSR_ICT_FALLING );
/* 52k ref - GPIO Timer 3 */
per = 40 ; // 40 usec
out_be32(&gpt[ET_52k].cr, (per/2)<<16 | 1); /* width, update_now */
out_be32(&gpt[ET_52k].cir, ( 33<<16) | per ); /* prescale(16), period(16) */
out_be32(&gpt[ET_52k].emsr,
MPC5xxx_GPT_EMSR_PWM | MPC5xxx_GPT_EMSR_CE | MPC5xxx_GPT_EMSR_CONTINOUS);
/* KP_active - GPIO Timer 4 */
out_be32(&gpt[ET_KP_ACTIVE].emsr,
MPC5xxx_GPT_EMSR_INP_CAPTURE | MPC5xxx_GPT_EMSR_ICT_FALLING );
/* Relay 1 - GPIO Timer 5 */
out_be32(&gpt[ET_RLY1].emsr,
MPC5xxx_GPT_EMSR_PWM | MPC5xxx_GPT_EMSR_CE | MPC5xxx_GPT_EMSR_CONTINOUS);
// MPC5xxx_GPT_EMSR_OUTPUT_1 | MPC5xxx_GPT_EMSR_INTERNAL);
/* Relay 2 - GPIO Timer 5 */
out_be32(&gpt[ET_RLY2].emsr,
MPC5xxx_GPT_EMSR_PWM | MPC5xxx_GPT_EMSR_CE | MPC5xxx_GPT_EMSR_CONTINOUS);
// MPC5xxx_GPT_EMSR_OUTPUT_1 | MPC5xxx_GPT_EMSR_INTERNAL);
/* LCD BL Lite- GPIO Timer 7 */
per = 4000 ; // 4 msec
out_be32(&gpt[ET_BKL].cr, (per/4)<<16 | 1); /* width, update_now */
out_be32(&gpt[ET_BKL].cir, ( 66<<16) | per ); /* prescale(16), period(16) */
out_be32(&gpt[ET_BKL].emsr,
MPC5xxx_GPT_EMSR_PWM | MPC5xxx_GPT_EMSR_CE | MPC5xxx_GPT_EMSR_CONTINOUS);
}
static int __init et_init (void)
{
#ifdef CONFIG_PROC_FS
struct proc_dir_entry * proc;
#endif
int ret = -ENODEV;
ret = register_chrdev(ET_MAJOR, ET_NAME, &et_fops);
if (ret < 0) {
printk(KERN_ERR ET_MSG "Couldn't register " ET_NAME " driver\n");
goto abort;
}
if (major == 0)
major = ret; /* dynamic */
#ifdef CONFIG_PROC_FS
proc = create_proc_entry(ET_NAME, S_IFREG | S_IRUGO, NULL);
if (proc == NULL) {
printk(KERN_ERR ET_MSG "failed to create /proc/"ET_NAME"\n");
goto abort_unregister;
}
proc->read_proc = et_read_proc;
proc->write_proc = et_write_proc;
#endif
if (request_irq(ET_PORT_TO_IRQ(ET_TIN), et_interrupt, 0, "et Trubine", NULL)) {
printk(KERN_ERR ET_MSG "couldn't register interrupts\n");
goto abort_remove_proc;
}
et_init_gpt();
printk(KERN_INFO "ET Display Driver v%s loaded ET_TIN irq %d\n",
ET_VERSION, ET_PORT_TO_IRQ(ET_TIN) );
intr->main_mask &= ~(0x000000ff); /* enable timer ints */
printk(KERN_INFO "et_init 00 intr->per_mask %08x\n", intr->per_mask);
printk(KERN_INFO "et_init 10 intr->ctrl %08x\n", intr->ctrl);
printk(KERN_INFO "et_init 14 intr->main_mask %08x\n", intr->main_mask);
printk(KERN_INFO "et_init 24 intr->enc_stat %08x\n", intr->enc_status);
printk(KERN_INFO "et_init 28 intr->crit_stat %08x\n", intr->crit_status);
printk(KERN_INFO "et_init 2c intr->main_stat %08x\n", intr->main_status);
printk(KERN_INFO "et_init 30 intr->per_stat %08x\n", intr->per_status);
printk(KERN_INFO "et_init 38 intr->per_error %08x\n", intr->per_error);
sti();
/*
volatile u32 per_mask; // INTR + 0x00
volatile u32 per_pri1; // INTR + 0x04
volatile u32 per_pri2; // INTR + 0x08
volatile u32 per_pri3; // INTR + 0x0c
volatile u32 ctrl; // INTR + 0x10
volatile u32 main_mask; // INTR + 0x14
volatile u32 main_pri1; // INTR + 0x18
volatile u32 main_pri2; // INTR + 0x1c
volatile u32 reserved1; // INTR + 0x20
volatile u32 enc_status; // INTR + 0x24
volatile u32 crit_status; // INTR + 0x28
volatile u32 main_status; // INTR + 0x2c
volatile u32 per_status; // INTR + 0x30
volatile u32 reserved2; // INTR + 0x34
volatile u32 per_error; // INTR + 0x38
*/
return 0;
abort_remove_proc:
remove_proc_entry(ET_NAME, NULL);
abort_unregister:
unregister_chrdev(major, ET_NAME);
abort:
return ret;
}
static void __devexit et_cleanup (void)
{
free_irq(ET_PORT_TO_IRQ(ET_TIN), NULL);
remove_proc_entry(ET_NAME, NULL);
unregister_chrdev(major, ET_NAME);
printk(KERN_INFO "ET Display Driver v%s unloaded\n", ET_VERSION);
}
EXPORT_NO_SYMBOLS;
module_init(et_init)
module_exit(et_cleanup)
next reply other threads:[~2006-02-24 15:59 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-24 15:59 bennett78 [this message]
2006-02-24 22:49 ` mpc5200 timer3 Interrupts stopped working bennett78
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=43FF2D69.3030902@digis.net \
--to=bennett78@digis.net \
--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).