Commit f58651b0 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

kernel: VIC interupt support via SPEC/SVEC drivers.

This patch unifies VIC interrupt handling by removing VIC support code from the driver
and using the one provided by the carrier. Since the SVEC now supports IRQs too, both
carriers can benefit from interrupts.
parent 18f9c3ca
......@@ -173,8 +173,6 @@ int fd_probe(struct fmc_device *fmc)
fd->fd_regs_base += 0x10000;
dev_info(dev, "fd_regs_base is %x\n", fd->fd_regs_base);
fd->fd_vic_base =
fmc_find_sdb_device(fmc->sdb, 0xce42, 0x00000013, NULL);
fd->fd_owregs_base = fd->fd_regs_base + 0x500;
spin_lock_init(&fd->lock);
......
/*
/*\
* ZIO interface for the fine-delay driver
*
* Copyright (C) 2012 CERN (www.cern.ch)
......@@ -29,7 +29,6 @@
#include "fine-delay.h"
#include "hw/fd_main_regs.h"
#include "hw/fd_channel_regs.h"
#include "hw/vic_regs.h"
static int fd_sw_fifo_len = FD_SW_FIFO_LEN;
module_param_named(fifo_len, fd_sw_fifo_len, int, 0444);
......@@ -284,32 +283,13 @@ out_unexpected:
* up, entering the interrupt again and again
*/
fmc->op->irq_ack(fmc);
fmc_writel(fmc, 0, fd->fd_vic_base + VIC_REG_EOIR);
return IRQ_HANDLED;
}
/* Unfortunately, on the spec this is GPIO9, i.e. IRQ(1) */
static struct fmc_gpio fd_gpio_on[] = {
{
.gpio = FMC_GPIO_IRQ(1),
.mode = GPIOF_DIR_IN,
.irqmode = IRQF_TRIGGER_RISING,
}
};
static struct fmc_gpio fd_gpio_off[] = {
{
.gpio = FMC_GPIO_IRQ(1),
.mode = GPIOF_DIR_IN,
.irqmode = 0,
}
};
int fd_irq_init(struct fd_dev *fd)
{
struct fmc_device *fmc = fd->fmc;
uint32_t vic_ctl;
int rv;
/* Check that the sw fifo size is a power of two */
if (fd_sw_fifo_len & (fd_sw_fifo_len - 1)) {
......@@ -338,27 +318,27 @@ int fd_irq_init(struct fd_dev *fd)
mod_timer(&fd->fifo_timer, jiffies + fd_timer_period_jiffies);
} else {
dev_info(fd->fmc->hwdev, "Using interrupts for input\n");
fmc->op->irq_request(fmc, fd_irq_handler, "fine-delay",
IRQF_SHARED);
fmc->irq = fd->fd_regs_base;
rv = fmc->op->irq_request(fmc, fd_irq_handler, "fine-delay", 0);
if (rv < 0) {
dev_err(&fd->fmc->dev,
"Failed to request the VIC interrupt\n");
return rv;
}
/*
* Then, configure the hardware: first fine delay,
* then vic, and finally the carrier
*/
/* current VHDL has a buglet: timeout is 8ns, not 1ms each */
fd_writel(fd, FD_TSBIR_TIMEOUT_W(10) /* should be ms */
| FD_TSBIR_THRESHOLD_W(15), /* samples */
fd_writel(fd, FD_TSBIR_TIMEOUT_W(10) /* milliseconds */
|FD_TSBIR_THRESHOLD_W(15), /* samples */
FD_REG_TSBIR);
fd_writel(fd, FD_EIC_IER_TS_BUF_NOTEMPTY, FD_REG_EIC_IER);
/* 4us edge emulation timer (counts in 16ns steps) */
vic_ctl = VIC_CTL_EMU_EDGE | VIC_CTL_EMU_LEN_W(4000 / 16);
fmc_writel(fmc, vic_ctl | VIC_CTL_ENABLE | VIC_CTL_POL,
fd->fd_vic_base + VIC_REG_CTL);
fmc_writel(fmc, 1, fd->fd_vic_base + VIC_REG_IER);
fmc->op->gpio_config(fmc, fd_gpio_on, ARRAY_SIZE(fd_gpio_on));
fd_writel(fd, ~0, FD_REG_EIC_IDR);
fd_writel(fd, FD_EIC_IER_TS_BUF_NOTEMPTY, FD_REG_EIC_IER);
}
/* let it run... */
......@@ -374,11 +354,7 @@ void fd_irq_exit(struct fd_dev *fd)
if (fd_timer_period_ms) {
del_timer_sync(&fd->fifo_timer);
} else {
/* disable interrupts: first carrier, than vic, then fd */
fmc->op->gpio_config(fmc, fd_gpio_off, ARRAY_SIZE(fd_gpio_off));
fmc_writel(fmc, 1, fd->fd_vic_base + VIC_REG_IDR);
fd_writel(fd, ~0, FD_REG_EIC_IDR);
fmc_writel(fmc, VIC_CTL_POL, fd->fd_vic_base + VIC_REG_CTL);
fmc->op->irq_free(fmc);
}
kfree(fd->sw_fifo.t);
......
......@@ -187,7 +187,6 @@ struct fd_dev {
unsigned long flags;
int fd_regs_base; /* sdb_find_device(cern, f19ede1a) */
int fd_owregs_base; /* regs_base + 0x500 */
int fd_vic_base; /* sdb_find_device(cern, 00000013) */
struct fmc_device *fmc;
struct zio_device *zdev, *hwzdev;
struct timer_list fifo_timer;
......
/*
Register definitions for slave core: Vectored Interrupt Controller (VIC)
* File : vic_regs.h
* Author : auto-generated by wbgen2 from wb_slave_vic.wb
* Created : Thu Oct 25 16:47:27 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wb_slave_vic.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WB_SLAVE_VIC_WB
#define __WBGEN2_REGDEFS_WB_SLAVE_VIC_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: VIC Control Register */
/* definitions for field: VIC Enable in reg: VIC Control Register */
#define VIC_CTL_ENABLE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: VIC output polarity in reg: VIC Control Register */
#define VIC_CTL_POL WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Emulate Edge sensitive output in reg: VIC Control Register */
#define VIC_CTL_EMU_EDGE WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Emulated Edge pulse timer in reg: VIC Control Register */
#define VIC_CTL_EMU_LEN_MASK WBGEN2_GEN_MASK(3, 16)
#define VIC_CTL_EMU_LEN_SHIFT 3
#define VIC_CTL_EMU_LEN_W(value) WBGEN2_GEN_WRITE(value, 3, 16)
#define VIC_CTL_EMU_LEN_R(reg) WBGEN2_GEN_READ(reg, 3, 16)
/* definitions for register: Raw Interrupt Status Register */
/* definitions for register: Interrupt Enable Register */
/* definitions for register: Interrupt Disable Register */
/* definitions for register: Interrupt Mask Register */
/* definitions for register: Vector Address Register */
/* definitions for register: Software Interrupt Register */
/* definitions for register: End Of Interrupt Acknowledge Register */
/* definitions for RAM: Interrupt Vector Table */
#define VIC_IVT_RAM_BYTES 0x00000080 /* size in bytes */
#define VIC_IVT_RAM_WORDS 0x00000020 /* size in 32-bit words, 32-bit aligned */
/* [0x0]: REG VIC Control Register */
#define VIC_REG_CTL 0x00000000
/* [0x4]: REG Raw Interrupt Status Register */
#define VIC_REG_RISR 0x00000004
/* [0x8]: REG Interrupt Enable Register */
#define VIC_REG_IER 0x00000008
/* [0xc]: REG Interrupt Disable Register */
#define VIC_REG_IDR 0x0000000c
/* [0x10]: REG Interrupt Mask Register */
#define VIC_REG_IMR 0x00000010
/* [0x14]: REG Vector Address Register */
#define VIC_REG_VAR 0x00000014
/* [0x18]: REG Software Interrupt Register */
#define VIC_REG_SWIR 0x00000018
/* [0x1c]: REG End Of Interrupt Acknowledge Register */
#define VIC_REG_EOIR 0x0000001c
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment