diff --git a/patches/spec.diff b/patches/spec.diff index 197c0e761056f4e0f1635bef3402c100670be5df..be3ca4f4a16dec68c8b4839e3849f7ab6d6b70cd 100644 --- a/patches/spec.diff +++ b/patches/spec.diff @@ -23,10 +23,18 @@ index 50cda24..585eda1 100644 #include <linux/fpga/fpga-mgr.h> #include <linux/delay.h> diff --git a/software/kernel/gn412x-gpio.c b/software/kernel/gn412x-gpio.c -index c5ca4e5..468d1a4 100644 +index fa7003c..5882b1e 100644 --- a/software/kernel/gn412x-gpio.c +++ b/software/kernel/gn412x-gpio.c -@@ -77,12 +77,18 @@ static int gn412x_dbg_init(struct gn412x_gpio_dev *gn412x) +@@ -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; @@ -48,7 +56,7 @@ index c5ca4e5..468d1a4 100644 goto err_dir; } -@@ -93,7 +99,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); if (IS_ERR_OR_NULL(file)) { err = PTR_ERR(file); @@ -57,7 +65,7 @@ index c5ca4e5..468d1a4 100644 "Cannot create debugfs file \"%s\" (%d)\n", GN412X_DBG_REG_NAME, err); goto err_reg32; -@@ -183,9 +189,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; @@ -74,7 +82,7 @@ index c5ca4e5..468d1a4 100644 chip->label, offset); return -EBUSY; } -@@ -264,13 +276,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); @@ -95,7 +103,24 @@ index c5ca4e5..468d1a4 100644 "Impossible to set GPIO IRQ %ld to both LEVEL and EDGE (0x%x)\n", d->hwirq, flow_type); return -EINVAL; -@@ -381,6 +399,12 @@ static irqreturn_t gn412x_gpio_irq_handler_t(int irq, void *arg) +@@ -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; @@ -108,7 +133,7 @@ index c5ca4e5..468d1a4 100644 gpio_int_status = gn412x_ioread32(gn412x, GNGPIO_INT_STATUS); gpio_int_status &= ~gn412x_ioread32(gn412x, GNGPIO_INT_MASK); if (!gpio_int_status) -@@ -388,8 +412,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; for_each_set_bit(i, &loop, GN4124_GPIO_MAX) { @@ -122,7 +147,7 @@ index c5ca4e5..468d1a4 100644 /* * Ok, now we execute the handler for the given IRQ. Please * note that this is not the action requested by the device -@@ -457,7 +485,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; @@ -134,10 +159,21 @@ index c5ca4e5..468d1a4 100644 irq_set_nested_thread(irq, nest); } -@@ -500,7 +532,11 @@ 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_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 @@ -146,7 +182,33 @@ index c5ca4e5..468d1a4 100644 gn412x->gpiochip.label = "gn412x-gpio"; gn412x->gpiochip.owner = THIS_MODULE; gn412x->gpiochip.request = gn412x_gpio_request; -@@ -529,6 +565,7 @@ 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.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); @@ -154,7 +216,7 @@ index c5ca4e5..468d1a4 100644 err = request_threaded_irq(platform_get_irq(pdev, 0), gn412x_gpio_irq_handler_h, gn412x_gpio_irq_handler_t, -@@ -537,6 +574,16 @@ static int gn412x_gpio_probe(struct platform_device *pdev) +@@ -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", @@ -171,8 +233,72 @@ index c5ca4e5..468d1a4 100644 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: +diff --git a/software/kernel/spec-core-fpga.c b/software/kernel/spec-core-fpga.c +index 4c339a3..d8bf776 100644 +--- a/software/kernel/spec-core-fpga.c ++++ b/software/kernel/spec-core-fpga.c +@@ -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 */ +@@ -736,7 +751,7 @@ static int spec_fpga_app_init(struct spec_fpga *spec_fpga) + 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; + diff --git a/software/kernel/spec-core.c b/software/kernel/spec-core.c -index 174efb8..b1f20f8 100644 +index c338c19..eeef8cd 100644 --- a/software/kernel/spec-core.c +++ b/software/kernel/spec-core.c @@ -15,6 +15,10 @@ @@ -187,7 +313,7 @@ index 174efb8..b1f20f8 100644 #include "platform_data/gn412x-gpio.h" #include "spec.h" diff --git a/software/kernel/spec-gn412x-dma.c b/software/kernel/spec-gn412x-dma.c -index a861737..e87934f 100644 +index a861737..98643a4 100644 --- a/software/kernel/spec-gn412x-dma.c +++ b/software/kernel/spec-gn412x-dma.c @@ -20,6 +20,8 @@ @@ -222,13 +348,19 @@ index a861737..e87934f 100644 static irqreturn_t gn412x_dma_irq_handler(int irq, void *arg) { -@@ -742,7 +746,12 @@ static int gn412x_dma_engine_init(struct gn412x_dma_device *gn412x_dma, +@@ -742,7 +746,18 @@ 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 ++ 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