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

Merge branch 'release/v1.4.9'

parents 005e1bf9 18cdb4b4
...@@ -2,6 +2,17 @@ ...@@ -2,6 +2,17 @@
Changelog 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 [1.4.8] 2020-02-12
================== ==================
Fixed Fixed
......
Subproject commit be61ce73a43d0231e8edc2f12133b918e3d1c9e4 Subproject commit 56d855fc3d97c43e6f21ad669ecfda90971f0982
...@@ -1027,8 +1027,8 @@ begin -- architecture top ...@@ -1027,8 +1027,8 @@ begin -- architecture top
g_RST_ACT_LOW => 0, -- active high reset (simpler internal logic) g_RST_ACT_LOW => 0, -- active high reset (simpler internal logic)
g_BANK_PORT_SELECT => get_ddr3_bank_port_select, g_BANK_PORT_SELECT => get_ddr3_bank_port_select,
g_MEMCLK_PERIOD => 3000, g_MEMCLK_PERIOD => 3000,
g_SIMULATION => boolean'image(g_SIMULATION), g_SIMULATION => to_upper(boolean'image(g_SIMULATION)),
g_CALIB_SOFT_IP => "TRUE", g_CALIB_SOFT_IP => to_upper(boolean'image(not g_SIMULATION)),
g_P0_MASK_SIZE => g_DDR_DATA_SIZE / 8, g_P0_MASK_SIZE => g_DDR_DATA_SIZE / 8,
g_P0_DATA_PORT_SIZE => g_DDR_DATA_SIZE, g_P0_DATA_PORT_SIZE => g_DDR_DATA_SIZE,
g_P0_BYTE_ADDR_WIDTH => 30, g_P0_BYTE_ADDR_WIDTH => 30,
......
...@@ -84,7 +84,6 @@ NET "ddr_udqs_n_b" IN_TERM = NONE; ...@@ -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?/*/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?/*/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_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 # Ignore async reset to DDR controller
NET "inst_spec_base/ddr_rst" TPTHRU = ddr_rst; NET "inst_spec_base/ddr_rst" TPTHRU = ddr_rst;
......
...@@ -19,7 +19,7 @@ ccflags-y += -I$(SPI_ABS)/include ...@@ -19,7 +19,7 @@ ccflags-y += -I$(SPI_ABS)/include
# priority to I2C, FMC headers from our sources # 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) 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
FPGA_MGR_BACKPORT_INCLUDE += -I$(FPGA_MGR_ABS)/include/linux FPGA_MGR_BACKPORT_INCLUDE += -I$(FPGA_MGR_ABS)/include/linux
LINUXINCLUDE := $(FPGA_MGR_BACKPORT_INCLUDE) $(LINUXINCLUDE) LINUXINCLUDE := $(FPGA_MGR_BACKPORT_INCLUDE) $(LINUXINCLUDE)
......
...@@ -23,7 +23,7 @@ FMC_VERSION ?= $(shell basename $(shell ls -d $(DKMSTREE)/fmc/* | grep -E "\/[0- ...@@ -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)) 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)) 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 FMC ?= $(DKMSTREE)/fmc/$(FMC_VERSION)/source
I2C ?= $(DKMSTREE)/i2c-ocores/$(I2C_VERSION)/source I2C ?= $(DKMSTREE)/i2c-ocores/$(I2C_VERSION)/source
SPI ?= $(DKMSTREE)/spi-ocores/$(SPI_VERSION)/source SPI ?= $(DKMSTREE)/spi-ocores/$(SPI_VERSION)/source
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* Author: Federico Vaga <federico.vaga@cern.ch> * Author: Federico Vaga <federico.vaga@cern.ch>
*/ */
#include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/fpga/fpga-mgr.h> #include <linux/fpga/fpga-mgr.h>
#include <linux/delay.h> #include <linux/delay.h>
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
struct gn412x_gpio_dev { struct gn412x_gpio_dev {
void __iomem *mem; void __iomem *mem;
struct gpio_chip gpiochip; struct gpio_chip gpiochip;
struct irq_chip irqchip;
struct completion compl; struct completion compl;
struct gn412x_platform_data *pdata; struct gn412x_platform_data *pdata;
...@@ -77,12 +78,18 @@ static int gn412x_dbg_init(struct gn412x_gpio_dev *gn412x) ...@@ -77,12 +78,18 @@ static int gn412x_dbg_init(struct gn412x_gpio_dev *gn412x)
struct dentry *dir, *file; struct dentry *dir, *file;
int err; 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)) { if (IS_ERR_OR_NULL(dir)) {
err = PTR_ERR(dir); err = PTR_ERR(dir);
dev_warn(gn412x->gpiochip.dev, dev_warn(dev,
"Cannot create debugfs directory \"%s\" (%d)\n", "Cannot create debugfs directory \"%s\" (%d)\n",
dev_name(gn412x->gpiochip.dev), err); dev_name(dev), err);
goto err_dir; goto err_dir;
} }
...@@ -93,7 +100,7 @@ static int gn412x_dbg_init(struct gn412x_gpio_dev *gn412x) ...@@ -93,7 +100,7 @@ static int gn412x_dbg_init(struct gn412x_gpio_dev *gn412x)
dir, &gn412x->dbg_reg32); dir, &gn412x->dbg_reg32);
if (IS_ERR_OR_NULL(file)) { if (IS_ERR_OR_NULL(file)) {
err = PTR_ERR(file); err = PTR_ERR(file);
dev_warn(gn412x->gpiochip.dev, dev_warn(dev,
"Cannot create debugfs file \"%s\" (%d)\n", "Cannot create debugfs file \"%s\" (%d)\n",
GN412X_DBG_REG_NAME, err); GN412X_DBG_REG_NAME, err);
goto err_reg32; goto err_reg32;
...@@ -183,9 +190,15 @@ static int gn412x_gpio_request(struct gpio_chip *chip, unsigned int offset) ...@@ -183,9 +190,15 @@ static int gn412x_gpio_request(struct gpio_chip *chip, unsigned int offset)
{ {
int val; 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); val = gn412x_gpio_reg_read(chip, GNGPIO_BYPASS_MODE, offset);
if (val) { 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); chip->label, offset);
return -EBUSY; return -EBUSY;
} }
...@@ -264,13 +277,19 @@ static int gn412x_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type) ...@@ -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); 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: * detect errors:
* - level and edge together cannot work * - level and edge together cannot work
*/ */
if ((flow_type & IRQ_TYPE_LEVEL_MASK) && if ((flow_type & IRQ_TYPE_LEVEL_MASK) &&
(flow_type & IRQ_TYPE_EDGE_BOTH)) { (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", "Impossible to set GPIO IRQ %ld to both LEVEL and EDGE (0x%x)\n",
d->hwirq, flow_type); d->hwirq, flow_type);
return -EINVAL; return -EINVAL;
...@@ -342,16 +361,6 @@ static void gn412x_gpio_irq_ack(struct irq_data *d) ...@@ -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 * 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) ...@@ -381,6 +390,12 @@ static irqreturn_t gn412x_gpio_irq_handler_t(int irq, void *arg)
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
int i; 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_STATUS);
gpio_int_status &= ~gn412x_ioread32(gn412x, GNGPIO_INT_MASK); gpio_int_status &= ~gn412x_ioread32(gn412x, GNGPIO_INT_MASK);
if (!gpio_int_status) if (!gpio_int_status)
...@@ -388,8 +403,12 @@ static irqreturn_t gn412x_gpio_irq_handler_t(int irq, void *arg) ...@@ -388,8 +403,12 @@ static irqreturn_t gn412x_gpio_irq_handler_t(int irq, void *arg)
loop = gpio_int_status; loop = gpio_int_status;
for_each_set_bit(i, &loop, GN4124_GPIO_MAX) { 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); 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 * Ok, now we execute the handler for the given IRQ. Please
* note that this is not the action requested by the device * 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, ...@@ -457,7 +476,11 @@ static void gn412x_gpio_irq_set_nested_thread(struct gn412x_gpio_dev *gn412x,
{ {
int irq; int irq;
#if KERNEL_VERSION(4, 14, 0) > LINUX_VERSION_CODE
irq = irq_find_mapping(gn412x->gpiochip.irqdomain, gpio); 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); irq_set_nested_thread(irq, nest);
} }
...@@ -500,7 +523,22 @@ static int gn412x_gpio_probe(struct platform_device *pdev) ...@@ -500,7 +523,22 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
} }
gn412x_iowrite32(gn412x, 0, GNGPIO_BYPASS_MODE); 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; gn412x->gpiochip.dev = &pdev->dev;
#else
gn412x->gpiochip.parent = &pdev->dev;
#endif
gn412x->gpiochip.label = "gn412x-gpio"; gn412x->gpiochip.label = "gn412x-gpio";
gn412x->gpiochip.owner = THIS_MODULE; gn412x->gpiochip.owner = THIS_MODULE;
gn412x->gpiochip.request = gn412x_gpio_request; gn412x->gpiochip.request = gn412x_gpio_request;
...@@ -513,22 +551,29 @@ static int gn412x_gpio_probe(struct platform_device *pdev) ...@@ -513,22 +551,29 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
gn412x->gpiochip.base = -1; gn412x->gpiochip.base = -1;
gn412x->gpiochip.ngpio = GN4124_GPIO_MAX; gn412x->gpiochip.ngpio = GN4124_GPIO_MAX;
gn412x->gpiochip.can_sleep = 0; 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); err = gpiochip_add(&gn412x->gpiochip);
if (err) if (err)
goto err_add; goto err_add;
gn412x_gpio_int_cfg_disable(gn412x); #if KERNEL_VERSION(4, 15, 0) > LINUX_VERSION_CODE
gn412x_iowrite32(gn412x, 0xFFFF, GNGPIO_INT_MASK_SET);
err = gpiochip_irqchip_add(&gn412x->gpiochip, err = gpiochip_irqchip_add(&gn412x->gpiochip,
&gn412x_gpio_irq_chip, &gn412x->irqchip,
0, handle_simple_irq, 0, handle_simple_irq,
IRQ_TYPE_NONE); IRQ_TYPE_NONE);
if (err) if (err)
goto err_add_irq; goto err_add_irq;
#endif
gn412x_gpio_irq_set_nested_thread_all(gn412x, true); 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), err = request_threaded_irq(platform_get_irq(pdev, 0),
gn412x_gpio_irq_handler_h, gn412x_gpio_irq_handler_h,
gn412x_gpio_irq_handler_t, gn412x_gpio_irq_handler_t,
...@@ -537,6 +582,16 @@ static int gn412x_gpio_probe(struct platform_device *pdev) ...@@ -537,6 +582,16 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
gn412x); gn412x);
if (err) { if (err) {
dev_err(gn412x->gpiochip.dev, "Can't request IRQ %d (%d)\n", 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); platform_get_irq(pdev, 0), err);
goto err_req; goto err_req;
} }
...@@ -549,8 +604,10 @@ static int gn412x_gpio_probe(struct platform_device *pdev) ...@@ -549,8 +604,10 @@ static int gn412x_gpio_probe(struct platform_device *pdev)
err_req: err_req:
gn412x_gpio_irq_set_nested_thread_all(gn412x, false); gn412x_gpio_irq_set_nested_thread_all(gn412x, false);
#if KERNEL_VERSION(4, 15, 0) > LINUX_VERSION_CODE
err_add_irq: err_add_irq:
gpiochip_remove(&gn412x->gpiochip); gpiochip_remove(&gn412x->gpiochip);
#endif
err_add: err_add:
iounmap(gn412x->mem); iounmap(gn412x->mem);
err_map: err_map:
......
...@@ -200,6 +200,21 @@ static struct resource spec_fpga_vic_res[] = { ...@@ -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 */ /* Vector Interrupt Controller */
static int spec_fpga_vic_init(struct spec_fpga *spec_fpga) 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) ...@@ -274,7 +289,7 @@ static int spec_fpga_dma_init(struct spec_fpga *spec_fpga)
ddr_status); ddr_status);
return -ENODEV; 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) { if (!vic_domain) {
dev_err(&spec_fpga->dev, dev_err(&spec_fpga->dev,
"Failed to load DMA engine: can't find VIC\n"); "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) ...@@ -429,7 +444,7 @@ static int spec_fpga_devices_init(struct spec_fpga *spec_fpga)
n_mfd++; 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) { if (!vic_domain) {
/* Remove IRQ resource from all devices */ /* Remove IRQ resource from all devices */
fpga_mfd_devs[0].num_resources = 1; /* FMC I2C */ fpga_mfd_devs[0].num_resources = 1; /* FMC I2C */
...@@ -718,29 +733,32 @@ static int spec_fpga_app_init(struct spec_fpga *spec_fpga) ...@@ -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) #define SPEC_FPGA_APP_RES_N (32 - SPEC_FPGA_APP_IRQ_BASE + 1)
struct pci_dev *pcidev = to_pci_dev(spec_fpga->dev.parent); struct pci_dev *pcidev = to_pci_dev(spec_fpga->dev.parent);
unsigned int res_n = SPEC_FPGA_APP_RES_N; unsigned int res_n = SPEC_FPGA_APP_RES_N;
struct resource res[SPEC_FPGA_APP_RES_N] = { struct resource *res;
[0] = {
.name = "app-mem",
.flags = IORESOURCE_MEM,
},
};
struct platform_device *pdev; struct platform_device *pdev;
struct irq_domain *vic_domain; struct irq_domain *vic_domain;
char app_name[SPEC_FPGA_APP_NAME_MAX]; char app_name[SPEC_FPGA_APP_NAME_MAX];
unsigned long app_offset; 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); app_offset = spec_fpga_csr_app_offset(spec_fpga);
if (!app_offset) { if (!app_offset) {
dev_warn(&spec_fpga->dev, "Application not found\n"); 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].start = pci_resource_start(pcidev, 0) + app_offset;
res[0].end = pci_resource_end(pcidev, 0); res[0].end = pci_resource_end(pcidev, 0);
if (spec_fpga->vic_pdev) 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 else
vic_domain = NULL; vic_domain = NULL;
...@@ -762,18 +780,21 @@ static int spec_fpga_app_init(struct spec_fpga *spec_fpga) ...@@ -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, err = spec_fpga_app_id_build(spec_fpga, app_offset,
app_name, SPEC_FPGA_APP_NAME_MAX); app_name, SPEC_FPGA_APP_NAME_MAX);
if (err) if (err)
return err; goto err_free;
spec_fpga_app_restart(spec_fpga); spec_fpga_app_restart(spec_fpga);
pdev = platform_device_register_resndata(&spec_fpga->dev, pdev = platform_device_register_resndata(&spec_fpga->dev,
app_name, PLATFORM_DEVID_AUTO, app_name, PLATFORM_DEVID_AUTO,
res, res_n, res, res_n,
NULL, 0); NULL, 0);
if (IS_ERR(pdev)) err = IS_ERR(pdev);
return PTR_ERR(pdev); if (err)
goto err_free;
spec_fpga->app_pdev = pdev; spec_fpga->app_pdev = pdev;
return 0; err_free:
kfree(res);
return err;
} }
static void spec_fpga_app_exit(struct spec_fpga *spec_fpga) static void spec_fpga_app_exit(struct spec_fpga *spec_fpga)
......
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/gpio/consumer.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 "platform_data/gn412x-gpio.h"
#include "spec.h" #include "spec.h"
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/version.h>
#include <linux/mod_devicetable.h>
/** /**
* dma_cookie_complete - complete a descriptor * dma_cookie_complete - complete a descriptor
...@@ -605,9 +607,11 @@ static int gn412x_dma_terminate_all(struct dma_chan *chan) ...@@ -605,9 +607,11 @@ static int gn412x_dma_terminate_all(struct dma_chan *chan)
return 0; return 0;
} }
#if KERNEL_VERSION(4, 0, 0) > LINUX_VERSION_CODE
static int gn412x_dma_device_control(struct dma_chan *chan, static int gn412x_dma_device_control(struct dma_chan *chan,
enum dma_ctrl_cmd cmd, enum dma_ctrl_cmd cmd,
unsigned long arg) unsigned long arg)
{ {
switch (cmd) { switch (cmd) {
case DMA_SLAVE_CONFIG: case DMA_SLAVE_CONFIG:
...@@ -624,7 +628,7 @@ static int gn412x_dma_device_control(struct dma_chan *chan, ...@@ -624,7 +628,7 @@ static int gn412x_dma_device_control(struct dma_chan *chan,
} }
return -ENODEV; return -ENODEV;
} }
#endif
static irqreturn_t gn412x_dma_irq_handler(int irq, void *arg) 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, ...@@ -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_alloc_chan_resources = gn412x_dma_alloc_chan_resources;
dma->device_free_chan_resources = gn412x_dma_free_chan_resources; dma->device_free_chan_resources = gn412x_dma_free_chan_resources;
dma->device_prep_slave_sg = gn412x_dma_prep_slave_sg; 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; 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_tx_status = gn412x_dma_tx_status;
dma->device_issue_pending = gn412x_dma_issue_pending; 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