Commit 3198df26 authored by Federico Vaga's avatar Federico Vaga

kernel: replace fmc_device with platform_device

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 04fa428e
[submodule "fmc-bus"]
path = software/fmc-bus
url = git://ohwr.org/fmc-projects/fmc-bus.git
[submodule "hdl/ip_cores/general-cores"] [submodule "hdl/ip_cores/general-cores"]
path = hdl/ip_cores/general-cores path = hdl/ip_cores/general-cores
url = git://ohwr.org/hdl-core-lib/general-cores.git url = git://ohwr.org/hdl-core-lib/general-cores.git
......
...@@ -4,23 +4,11 @@ CURDIR:=$(shell /bin/pwd) ...@@ -4,23 +4,11 @@ CURDIR:=$(shell /bin/pwd)
REPO_PARENT ?= $(CURDIR)/.. REPO_PARENT ?= $(CURDIR)/..
-include $(REPO_PARENT)/parent_common.mk -include $(REPO_PARENT)/parent_common.mk
all: include/hw kernel lib tools
FMC_BUS ?= fmc-bus DIRS = kernel lib tools
# Use the absolute path so it can be used by submodule
# FMC_BUS_ABS has to be absolut path, due to beeing passed to the Kbuild
FMC_BUS_ABS ?= $(abspath $(FMC_BUS) )
export FMC_BUS_ABS
DIRS = $(FMC_BUS_ABS) include/hw kernel lib tools
kernel: $(FMC_BUS_ABS) include/hw
kernel: include/hw
tools: lib tools: lib
# we take only headers from svec-sw, no need to compile
kernel: fmc-bus-init_repo
.PHONY: all clean modules install modules_install $(DIRS) .PHONY: all clean modules install modules_install $(DIRS)
.PHONY: gitmodules prereq_install prereq_install_warn .PHONY: gitmodules prereq_install prereq_install_warn
...@@ -37,20 +25,3 @@ modules_install: TARGET = modules_install ...@@ -37,20 +25,3 @@ modules_install: TARGET = modules_install
$(DIRS): $(DIRS):
$(MAKE) -C $@ $(TARGET) $(MAKE) -C $@ $(TARGET)
SUBMOD = $(FMC_BUS_ABS)
prereq_install_warn:
@test -f .prereq_installed || \
echo -e "\n\n\tWARNING: Consider \"make prereq_install\"\n"
prereq_install:
for d in $(SUBMOD); do $(MAKE) -C $$d modules_install || exit 1; done
touch .prereq_installed
$(FMC_BUS_ABS): fmc-bus-init_repo
# init submodule if missing
fmc-bus-init_repo:
@test -d $(FMC_BUS_ABS)/doc || ( echo "Checking out submodule $(FMC_BUS_ABS)" && git submodule update --init $(FMC_BUS_ABS) )
fmc-bus @ 13e4f901
Subproject commit 13e4f901ec39bd86e40dbce972b07853c666873f
LINUX ?= /lib/modules/$(shell uname -r)/build LINUX ?= /lib/modules/$(shell uname -r)/build
FMC_BUS ?= $(src)/../fmc-bus
KBUILD_EXTRA_SYMBOLS := \
$(ZIO)/Module.symvers \
$(FMC_BUS)/kernel/Module.symvers
GIT_VERSION = $(shell cd $(src); git describe --always --dirty --long --tags) GIT_VERSION = $(shell cd $(src); git describe --always --dirty --long --tags)
...@@ -15,10 +10,6 @@ else ...@@ -15,10 +10,6 @@ else
ccflags-y += -DCERN_SUPER_MODULE="" ccflags-y += -DCERN_SUPER_MODULE=""
endif endif
# The library includes <sdb.h>, so point -I directtly there
# include our header before to avoid conflicts with the kernel
LINUXINCLUDE := -I$(FMC_BUS)/kernel/include $(LINUXINCLUDE)
ccflags-y += -DGIT_VERSION=\"$(GIT_VERSION)\" \ ccflags-y += -DGIT_VERSION=\"$(GIT_VERSION)\" \
-I$(src) \ -I$(src) \
-I$(src)/../include -I$(src)/../include
......
...@@ -35,14 +35,19 @@ ...@@ -35,14 +35,19 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/platform_device.h>
#include <linux/fmc-sdb.h>
#include <hw/mockturtle_cpu_csr.h> #include <hw/mockturtle_cpu_csr.h>
#include <hw/mockturtle_queue.h> #include <hw/mockturtle_queue.h>
#include "mockturtle-drv.h" #include "mockturtle-drv.h"
struct trtl_memory_ops memops = {
.read =NULL,
.write = NULL,
};
static int trtl_dev_uevent(struct device *dev, struct kobj_uevent_env *env) static int trtl_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{ {
add_uevent_var(env, "DEVMODE=%#o", 0440); add_uevent_var(env, "DEVMODE=%#o", 0440);
...@@ -297,7 +302,7 @@ static void trtl_dev_release(struct device *dev) ...@@ -297,7 +302,7 @@ static void trtl_dev_release(struct device *dev)
static long trtl_ioctl_io(struct trtl_dev *trtl, void __user *uarg) static long trtl_ioctl_io(struct trtl_dev *trtl, void __user *uarg)
{ {
struct trtl_smem_io io; struct trtl_smem_io io;
uint32_t addr; void *addr;
int err; int err;
/* Copy the message from user space*/ /* Copy the message from user space*/
...@@ -359,7 +364,8 @@ static ssize_t trtl_write(struct file *f, const char __user *buf, ...@@ -359,7 +364,8 @@ static ssize_t trtl_write(struct file *f, const char __user *buf,
size_t count, loff_t *offp) size_t count, loff_t *offp)
{ {
struct trtl_dev *trtl = f->private_data; struct trtl_dev *trtl = f->private_data;
uint32_t val, addr; uint32_t val;
void *addr;
int err, i; int err, i;
if (*offp + count >= TRTL_SMEM_MAX_SIZE) if (*offp + count >= TRTL_SMEM_MAX_SIZE)
...@@ -394,7 +400,8 @@ static ssize_t trtl_read(struct file *f, char __user *buf, ...@@ -394,7 +400,8 @@ static ssize_t trtl_read(struct file *f, char __user *buf,
size_t count, loff_t *offp) size_t count, loff_t *offp)
{ {
struct trtl_dev *trtl = f->private_data; struct trtl_dev *trtl = f->private_data;
uint32_t val, addr; uint32_t val;
void *addr;
int err, i; int err, i;
if (*offp + count >= TRTL_SMEM_MAX_SIZE) if (*offp + count >= TRTL_SMEM_MAX_SIZE)
...@@ -470,7 +477,7 @@ static void trtl_hmq_release(struct device *dev) ...@@ -470,7 +477,7 @@ static void trtl_hmq_release(struct device *dev)
static int trtl_probe_hmq(struct trtl_dev *trtl, unsigned int slot, static int trtl_probe_hmq(struct trtl_dev *trtl, unsigned int slot,
unsigned int is_input) unsigned int is_input)
{ {
struct fmc_device *fmc = to_fmc_dev(trtl); struct platform_device *pdev = to_pdev_dev(trtl);
struct trtl_hmq *hmq; struct trtl_hmq *hmq;
uint32_t val; uint32_t val;
int err; int err;
...@@ -486,7 +493,7 @@ static int trtl_probe_hmq(struct trtl_dev *trtl, unsigned int slot, ...@@ -486,7 +493,7 @@ static int trtl_probe_hmq(struct trtl_dev *trtl, unsigned int slot,
return err; return err;
err = dev_set_name(&hmq->dev, "trtl-%04x-hmq-%c-%02d", err = dev_set_name(&hmq->dev, "trtl-%04x-hmq-%c-%02d",
fmc->device_id, is_input ? 'i':'o', hmq->index); pdev->id, is_input ? 'i':'o', hmq->index);
if (err) if (err)
return err; return err;
...@@ -538,28 +545,72 @@ static int trtl_probe_hmq(struct trtl_dev *trtl, unsigned int slot, ...@@ -538,28 +545,72 @@ static int trtl_probe_hmq(struct trtl_dev *trtl, unsigned int slot,
return 0; return 0;
} }
static int trtl_resource_validation(struct platform_device *pdev)
{
struct resource *r;
r = platform_get_resource(pdev, IORESOURCE_IRQ, TRTL_IRQ_HMQ);
if (!r) {
dev_err(&pdev->dev,
"Mock Turtle need an interrupt source for the Host Message Queue\n");
return -ENXIO;
}
r = platform_get_resource(pdev, IORESOURCE_IRQ, TRTL_IRQ_DBG);
if (!r) {
dev_err(&pdev->dev,
"Mock Turtle debug interrupt source missing, no debug information will be provided\n");
}
r = platform_get_resource(pdev, IORESOURCE_MEM, TRTL_MEM_BASE);
if (!r) {
dev_err(&pdev->dev,
"Mock Turtle need base address\n");
return -ENXIO;
}
return 0;
}
/** /**
* It initialize the WRNC device (device, CPUs, HMQs) * It initialize the WRNC device (device, CPUs, HMQs)
*/ */
int trtl_probe(struct fmc_device *fmc) int trtl_probe(struct platform_device *pdev)
{ {
struct trtl_dev *trtl; struct trtl_dev *trtl;
int err, i; int err, i;
uint32_t tmp; uint32_t tmp;
struct resource *r;
/* Create a WRNC instance */ err = trtl_resource_validation(pdev);
trtl = devm_kzalloc(&fmc->dev, sizeof(struct trtl_dev), GFP_KERNEL); if (err)
return err;
/* Create a MockTurtle instance */
trtl = devm_kzalloc(&pdev->dev, sizeof(struct trtl_dev), GFP_KERNEL);
if (!trtl) if (!trtl)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&trtl->lock_cpu_sel); spin_lock_init(&trtl->lock_cpu_sel);
fmc_set_drvdata(fmc, trtl); platform_set_drvdata(pdev, trtl);
err = fmc_scan_sdb_tree(fmc, 0x0); /* Assign IO operation */
if (err < 0 && err != -EBUSY) { switch (pdev->id_entry->driver_data) {
dev_err(fmc->hwdev, "SDB is missing\n"); case TRTL_VER_SPEC:
return err; memops.read = ioread32;
memops.write = iowrite32;
break;
case TRTL_VER_SVEC:
memops.read = ioread32be;
memops.write = iowrite32be;
break;
default:
dev_err(&trtl->dev, "Unknow version %lu\n",
pdev->id_entry->driver_data);
return -EINVAL;
} }
trtl->base_core = fmc_find_sdb_device(fmc->sdb, 0xce42, 0x90de, NULL);
r = platform_get_resource(pdev, IORESOURCE_MEM, TRTL_MEM_BASE);
trtl->base_core = ioremap(r->start, resource_size(r));
/* FIXME use SDB - <base> + <CSR offset> */ /* FIXME use SDB - <base> + <CSR offset> */
trtl->base_csr = trtl->base_core + 0xC000; trtl->base_csr = trtl->base_core + 0xC000;
trtl->base_smem = trtl->base_core + 0x10000; trtl->base_smem = trtl->base_core + 0x10000;
...@@ -567,14 +618,14 @@ int trtl_probe(struct fmc_device *fmc) ...@@ -567,14 +618,14 @@ int trtl_probe(struct fmc_device *fmc)
trtl->base_gcr = trtl->base_hmq + MQUEUE_BASE_GCR; trtl->base_gcr = trtl->base_hmq + MQUEUE_BASE_GCR;
/* Register the device */ /* Register the device */
err = dev_set_name(&trtl->dev, "trtl-%04x", fmc->device_id); err = dev_set_name(&trtl->dev, "trtl-%04x", pdev->id);
if (err) if (err)
return err; return err;
err = trtl_minor_get(&trtl->dev, TRTL_DEV); err = trtl_minor_get(&trtl->dev, TRTL_DEV);
if (err) if (err)
return err; return err;
trtl->dev.class = &trtl_cdev_class; trtl->dev.class = &trtl_cdev_class;
trtl->dev.parent = &fmc->dev; trtl->dev.parent = &pdev->dev;
trtl->dev.groups = trtl_dev_groups; trtl->dev.groups = trtl_dev_groups;
trtl->dev.release = trtl_dev_release; trtl->dev.release = trtl_dev_release;
err = device_register(&trtl->dev); err = device_register(&trtl->dev);
...@@ -591,17 +642,17 @@ int trtl_probe(struct fmc_device *fmc) ...@@ -591,17 +642,17 @@ int trtl_probe(struct fmc_device *fmc)
/* Get the Application ID */ /* Get the Application ID */
trtl->app_id = trtl_ioread(trtl, trtl->base_csr + WRN_CPU_CSR_REG_APP_ID); trtl->app_id = trtl_ioread(trtl, trtl->base_csr + WRN_CPU_CSR_REG_APP_ID);
dev_info(&fmc->dev, "Application ID: 0x%08x\n", trtl->app_id); dev_info(&pdev->dev, "Application ID: 0x%08x\n", trtl->app_id);
/* Get and check the number of COREs */ /* Get and check the number of COREs */
trtl->n_cpu = trtl_ioread(trtl, trtl->n_cpu = trtl_ioread(trtl,
trtl->base_csr + WRN_CPU_CSR_REG_CORE_COUNT); trtl->base_csr + WRN_CPU_CSR_REG_CORE_COUNT);
if (trtl->n_cpu < 1 || trtl->n_cpu > TRTL_MAX_CPU) { if (trtl->n_cpu < 1 || trtl->n_cpu > TRTL_MAX_CPU) {
dev_err(&fmc->dev, "invalid number of CPU (%d)\n", trtl->n_cpu); dev_err(&pdev->dev, "invalid number of CPU (%d)\n", trtl->n_cpu);
err = -EINVAL; err = -EINVAL;
goto out_n_cpu; goto out_n_cpu;
} }
dev_info(&fmc->dev, "Detected %d CPUs\n", trtl->n_cpu); dev_info(&pdev->dev, "Detected %d CPUs\n", trtl->n_cpu);
/* Pause all CPUs */ /* Pause all CPUs */
trtl_cpu_enable_set(trtl, (1 << trtl->n_cpu) - 1); trtl_cpu_enable_set(trtl, (1 << trtl->n_cpu) - 1);
...@@ -617,7 +668,7 @@ int trtl_probe(struct fmc_device *fmc) ...@@ -617,7 +668,7 @@ int trtl_probe(struct fmc_device *fmc)
if (err) if (err)
goto out_cpu; goto out_cpu;
err = dev_set_name(&trtl->cpu[i].dev, "trtl-%04x-cpu-%02d", err = dev_set_name(&trtl->cpu[i].dev, "trtl-%04x-cpu-%02d",
fmc->device_id, trtl->cpu[i].index); pdev->id, trtl->cpu[i].index);
if (err) if (err)
goto out_cpu; goto out_cpu;
trtl->cpu[i].dev.class = &trtl_cdev_class; trtl->cpu[i].dev.class = &trtl_cdev_class;
...@@ -635,12 +686,12 @@ int trtl_probe(struct fmc_device *fmc) ...@@ -635,12 +686,12 @@ int trtl_probe(struct fmc_device *fmc)
trtl->n_hmq_out = (tmp & MQUEUE_GCR_SLOT_COUNT_N_OUT_MASK) >> trtl->n_hmq_out = (tmp & MQUEUE_GCR_SLOT_COUNT_N_OUT_MASK) >>
MQUEUE_GCR_SLOT_COUNT_N_OUT_SHIFT; MQUEUE_GCR_SLOT_COUNT_N_OUT_SHIFT;
if (trtl->n_hmq_in + trtl->n_hmq_out >= TRTL_MAX_HMQ_SLOT) { if (trtl->n_hmq_in + trtl->n_hmq_out >= TRTL_MAX_HMQ_SLOT) {
dev_err(&fmc->dev, "trtl: invalid number of HMQ slots (in %d out %d)\n", dev_err(&pdev->dev, "trtl: invalid number of HMQ slots (in %d out %d)\n",
trtl->n_hmq_in, trtl->n_hmq_out); trtl->n_hmq_in, trtl->n_hmq_out);
err = -EINVAL; err = -EINVAL;
goto out_n_slot; goto out_n_slot;
} }
dev_info(&fmc->dev, "Detected slots: %d input, %d output\n", dev_info(&pdev->dev, "Detected slots: %d input, %d output\n",
trtl->n_hmq_in, trtl->n_hmq_out); trtl->n_hmq_in, trtl->n_hmq_out);
/* Configure slots */ /* Configure slots */
...@@ -659,14 +710,13 @@ int trtl_probe(struct fmc_device *fmc) ...@@ -659,14 +710,13 @@ int trtl_probe(struct fmc_device *fmc)
* Great everything is configured properly, we can enable the interrupts * Great everything is configured properly, we can enable the interrupts
* now and start working. * now and start working.
*/ */
fmc->irq = trtl->base_core; r = platform_get_resource(pdev, IORESOURCE_IRQ, TRTL_IRQ_HMQ);
err = fmc_irq_request(fmc, trtl_irq_handler, err = request_irq(r->start, trtl_irq_handler, 0,
(char *)dev_name(&trtl->dev), r->name, trtl);
0 /*VIC is used */);
if (err) { if (err) {
dev_err(&trtl->dev, dev_err(&trtl->dev,
"Cannot request IRQ 0x%x - we'll not receive/send messages\n", "Cannot request IRQ %lld - we'll not receive/send messages\n",
fmc->irq); r->start);
} }
/* Enable only necessary interrupts */ /* Enable only necessary interrupts */
...@@ -682,12 +732,10 @@ int trtl_probe(struct fmc_device *fmc) ...@@ -682,12 +732,10 @@ int trtl_probe(struct fmc_device *fmc)
if (err) if (err)
dev_err(&trtl->dev, "Console not available (err: %d)\n", -err); dev_err(&trtl->dev, "Console not available (err: %d)\n", -err);
/* Pin the carrier */ /* TODO Pin the carrier - do we need this? */
if (!try_module_get(fmc->owner))
goto out_mod;
return 0; return 0;
out_mod:
out_hmq_out: out_hmq_out:
while (--i) while (--i)
device_unregister(&trtl->hmq_out[i].dev); device_unregister(&trtl->hmq_out[i].dev);
...@@ -710,18 +758,15 @@ out_dbg: ...@@ -710,18 +758,15 @@ out_dbg:
/** /**
* It remove the WRNC device (device, CPUs, HMQs) and free irq handler * It remove the WRNC device (device, CPUs, HMQs) and free irq handler
*/ */
int trtl_remove(struct fmc_device *fmc) int trtl_remove(struct platform_device *pdev)
{ {
struct trtl_dev *trtl = fmc_get_drvdata(fmc); struct trtl_dev *trtl = platform_get_drvdata(pdev);
int i; int i;
trtl_tty_remove(trtl); trtl_tty_remove(trtl);
trtl_iowrite(trtl, 0x0, trtl->base_gcr + MQUEUE_GCR_IRQ_MASK); trtl_iowrite(trtl, 0x0, trtl->base_gcr + MQUEUE_GCR_IRQ_MASK);
fmc->irq = trtl->base_core; free_irq(platform_get_irq(pdev, TRTL_IRQ_HMQ), trtl);
fmc_irq_free(fmc);
trtl_iowrite(trtl, 0x0, trtl->base_csr + WRN_CPU_CSR_REG_DBG_IMSK);
debugfs_remove_recursive(trtl->dbg_dir); debugfs_remove_recursive(trtl->dbg_dir);
...@@ -738,31 +783,30 @@ int trtl_remove(struct fmc_device *fmc) ...@@ -738,31 +783,30 @@ int trtl_remove(struct fmc_device *fmc)
msleep(50); msleep(50);
device_unregister(&trtl->dev); device_unregister(&trtl->dev);
/* Release the carrier */ /* TODO Release the carrier - symmetric to pin */
module_put(fmc->owner);
return 0; return 0;
} }
static const struct platform_device_id trtl_id[] = {
/**
* List of device to match.
*/
static struct fmc_fru_id trtl_fru_id[] = {
{ {
.product_name = "wr-node-core" .name = "mock-turtle-spec",
.driver_data = TRTL_VER_SPEC,
}, {
.name = "mock-turtle-svec",
.driver_data = TRTL_VER_SVEC,
}, },
/* TODO we should support different version */
}; };
static struct fmc_driver trtl_dev_drv = { static struct platform_driver trtl_platform_driver = {
.version = FMC_VERSION, .driver = {
.driver.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
},
.probe = trtl_probe, .probe = trtl_probe,
.remove = trtl_remove, .remove = trtl_remove,
.id_table = { .id_table = trtl_id,
.fru_id = trtl_fru_id,
.fru_id_nr = ARRAY_SIZE(trtl_fru_id),
},
}; };
struct tty_driver trtl_tty_driver = { struct tty_driver trtl_tty_driver = {
...@@ -779,7 +823,7 @@ struct tty_driver trtl_tty_driver = { ...@@ -779,7 +823,7 @@ struct tty_driver trtl_tty_driver = {
}; };
/** /**
* Allocate resources for the driver. Char devices and FMC driver * Allocate resources for the driver. Char devices and platform driver
*/ */
static int trtl_init(void) static int trtl_init(void)
{ {
...@@ -834,8 +878,8 @@ static int trtl_init(void) ...@@ -834,8 +878,8 @@ static int trtl_init(void)
goto out_tty; goto out_tty;
} }
/* Register the FMC driver */ /* Register the platform driver */
err = fmc_driver_register(&trtl_dev_drv); err = platform_driver_register(&trtl_platform_driver);
if (err) if (err)
goto out_reg; goto out_reg;
...@@ -864,8 +908,9 @@ out_all: ...@@ -864,8 +908,9 @@ out_all:
*/ */
static void trtl_exit(void) static void trtl_exit(void)
{ {
fmc_driver_unregister(&trtl_dev_drv);
tty_unregister_driver(&trtl_tty_driver); tty_unregister_driver(&trtl_tty_driver);
platform_driver_unregister(&trtl_platform_driver);
cdev_del(&cdev_hmq); cdev_del(&cdev_hmq);
cdev_del(&cdev_cpu); cdev_del(&cdev_cpu);
cdev_del(&cdev_dev); cdev_del(&cdev_dev);
......
...@@ -22,10 +22,9 @@ ...@@ -22,10 +22,9 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/uaccess.h>
#include <linux/fmc.h>
#include <hw/mockturtle_cpu_csr.h> #include <hw/mockturtle_cpu_csr.h>
#include "mockturtle-drv.h" #include "mockturtle-drv.h"
......
...@@ -20,8 +20,9 @@ ...@@ -20,8 +20,9 @@
#ifndef __TRTL_H__ #ifndef __TRTL_H__
#define __TRTL_H__ #define __TRTL_H__
#include <linux/platform_device.h>
#include <linux/irqreturn.h>
#include <linux/circ_buf.h> #include <linux/circ_buf.h>
#include <linux/fmc.h>
#include <linux/tty.h> #include <linux/tty.h>
#include "hw/mockturtle_queue.h" #include "hw/mockturtle_queue.h"
...@@ -35,7 +36,7 @@ ...@@ -35,7 +36,7 @@
#define to_trtl_cpu(_dev) (container_of(_dev, struct trtl_cpu, dev)) #define to_trtl_cpu(_dev) (container_of(_dev, struct trtl_cpu, dev))
#define to_trtl_dev(_dev) (container_of(_dev, struct trtl_dev, dev)) #define to_trtl_dev(_dev) (container_of(_dev, struct trtl_dev, dev))
#define to_fmc_dev(_trtl) (container_of(_trtl->dev.parent, struct fmc_device, dev)) #define to_pdev_dev(_trtl) (container_of(_trtl->dev.parent, struct platform_device, dev))
#define to_trtl_hmq(_dev) (container_of(_dev, struct trtl_hmq, dev)) #define to_trtl_hmq(_dev) (container_of(_dev, struct trtl_hmq, dev))
#define TRTL_FLAG_HMQ_DIR (1 << 0) /**< 1 CPU input, 0 CPU output */ #define TRTL_FLAG_HMQ_DIR (1 << 0) /**< 1 CPU input, 0 CPU output */
...@@ -46,6 +47,23 @@ ...@@ -46,6 +47,23 @@
#define TRTL_FLAG_HMQ_SYNC_WAIT (1 << 3) /**< wait sync answer */ #define TRTL_FLAG_HMQ_SYNC_WAIT (1 << 3) /**< wait sync answer */
#define TRTL_FLAG_HMQ_SYNC_READY (1 << 4) /**< sync answer is ready */ #define TRTL_FLAG_HMQ_SYNC_READY (1 << 4) /**< sync answer is ready */
extern struct class trtl_cdev_class;
enum mock_turtle_versions {
TRTL_VER_SPEC = 0,
TRTL_VER_SVEC,
/* TODO actually all versioning */
};
enum mockturtle_irq_resource {
TRTL_IRQ_HMQ = 0,
TRTL_IRQ_DBG,
};
enum mockturtle_mem_resource {
TRTL_MEM_BASE = 0,
};
static inline uint32_t trtl_get_sequence(struct trtl_msg *msg) static inline uint32_t trtl_get_sequence(struct trtl_msg *msg)
{ {
...@@ -57,6 +75,12 @@ struct trtl_msg_filter_element { ...@@ -57,6 +75,12 @@ struct trtl_msg_filter_element {
struct list_head list; struct list_head list;
}; };
struct trtl_memory_ops {
u32 (*read)(void *addr);
void (*write)(u32 value, void *addr);
};
extern struct trtl_memory_ops memops;
/** /**
* Available type of devices * Available type of devices
...@@ -111,7 +135,7 @@ struct trtl_hmq { ...@@ -111,7 +135,7 @@ struct trtl_hmq {
uint32_t status; /**< describe the status of the HMQ slot from the uint32_t status; /**< describe the status of the HMQ slot from the
cpu point of view */ cpu point of view */
uint32_t base_sr; /**< base address of the slot register */ void *base_sr; /**< base address of the slot register */
struct list_head list_msg_input; /**< list of messages to struct list_head list_msg_input; /**< list of messages to
input slot */ input slot */
unsigned int n_input; /**< number of messages in the list */ unsigned int n_input; /**< number of messages in the list */
...@@ -183,12 +207,12 @@ struct trtl_dev { ...@@ -183,12 +207,12 @@ struct trtl_dev {
unsigned int n_hmq_out; /**< number of output slots in the HMQ */ unsigned int n_hmq_out; /**< number of output slots in the HMQ */
struct trtl_hmq hmq_in[MAX_MQUEUE_SLOTS]; /**< HMQ input instances */ struct trtl_hmq hmq_in[MAX_MQUEUE_SLOTS]; /**< HMQ input instances */
struct trtl_hmq hmq_out[MAX_MQUEUE_SLOTS]; /**< HMQ output instances */ struct trtl_hmq hmq_out[MAX_MQUEUE_SLOTS]; /**< HMQ output instances */
uint32_t base_core; /**< base address of the WRNC component */ void *base_core; /**< base address of the WRNC component */
uint32_t base_csr; /**< base address of the Shared Control Register */ void *base_csr; /**< base address of the Shared Control Register */
uint32_t base_hmq; /**< base address of the HMQ */ void *base_hmq; /**< base address of the HMQ */
uint32_t base_gcr; /**< base address of the Global Control Register void *base_gcr; /**< base address of the Global Control Register
for the HMQ */ for the HMQ */
uint32_t base_smem; /**< base address of the Shared Memory */ void *base_smem; /**< base address of the Shared Memory */
uint32_t irq_mask; /**< IRQ mask in use */ uint32_t irq_mask; /**< IRQ mask in use */
enum trtl_smem_modifier mod; /**< smem operation modifier */ enum trtl_smem_modifier mod; /**< smem operation modifier */
...@@ -199,19 +223,15 @@ struct trtl_dev { ...@@ -199,19 +223,15 @@ struct trtl_dev {
struct spinlock lock_cpu_sel; struct spinlock lock_cpu_sel;
}; };
static inline u32 trtl_ioread(struct trtl_dev *trtl, int addr) static inline u32 trtl_ioread(struct trtl_dev *trtl, void *addr)
{ {
struct fmc_device *fmc = to_fmc_dev(trtl); return memops.read(addr);
return fmc_readl(fmc, addr);
} }
static inline void trtl_iowrite(struct trtl_dev *trtl, static inline void trtl_iowrite(struct trtl_dev *trtl,
u32 value, int addr) u32 value, void *addr)
{ {
struct fmc_device *fmc = to_fmc_dev(trtl); return memops.write(value, addr);
fmc_writel(fmc, value, addr);
} }
/* Global data */ /* Global data */
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <linux/circ_buf.h> #include <linux/circ_buf.h>
#include <hw/mockturtle_queue.h> #include <hw/mockturtle_queue.h>
#include <hw/mockturtle_cpu_csr.h>
#include "mockturtle-drv.h" #include "mockturtle-drv.h"
int hmq_default_buf_size = 8192; /**< default buffer size in byte */ int hmq_default_buf_size = 8192; /**< default buffer size in byte */
...@@ -1001,8 +1001,7 @@ static void trtl_irq_handler_output(struct trtl_hmq *hmq) ...@@ -1001,8 +1001,7 @@ static void trtl_irq_handler_output(struct trtl_hmq *hmq)
*/ */
irqreturn_t trtl_irq_handler(int irq_core_base, void *arg) irqreturn_t trtl_irq_handler(int irq_core_base, void *arg)
{ {
struct fmc_device *fmc = arg; struct trtl_dev *trtl =arg;
struct trtl_dev *trtl = fmc_get_drvdata(fmc);
uint32_t status; uint32_t status;
int i, j, n_disp = 0; int i, j, n_disp = 0;
...@@ -1038,7 +1037,7 @@ irqreturn_t trtl_irq_handler(int irq_core_base, void *arg) ...@@ -1038,7 +1037,7 @@ irqreturn_t trtl_irq_handler(int irq_core_base, void *arg)
if (status && n_disp < hmq_max_irq_loop) if (status && n_disp < hmq_max_irq_loop)
goto dispatch_irq; goto dispatch_irq;
fmc_irq_ack(fmc); /* TODO irq_ack - should be done by vic chip */
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -105,8 +105,7 @@ static void trtl_tty_handler_getchar(struct trtl_cpu *cpu) ...@@ -105,8 +105,7 @@ static void trtl_tty_handler_getchar(struct trtl_cpu *cpu)
static irqreturn_t trtl_tty_handler(int irq, void *arg) static irqreturn_t trtl_tty_handler(int irq, void *arg)
{ {
struct fmc_device *fmc = arg; struct trtl_dev *trtl = arg;
struct trtl_dev *trtl = fmc_get_drvdata(fmc);
uint32_t status; uint32_t status;
int i, max_irq = 32, lock; int i, max_irq = 32, lock;
...@@ -215,14 +214,13 @@ static void trtl_tty_port_exit(struct trtl_cpu *cpu) ...@@ -215,14 +214,13 @@ static void trtl_tty_port_exit(struct trtl_cpu *cpu)
void trtl_tty_remove(struct trtl_dev *trtl) void trtl_tty_remove(struct trtl_dev *trtl)
{ {
struct fmc_device *fmc = to_fmc_dev(trtl); struct platform_device *pdev = to_pdev_dev(trtl);
int i; int i;
/* Disable the interrupts on the Mock Turtle */ /* Disable the interrupts on the Mock Turtle */
trtl_iowrite(trtl, 0x0, trtl->base_csr + WRN_CPU_CSR_REG_DBG_IMSK); trtl_iowrite(trtl, 0x0, trtl->base_csr + WRN_CPU_CSR_REG_DBG_IMSK);
fmc->irq = trtl->base_core + 1; free_irq(platform_get_irq(pdev, TRTL_IRQ_DBG), trtl);
fmc_irq_free(fmc);
for (i = 0; i < trtl->n_cpu; ++i) for (i = 0; i < trtl->n_cpu; ++i)
trtl_tty_port_exit(&trtl->cpu[i]); trtl_tty_port_exit(&trtl->cpu[i]);
...@@ -231,7 +229,8 @@ void trtl_tty_remove(struct trtl_dev *trtl) ...@@ -231,7 +229,8 @@ void trtl_tty_remove(struct trtl_dev *trtl)
int trtl_tty_probe(struct trtl_dev *trtl) int trtl_tty_probe(struct trtl_dev *trtl)
{ {
struct fmc_device *fmc = to_fmc_dev(trtl); struct platform_device *pdev = to_pdev_dev(trtl);
struct resource *r;
int i, err; int i, err;
for (i = 0; i < trtl->n_cpu; ++i) { for (i = 0; i < trtl->n_cpu; ++i) {
...@@ -240,13 +239,18 @@ int trtl_tty_probe(struct trtl_dev *trtl) ...@@ -240,13 +239,18 @@ int trtl_tty_probe(struct trtl_dev *trtl)
goto err_port; goto err_port;
} }
/* Enable debug interrupts */ r = platform_get_resource(pdev, IORESOURCE_IRQ, TRTL_IRQ_DBG);
fmc->irq = trtl->base_core + 1; if (r) {
err = fmc_irq_request(fmc, trtl_tty_handler, /* Enable debug interrupts */
(char *)dev_name(&trtl->cpu[i].dev), err = request_irq(r->start, trtl_tty_handler, 0,
0 /*VIC is used */); r->name, trtl);
if (err) if (err) {
goto err_irq; dev_err(&trtl->dev,
"Cannot request IRQ %lld - we'll not receive debug messages\n",
r->start);
goto err_irq;
}
}
return 0; return 0;
......
...@@ -67,7 +67,7 @@ class Wrnc(object): ...@@ -67,7 +67,7 @@ class Wrnc(object):
self.device = None self.device = None
if device_id is not None: if device_id is not None:
self.device = self.libwrnc.wrnc_open_by_fmc(self.device_id) self.device = self.libwrnc.wrnc_open_by_id(self.device_id)
if lun is not None: if lun is not None:
self.device = self.libwrnc.wrnc_open_by_lun(self.lun) self.device = self.libwrnc.wrnc_open_by_lun(self.lun)
......
...@@ -211,13 +211,13 @@ out_stat: ...@@ -211,13 +211,13 @@ out_stat:
/** /**
* It opens a WRNC device using its FMC device_id. The white-rabbit node-core * It opens a WRNC device using its device_id. The white-rabbit node-core
* driver is based upon the FMC bus infrastructure, so all trtl devices are * driver is based upon the platform bus infrastructure, so all trtl devices are
* identified with their fmc-bus-id. * identified with their platform id.
* @param[in] device_id FMC device id of the device to use * @param[in] device_id device id of the device to use
* @return the WRNC token, NULL on error and errno is appropriately set * @return the WRNC token, NULL on error and errno is appropriately set
*/ */
struct trtl_dev *trtl_open_by_fmc(uint32_t device_id) struct trtl_dev *trtl_open_by_id(uint32_t device_id)
{ {
char name[12]; char name[12];
...@@ -230,9 +230,9 @@ struct trtl_dev *trtl_open_by_fmc(uint32_t device_id) ...@@ -230,9 +230,9 @@ struct trtl_dev *trtl_open_by_fmc(uint32_t device_id)
* It opens a WRNC device using its Logical Unit Number. The Logical Unit Number * It opens a WRNC device using its Logical Unit Number. The Logical Unit Number
* is an instance number of a particular hardware. The LUN to use is the carrier * is an instance number of a particular hardware. The LUN to use is the carrier
* one, and not the mezzanine one (if any). * one, and not the mezzanine one (if any).
* The driver is not aware of LUNs but only of FMC-id. So, if this function does * The driver is not aware of LUNs but only of device-id. So, if this function does
* not work it means that your installation lacks of symbolic links that * not work it means that your installation lacks of symbolic links that
* convert LUNs to FMC-ids. * convert LUNs to device-ids.
* @param[in] lun Logical Unit Number of the device to use * @param[in] lun Logical Unit Number of the device to use
* @return the WRNC token, NULL on error and errno is appropriately set * @return the WRNC token, NULL on error and errno is appropriately set
*/ */
...@@ -255,13 +255,13 @@ struct trtl_dev *trtl_open_by_lun(unsigned int lun) ...@@ -255,13 +255,13 @@ struct trtl_dev *trtl_open_by_lun(unsigned int lun)
return NULL; return NULL;
} }
return trtl_open_by_fmc(dev_id); return trtl_open_by_id(dev_id);
} }
/** /**
* It closes a WRNC device opened with one of the following functions: * It closes a WRNC device opened with one of the following functions:
* trtl_open(), wrcn_open_by_lun(), trtl_open_by_fmc() * trtl_open(), wrcn_open_by_lun(), trtl_open_by_id()
* @param[in] trtl device token * @param[in] trtl device token
*/ */
void trtl_close(struct trtl_dev *trtl) void trtl_close(struct trtl_dev *trtl)
......
...@@ -64,9 +64,6 @@ struct trtl_hmq { ...@@ -64,9 +64,6 @@ struct trtl_hmq {
int fd; /**< file descriptor */ int fd; /**< file descriptor */
}; };
#define TRTL_FMC_OFFSET 2 /* FIXME this is an hack because fmc-bus does not allow
us a dynamic allocation of fake fmc devices */
#define TRTL_NAME_LEN 16 #define TRTL_NAME_LEN 16
#define TRTL_PATH_LEN 32 #define TRTL_PATH_LEN 32
...@@ -119,7 +116,7 @@ extern char **trtl_list(); ...@@ -119,7 +116,7 @@ extern char **trtl_list();
extern void trtl_list_free(char **list); extern void trtl_list_free(char **list);
extern struct trtl_dev *trtl_open(const char *device); extern struct trtl_dev *trtl_open(const char *device);
extern struct trtl_dev *trtl_open_by_fmc(uint32_t device_id); extern struct trtl_dev *trtl_open_by_id(uint32_t device_id);
extern struct trtl_dev *trtl_open_by_lun(unsigned int lun) __attribute__((deprecated)); extern struct trtl_dev *trtl_open_by_lun(unsigned int lun) __attribute__((deprecated));
extern void trtl_close(struct trtl_dev *trtl); extern void trtl_close(struct trtl_dev *trtl);
extern char *trtl_name_get(struct trtl_dev *trtl); extern char *trtl_name_get(struct trtl_dev *trtl);
......
...@@ -87,7 +87,7 @@ int main(int argc, char *argv[]) ...@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
/* Open all devices */ /* Open all devices */
for (i = 0; i < di; i++) { for (i = 0; i < di; i++) {
trtl[i] = trtl_open_by_fmc(dev_id[i]); trtl[i] = trtl_open_by_id(dev_id[i]);
if (!trtl[i]) { if (!trtl[i]) {
fprintf(stderr, "Cannot open Mock Turtle device: %s\n", fprintf(stderr, "Cannot open Mock Turtle device: %s\n",
trtl_strerror(errno)); trtl_strerror(errno));
......
...@@ -87,7 +87,7 @@ int main(int argc, char *argv[]) ...@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
} }
trtl = trtl_open_by_fmc(dev_id); trtl = trtl_open_by_id(dev_id);
if (!trtl) { if (!trtl) {
fprintf(stderr, "Cannot open Mock Turtle device: %s\n", trtl_strerror(errno)); fprintf(stderr, "Cannot open Mock Turtle device: %s\n", trtl_strerror(errno));
exit(1); exit(1);
......
...@@ -141,7 +141,7 @@ void *message_thread(void *arg) ...@@ -141,7 +141,7 @@ void *message_thread(void *arg)
/* Open the device */ /* Open the device */
if (!trtl) if (!trtl)
trtl = trtl_open_by_fmc(th_data->dev_id); trtl = trtl_open_by_id(th_data->dev_id);
if (!trtl) { if (!trtl) {
fprintf(stderr, "Cannot open Mock Turtle device: %s\n", trtl_strerror(errno)); fprintf(stderr, "Cannot open Mock Turtle device: %s\n", trtl_strerror(errno));
......
...@@ -108,7 +108,7 @@ int main(int argc, char *argv[]) ...@@ -108,7 +108,7 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
trtl = trtl_open_by_fmc(dev_id); trtl = trtl_open_by_id(dev_id);
if (!trtl) { if (!trtl) {
fprintf(stderr, "Cannot open Mock Turtle device: %s\n", trtl_strerror(errno)); fprintf(stderr, "Cannot open Mock Turtle device: %s\n", trtl_strerror(errno));
exit(1); exit(1);
......
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