Skip to content
Snippets Groups Projects
Commit d8f1dc9f authored by Adam Wujek's avatar Adam Wujek :speech_balloon:
Browse files

Merge commit 'adam-update_kernel_3.16.37'


Signed-off-by: default avatarAdam Wujek <adam.wujek@cern.ch>
parents 4744f847 ac693f95
No related merge requests found
Showing
with 1498 additions and 398 deletions
...@@ -15,8 +15,8 @@ barebox-2014.04.0.tar.bz2 e1f089fc24cc7f24478e663c0e3b91d9 \ ...@@ -15,8 +15,8 @@ barebox-2014.04.0.tar.bz2 e1f089fc24cc7f24478e663c0e3b91d9 \
http://www.barebox.org/download/barebox-2014.04.0.tar.bz2 http://www.barebox.org/download/barebox-2014.04.0.tar.bz2
# kernel # kernel
linux-2.6.39.tar.bz2 1aab7a741abe08d42e8eccf20de61e05 \ linux-3.16.37.tar.xz fc4e8c469cf852a128e160f2910c1f21 \
http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.tar.bz2 https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.37.tar.xz
# our gateware binaries # our gateware binaries
wrs-gw-v4.2-20150826.tar.gz 807117326f6d5b1b53ebc95ca093fc44 \ wrs-gw-v4.2-20150826.tar.gz 807117326f6d5b1b53ebc95ca093fc44 \
......
#!/bin/bash #!/bin/bash
KERVER=2.6.39
# check variables, like all scripts herein do # check variables, like all scripts herein do
WRS_SCRIPT_NAME=$(basename $0) WRS_SCRIPT_NAME=$(basename $0)
if [ -z "$WRS_BASE_DIR" ]; then if [ -z "$WRS_BASE_DIR" ]; then
...@@ -13,8 +11,9 @@ fi ...@@ -13,8 +11,9 @@ fi
wrs_check_vars WRS_OUTPUT_DIR WRS_DOWNLOAD_DIR CROSS_COMPILE wrs_check_vars WRS_OUTPUT_DIR WRS_DOWNLOAD_DIR CROSS_COMPILE
wrs_echo "--- Linux kernel for switch" wrs_echo "--- Linux kernel for switch"
tarname="linux-${KERVER}.tar.bz2"
patchdir="${WRS_BASE_DIR}/../patches/kernel/v${KERVER}" tarname="linux-${KVER}.tar.xz"
patchdir="${WRS_BASE_DIR}/../patches/kernel/v${KVER}"
wrs_download $tarname wrs_download $tarname
mkdir -p $WRS_OUTPUT_DIR/build || wrs_die "mkdir build" mkdir -p $WRS_OUTPUT_DIR/build || wrs_die "mkdir build"
...@@ -22,9 +21,10 @@ mkdir -p $WRS_OUTPUT_DIR/images || wrs_die "mkdir images" ...@@ -22,9 +21,10 @@ mkdir -p $WRS_OUTPUT_DIR/images || wrs_die "mkdir images"
# go to the build dir and compile it, using our configuration # go to the build dir and compile it, using our configuration
cd $WRS_OUTPUT_DIR/build cd $WRS_OUTPUT_DIR/build
dirname="linux-${KERVER}" dirname="linux-${KVER}"
rm -rf $dirname rm -rf $dirname
tar xjf ${WRS_DOWNLOAD_DIR}/$tarname || wrs_die "untar $tarname" # xz archive, so use "J" for tar
tar xJf ${WRS_DOWNLOAD_DIR}/$tarname || wrs_die "untar $tarname"
# apply patches # apply patches
cd $dirname cd $dirname
...@@ -34,7 +34,7 @@ done ...@@ -34,7 +34,7 @@ done
# copy the config and replace "-j" level. First remove it in case it's left in # copy the config and replace "-j" level. First remove it in case it's left in
CFG="${patchdir}/linux-config-wrswitch" CFG=$WRS_BASE_DIR/../configs/wrs_linux_defconfig
if [ "x$WRS_KERNEL_CONFIG" != "x" ]; then if [ "x$WRS_KERNEL_CONFIG" != "x" ]; then
if [ -f $WRS_KERNEL_CONFIG ]; then if [ -f $WRS_KERNEL_CONFIG ]; then
CFG=$WRS_KERNEL_CONFIG CFG=$WRS_KERNEL_CONFIG
...@@ -50,7 +50,7 @@ make oldconfig || wrs_die "kernel config" ...@@ -50,7 +50,7 @@ make oldconfig || wrs_die "kernel config"
make $WRS_MAKE_J zImage modules || wrs_die "kernel compilation" make $WRS_MAKE_J zImage modules || wrs_die "kernel compilation"
mkdir -p $WRS_OUTPUT_DIR/images/lib/modules/$KERVER/kernel mkdir -p $WRS_OUTPUT_DIR/images/lib/modules/$KVER/kernel
cp $(find . -name '*.ko') $WRS_OUTPUT_DIR/images/lib/modules/$KERVER/kernel cp $(find . -name '*.ko') $WRS_OUTPUT_DIR/images/lib/modules/$KVER/kernel
cp arch/$ARCH/boot/zImage $WRS_OUTPUT_DIR/images cp arch/$ARCH/boot/zImage $WRS_OUTPUT_DIR/images
...@@ -16,7 +16,7 @@ mkdir -p $WRS_OUTPUT_DIR/build || wrs_die "mkdir build" ...@@ -16,7 +16,7 @@ mkdir -p $WRS_OUTPUT_DIR/build || wrs_die "mkdir build"
mkdir -p $WRS_OUTPUT_DIR/images || wrs_die "mkdir images" mkdir -p $WRS_OUTPUT_DIR/images || wrs_die "mkdir images"
# check that the kernel has been compiled (or at least configured) # check that the kernel has been compiled (or at least configured)
export LINUX="$WRS_OUTPUT_DIR/build/linux-2.6.39" export LINUX="$WRS_OUTPUT_DIR/build/linux-$KVER"
test -f $LINUX/.config || wrs_die "no kernel in $LINUX" test -f $LINUX/.config || wrs_die "no kernel in $LINUX"
cd $WRS_BASE_DIR/../kernel cd $WRS_BASE_DIR/../kernel
make $WRS_MAKE_J || wrs_die "white rabbit kernel modules" make $WRS_MAKE_J || wrs_die "white rabbit kernel modules"
......
...@@ -21,7 +21,7 @@ make clean ...@@ -21,7 +21,7 @@ make clean
# we need LINUX and CROSS_COMPILE. The latter is there for sure # we need LINUX and CROSS_COMPILE. The latter is there for sure
if [ "x$LINUX" == "x" ]; then if [ "x$LINUX" == "x" ]; then
export LINUX="$WRS_OUTPUT_DIR/build/linux-2.6.39" export LINUX="$WRS_OUTPUT_DIR/build/linux-$KVER"
fi fi
......
...@@ -17,7 +17,7 @@ installdir="$WRS_OUTPUT_DIR/images/wr" ...@@ -17,7 +17,7 @@ installdir="$WRS_OUTPUT_DIR/images/wr"
# This time build is done in-place, but the output is a tree in images/wr. # This time build is done in-place, but the output is a tree in images/wr.
# Some of the makefiles inside use # Some of the makefiles inside use
export LINUX="$WRS_OUTPUT_DIR/build/linux-2.6.39" export LINUX="$WRS_OUTPUT_DIR/build/linux-$KVER"
cd $sourcedir cd $sourcedir
make clean || wrs_die "Error cleaning user space" make clean || wrs_die "Error cleaning user space"
......
...@@ -37,6 +37,7 @@ export PATH="$PATH:/usr/sbin" ...@@ -37,6 +37,7 @@ export PATH="$PATH:/usr/sbin"
WRS_TOOLS="git gcc g++ ar as m4 msgfmt md5sum make" WRS_TOOLS="git gcc g++ ar as m4 msgfmt md5sum make"
WRS_TOOLS="$WRS_TOOLS awk unzip patch bison flex ncursesw5-config" WRS_TOOLS="$WRS_TOOLS awk unzip patch bison flex ncursesw5-config"
WRS_TOOLS="$WRS_TOOLS fakeroot makeinfo" WRS_TOOLS="$WRS_TOOLS fakeroot makeinfo"
WRS_TOOLS="$WRS_TOOLS xz"
wrs_check_tools $WRS_TOOLS wrs_check_tools $WRS_TOOLS
...@@ -48,6 +49,9 @@ fi ...@@ -48,6 +49,9 @@ fi
export WRS_SCRIPTS_DIR=${WRS_BASE_DIR}/scripts export WRS_SCRIPTS_DIR=${WRS_BASE_DIR}/scripts
# Export Linux kernel version in use
export KVER="3.16.37"
# Export Buildroot version in use # Export Buildroot version in use
export BRVER="2016.02" export BRVER="2016.02"
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
# Buildroot 2016.02 Configuration # Buildroot 2016.02 Configuration
# #
BR2_HAVE_DOT_CONFIG=y BR2_HAVE_DOT_CONFIG=y
BR2_HOST_GCC_AT_LEAST_4_7=y
BR2_HOST_GCC_AT_LEAST_4_8=y
# #
# Target options # Target options
...@@ -153,9 +151,36 @@ BR2_TOOLCHAIN_BUILDROOT_VENDOR="buildroot" ...@@ -153,9 +151,36 @@ BR2_TOOLCHAIN_BUILDROOT_VENDOR="buildroot"
# BR2_KERNEL_HEADERS_3_18 is not set # BR2_KERNEL_HEADERS_3_18 is not set
# BR2_KERNEL_HEADERS_4_1 is not set # BR2_KERNEL_HEADERS_4_1 is not set
# BR2_KERNEL_HEADERS_4_3 is not set # BR2_KERNEL_HEADERS_4_3 is not set
BR2_KERNEL_HEADERS_4_4=y # BR2_KERNEL_HEADERS_4_4 is not set
# BR2_KERNEL_HEADERS_VERSION is not set BR2_KERNEL_HEADERS_VERSION=y
BR2_DEFAULT_KERNEL_HEADERS="4.4.3" BR2_DEFAULT_KERNEL_VERSION="3.16.37"
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_4 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_3 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_2 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_1 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_0 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_19 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_18 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_17 is not set
BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_16=y
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_15 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_14 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_13 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_12 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_11 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_10 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_9 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_8 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_7 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_6 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_5 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_4 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_3 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_2 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_1 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_0 is not set
# BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_REALLY_OLD is not set
BR2_DEFAULT_KERNEL_HEADERS="3.16.37"
BR2_TOOLCHAIN_BUILDROOT_UCLIBC=y BR2_TOOLCHAIN_BUILDROOT_UCLIBC=y
# BR2_TOOLCHAIN_BUILDROOT_GLIBC is not set # BR2_TOOLCHAIN_BUILDROOT_GLIBC is not set
# BR2_TOOLCHAIN_BUILDROOT_MUSL is not set # BR2_TOOLCHAIN_BUILDROOT_MUSL is not set
...@@ -239,15 +264,7 @@ BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_13=y ...@@ -239,15 +264,7 @@ BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_13=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_14=y BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_14=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_15=y BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_15=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_16=y BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_16=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_17=y BR2_TOOLCHAIN_HEADERS_AT_LEAST="3.16"
BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_18=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_19=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_4_0=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_4_1=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_4_2=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_4_3=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_4_4=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST="4.4"
BR2_TOOLCHAIN_GCC_AT_LEAST_4_3=y BR2_TOOLCHAIN_GCC_AT_LEAST_4_3=y
BR2_TOOLCHAIN_GCC_AT_LEAST_4_4=y BR2_TOOLCHAIN_GCC_AT_LEAST_4_4=y
BR2_TOOLCHAIN_GCC_AT_LEAST_4_5=y BR2_TOOLCHAIN_GCC_AT_LEAST_4_5=y
......
...@@ -727,7 +727,7 @@ Specification ...@@ -727,7 +727,7 @@ Specification
| **I/O** | 32bit Async Bridge with FPGA\ | | **I/O** | 32bit Async Bridge with FPGA\ |
| | 100Base-T Ethernet | | | 100Base-T Ethernet |
+--------------------+-------------------------------------------------+ +--------------------+-------------------------------------------------+
| **OS** | Linux (Kernel v2.6.39) | | **OS** | Linux (Kernel v3.16.37) |
+--------------------+-------------------------------------------------+ +--------------------+-------------------------------------------------+
......
...@@ -363,7 +363,7 @@ The messages of a download run are like the following ones: ...@@ -363,7 +363,7 @@ The messages of a download run are like the following ones:
2016-06-02 17:10:46: --- Downloading base packages 2016-06-02 17:10:46: --- Downloading base packages
2016-06-02 17:10:50: Retrieved at91bootstrap-3-3.0.tar.gz from upstream 2016-06-02 17:10:50: Retrieved at91bootstrap-3-3.0.tar.gz from upstream
2016-06-02 17:10:51: Retrieved barebox-2014.04.0.tar.bz2 from upstream 2016-06-02 17:10:51: Retrieved barebox-2014.04.0.tar.bz2 from upstream
2016-06-02 17:11:21: Retrieved linux-2.6.39.tar.bz2 from upstream 2016-06-02 17:11:21: Retrieved linux-3.16.37.tar.xz from upstream
2016-06-02 17:11:22: Retrieved wrs-gw-v4.2-20150826.tar.gz from upstream 2016-06-02 17:11:22: Retrieved wrs-gw-v4.2-20150826.tar.gz from upstream
2016-06-02 17:11:27: Retrieved buildroot-2016.02.tar.bz2 from upstream 2016-06-02 17:11:27: Retrieved buildroot-2016.02.tar.bz2 from upstream
@end smallexample @end smallexample
...@@ -736,31 +736,26 @@ in two lines with a local variable to fit the page with in documentation): ...@@ -736,31 +736,26 @@ in two lines with a local variable to fit the page with in documentation):
@node The Linux Kernel @node The Linux Kernel
@subsection The Linux Kernel @subsection The Linux Kernel
The kernel is currently version 2.6.39, compiled from an uncompressed The kernel is currently version 3.16.37, compiled from an uncompressed
tar file (so not within a @i{git} repository). The upstream tar file (so not within a @i{git} repository). The upstream
vanilla kernel is downloaded, then vanilla kernel is downloaded, then
local patches are applied (they come from a @i{git} local patches are applied (they come from a @i{git}
repository, but they are currently applied with a simple @i{patch} repository, but they are currently applied with a simple @i{patch}
command). command).
The relevant patches are available in @i{patches/kernel/v2.6.39}, The relevant patches are available in @i{patches/kernel/v3.16.37},
and are currently the following ones: and are currently the following ones:
@example @example
0001-wrs3-changes-to-g45ek.patch 0001-initramfs-stop-after-one-cpio-archive.patch
0002-initramfs-stop-after-one-cpio-archive.patch 0002-arm-fiq-allow-modules-to-exploit-the-fiq-mechanism.patch
0003-at91-NR_IRQS-increase-by-64-to-fit-custom-muxes.patch 0003-mtd_dataflash-Read-EDI-bytes-in-JEDEC-to-support-AT4.patch
0004-irq-export-symbols-for-external-irq-controller.patch 0004-wr-switch-sam9m10g45ek-enable-FPGA-access-from-EBI1-.patch
0005-Change-Vbus-pin.patch 0005-wr-switch-sam9m10g45ek-change-USB-vbus_pin-from-PB19.patch
0006-arm-fiq-allow-modules-to-exploit-the-fiq-mechanism.patch 0006-wr-switch-sam9m10g45ek-store-device-partitioning.patch
0007-mtd-nand-sam9g45-can-hwecc-like-9263.patch 0007-wr-switch-sam9m10g45ek-more-relaxed-nand-timings.patch
0008-wrs3-use-correct-nand-partitioning.patch 0008-wr-switch-sam9m10g45ek-provide-bootcount-using-scrat.patch
0009-at91-udc-force-full-speed.patch 0009-wr-switch-at91-udc-force-full-speed.patch
0010-sam9m10g45ek-for-wrs-new-partitioning.patch
0011-sam9m10g45ek-for-wrs-final-partitions-for-V4.1.patch
0012-sam9m10g45ek-for-wrs-more-relaxed-nand-timings.patch
0013-mtd_dataflash-Read-EDI-JEDEC-to-support-AT45DB641E.patch
0014-sam9m10g45ek-for-wrs-provide-bootcount-using-scratch.patch
@end example @end example
The configuration we use to build the kernel is not a patch but a plain The configuration we use to build the kernel is not a patch but a plain
...@@ -797,7 +792,7 @@ Currently, the package includes the following modules: ...@@ -797,7 +792,7 @@ Currently, the package includes the following modules:
@itemize @bullet @itemize @bullet
@item @i{wr_vic.ko}: the interrupt controller for in-FPGA devices. @item @i{htvic.ko}: the interrupt controller for in-FPGA devices.
@item @i{wr-nic.ko}: the network ``card'' driver for WR ports. @item @i{wr-nic.ko}: the network ``card'' driver for WR ports.
@item @i{wr_rtu.ko}: the routing-table interface between the @item @i{wr_rtu.ko}: the routing-table interface between the
switching core and the associated user-space daemon. switching core and the associated user-space daemon.
...@@ -812,6 +807,8 @@ This is considered acceptable, because system time is only ...@@ -812,6 +807,8 @@ This is considered acceptable, because system time is only
used for logging. used for logging.
@item @i{wrs_devices.ko}: a dummy module that register our platform devices.
@end itemize @end itemize
@c -------------------------------------------------------------------------- @c --------------------------------------------------------------------------
......
...@@ -141,13 +141,6 @@ waiting for the boot loader to be sent to RAM from USB. ...@@ -141,13 +141,6 @@ waiting for the boot loader to be sent to RAM from USB.
@itemize @bullet @itemize @bullet
@item 2.6.39 is pretty old nowadays. We should move to a recent kernel.
Unfortunately this means writing the ``device tree'' crap for our board,
as everything nowadays is device-tree-based. Which in my opinion has
been designed by our competitors, to kill us slowly and painfully.
In addition, our patches must be ported forward. A patch-set for 3.14
is currently work in progress.
@item The @i{wr-nic} driver is very similar to what we run for the SPEC, @item The @i{wr-nic} driver is very similar to what we run for the SPEC,
we went forward in merging it with the one in @i{spec-sw} but a few we went forward in merging it with the one in @i{spec-sw} but a few
lines are still different. Unifying will allow using a driver lines are still different. Unifying will allow using a driver
......
DIRS = wr_vic wr_nic wr_rtu wr_pstats wr_clocksource DIRS = coht_vic wr_nic wr_rtu wr_pstats wr_clocksource wrs_devices
# We may "LINUX ?= /usr/src/linux-wrswitch", but it's better to leave it empty # We may "LINUX ?= /usr/src/linux-wrswitch", but it's better to leave it empty
......
ccflags-y += -Werror
obj-m := htvic.o
export ARCH ?= arm
export CROSS_COMPILE ?= $(CROSS_COMPILE_ARM)
all: modules
modules:
$(MAKE) -C $(LINUX) M=$(shell /bin/pwd)
clean:
$(MAKE) -C $(LINUX) M=$(shell /bin/pwd) clean
gtags:
gtags --statistics
.PHONY: all clean gtags
/*
* Driver for the HT-VIC IRQ controller
*
* Copyright (c) 2016 CERN
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* 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.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
#include <linux/irqchip/chained_irq.h>
#else
static inline void chained_irq_enter(struct irq_chip *chip,
struct irq_desc *desc)
{
/* FastEOI controllers require no action on entry. */
if (chip->irq_eoi)
return;
if (chip->irq_mask_ack) {
chip->irq_mask_ack(&desc->irq_data);
} else {
chip->irq_mask(&desc->irq_data);
if (chip->irq_ack)
chip->irq_ack(&desc->irq_data);
}
}
static inline void chained_irq_exit(struct irq_chip *chip,
struct irq_desc *desc)
{
if (chip->irq_eoi)
chip->irq_eoi(&desc->irq_data);
else
chip->irq_unmask(&desc->irq_data);
}
#endif
#include "htvic.h"
struct memory_ops memop = {
.read = NULL,
.write = NULL,
};
/**
* End of interrupt for the VIC. In case of level interrupt,
* there is no way to delegate this to the kernel
*/
static void htvic_eoi(struct irq_data *d)
{
struct htvic_device *vic = irq_data_get_irq_chip_data(d);
/*
* Any write operation acknowledges the pending interrupt.
* Then, VIC advances to another pending interrupt(s) or
* releases the master interrupt output.
*/
htvic_iowrite(vic, 1, vic->kernel_va + VIC_REG_EOIR);
}
static void htvic_mask_disable_reg(struct irq_data *d)
{
struct htvic_device *htvic = irq_data_get_irq_chip_data(d);
htvic_iowrite(htvic, 1 << d->hwirq,
htvic->kernel_va + VIC_REG_IDR);
}
static void htvic_unmask_enable_reg(struct irq_data *d)
{
struct htvic_device *htvic = irq_data_get_irq_chip_data(d);
htvic_iowrite(htvic, 1 << d->hwirq,
htvic->kernel_va + VIC_REG_IER);
}
static void htvic_irq_ack(struct irq_data *d)
{
}
/**
*
*/
static unsigned int htvic_irq_startup(struct irq_data *d)
{
struct htvic_device *vic = irq_data_get_irq_chip_data(d);
int ret;
ret = try_module_get(vic->pdev->dev.driver->owner);
if (ret == 0) { /* 0 fail, 1 success */
dev_err(&vic->pdev->dev,
"Cannot pin the \"%s\" driver. Something really wrong is going on\n",
vic->pdev->dev.driver->name);
return 1;
}
htvic_unmask_enable_reg(d);
return 0;
}
/**
* Executed when a driver does `free_irq()`.
*/
static void htvic_irq_shutdown(struct irq_data *d)
{
struct htvic_device *vic = irq_data_get_irq_chip_data(d);
htvic_mask_disable_reg(d);
module_put(vic->pdev->dev.driver->owner);
}
static struct irq_chip htvic_chip = {
.name = "HT-VIC",
.irq_startup = htvic_irq_startup,
.irq_shutdown = htvic_irq_shutdown,
.irq_ack = htvic_irq_ack,
.irq_eoi = htvic_eoi,
.irq_mask_ack = htvic_mask_disable_reg,
.irq_mask = htvic_mask_disable_reg,
.irq_unmask = htvic_unmask_enable_reg,
};
/**
* It match a given device with the irq_domain. `struct device_node *` is just
* a convention. actually it can be anything (I do not understand why kernel
* people did not use `void *`)
*
* In our case here we expect a string because we identify this domain by
* name
*/
static int htvic_irq_domain_match(struct irq_domain *d, struct device_node *node)
{
char *name = (char *)node;
if (strcmp(d->name, name) == 0)
return 1;
return 0;
}
/**
* Given the hardware IRQ and the Linux IRQ number (virtirq), configure the
* Linux IRQ number in order to handle properly the incoming interrupts
* on the hardware IRQ line.
*/
static int htvic_irq_domain_map(struct irq_domain *h,
unsigned int virtirq,
irq_hw_number_t hwirq)
{
struct htvic_device *htvic = h->host_data;
struct irq_desc *desc = irq_to_desc(virtirq);
#if 0
struct resource *r = platform_get_resource(htvic->pdev,
IORESOURCE_IRQ, 0);
#endif
irq_set_chip(virtirq, &htvic_chip);
irq_set_handler(virtirq, handle_simple_irq);
/*
* It MUST be no-thread because the VIC EOI must occur AFTER
* the device handler ack its signal. Any whay the interrupt from
* the carrier is already threaded
*/
desc->status_use_accessors |= IRQ_NOTHREAD;
/* The VIC is only level, it emulates edge */
#if 0
if (r->flags & (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE)) {
__irq_set_handler(virtirq, handle_edge_irq, 0, NULL);
} else {
dev_err(&htvic->pdev->dev,
"Invalid IRQ resource, it must be explicit if it is edge or level\n");
return -EINVAL;
}
#endif
irq_set_chip_data(virtirq, htvic);
irq_set_handler_data(virtirq, htvic);
return 0;
}
static struct irq_domain_ops htvic_irq_domain_ops = {
.match = htvic_irq_domain_match,
.map = htvic_irq_domain_map,
};
/**
* Handle cascade IRQ coming from the platform and re-route it properly.
* When the platform receives an interrupt it will call than this function
* which then will call the proper handler
*/
static void htvic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
{
struct htvic_device *htvic = irq_get_handler_data(irq);
struct irq_chip *chip = irq_get_chip(irq);
unsigned int cascade_irq, /* i = 0, */ vect;
/* unsigned long status; */
chained_irq_enter(chip, desc);
do {
vect = htvic_ioread(htvic, htvic->kernel_va + VIC_REG_VAR) & 0xFF;
if (vect >= VIC_MAX_VECTORS)
goto out;
cascade_irq = irq_find_mapping(htvic->domain, vect);
generic_handle_irq(cascade_irq);
/**
* ATTENTION here the ack is actually an EOI.The kernel
* does not export the handle_edge_eoi_irq() handler which
* is the one we need here. The kernel offers us the
* handle_edge_irq() which use only the ack() function.
* So what actually we need to to is to call the ack
* function but not the eoi function.
*/
htvic_eoi(irq_get_irq_data(cascade_irq));
} while(htvic_ioread(htvic, htvic->kernel_va + VIC_REG_RISR));
out:
chained_irq_exit(chip, desc);
}
/**
* Mapping of HTVIC irqs to Linux irqs using linear IRQ domain
*/
static int htvic_irq_mapping(struct htvic_device *htvic)
{
struct irq_desc *desc;
int i, irq;
htvic->domain = irq_domain_add_linear(NULL, VIC_MAX_VECTORS,
&htvic_irq_domain_ops, htvic);
if (!htvic->domain)
return -ENOMEM;
htvic->domain->name = kasprintf(GFP_KERNEL, "%s",
dev_name(&htvic->pdev->dev));
/* Create the mapping between HW irq and virtual IRQ number */
for (i = 0; i < VIC_MAX_VECTORS; ++i) {
htvic->hwid[i] = htvic_ioread(htvic, htvic->kernel_va +
VIC_IVT_RAM_BASE + 4 * i);
htvic_iowrite(htvic, i,
htvic->kernel_va + VIC_IVT_RAM_BASE + 4 * i);
irq = irq_create_mapping(htvic->domain, i);
if (irq <= 0)
goto out;
}
irq = platform_get_irq(htvic->pdev, 0);
desc = irq_to_desc(irq);
htvic->platform_handle_irq = desc->handle_irq;
htvic->platform_handler_data = desc->irq_data.handler_data;
if (irq_set_handler_data(irq, htvic) != 0)
BUG();
irq_set_chained_handler(irq, htvic_handle_cascade_irq);
return 0;
out:
irq_domain_remove(htvic->domain);
return -EPERM;
}
/**
* Check if the platform is providing all the necessary information
* for the HTVIC to work properly.
*
* The HTVIC needs the following informations:
* - a Linux IRQ number where it should attach itself
* - a virtual address where to find the component
*/
static int htvic_validation(struct platform_device *pdev)
{
struct resource *r;
r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!r) {
dev_err(&pdev->dev, "Carrier IRQ number is missing\n");
return -EINVAL;
}
if (!(r->flags & (IORESOURCE_IRQ_HIGHEDGE |
IORESOURCE_IRQ_LOWEDGE |
IORESOURCE_IRQ_HIGHLEVEL |
IORESOURCE_IRQ_LOWLEVEL))) {
dev_err(&pdev->dev,
"Edge/Level High/Low information missing\n");
return -EINVAL;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, HTVIC_MEM_BASE);
if (!r) {
dev_err(&pdev->dev, "VIC base address is missing\n");
return -EINVAL;
}
return 0;
}
/**
* It acks any pending interrupt in order to avoid to bring the HTVIC
* to a stable status (possibly)
*/
static inline void htvic_ack_pending(struct htvic_device *htvic)
{
while (htvic_ioread(htvic, htvic->kernel_va + VIC_REG_RISR))
htvic_iowrite(htvic, 1, htvic->kernel_va + VIC_REG_EOIR);
}
/**
* Create a new instance for this driver.
*/
static int htvic_probe(struct platform_device *pdev)
{
struct htvic_device *htvic;
const struct resource *r;
uint32_t ctl;
int ret;
/*
* TODO theoretically speaking all the confguration should come
* from a platform_data structure. Since we do not have it yet,
* we proceed this way
*/
switch(pdev->id_entry->driver_data) {
case HTVIC_VER_SPEC:
case HTVIC_VER_WRSWI:
memop.read = __htvic_ioread32;
memop.write = __htvic_iowrite32;
break;
case HTVIC_VER_SVEC:
memop.read = __htvic_ioread32be;
memop.write = __htvic_iowrite32be;
break;
default:
ret = -EINVAL;
goto out_memop;
}
ret = htvic_validation(pdev);
if (ret)
return ret;
htvic = kzalloc(sizeof(struct htvic_device), GFP_KERNEL);
if (!htvic)
return -ENOMEM;
dev_set_drvdata(&pdev->dev, htvic);
htvic->pdev = pdev;
r = platform_get_resource(pdev, IORESOURCE_MEM, HTVIC_MEM_BASE);
htvic->kernel_va = ioremap(r->start, resource_size(r));
/* Disable the VIC during the configuration */
htvic_iowrite(htvic, 0, htvic->kernel_va + VIC_REG_CTL);
/* Disable also all interrupt lines */
htvic_iowrite(htvic, ~0, htvic->kernel_va + VIC_REG_IDR);
/* Ack any pending interrupt */
htvic_ack_pending(htvic);
ret = htvic_irq_mapping(htvic);
if (ret)
goto out_map;
/* VIC configuration */
ctl = 0;
ctl |= VIC_CTL_ENABLE;
switch (pdev->id_entry->driver_data) {
case HTVIC_VER_SPEC:
ctl |= VIC_CTL_POL;
ctl |= VIC_CTL_EMU_EDGE;
ctl |= VIC_CTL_EMU_LEN_W(250);
break;
case HTVIC_VER_SVEC:
ctl |= VIC_CTL_POL;
ctl |= VIC_CTL_EMU_EDGE;
ctl |= VIC_CTL_EMU_LEN_W(1000);
break;
case HTVIC_VER_WRSWI:
break;
default:
goto out_ctl;
}
htvic_iowrite(htvic, ctl, htvic->kernel_va + VIC_REG_CTL);
return 0;
out_ctl:
out_map:
kfree(htvic);
out_memop:
return ret;
}
/**
* Copied from kernel 3.6 since it's not exported
* And modified a bit because other helpers are not exported
*/
void __htvic_irq_shutdown(struct irq_desc *desc)
{
/* irq_state_set_disabled(desc); */
desc->irq_data.state_use_accessors |= IRQD_IRQ_DISABLED;
desc->depth = 1;
if (desc->irq_data.chip->irq_shutdown)
desc->irq_data.chip->irq_shutdown(&desc->irq_data);
else if (desc->irq_data.chip->irq_disable)
desc->irq_data.chip->irq_disable(&desc->irq_data);
else
desc->irq_data.chip->irq_mask(&desc->irq_data);
/* irq_state_set_masked(desc); */
desc->irq_data.state_use_accessors |= IRQD_IRQ_MASKED;
}
/**
* Unload the htvic driver from the platform
*/
static int htvic_remove(struct platform_device *pdev)
{
struct htvic_device *htvic = dev_get_drvdata(&pdev->dev);
struct irq_desc *desc = irq_to_desc(platform_get_irq(htvic->pdev, 0));
int i;
/*
* Disable all interrupts to prevent spurious interrupt
* Disable also the HTVIC component for the very same reason,
* but this way on next instance even if we enable the VIC
* no interrupt will come unless configured.
*/
htvic_iowrite(htvic, ~0, htvic->kernel_va + VIC_REG_IDR);
htvic_iowrite(htvic, 0, htvic->kernel_va + VIC_REG_CTL);
/*
* Restore HTVIC vector table with it's original content
* Release Linux IRQ number
*/
for (i = 0; i < VIC_MAX_VECTORS; i++) {
htvic_iowrite(htvic, htvic->hwid[i], htvic->kernel_va + VIC_IVT_RAM_BASE + 4 * i);
irq_dispose_mapping(irq_find_mapping(htvic->domain, i));
}
/*
* Restore the platform IRQ status by undoing what
* irq_set_chained_handler() does in the kernel. I have to do it
* manually here because it was not thought that an IRQ controller
* may appear later in time.
*/
__htvic_irq_shutdown(desc); /* free_irq() */
irq_set_handler(desc->irq_data.irq, htvic->platform_handle_irq);
irq_set_handler_data(desc->irq_data.irq, htvic->platform_handler_data);
irq_modify_status(desc->irq_data.irq,
IRQ_NOPROBE | IRQ_NOREQUEST | IRQ_NOTHREAD,
0);
/*
* Clear the memory and restore flags when needed
*/
kfree(htvic->domain->name);
irq_domain_remove(htvic->domain);
kfree(htvic);
return 0;
}
/**
* List of supported platform
*/
static const struct platform_device_id htvic_id_table[] = {
{ /* SPEC compatible */
.name = "htvic-spec",
.driver_data = HTVIC_VER_SPEC,
}, { /* SVEC compatible */
.name = "htvic-svec",
.driver_data = HTVIC_VER_SVEC,
}, {
.name = "htvic-wr-swi",
.driver_data = HTVIC_VER_WRSWI,
},
{},
};
static struct platform_driver htvic_driver = {
.driver = {
.name = "htvic",
.owner = THIS_MODULE,
},
.id_table = htvic_id_table,
.probe = htvic_probe,
.remove = htvic_remove,
};
module_platform_driver(htvic_driver);
MODULE_AUTHOR("Federico Vaga <federico.vaga@cern.ch>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("CERN BECOHT VHDL Vector Interrupt Controller - HTVIC");
/*
* Copyright (c) 2016 CERN
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* 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.
*/
#ifndef __HTVIC_H__
#define __HTVIC_H__
#include "htvic_regs.h"
#define VIC_MAX_VECTORS 32
#define VIC_SDB_VENDOR 0xce42
#define VIC_SDB_DEVICE 0x0013
#define VIC_IRQ_BASE_NUMBER 0
enum htvic_versions {
HTVIC_VER_SPEC = 0,
HTVIC_VER_SVEC,
HTVIC_VER_WRSWI,
};
enum htvic_mem_resources {
HTVIC_MEM_BASE = 0,
};
struct htvic_data {
uint32_t is_edge; /* 1 edge, 0 level */
uint32_t is_raising; /* 1 raising, 0 falling */
uint32_t pulse_len;
};
struct htvic_device {
struct platform_device *pdev;
struct irq_domain *domain;
unsigned int hwid[VIC_MAX_VECTORS]; /**> original ID from FPGA */
struct htvic_data *data;
void __iomem *kernel_va;
irq_flow_handler_t platform_handle_irq;
void *platform_handler_data;
};
struct memory_ops {
u32 (*read)(void *addr);
void (*write)(u32 value, void *addr);
};
extern struct memory_ops memop;
static inline u32 htvic_ioread(struct htvic_device *htvic, void __iomem *addr)
{
return memop.read(addr);
}
static inline void htvic_iowrite(struct htvic_device *htvic,
u32 value, void __iomem *addr)
{
return memop.write(value, addr);
}
static inline u32 __htvic_ioread32(void *addr)
{
return ioread32(addr);
}
static inline u32 __htvic_ioread32be(void *addr)
{
return ioread32be(addr);
}
static inline void __htvic_iowrite32(u32 value,void __iomem *addr)
{
iowrite32(value, addr);
}
static inline void __htvic_iowrite32be(u32 value, void __iomem *addr)
{
iowrite32be(value, addr);
}
#endif
/*
Register definitions for slave core: Vectored Interrupt Controller (VIC)
* File : here.h
* Author : auto-generated by wbgen2 from wb_slave_vic.wb
* Created : Thu Jul 14 15:43:13 2016
* 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
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <inttypes.h>
#endif
#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_BASE 0x00000080 /* base address */
#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
...@@ -109,7 +109,7 @@ static void wrcs_timer_fn(unsigned long unused) ...@@ -109,7 +109,7 @@ static void wrcs_timer_fn(unsigned long unused)
return; return;
} }
clocksource_register(&wrcs_cs); clocksource_register_hz(&wrcs_cs, WRCS_FREQUENCY);
wrcs_is_registered = 1; wrcs_is_registered = 1;
/* And don't restart the timer */ /* And don't restart the timer */
} }
...@@ -122,8 +122,6 @@ static int wrcs_init(void) ...@@ -122,8 +122,6 @@ static int wrcs_init(void)
return -EIO; return -EIO;
} }
clocksource_calc_mult_shift(&wrcs_cs, WRCS_FREQUENCY, 1);
/* Fire the timer */ /* Fire the timer */
mod_timer(&wrcs_timer, jiffies + HZ); mod_timer(&wrcs_timer, jiffies + HZ);
return 0; return 0;
......
...@@ -20,10 +20,19 @@ ...@@ -20,10 +20,19 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irqdomain.h>
#include "wr-nic.h" #include "wr-nic.h"
#include "nic-mem.h" #include "nic-mem.h"
/**
* IRQ domain to be used. This is static here but in general it should be
* a module parameter or somehow configurable. For the time being we keep
* it hard-coded here.
*/
static const char *irqdomain_name = "htvic-wr-swi.0";
#if WR_IS_NODE /* Our platform_data is different in node vs switch */ #if WR_IS_NODE /* Our platform_data is different in node vs switch */
#include "../spec-nic.h" #include "../spec-nic.h"
static inline struct wrn_dev *wrn_from_pdev(struct platform_device *pdev) static inline struct wrn_dev *wrn_from_pdev(struct platform_device *pdev)
...@@ -42,7 +51,15 @@ static inline struct wrn_dev *wrn_from_pdev(struct platform_device *pdev) ...@@ -42,7 +51,15 @@ static inline struct wrn_dev *wrn_from_pdev(struct platform_device *pdev)
static int wrn_remove(struct platform_device *pdev) static int wrn_remove(struct platform_device *pdev)
{ {
struct wrn_dev *wrn = wrn_from_pdev(pdev); struct wrn_dev *wrn = wrn_from_pdev(pdev);
int i; int i, irq;
struct irq_domain *irqdomain;
irqdomain = irq_find_host((struct device_node *)irqdomain_name);
if (!irqdomain) {
dev_err(&pdev->dev, "The IRQ domain %s does not exist\n",
irqdomain_name);
return -EINVAL;
}
if (WR_IS_SWITCH) { if (WR_IS_SWITCH) {
spin_lock(&wrn->lock); spin_lock(&wrn->lock);
...@@ -71,8 +88,10 @@ static int wrn_remove(struct platform_device *pdev) ...@@ -71,8 +88,10 @@ static int wrn_remove(struct platform_device *pdev)
/* Unregister all interrupts that were registered */ /* Unregister all interrupts that were registered */
for (i = 0; wrn->irq_registered; i++) { for (i = 0; wrn->irq_registered; i++) {
static int irqs[] = WRN_IRQ_NUMBERS; static int irqs[] = WRN_IRQ_NUMBERS;
if (wrn->irq_registered & (1 << i)) if (wrn->irq_registered & (1 << i)) {
free_irq(irqs[i], wrn); irq = irq_find_mapping(irqdomain, irqs[i]);
free_irq(irq, wrn);
}
wrn->irq_registered &= ~(1 << i); wrn->irq_registered &= ~(1 << i);
} }
return 0; return 0;
...@@ -113,12 +132,20 @@ static int wrn_probe(struct platform_device *pdev) ...@@ -113,12 +132,20 @@ static int wrn_probe(struct platform_device *pdev)
struct net_device *netdev; struct net_device *netdev;
struct wrn_ep *ep; struct wrn_ep *ep;
struct wrn_dev *wrn = wrn_from_pdev(pdev); struct wrn_dev *wrn = wrn_from_pdev(pdev);
int i, err = 0; int i, err = 0, irq;
/* Lazily: irqs are not in the resource list */ /* Lazily: irqs are not in the resource list */
static int irqs[] = WRN_IRQ_NUMBERS; static int irqs[] = WRN_IRQ_NUMBERS;
static char *irq_names[] = WRN_IRQ_NAMES; static char *irq_names[] = WRN_IRQ_NAMES;
static irq_handler_t irq_handlers[] = WRN_IRQ_HANDLERS; static irq_handler_t irq_handlers[] = WRN_IRQ_HANDLERS;
struct irq_domain *irqdomain;
irqdomain = irq_find_host((struct device_node *)irqdomain_name);
if (!irqdomain) {
dev_err(&pdev->dev, "The IRQ domain %s does not exist\n",
irqdomain_name);
return -EINVAL;
}
/* No need to lock_irq: we only protect count and continue unlocked */ /* No need to lock_irq: we only protect count and continue unlocked */
if (WR_IS_SWITCH) { if (WR_IS_SWITCH) {
...@@ -148,7 +175,8 @@ static int wrn_probe(struct platform_device *pdev) ...@@ -148,7 +175,8 @@ static int wrn_probe(struct platform_device *pdev)
if (WR_IS_SWITCH) { if (WR_IS_SWITCH) {
/* Register the interrupt handlers (not shared) */ /* Register the interrupt handlers (not shared) */
for (i = 0; i < ARRAY_SIZE(irq_names); i++) { for (i = 0; i < ARRAY_SIZE(irq_names); i++) {
err = request_irq(irqs[i], irq_handlers[i], irq = irq_find_mapping(irqdomain, irqs[i]);
err = request_irq(irq, irq_handlers[i],
IRQF_TRIGGER_LOW, irq_names[i], wrn); IRQF_TRIGGER_LOW, irq_names[i], wrn);
if (err) if (err)
goto out; goto out;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#define NSEC_PER_TICK (NSEC_PER_SEC / REFCLK_FREQ) #define NSEC_PER_TICK (NSEC_PER_SEC / REFCLK_FREQ)
/* The interrupt is one of those managed by our WRVIC device */ /* The interrupt is one of those managed by our WRVIC device */
#define WRN_IRQ_BASE 192 #define WRN_IRQ_BASE 0
#define WRN_IRQ_NIC (WRN_IRQ_BASE + 0) #define WRN_IRQ_NIC (WRN_IRQ_BASE + 0)
#define WRN_IRQ_TSTAMP (WRN_IRQ_BASE + 1) #define WRN_IRQ_TSTAMP (WRN_IRQ_BASE + 1)
//#define WRN_IRQ_PPSG (WRN_IRQ_BASE + ) //#define WRN_IRQ_PPSG (WRN_IRQ_BASE + )
......
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