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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.