Commit 7179590e authored by Federico Vaga's avatar Federico Vaga

Merge branch 'release/v1.4.9'

parents 005e1bf9 18cdb4b4
......@@ -2,6 +2,17 @@
Changelog
=========
[1.4.9] 2020-03-10
==================
Added
-----
- [sw] support for kernel version more recent than 3.10 (RedHat)
Fixed
-----
- [sw] reduce allocation on stack
[1.4.8] 2020-02-12
==================
Fixed
......
Subproject commit be61ce73a43d0231e8edc2f12133b918e3d1c9e4
Subproject commit 56d855fc3d97c43e6f21ad669ecfda90971f0982
......@@ -1027,8 +1027,8 @@ begin -- architecture top
g_RST_ACT_LOW => 0, -- active high reset (simpler internal logic)
g_BANK_PORT_SELECT => get_ddr3_bank_port_select,
g_MEMCLK_PERIOD => 3000,
g_SIMULATION => boolean'image(g_SIMULATION),
g_CALIB_SOFT_IP => "TRUE",
g_SIMULATION => to_upper(boolean'image(g_SIMULATION)),
g_CALIB_SOFT_IP => to_upper(boolean'image(not g_SIMULATION)),
g_P0_MASK_SIZE => g_DDR_DATA_SIZE / 8,
g_P0_DATA_PORT_SIZE => g_DDR_DATA_SIZE,
g_P0_BYTE_ADDR_WIDTH => 30,
......
......@@ -84,7 +84,6 @@ NET "ddr_udqs_n_b" IN_TERM = NONE;
NET "inst_spec_base/*cmp_ddr_ctrl_bank?/*/c?_pll_lock" TIG;
NET "inst_spec_base/*cmp_ddr_ctrl_bank?/*/memc?_mcb_raw_wrapper_inst/selfrefresh_mcb_mode" TIG;
NET "inst_spec_base/*cmp_ddr_ctrl_bank?/*/mcb_soft_calibration_inst/DONE_SOFTANDHARD_CAL" TIG;
#NET "inst_base/*cmp_ddr_ctrl_bank?/*/mcb_soft_calibration_inst/SELFREFRESH_MCB_REQ" TIG;
# Ignore async reset to DDR controller
NET "inst_spec_base/ddr_rst" TPTHRU = ddr_rst;
......
......@@ -19,7 +19,7 @@ ccflags-y += -I$(SPI_ABS)/include
# priority to I2C, FMC headers from our sources
LINUXINCLUDE := -I$(FMC_ABS)/include -I$(FMC_ABS)/include/linux -I$(I2C_ABS)/include -I$(I2C_ABS)/include/linux $(LINUXINCLUDE)
ifeq ($(CONFIG_FPGA_MGR_BACKPORT), y)
ifneq ($(FPGA_MGR_ABS), "")
FPGA_MGR_BACKPORT_INCLUDE := -I$(FPGA_MGR_ABS)/include
FPGA_MGR_BACKPORT_INCLUDE += -I$(FPGA_MGR_ABS)/include/linux
LINUXINCLUDE := $(FPGA_MGR_BACKPORT_INCLUDE) $(LINUXINCLUDE)
......
......@@ -23,7 +23,7 @@ FMC_VERSION ?= $(shell basename $(shell ls -d $(DKMSTREE)/fmc/* | grep -E "\/[0-
I2C_VERSION ?= $(shell basename $(shell ls -d $(DKMSTREE)/i2c-ocores/* | grep -E "\/[0-9]+\.[0-9]+\.[0-9]+" | sort -V | tail -n 1))
SPI_VERSION ?= $(shell basename $(shell ls -d $(DKMSTREE)/spi-ocores/* | grep -E "\/[0-9]+\.[0-9]+\.[0-9]+" | sort -V | tail -n 1))
CONFIG_FPGA_MGR_BACKPORT_PATH ?= $(DKMSTREE)/fpga_mgr/$(FPGA_MGR_VERSION)/source
FPGA_MGR ?= $(DKMSTREE)/fpga_mgr/$(FPGA_MGR_VERSION)/source
FMC ?= $(DKMSTREE)/fmc/$(FMC_VERSION)/source
I2C ?= $(DKMSTREE)/i2c-ocores/$(I2C_VERSION)/source
SPI ?= $(DKMSTREE)/spi-ocores/$(SPI_VERSION)/source
......
......@@ -4,6 +4,7 @@
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/fpga/fpga-mgr.h>
#include <linux/delay.h>
......
......@@ -19,6 +19,7 @@
struct gn412x_gpio_dev {
void __iomem *mem;
struct gpio_chip gpiochip;
struct irq_chip irqchip;
struct completion compl;
struct gn412x_platform_data *pdata;
......@@ -77,12 +78,18 @@ static int gn412x_dbg_init(struct gn412x_gpio_dev *gn412x)
struct dentry *dir, *file;
int err;
dir = debugfs_create_dir(dev_name(gn412x->gpiochip.dev), NULL);
#if KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE
struct device *dev = gn412x->gpiochip.dev;
#else
struct device *dev = gn412x->gpiochip.parent;
#endif
dir = debugfs_create_dir(dev_name(dev), NULL);
if (IS_ERR_OR_NULL(dir)) {
err = PTR_ERR(dir);
dev_warn(gn412x->gpiochip.dev,
dev_warn(dev,
"Cannot create debugfs directory \"%s\" (%d)\n",
dev_name(gn412x->gpiochip.dev), err);
dev_name(dev), err);
goto err_dir;
}
......@@ -93,7 +100,7 @@ static int gn412x_dbg_init(struct gn412x_gpio_dev *gn412x)
dir, &gn412x->dbg_reg32);
if (IS_ERR_OR_NULL(file)) {
err = PTR_ERR(file);
dev_warn(gn412x->gpiochip.dev,
dev_warn(dev,
"Cannot create debugfs file \"%s\" (%d)\n",
GN412X_DBG_REG_NAME, err);
goto err_reg32;
......@@ -183,9 +190,15 @@ static int gn412x_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
int val;
#if KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE
struct device *dev = chip->dev;
#else
struct device *dev = chip->parent;
#endif
val = gn412x_gpio_reg_read(chip, GNGPIO_BYPASS_MODE, offset);
if (val) {
dev_err(chip->dev, "%s GPIO %d is in BYPASS mode\n",
dev_err(dev, "%s GPIO %d is in BYPASS mode\n",
chip->label, offset);
return -EBUSY;
}
......@@ -264,13 +277,19 @@ static int gn412x_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
#if KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE
struct device *dev = gc->dev;
#else
struct device *dev = gc->parent;
#endif
/*
* detect errors:
* - level and edge together cannot work
*/
if ((flow_type & IRQ_TYPE_LEVEL_MASK) &&
(flow_type & IRQ_TYPE_EDGE_BOTH)) {
dev_err(gc->dev,
dev_err(dev,
"Impossible to set GPIO IRQ %ld to both LEVEL and EDGE (0x%x)\n",
d->hwirq, flow_type);
return -EINVAL;
......@@ -342,16 +361,6 @@ static void gn412x_gpio_irq_ack(struct irq_data *d)
*/
}
static struct irq_chip gn412x_gpio_irq_chip = {
.name = "GN412X-GPIO",
.irq_startup = gn412x_gpio_irq_startup,
.irq_disable = gn412x_gpio_irq_disable,
.irq_mask = gn412x_gpio_irq_mask,
.irq_unmask = gn412x_gpio_irq_unmask,
.irq_set_type = gn412x_gpio_irq_set_type,
.irq_ack = gn412x_gpio_irq_ack,
};
/**
* This will run in hard-IRQ context since we do not have much to do
*/
......@@ -381,6 +390,12 @@ static irqreturn_t gn412x_gpio_irq_handler_t(int irq, void *arg)
irqreturn_t ret = IRQ_NONE;
int i;
#if KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE
struct device *dev = gc->dev;
#else
struct device *dev = gc->parent;
#endif
gpio_int_status = gn412x_ioread32(gn412x, GNGPIO_INT_STATUS);
gpio_int_status &= ~gn412x_ioread32(gn412x, GNGPIO_INT_MASK);
if (!gpio_int_status)
......@@ -388,8 +403,12 @@ static irqreturn_t gn412x_gpio_irq_handler_t(int irq, void *arg)
loop = gpio_int_status;
for_each_set_bit(i, &loop, GN4124_GPIO_MAX) {
#if KERNEL_VERSION(4, 14, 0) > LINUX_VERSION_CODE
cascade_irq = irq_find_mapping(gc->irqdomain, i);
dev_dbg(gc->dev, "GPIO: %d, IRQ: %d\n", i, cascade_irq);
#else
cascade_irq = irq_find_mapping(gc->irq.domain, i);
#endif
dev_dbg(dev, "GPIO: %d, IRQ: %d\n", i, cascade_irq);
/*
* Ok, now we execute the handler for the given IRQ. Please
* note that this is not the action requested by the device
......@@ -457,7 +476,11 @@ static void gn412x_gpio_irq_set_nested_thread(struct gn412x_gpio_dev *gn412x,
{
int irq;
#if KERNEL_VERSION(4, 14, 0) > LINUX_VERSION_CODE
irq = irq_find_mapping(gn412x->gpiochip.irqdomain, gpio);
#else
irq = irq_find_mapping(gn412x->gpiochip.irq.domain, gpio);
#endif
irq_set_nested_thread(irq, nest);
}
......@@ -500,7 +523,22 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
}
gn412x_iowrite32(gn412x, 0, GNGPIO_BYPASS_MODE);
gn412x_gpio_int_cfg_disable(gn412x);
gn412x_iowrite32(gn412x, 0xFFFF, GNGPIO_INT_MASK_SET);
gn412x->irqchip.name = "GN412X-GPIO",
gn412x->irqchip.irq_startup = gn412x_gpio_irq_startup,
gn412x->irqchip.irq_disable = gn412x_gpio_irq_disable,
gn412x->irqchip.irq_mask = gn412x_gpio_irq_mask,
gn412x->irqchip.irq_unmask = gn412x_gpio_irq_unmask,
gn412x->irqchip.irq_set_type = gn412x_gpio_irq_set_type,
gn412x->irqchip.irq_ack = gn412x_gpio_irq_ack,
#if KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE
gn412x->gpiochip.dev = &pdev->dev;
#else
gn412x->gpiochip.parent = &pdev->dev;
#endif
gn412x->gpiochip.label = "gn412x-gpio";
gn412x->gpiochip.owner = THIS_MODULE;
gn412x->gpiochip.request = gn412x_gpio_request;
......@@ -513,22 +551,29 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
gn412x->gpiochip.base = -1;
gn412x->gpiochip.ngpio = GN4124_GPIO_MAX;
gn412x->gpiochip.can_sleep = 0;
#if KERNEL_VERSION(4, 15, 0) <= LINUX_VERSION_CODE
gn412x->gpiochip.irq.chip = &gn412x->irqchip;
gn412x->gpiochip.irq.first = 0;
gn412x->gpiochip.irq.handler = handle_simple_irq;
gn412x->gpiochip.irq.default_type = IRQ_TYPE_NONE;
gn412x->gpiochip.irq.threaded = true;
#endif
err = gpiochip_add(&gn412x->gpiochip);
if (err)
goto err_add;
gn412x_gpio_int_cfg_disable(gn412x);
gn412x_iowrite32(gn412x, 0xFFFF, GNGPIO_INT_MASK_SET);
#if KERNEL_VERSION(4, 15, 0) > LINUX_VERSION_CODE
err = gpiochip_irqchip_add(&gn412x->gpiochip,
&gn412x_gpio_irq_chip,
&gn412x->irqchip,
0, handle_simple_irq,
IRQ_TYPE_NONE);
if (err)
goto err_add_irq;
#endif
gn412x_gpio_irq_set_nested_thread_all(gn412x, true);
#if KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE
err = request_threaded_irq(platform_get_irq(pdev, 0),
gn412x_gpio_irq_handler_h,
gn412x_gpio_irq_handler_t,
......@@ -537,6 +582,16 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
gn412x);
if (err) {
dev_err(gn412x->gpiochip.dev, "Can't request IRQ %d (%d)\n",
#else
err = request_threaded_irq(platform_get_irq(pdev, 0),
gn412x_gpio_irq_handler_h,
gn412x_gpio_irq_handler_t,
IRQF_SHARED,
dev_name(gn412x->gpiochip.parent),
gn412x);
if (err) {
dev_err(gn412x->gpiochip.parent, "Can't request IRQ %d (%d)\n",
#endif
platform_get_irq(pdev, 0), err);
goto err_req;
}
......@@ -549,8 +604,10 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
err_req:
gn412x_gpio_irq_set_nested_thread_all(gn412x, false);
#if KERNEL_VERSION(4, 15, 0) > LINUX_VERSION_CODE
err_add_irq:
gpiochip_remove(&gn412x->gpiochip);
#endif
err_add:
iounmap(gn412x->mem);
err_map:
......
......@@ -200,6 +200,21 @@ static struct resource spec_fpga_vic_res[] = {
},
};
struct irq_domain *spec_fpga_irq_find_host(struct device *dev)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
struct irq_fwspec fwspec = {
.fwnode = dev->fwnode,
.param_count = 2,
.param[0] = ((unsigned long)dev >> 32) & 0xffffffff,
.param[1] = ((unsigned long)dev) & 0xffffffff,
};
return irq_find_matching_fwspec(&fwspec, DOMAIN_BUS_ANY);
#else
return (irq_find_host((void *)dev));
#endif
}
/* Vector Interrupt Controller */
static int spec_fpga_vic_init(struct spec_fpga *spec_fpga)
{
......@@ -274,7 +289,7 @@ static int spec_fpga_dma_init(struct spec_fpga *spec_fpga)
ddr_status);
return -ENODEV;
}
vic_domain = irq_find_host((void *)&spec_fpga->vic_pdev->dev);
vic_domain = spec_fpga_irq_find_host(&spec_fpga->vic_pdev->dev);
if (!vic_domain) {
dev_err(&spec_fpga->dev,
"Failed to load DMA engine: can't find VIC\n");
......@@ -429,7 +444,7 @@ static int spec_fpga_devices_init(struct spec_fpga *spec_fpga)
n_mfd++;
}
vic_domain = irq_find_host((void *)&spec_fpga->vic_pdev->dev);
vic_domain = spec_fpga_irq_find_host(&spec_fpga->vic_pdev->dev);
if (!vic_domain) {
/* Remove IRQ resource from all devices */
fpga_mfd_devs[0].num_resources = 1; /* FMC I2C */
......@@ -718,29 +733,32 @@ static int spec_fpga_app_init(struct spec_fpga *spec_fpga)
#define SPEC_FPGA_APP_RES_N (32 - SPEC_FPGA_APP_IRQ_BASE + 1)
struct pci_dev *pcidev = to_pci_dev(spec_fpga->dev.parent);
unsigned int res_n = SPEC_FPGA_APP_RES_N;
struct resource res[SPEC_FPGA_APP_RES_N] = {
[0] = {
.name = "app-mem",
.flags = IORESOURCE_MEM,
},
};
struct resource *res;
struct platform_device *pdev;
struct irq_domain *vic_domain;
char app_name[SPEC_FPGA_APP_NAME_MAX];
unsigned long app_offset;
int err;
int err = 0;
res = kcalloc(SPEC_FPGA_APP_RES_N, sizeof(*res), GFP_KERNEL);
if (!res)
return -ENOMEM;
res[0].name = "app-mem";
res[0].flags = IORESOURCE_MEM;
app_offset = spec_fpga_csr_app_offset(spec_fpga);
if (!app_offset) {
dev_warn(&spec_fpga->dev, "Application not found\n");
return 0;
err = 0;
goto err_free;
}
res[0].start = pci_resource_start(pcidev, 0) + app_offset;
res[0].end = pci_resource_end(pcidev, 0);
if (spec_fpga->vic_pdev)
vic_domain = irq_find_host((void *)&spec_fpga->vic_pdev->dev);
vic_domain = spec_fpga_irq_find_host(&spec_fpga->vic_pdev->dev);
else
vic_domain = NULL;
......@@ -762,18 +780,21 @@ static int spec_fpga_app_init(struct spec_fpga *spec_fpga)
err = spec_fpga_app_id_build(spec_fpga, app_offset,
app_name, SPEC_FPGA_APP_NAME_MAX);
if (err)
return err;
goto err_free;
spec_fpga_app_restart(spec_fpga);
pdev = platform_device_register_resndata(&spec_fpga->dev,
app_name, PLATFORM_DEVID_AUTO,
res, res_n,
NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
err = IS_ERR(pdev);
if (err)
goto err_free;
spec_fpga->app_pdev = pdev;
return 0;
err_free:
kfree(res);
return err;
}
static void spec_fpga_app_exit(struct spec_fpga *spec_fpga)
......
......@@ -15,6 +15,11 @@
#include <linux/moduleparam.h>
#include <linux/mfd/core.h>
#include <linux/gpio/consumer.h>
#include <linux/version.h>
#include <linux/uaccess.h>
#if KERNEL_VERSION(3, 17, 0) <= LINUX_VERSION_CODE
#include <linux/gpio/machine.h>
#endif
#include "platform_data/gn412x-gpio.h"
#include "spec.h"
......
......@@ -20,6 +20,8 @@
#include <linux/delay.h>
#include <linux/debugfs.h>
#include <linux/dma-mapping.h>
#include <linux/version.h>
#include <linux/mod_devicetable.h>
/**
* dma_cookie_complete - complete a descriptor
......@@ -605,9 +607,11 @@ static int gn412x_dma_terminate_all(struct dma_chan *chan)
return 0;
}
#if KERNEL_VERSION(4, 0, 0) > LINUX_VERSION_CODE
static int gn412x_dma_device_control(struct dma_chan *chan,
enum dma_ctrl_cmd cmd,
unsigned long arg)
enum dma_ctrl_cmd cmd,
unsigned long arg)
{
switch (cmd) {
case DMA_SLAVE_CONFIG:
......@@ -624,7 +628,7 @@ static int gn412x_dma_device_control(struct dma_chan *chan,
}
return -ENODEV;
}
#endif
static irqreturn_t gn412x_dma_irq_handler(int irq, void *arg)
{
......@@ -742,7 +746,19 @@ static int gn412x_dma_engine_init(struct gn412x_dma_device *gn412x_dma,
dma->device_alloc_chan_resources = gn412x_dma_alloc_chan_resources;
dma->device_free_chan_resources = gn412x_dma_free_chan_resources;
dma->device_prep_slave_sg = gn412x_dma_prep_slave_sg;
#if KERNEL_VERSION(4, 0, 0) > LINUX_VERSION_CODE
dma->device_control = gn412x_dma_device_control;
#else
/* TODO: adjust/verify addr widths, direction and granularity. */
dma->src_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma->dst_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma->directions =
1 << DMA_DEV_TO_MEM |
1 << DMA_MEM_TO_DEV;
dma->residue_granularity = 0;
dma->device_config = gn412x_dma_slave_config;
dma->device_terminate_all = gn412x_dma_terminate_all;
#endif
dma->device_tx_status = gn412x_dma_tx_status;
dma->device_issue_pending = gn412x_dma_issue_pending;
......
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