Commit d8f1dc9f authored by Adam Wujek's avatar Adam Wujek 💬

Merge commit 'adam-update_kernel_3.16.37'

Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parents 4744f847 ac693f95
......@@ -15,8 +15,8 @@ barebox-2014.04.0.tar.bz2 e1f089fc24cc7f24478e663c0e3b91d9 \
http://www.barebox.org/download/barebox-2014.04.0.tar.bz2
# kernel
linux-2.6.39.tar.bz2 1aab7a741abe08d42e8eccf20de61e05 \
http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.tar.bz2
linux-3.16.37.tar.xz fc4e8c469cf852a128e160f2910c1f21 \
https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.37.tar.xz
# our gateware binaries
wrs-gw-v4.2-20150826.tar.gz 807117326f6d5b1b53ebc95ca093fc44 \
......
#!/bin/bash
KERVER=2.6.39
# check variables, like all scripts herein do
WRS_SCRIPT_NAME=$(basename $0)
if [ -z "$WRS_BASE_DIR" ]; then
......@@ -13,8 +11,9 @@ fi
wrs_check_vars WRS_OUTPUT_DIR WRS_DOWNLOAD_DIR CROSS_COMPILE
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
mkdir -p $WRS_OUTPUT_DIR/build || wrs_die "mkdir build"
......@@ -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
cd $WRS_OUTPUT_DIR/build
dirname="linux-${KERVER}"
dirname="linux-${KVER}"
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
cd $dirname
......@@ -34,7 +34,7 @@ done
# 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 [ -f $WRS_KERNEL_CONFIG ]; then
CFG=$WRS_KERNEL_CONFIG
......@@ -50,7 +50,7 @@ make oldconfig || wrs_die "kernel config"
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
......@@ -16,7 +16,7 @@ mkdir -p $WRS_OUTPUT_DIR/build || wrs_die "mkdir build"
mkdir -p $WRS_OUTPUT_DIR/images || wrs_die "mkdir images"
# 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"
cd $WRS_BASE_DIR/../kernel
make $WRS_MAKE_J || wrs_die "white rabbit kernel modules"
......
......@@ -21,7 +21,7 @@ make clean
# we need LINUX and CROSS_COMPILE. The latter is there for sure
if [ "x$LINUX" == "x" ]; then
export LINUX="$WRS_OUTPUT_DIR/build/linux-2.6.39"
export LINUX="$WRS_OUTPUT_DIR/build/linux-$KVER"
fi
......
......@@ -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.
# 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
make clean || wrs_die "Error cleaning user space"
......
......@@ -37,6 +37,7 @@ export PATH="$PATH:/usr/sbin"
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 fakeroot makeinfo"
WRS_TOOLS="$WRS_TOOLS xz"
wrs_check_tools $WRS_TOOLS
......@@ -48,6 +49,9 @@ fi
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 BRVER="2016.02"
......
......@@ -3,8 +3,6 @@
# Buildroot 2016.02 Configuration
#
BR2_HAVE_DOT_CONFIG=y
BR2_HOST_GCC_AT_LEAST_4_7=y
BR2_HOST_GCC_AT_LEAST_4_8=y
#
# Target options
......@@ -153,9 +151,36 @@ BR2_TOOLCHAIN_BUILDROOT_VENDOR="buildroot"
# BR2_KERNEL_HEADERS_3_18 is not set
# BR2_KERNEL_HEADERS_4_1 is not set
# BR2_KERNEL_HEADERS_4_3 is not set
BR2_KERNEL_HEADERS_4_4=y
# BR2_KERNEL_HEADERS_VERSION is not set
BR2_DEFAULT_KERNEL_HEADERS="4.4.3"
# BR2_KERNEL_HEADERS_4_4 is not set
BR2_KERNEL_HEADERS_VERSION=y
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_GLIBC is not set
# BR2_TOOLCHAIN_BUILDROOT_MUSL is not set
......@@ -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_15=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_16=y
BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_17=y
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_HEADERS_AT_LEAST="3.16"
BR2_TOOLCHAIN_GCC_AT_LEAST_4_3=y
BR2_TOOLCHAIN_GCC_AT_LEAST_4_4=y
BR2_TOOLCHAIN_GCC_AT_LEAST_4_5=y
......
......@@ -727,7 +727,7 @@ Specification
| **I/O** | 32bit Async Bridge with FPGA\ |
| | 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:
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: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:27: Retrieved buildroot-2016.02.tar.bz2 from upstream
@end smallexample
......@@ -736,31 +736,26 @@ in two lines with a local variable to fit the page with in documentation):
@node 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
vanilla kernel is downloaded, then
local patches are applied (they come from a @i{git}
repository, but they are currently applied with a simple @i{patch}
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:
@example
0001-wrs3-changes-to-g45ek.patch
0002-initramfs-stop-after-one-cpio-archive.patch
0003-at91-NR_IRQS-increase-by-64-to-fit-custom-muxes.patch
0004-irq-export-symbols-for-external-irq-controller.patch
0005-Change-Vbus-pin.patch
0006-arm-fiq-allow-modules-to-exploit-the-fiq-mechanism.patch
0007-mtd-nand-sam9g45-can-hwecc-like-9263.patch
0008-wrs3-use-correct-nand-partitioning.patch
0009-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
0001-initramfs-stop-after-one-cpio-archive.patch
0002-arm-fiq-allow-modules-to-exploit-the-fiq-mechanism.patch
0003-mtd_dataflash-Read-EDI-bytes-in-JEDEC-to-support-AT4.patch
0004-wr-switch-sam9m10g45ek-enable-FPGA-access-from-EBI1-.patch
0005-wr-switch-sam9m10g45ek-change-USB-vbus_pin-from-PB19.patch
0006-wr-switch-sam9m10g45ek-store-device-partitioning.patch
0007-wr-switch-sam9m10g45ek-more-relaxed-nand-timings.patch
0008-wr-switch-sam9m10g45ek-provide-bootcount-using-scrat.patch
0009-wr-switch-at91-udc-force-full-speed.patch
@end example
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:
@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_rtu.ko}: the routing-table interface between the
switching core and the associated user-space daemon.
......@@ -812,6 +807,8 @@ This is considered acceptable, because system time is only
used for logging.
@item @i{wrs_devices.ko}: a dummy module that register our platform devices.
@end itemize
@c --------------------------------------------------------------------------
......
......@@ -141,13 +141,6 @@ waiting for the boot loader to be sent to RAM from USB.
@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,
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
......
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
......
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
This diff is collapsed.
/*
* 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)
return;
}
clocksource_register(&wrcs_cs);
clocksource_register_hz(&wrcs_cs, WRCS_FREQUENCY);
wrcs_is_registered = 1;
/* And don't restart the timer */
}
......@@ -122,8 +122,6 @@ static int wrcs_init(void)
return -EIO;
}
clocksource_calc_mult_shift(&wrcs_cs, WRCS_FREQUENCY, 1);
/* Fire the timer */
mod_timer(&wrcs_timer, jiffies + HZ);
return 0;
......
......@@ -20,10 +20,19 @@
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/irqdomain.h>
#include "wr-nic.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 */
#include "../spec-nic.h"
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)
{
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) {
spin_lock(&wrn->lock);
......@@ -71,8 +88,10 @@ static int wrn_remove(struct platform_device *pdev)
/* Unregister all interrupts that were registered */
for (i = 0; wrn->irq_registered; i++) {
static int irqs[] = WRN_IRQ_NUMBERS;
if (wrn->irq_registered & (1 << i))
free_irq(irqs[i], wrn);
if (wrn->irq_registered & (1 << i)) {
irq = irq_find_mapping(irqdomain, irqs[i]);
free_irq(irq, wrn);
}
wrn->irq_registered &= ~(1 << i);
}
return 0;
......@@ -113,12 +132,20 @@ static int wrn_probe(struct platform_device *pdev)
struct net_device *netdev;
struct wrn_ep *ep;
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 */
static int irqs[] = WRN_IRQ_NUMBERS;
static char *irq_names[] = WRN_IRQ_NAMES;
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 */
if (WR_IS_SWITCH) {
......@@ -148,7 +175,8 @@ static int wrn_probe(struct platform_device *pdev)
if (WR_IS_SWITCH) {
/* Register the interrupt handlers (not shared) */
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);
if (err)
goto out;
......
......@@ -20,7 +20,7 @@
#define NSEC_PER_TICK (NSEC_PER_SEC / REFCLK_FREQ)
/* 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_TSTAMP (WRN_IRQ_BASE + 1)
//#define WRN_IRQ_PPSG (WRN_IRQ_BASE + )
......
......@@ -28,6 +28,13 @@
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <linux/netdevice.h>
#include <linux/irqdomain.h>
/*
* Ugly trick to be able to use headers that have been moved out
* from mach/ directory
*/
#include <mach/../../at91_aic.h>
#include "../wbgen-regs/pstats-regs.h"
#include "wr_pstats.h"
......@@ -35,6 +42,13 @@
#define pstats_readl(device, r) __raw_readl(&device.regs->r)
#define pstats_writel(val, device, r) __raw_writel(val, &device.regs->r)
/**
* 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";
static int pstats_nports = PSTATS_DEFAULT_NPORTS;
static uint32_t portmsk;
static unsigned int firmware_version; /* FPGA firmware version */
......@@ -436,8 +450,16 @@ static struct ctl_table_header *pstats_header;
static int __init pstats_init(void)
{
int i, err = 0;
int i, err = 0, irq;
unsigned int data;
struct irq_domain *irqdomain;
irqdomain = irq_find_host((struct device_node *)irqdomain_name);
if (!irqdomain) {
pr_err("pstat: The IRQ domain %s does not exist\n",
irqdomain_name);
return -EINVAL;
}
if (pstats_nports > PSTATS_MAX_NPORTS) {
printk(KERN_ERR "%s: Too many ports for pstats %u,"
......@@ -525,7 +547,8 @@ static int __init pstats_init(void)
/*request pstats IRQ*/
pstats_irq_disable(PSTATS_ALL_MSK);
err = request_irq(WRVIC_BASE_IRQ+WR_PSTATS_IRQ, pstats_irq_handler,
irq = irq_find_mapping(irqdomain, WR_PSTATS_IRQ);
err = request_irq(irq, pstats_irq_handler,
IRQF_SHARED, "wr_pstats", &pstats_dev);
if (err) {
printk(KERN_ERR "%s: cannot request interrupt\n",
......@@ -553,8 +576,19 @@ err_exit:
static void __exit pstats_exit(void)
{
int irq;
struct irq_domain *irqdomain;
pstats_irq_disable(PSTATS_ALL_MSK);
free_irq(WRVIC_BASE_IRQ+WR_PSTATS_IRQ, &pstats_dev);
irqdomain = irq_find_host((struct device_node *)irqdomain_name);
if (!irqdomain) {
pr_err("pstat: The IRQ domain %s does not exist\n",
irqdomain_name);
} else {
irq = irq_find_mapping(irqdomain, WR_PSTATS_IRQ);
free_irq(irq, &pstats_dev);
}
wr_nic_pstats_callback = NULL;
......
......@@ -39,6 +39,13 @@
#include <linux/wait.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/irqdomain.h>
/*
* Ugly trick to be able to use headers that have been moved out
* from mach/ directory
*/
#include <mach/../../at91_aic.h>
#include "../wbgen-regs/rtu-regs.h"
#include "wr_rtu.h"
......@@ -64,6 +71,13 @@ static struct RTU_WB __iomem *regs;
#define wr_rtu_readl(r) __raw_readl(&regs->r);
#define wr_rtu_writel(val, r) __raw_writel(val, &regs->r);
/**
* 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";
static void wr_rtu_enable_irq(void)
{
wr_rtu_writel(RTU_EIC_IER_NEMPTY, EIC_IER);
......@@ -153,6 +167,15 @@ static struct miscdevice wr_rtu_misc = {
static int __init wr_rtu_init(void)
{
int err;
int irq;
struct irq_domain *irqdomain;
irqdomain = irq_find_host((struct device_node *)irqdomain_name);
if (!irqdomain) {
pr_err("pstat: The IRQ domain %s does not exist\n",
irqdomain_name);
return -EINVAL;
}
// register misc device
err = misc_register(&wr_rtu_misc);
......@@ -176,9 +199,8 @@ static int __init wr_rtu_init(void)
// register interrupt handler
wr_rtu_disable_irq();
err = request_irq(
WRVIC_BASE_IRQ + WR_RTU_IRQ,
wr_rtu_interrupt,
irq = irq_find_mapping(irqdomain, WR_RTU_IRQ);
err = request_irq(irq, wr_rtu_interrupt,
IRQF_SHARED,
"wr-rtu",
(void*)regs
......@@ -203,10 +225,20 @@ static int __init wr_rtu_init(void)
static void __exit wr_rtu_exit(void)
{
int irq;
struct irq_domain *irqdomain;
// disable RTU interrupts
wr_rtu_disable_irq();
// Unregister IRQ handler
free_irq(WRVIC_BASE_IRQ + WR_RTU_IRQ, (void*)regs);
irqdomain = irq_find_host((struct device_node *)irqdomain_name);