Commit 1bf3ef45 authored by Federico Vaga's avatar Federico Vaga

Merge branch 'feature/linux-compat' into develop

The driver builds on kernels from 3.6 to 5.0
Tested on v4.14
Tested on v3.6 with FPGA manager backport
parents f6c3b2b0 bc8202e1
......@@ -9,16 +9,21 @@ endif
ccflags-y += -DADDITIONAL_VERSIONS="$(SUBMODULE_VERSIONS)"
ccflags-y += -DGIT_VERSION=\"$(GIT_VERSION)\"
ccflags-y += -I$(FPGA_MGR_ABS)/include
ccflags-y += -Wall -Werror
# priority to I2C headers from our sources
LINUXINCLUDE := -I$(FMC_MGR_ABS)/include -I$(FMC_MGR_ABS)/include/linux $(LINUXINCLUDE)
ccflags-$(CONFIG_FPGA_MGR_BACKPORT) += -DCONFIG_FPGA_MGR_BACKPORT
ccflags-$(CONFIG_FPGA_MGR_BACKPORT) += -I$(CONFIG_FPGA_MGR_BACKPORT_PATH_ABS)/include
KBUILD_EXTRA_SYMBOLS += $(FPGA_MGR_ABS)/drivers/fpga/Module.symvers
ifeq ($(CONFIG_FPGA_MGR_BACKPORT), y)
CONFIG_FPGA_MGR_BACKPORT_INCLUDE := -I$(CONFIG_FPGA_MGR_BACKPORT_PATH_ABS)/include
CONFIG_FPGA_MGR_BACKPORT_INCLUDE += -I$(CONFIG_FPGA_MGR_BACKPORT_PATH_ABS)/include/linux
LINUXINCLUDE := $(CONFIG_FPGA_MGR_BACKPORT_INCLUDE) $(LINUXINCLUDE)
KBUILD_EXTRA_SYMBOLS += $(CONFIG_FPGA_MGR_BACKPORT_PATH_ABS)/drivers/fpga/Module.symvers
endif
obj-m := spec.o
spec-objs := spec-core.o
spec-objs += spec-fpga.o
spec-objs += spec-irq.o
spec-objs += spec-compat.o
......@@ -5,12 +5,12 @@ REPO_PARENT ?= $(shell /bin/pwd)/../..
LINUX ?= /lib/modules/$(shell uname -r)/build
FPGA_MGR_ABS ?= $(abspath $(FPGA_MGR))
FMC_ABS ?= $(abspath $(FMC))
I2C_ABS ?= $(abspath $(I2C))
CONFIG_FPGA_MGR_BACKPORT_PATH_ABS ?= $(abspath $(CONFIG_FPGA_MGR_BACKPORT_PATH))
GIT_VERSION = $(shell git describe --dirty --long --tags)
export GIT_VERSION
......@@ -19,7 +19,7 @@ all: modules
.PHONY: all modules clean help install modules_install
modules help install modules_install:
$(MAKE) -C $(LINUX) M=$(shell pwd) GIT_VERSION=$(GIT_VERSION) FPGA_MGR_ABS=$(FPGA_MGR_ABS) $@
$(MAKE) -C $(LINUX) M=$(shell pwd) GIT_VERSION=$(GIT_VERSION) CONFIG_FPGA_MGR_BACKPORT_PATH_ABS=$(CONFIG_FPGA_MGR_BACKPORT_PATH_ABS) CONFIG_FPGA_MGR_BACKPORT=$(CONFIG_FPGA_MGR_BACKPORT) $@
# be able to run the "clean" rule even if $(LINUX) is not valid
clean:
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2017 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#include <linux/fpga/fpga-mgr.h>
#include <linux/version.h>
#include "spec-compat.h"
int compat_get_fpga_last_word_size(struct fpga_image_info *info, size_t count)
{
#if KERNEL_VERSION(4,16,0) > LINUX_VERSION_CODE && !defined(CONFIG_FPGA_MGR_BACKPORT)
return count;
#else
return info ? info->count : count;
#endif
}
#if KERNEL_VERSION(4,10,0) > LINUX_VERSION_CODE && !defined(CONFIG_FPGA_MGR_BACKPORT)
int compat_spec_fpga_write_init(struct fpga_manager *mgr,
u32 flags,
const char *buf, size_t count)
{
return spec_fpga_write_init(mgr, NULL, buf, count);
}
int compat_spec_fpga_write_complete(struct fpga_manager *mgr,
u32 flags)
{
return spec_fpga_write_complete(mgr, NULL);
}
#else
int compat_spec_fpga_write_init(struct fpga_manager *mgr,
struct fpga_image_info *info,
const char *buf, size_t count)
{
return spec_fpga_write_init(mgr, info, buf, count);
}
int compat_spec_fpga_write_complete(struct fpga_manager *mgr,
struct fpga_image_info *info)
{
return spec_fpga_write_complete(mgr, info);
}
#endif
#if KERNEL_VERSION(4,18,0) > LINUX_VERSION_CODE && !defined(CONFIG_FPGA_MGR_BACKPORT)
struct fpga_manager *compat_fpga_mgr_create(struct device *dev, const char *name,
const struct fpga_manager_ops *mops,
void *priv)
{
int err;
err = fpga_mgr_register(dev, name, mops, priv);
if (err)
return NULL;
return (struct fpga_manager *)dev;
}
void compat_fpga_mgr_free(struct fpga_manager *mgr)
{
fpga_mgr_unregister((struct device *)mgr);
}
int compat_fpga_mgr_register(struct fpga_manager *mgr)
{
return mgr ? 0 : 1;
}
void compat_fpga_mgr_unregister(struct fpga_manager *mgr)
{
fpga_mgr_unregister((struct device *)mgr);
}
#else
struct fpga_manager *compat_fpga_mgr_create(struct device *dev,
const char *name,
const struct fpga_manager_ops *mops,
void *priv)
{
return fpga_mgr_create(dev, name, mops, priv);
}
void compat_fpga_mgr_free(struct fpga_manager *mgr)
{
fpga_mgr_free(mgr);
}
int compat_fpga_mgr_register(struct fpga_manager *mgr)
{
return fpga_mgr_register(mgr);
}
void compat_fpga_mgr_unregister(struct fpga_manager *mgr)
{
fpga_mgr_unregister(mgr);
}
#endif
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2017 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#include <linux/fpga/fpga-mgr.h>
#include <linux/types.h>
#include <linux/version.h>
#if KERNEL_VERSION(4,10,0) <= LINUX_VERSION_CODE
#if KERNEL_VERSION(4,16,0) > LINUX_VERSION_CODE
/* So that we select the buffer size because smaller */
#define compat_fpga_ops_initial_header_size .initial_header_size = 0xFFFFFFFF,
#else
#define compat_fpga_ops_initial_header_size .initial_header_size = 0,
#endif
#else
#define compat_fpga_ops_initial_header_size
#endif
#if KERNEL_VERSION(4,16,0) > LINUX_VERSION_CODE && ! defined(CONFIG_FPGA_MGR_BACKPORT)
#define compat_fpga_ops_groups
#else
#define compat_fpga_ops_groups .groups = NULL,
#endif
#if KERNEL_VERSION(4,10,0) > LINUX_VERSION_CODE && ! defined(CONFIG_FPGA_MGR_BACKPORT)
struct fpga_image_info;
#endif
int spec_fpga_write_init(struct fpga_manager *mgr,
struct fpga_image_info *info,
const char *buf, size_t count);
int spec_fpga_write_complete(struct fpga_manager *mgr,
struct fpga_image_info *info);
#if KERNEL_VERSION(4,10,0) > LINUX_VERSION_CODE && ! defined(CONFIG_FPGA_MGR_BACKPORT)
int compat_spec_fpga_write_init(struct fpga_manager *mgr, u32 flags,
const char *buf, size_t count);
int compat_spec_fpga_write_complete(struct fpga_manager *mgr, u32 flags);
#else
int compat_spec_fpga_write_init(struct fpga_manager *mgr,
struct fpga_image_info *info,
const char *buf, size_t count);
int compat_spec_fpga_write_complete(struct fpga_manager *mgr,
struct fpga_image_info *info);
#endif
int compat_get_fpga_last_word_size(struct fpga_image_info *info,
size_t count);
struct fpga_manager *compat_fpga_mgr_create(struct device *dev,
const char *name,
const struct fpga_manager_ops *mops,
void *priv);
void compat_fpga_mgr_free(struct fpga_manager *mgr);
int compat_fpga_mgr_register(struct fpga_manager *mgr);
void compat_fpga_mgr_unregister(struct fpga_manager *mgr);
......@@ -4,10 +4,11 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <linux/fpga/fpga-mgr.h>
#include <linux/delay.h>
#include "spec.h"
#include "spec-compat.h"
static inline uint8_t reverse_bits8(uint8_t x)
{
......@@ -240,15 +241,16 @@ static enum fpga_mgr_states spec_fpga_state(struct fpga_manager *mgr)
}
static int spec_fpga_write_init(struct fpga_manager *mgr,
struct fpga_image_info *info,
const char *buf, size_t count)
int spec_fpga_write_init(struct fpga_manager *mgr,
struct fpga_image_info *info,
const char *buf, size_t count)
{
struct spec_dev *spec = mgr->priv;
int err = 0;
int err = 0, last_word_size;
gn4124_fpga_gpio_config(spec);
err = gn4124_fpga_fcl_init(spec, info->count & 0x3);
last_word_size = compat_get_fpga_last_word_size(info, count) & 0x3;
err = gn4124_fpga_fcl_init(spec, last_word_size);
if (err < 0)
goto err;
......@@ -259,7 +261,6 @@ err:
return err;
}
static int spec_fpga_write(struct fpga_manager *mgr, const char *buf, size_t count)
{
struct spec_dev *spec = mgr->priv;
......@@ -268,8 +269,8 @@ static int spec_fpga_write(struct fpga_manager *mgr, const char *buf, size_t cou
}
static int spec_fpga_write_complete(struct fpga_manager *mgr,
struct fpga_image_info *info)
int spec_fpga_write_complete(struct fpga_manager *mgr,
struct fpga_image_info *info)
{
struct spec_dev *spec = mgr->priv;
int err;
......@@ -292,15 +293,15 @@ static void spec_fpga_remove(struct fpga_manager *mgr)
/* do nothing */
}
static const struct fpga_manager_ops spec_fpga_ops = {
.initial_header_size = 0,
compat_fpga_ops_initial_header_size
compat_fpga_ops_groups
.state = spec_fpga_state,
.write_init = spec_fpga_write_init,
.write_init = compat_spec_fpga_write_init,
.write = spec_fpga_write,
.write_complete = spec_fpga_write_complete,
.write_complete = compat_spec_fpga_write_complete,
.fpga_remove = spec_fpga_remove,
.groups = NULL,
};
......@@ -308,18 +309,15 @@ int spec_fpga_init(struct spec_dev *spec)
{
int err;
if (!spec)
return -EINVAL;
spec->mgr = fpga_mgr_create(&spec->dev,
dev_name(&spec->dev),
&spec_fpga_ops, spec);
if (!spec->mgr)
spec->mgr = compat_fpga_mgr_create(&spec->dev,
dev_name(&spec->dev),
&spec_fpga_ops, spec);
if (!spec || !spec->mgr)
return -EPERM;
err = fpga_mgr_register(spec->mgr);
err = compat_fpga_mgr_register(spec->mgr);
if (err) {
fpga_mgr_free(spec->mgr);
compat_fpga_mgr_free(spec->mgr);
return err;
}
......@@ -328,7 +326,7 @@ int spec_fpga_init(struct spec_dev *spec)
void spec_fpga_exit(struct spec_dev *spec)
{
if (!spec || !spec->mgr)
if (!spec)
return;
fpga_mgr_unregister(spec->mgr);
compat_fpga_mgr_unregister(spec->mgr);
}
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