Commit a697fda8 authored by Federico Vaga's avatar Federico Vaga

Merge branch '1-review-vaibhav-patches' into 'master'

Resolve "Review Vaibhav Patches"

Closes #1

See merge request be-cem-edl/fec/hardware-modules/fmc!1
parents d3cd6091 94e11560
......@@ -58,6 +58,9 @@ Makefile.specific
GTAGS
GPATH
GRTAGS
*.mod
*.mod.c
*.*cmd
# Documentation
_build/
......@@ -3,71 +3,66 @@
# SPDX-FileCopyrightText: 2019 CERN
---
variables:
KOJI_TARGET: 'ohwr7'
KOJI_DISTTAG: '.el7.cern'
DIST_PATH: distribution
BUILD_PATH: distribution/build
stages:
- static-analysis
- build
- dkms
- srpm
- kscratch
- kbuild
include:
- project: 'be-cem-edl/evergreen/gitlab-ci'
ref: master
file:
- 'edl-gitlab-ci.yml'
reuse:
stage: static-analysis
cppcheck:
stage: analyse
image:
name: fsfe/reuse:latest
entrypoint: [""]
name: gitlab-registry.cern.ch/coht/common-containers/static-analysis:latest
script:
- reuse lint
- make cppcheck
cppcheck:
stage: static-analysis
documentation:
stage: build
image:
name: gitlab-registry.cern.ch/coht/common-containers/documentation:latest
script:
- yum install -y cppcheck
- make cppcheck
- make -C Documentation/fmc html KERNELSRC=$(ls -1dr /linux-* | head -n 1)
- mkdir -p $EDL_CI_EOS_OUTPUT_DIR
- cp -a Documentation/fmc/_build/html/* $EDL_CI_EOS_OUTPUT_DIR
artifacts:
paths:
- $EDL_CI_EOS_OUTPUT_DIR
build-centos-7:
stage: build
variables:
KERNELSRC: /usr/src/kernels/*/
image:
name: gitlab-registry.cern.ch/coht/common-containers/build-centos-7:latest
script:
- make modules
build:
build-kernel:
stage: build
allow_failure: true
image:
name: gitlab-registry.cern.ch/coht/common-containers/build-kernel:latest
parallel:
matrix:
- VERSION: [5.10.149, 5.15.74]
script:
- yum install -y kernel-devel
- LINUX=/usr/src/kernels/*/ make modules
- source /linux-versions.sh
- fetch $VERSION && prepare $VERSION && export LINUX=$(linux $VERSION) && export KERNELSRC=$(linux $VERSION)
- make modules
build_dkms_rpm:
stage: dkms
stage: release
script:
- yum install -y dkms
- make -C distribution dkms-rpm
build_srpm:
stage: srpm
stage: release
script:
- yum-builddep -y ${DIST_PATH}/*.spec
- LINUX=/usr/src/kernels/*/ make -C distribution srpm
- KERNELSRC=/usr/src/kernels/*/ make -C distribution srpm
artifacts:
paths:
- distribution/build/SRPMS/${CI_PROJECT_NAME}*src.rpm
expire_in: 1 day
.koji_deps_template: &koji_deps
before_script:
- yum install -y koji krb5-workstation rpm-build
- echo ${OHWR_PASSWORD} | kinit ${OHWR_USER}
kscratch:
<<: *koji_deps
stage: kscratch
script:
- koji --config=.koji build --wait --scratch ${KOJI_TARGET} distribution/build/SRPMS/${CI_PROJECT_NAME}*src.rpm
kbuild-ohwr:
<<: *koji_deps
stage: kbuild
only:
- tags
script:
- koji --config=.koji build --wait ${KOJI_TARGET} distribution/build/SRPMS/${CI_PROJECT_NAME}*src.rpm
......@@ -7,7 +7,7 @@
# REPO_PARENT ?=
# -include $(REPO_PARENT)/parent_common.mk
LINUX ?= /lib/modules/$(shell uname -r)/build
KERNELSRC ?= /lib/modules/$(shell uname -r)/build
SPHINXOPTS = -Drelease=$(shell git describe) -Dversion=$(shell git describe | cut -d "-" -f 1 | tr -d "v")
SPHINXBUILD ?= sphinx-build
......@@ -23,4 +23,4 @@ help:
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
LINUX=$(LINUX) $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
KERNELSRC=$(KERNELSRC) $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
......@@ -16,9 +16,9 @@ import sphinx
# the Docs). In a normal build, these are supplied from the Makefile via command
# line arguments.
linux = os.getenv("LINUX", None)
linux = os.getenv("KERNELSRC", None)
if linux is None:
raise Exception("Missing LINUX environment variable")
raise Exception("Missing KERNELSRC environment variable")
kerneldoc_bin = os.path.join(linux, 'scripts/kernel-doc')
kerneldoc_srctree = '../../'
......
......@@ -5,16 +5,16 @@
-include Makefile.specific
# include parent_common.mk for buildsystem's defines
#use absolute path for REPO_PARENT
REPO_PARENT ?= $(shell /bin/pwd)/../..
REPO_PARENT ?= $(shell /bin/pwd)/../../..
-include $(REPO_PARENT)/parent_common.mk
LINUX ?= /lib/modules/$(shell uname -r)/build
KERNELSRC ?= /lib/modules/$(shell uname -r)/build
export CONFIG_FMC=m
all: modules
clean modules help modules_install coccicheck:
make -C $(LINUX) M=$(shell pwd) $@
make -C $(KERNELSRC) M=$(shell pwd) $@
.PHONY: all modules clean help install modules_install
......@@ -7,10 +7,15 @@
#include <linux/module.h>
#include <linux/memory.h>
#include <linux/fmc.h>
#include <linux/slab.h>
#include <linux/ipmi/fru.h>
#include "fmc-internal.h"
#include "fmc-compat.h"
#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
#include <linux/nvmem-consumer.h>
#endif
#define FRU_EEPROM_NAME "fru_eeprom"
/**
......@@ -18,11 +23,14 @@
*/
#define FMC_EEPROM_TYPE_DEFAULT "24c02"
/**
* Setup function for the AT24C02 EEPROM. What we need to do here is to
* quickly validate the EEPROM content. The EEPROM should contain a valid
* FRU.
*/
#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
const struct property_entry at24_24c02[AT24_NUM_PROPERTIES] = {
PROPERTY_ENTRY_U32("size", 256),
PROPERTY_ENTRY_U32("pagesize", 8),
PROPERTY_ENTRY_U32("address-width", 16),
{ }
};
#else
static void fmc_slot_eeprom_setup(struct memory_accessor *macc, void *context)
{
struct fmc_slot *slot = context;
......@@ -39,9 +47,10 @@ static const struct at24_platform_data at24_24c02 = {
.flags = 0,
.setup = fmc_slot_eeprom_setup,
};
#endif /* KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE */
/**
* Initialize I2C EEPROM info with standad values
* Initialize I2C EEPROM info with standard values
*/
static void fmc_slot_eeprom_init(struct fmc_slot *slot,
struct i2c_board_info *info,
......@@ -49,7 +58,11 @@ static void fmc_slot_eeprom_init(struct fmc_slot *slot,
{
strncpy(info->type, name, I2C_NAME_SIZE - 1);
info->addr = FMC_EEPROM_ADDR_SPACE;
#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
info->properties = slot->at24_data;
#else
info->platform_data = &slot->at24_data;
#endif
}
static void fmc_slot_eeprom_init_default(struct fmc_slot *slot,
......@@ -57,8 +70,37 @@ static void fmc_slot_eeprom_init_default(struct fmc_slot *slot,
{
memset(info, 0, sizeof(*info));
fmc_slot_eeprom_init(slot, info, FMC_EEPROM_TYPE_DEFAULT);
#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
memcpy(&slot->at24_data, &at24_24c02, sizeof(slot->at24_data));
slot->at24_data.context = slot;
#else
memcpy(slot->at24_data, &at24_24c02, sizeof(slot->at24_data));
#endif
}
/**
* fmc_nvmem_device_find_match() - Find the nvmem device
* @dev: nvmem_device (provided by nvmem-consumeer framework)
* @data: name of device that uses nvmem device
*
* This function is executed by the nvmem-consumer framework to find our
* nvmem device. The way this framework is designed, we only have the info
* about the parent device which is handled by i2c.
* One pattern which is helpful is that the nvmem framework names its
* devices by just appending an id to the name of the parent device. So,
* if the parent device is "2-0050", the nvmem device will be 2-0050<id>.
*
* The silver lining in our case is that as per FMC standard, we have only
* one eeprom/nvmem device per i2c handler. Thus, we just need to check
* that out of all nvmem devices, which one contains the name of our
* i2c handler.
*/
int fmc_nvmem_device_find_match(struct device *dev, const void *data)
{
const char *s1 = dev_name(dev);
const char *s2 = (const char*) data;
return !memcmp(s1, s2, strlen(s2));
}
/**
......@@ -71,13 +113,19 @@ static void fmc_slot_eeprom_init_default(struct fmc_slot *slot,
ssize_t fmc_slot_eeprom_read(struct fmc_slot *slot,
void *buf, off_t offset, size_t count)
{
int err = 0;
#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
err = nvmem_device_read(slot->nvmem, offset, count, buf);
#else
/*
* TODO if we export this function, do we have to lock it when we
* use it? Think about it
*/
if (!slot->macc || !slot->macc->read)
return -ENODEV;
return slot->macc->read(slot->macc, buf, offset, count);
err = slot->macc->read(slot->macc, buf, offset, count);
#endif
return err;
}
EXPORT_SYMBOL(fmc_slot_eeprom_read);
......@@ -103,6 +151,9 @@ static int __fmc_slot_eeprom_add(struct fmc_slot *slot,
{
struct i2c_board_info info_l = *info;
int err;
#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
char *nvmem_parent_name;
#endif
if (!fmc_slot_present(slot))
return -ENODEV;
......@@ -128,6 +179,25 @@ static int __fmc_slot_eeprom_add(struct fmc_slot *slot,
dev_err(&slot->dev, "Failed to create eeprom symlink to %s\n",
dev_name(&slot->eeprom->dev));
#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
nvmem_parent_name = kzalloc(strlen(dev_name(&slot->eeprom->dev)) + 1,
GFP_KERNEL);
if (!nvmem_parent_name)
return -ENOMEM;
snprintf(nvmem_parent_name, strlen(dev_name(&slot->eeprom->dev)),
"%s", dev_name(&slot->eeprom->dev));
slot->nvmem = nvmem_device_find(nvmem_parent_name,
fmc_nvmem_device_find_match);
kfree(nvmem_parent_name);
if (IS_ERR_OR_NULL(slot->nvmem)) {
int err = PTR_ERR(slot->nvmem);
slot->nvmem = NULL;
return err;
}
#endif
return 0;
}
......@@ -156,13 +226,20 @@ int fmc_slot_eeprom_add(struct fmc_slot *slot)
*/
void fmc_slot_eeprom_del(struct fmc_slot *slot)
{
#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE
nvmem_device_put(slot->nvmem);
slot->nvmem = NULL;
#endif
if (!slot || !slot->eeprom)
return;
sysfs_remove_link(&slot->dev.kobj, FRU_EEPROM_NAME);
i2c_unregister_device(slot->eeprom);
slot->eeprom = NULL;
#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
slot->macc = NULL;
#endif
}
/**
......@@ -207,19 +284,25 @@ int fmc_slot_eeprom_type_set(struct fmc_slot *slot, const char *type)
memset(&i2c_info, 0, sizeof(i2c_info));
#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
memset(&slot->at24_data, 0, sizeof(slot->at24_data));
#else
memset(slot->at24_data, 0, sizeof(slot->at24_data));
#endif
len = (len * 1024) / 8;
/*
* For sizes between 1K and 16K the EEPROM uses part of the device
* address as internal memory address
*/
if (len > 4096) /* 32K 4KiB */
slot->at24_data.flags = AT24_FLAG_ADDR16;
else if (len > 131072) /* 1024K 128KiB */
if (len > 131072) /* 1024K 128KiB */
return -EINVAL;
fmc_slot_eeprom_init(slot, &i2c_info, type);
#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
if (len > 4096) /* 32K 4KiB */
slot->at24_data.flags = AT24_FLAG_ADDR16;
slot->at24_data.byte_len = len;
slot->at24_data.page_size = 1; /* 1Byte page to play safe */
slot->at24_data.setup = fmc_slot_eeprom_setup;
......@@ -229,7 +312,15 @@ int fmc_slot_eeprom_type_set(struct fmc_slot *slot, const char *type)
i2c_info.type, i2c_info.addr,
slot->at24_data.byte_len, slot->at24_data.page_size,
slot->at24_data.flags);
#else
slot->at24_data[0] = PROPERTY_ENTRY_U32("size", len);
slot->at24_data[1] = PROPERTY_ENTRY_U32("pagesize", 1);
if (len > 4096) /* 32K 4KiB */
slot->at24_data[2] = PROPERTY_ENTRY_U32("address-width", 16);
dev_dbg(&slot->dev, "%s 0x%x %d\n",
i2c_info.type, i2c_info.addr, len);
#endif
return fmc_slot_eeprom_replace(slot, &i2c_info);
}
EXPORT_SYMBOL(fmc_slot_eeprom_type_set);
......
......@@ -5,12 +5,6 @@
*/
#include <linux/version.h>
#if KERNEL_VERSION(3, 11, 0) > LINUX_VERSION_CODE
/*
* On kernel 3.11 and greater this is included
*/
#include <linux/slab.h>
#include <linux/ipmi/fru.h>
......@@ -77,5 +71,3 @@ char *fru_get_part_number(struct fru_common_header *header)
return __fru_alloc_get_tl(header, 3);
}
EXPORT_SYMBOL(fru_get_part_number);
#endif
......@@ -11,13 +11,13 @@
#include <linux/spinlock.h>
#include <linux/version.h>
#if KERNEL_VERSION(5, 1, 0) > LINUX_VERSION_CODE
#if KERNEL_VERSION(3, 10, 0) <= LINUX_VERSION_CODE
#include <linux/platform_data/at24.h>
#else
#include <linux/i2c/at24.h>
#endif
#endif
#ifndef _LINUX_FMC_H
#define _LINUX_FMC_H
......@@ -86,8 +86,14 @@ struct fmc_slot {
struct i2c_client *eeprom;
#if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
#define AT24_NUM_PROPERTIES 4
struct property_entry at24_data[AT24_NUM_PROPERTIES];
struct nvmem_device *nvmem;
#else
struct memory_accessor *macc;
struct at24_platform_data at24_data;
#endif
};
/**
......
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