* [PATCH 00/12] Eberspaecher Flexcard PMC II base support
@ 2016-12-14 0:11 Holger Dengler
2016-12-14 0:11 ` [PATCH 01/12] mfd: Eberspaecher Flexcard PMC II Carrier Board support Holger Dengler
` (12 more replies)
0 siblings, 13 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler
The Eberspaecher Flexcard PMC II is a PMC (PCI Mezzanine Card) II
carrier board. The carrier board can take up to 4 exchangeable physical
layer boards for CAN, FlexRay or Ethernet.
This patchset adds support for the common infrastructure of the carrier
board.
This patch series apply on v4.9.
First post: http://www.spinics.net/lists/netdev/msg246290.html
Second post: http://www.spinics.net/lists/kernel/msg1954275.html
According to the comments regarding our first posting, the MFD driver
patchset has been split up into separate functional parts.
According to the comments regarding our second port, we moved the
separated driver to their particular subsystems. All other comments
are also reflected.
The timer functionality was wrongly named as clocksource in the second post,
although it is a posix_clock. We renamed it and moved it together with the
misc_device funtions to drivers/misc/. If someone know a better place for
the posix_clock, please let me know.
The irq part of the mfd driver has been mainly reworked (thanks to Thomas
and Sebastian for their input). The irq-demux is now implementet without a
loop and the irq_chips share the irq-table and functions.
Holger Dengler (12):
mfd: Eberspaecher Flexcard PMC II Carrier Board support
mfd: flexcard: add flexcard misc mfd-cell
mfd: flexcard: add posix clock mfd-cell
mfd: flexcard: add interrupt support
mfd: flexcard: add DMA interrupts
mfd: flexcard: add DMA device
mfd: flexcard: add UIO IRQ devices
misc: Flexcard misc device support
misc: flexcard: add device attributes
misc: Flexcard basic timestamp counter support
misc: flexcard: Support timestamp trigger selection
dma: Flexcard DMA ringbuffer demux driver
drivers/dma/Kconfig | 9 +
drivers/dma/Makefile | 1 +
drivers/dma/flexcard/Makefile | 2 +
drivers/dma/flexcard/core.c | 292 ++++++++++++++++++++++
drivers/dma/flexcard/flexcard-dma.h | 218 +++++++++++++++++
drivers/dma/flexcard/parser.c | 227 +++++++++++++++++
drivers/mfd/Kconfig | 14 ++
drivers/mfd/Makefile | 3 +
drivers/mfd/flexcard_core.c | 476 ++++++++++++++++++++++++++++++++++++
drivers/mfd/flexcard_irq.c | 305 +++++++++++++++++++++++
drivers/misc/Kconfig | 15 ++
drivers/misc/Makefile | 2 +
drivers/misc/flexcard_misc.c | 361 +++++++++++++++++++++++++++
drivers/misc/flexcard_posixclock.c | 295 ++++++++++++++++++++++
include/linux/mfd/flexcard.h | 116 +++++++++
include/uapi/linux/Kbuild | 1 +
include/uapi/linux/flexcard.h | 80 ++++++
17 files changed, 2417 insertions(+)
create mode 100644 drivers/dma/flexcard/Makefile
create mode 100644 drivers/dma/flexcard/core.c
create mode 100644 drivers/dma/flexcard/flexcard-dma.h
create mode 100644 drivers/dma/flexcard/parser.c
create mode 100644 drivers/mfd/flexcard_core.c
create mode 100644 drivers/mfd/flexcard_irq.c
create mode 100644 drivers/misc/flexcard_misc.c
create mode 100644 drivers/misc/flexcard_posixclock.c
create mode 100644 include/linux/mfd/flexcard.h
create mode 100644 include/uapi/linux/flexcard.h
--
2.1.4
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 01/12] mfd: Eberspaecher Flexcard PMC II Carrier Board support
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 8:38 ` Arnd Bergmann
2016-12-14 0:11 ` [PATCH 02/12] mfd: flexcard: add flexcard misc mfd-cell Holger Dengler
` (11 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Eberspaecher Flexcard PMC II is a PMC (PCI Mezzanine Card) II
carrier board. The carrier board can take up to 4 exchangeable physical
layer boards for e.g. CAN, FlexRay or Ethernet.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/Kconfig | 10 ++
drivers/mfd/Makefile | 2 +
drivers/mfd/flexcard_core.c | 218 ++++++++++++++++++++++++++++++++++++++++++
include/linux/mfd/flexcard.h | 103 ++++++++++++++++++++
include/uapi/linux/Kbuild | 1 +
include/uapi/linux/flexcard.h | 64 +++++++++++++
6 files changed, 398 insertions(+)
create mode 100644 drivers/mfd/flexcard_core.c
create mode 100644 include/linux/mfd/flexcard.h
create mode 100644 include/uapi/linux/flexcard.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c6df644..a5a12da 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -299,6 +299,16 @@ config MFD_EXYNOS_LPASS
Select this option to enable support for Samsung Exynos Low Power
Audio Subsystem.
+config MFD_FLEXCARD
+ tristate "Eberspaecher Flexcard PMC II Carrier Board"
+ select MFD_CORE
+ depends on PCI
+ help
+ This is the core driver for the Eberspaecher Flexcard
+ PMC (PCI Mezzanine Card) II carrier board. This carrier board
+ can take up to 4 exchangeable physical layer boards for
+ CAN, FlexRay or Ethernet.
+
config MFD_MC13XXX
tristate
depends on (SPI_MASTER || I2C)
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 9834e66..843e57c 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -211,3 +211,5 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
+flexcard-objs := flexcard_core.o
+obj-$(CONFIG_MFD_FLEXCARD) += flexcard.o
diff --git a/drivers/mfd/flexcard_core.c b/drivers/mfd/flexcard_core.c
new file mode 100644
index 0000000..e580971
--- /dev/null
+++ b/drivers/mfd/flexcard_core.c
@@ -0,0 +1,218 @@
+/*
+ * Eberspächer Flexcard PMC II Carrier Board PCI Driver
+ *
+ * Copyright (c) 2014 - 2016, Linutronix GmbH
+ * Author: Benedikt Spranger <b.spranger@linutronix.de>
+ * Holger Dengler <dengler@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/flexcard.h>
+
+#define FLEXCARD_CAN_OFFSET 0x2000
+#define FLEXCARD_CAN_SIZE 0x2000
+
+#define FLEXCARD_FR_OFFSET 0x4000
+#define FLEXCARD_FR_SIZE 0x2000
+
+enum flexcard_cell_id {
+ FLEXCARD_CELL_CAN,
+ FLEXCARD_CELL_FLEXRAY,
+};
+
+static int flexcard_tiny_can(struct flexcard_device *priv,
+ int idx, int id, u32 offset)
+{
+ struct mfd_cell *cell = &priv->cells[idx];
+ struct resource *res = &priv->res[idx];
+ struct pci_dev *pci = priv->pdev;
+
+ cell->name = "flexcard-dcan";
+ cell->resources = res;
+ cell->num_resources = 1;
+ cell->id = id;
+
+ res->name = "flexcard-dcan";
+ res->flags = IORESOURCE_MEM;
+ res->parent = &pci->resource[1];
+ res->start = pci->resource[1].start + offset;
+ res->end = res->start + FLEXCARD_CAN_SIZE - 1;
+
+ if (res->end > pci->resource[1].end)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int flexcard_tiny_flexray(struct flexcard_device *priv,
+ int idx, int id, u32 offset)
+{
+ struct mfd_cell *cell = &priv->cells[idx];
+ struct resource *res = &priv->res[idx];
+ struct pci_dev *pci = priv->pdev;
+
+ cell->name = "flexcard-eray";
+ cell->resources = res;
+ cell->num_resources = 1;
+ cell->id = id;
+
+ res->name = "flexcard-eray";
+ res->flags = IORESOURCE_MEM;
+ res->parent = &pci->resource[1];
+ res->start = pci->resource[1].start + offset;
+ res->end = res->start + FLEXCARD_FR_SIZE - 1;
+
+ if (res->end > pci->resource[1].end)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int flexcard_tiny_probe(struct flexcard_device *priv)
+{
+ struct pci_dev *pdev = priv->pdev;
+ u32 fc_slic0, offset = 0;
+ u8 nr_can, nr_fr, nr;
+ int i, ret;
+
+ /*
+ * Reading FC_LIC[0] register to determine the number of CAN and
+ * FlexRay Devices
+ */
+ fc_slic0 = readl(&priv->bar0->conf.fc_slic[0]);
+ nr_can = (fc_slic0 >> 4) & 0xf;
+ nr_fr = fc_slic0 & 0xf;
+ nr = nr_can + nr_fr;
+
+ dev_info(&pdev->dev, "tinys: CAN: %d FR: %d", nr_can, nr_fr);
+
+ priv->cells = devm_kzalloc(&pdev->dev, nr * sizeof(struct mfd_cell),
+ GFP_KERNEL);
+ if (!priv->cells)
+ return -ENOMEM;
+
+ priv->res = devm_kzalloc(&pdev->dev, nr * sizeof(struct resource),
+ GFP_KERNEL);
+ if (!priv->res)
+ return -ENOMEM;
+
+ for (i = 0; i < nr_fr; i++) {
+ ret = flexcard_tiny_flexray(priv, i, i, offset);
+ if (ret)
+ return ret;
+ offset += FLEXCARD_FR_OFFSET;
+ }
+
+ for (i = 0; i < nr_can; i++) {
+ ret = flexcard_tiny_can(priv, nr_fr + i, i, offset);
+ if (ret)
+ return ret;
+ offset += FLEXCARD_CAN_OFFSET;
+ }
+
+ return mfd_add_devices(&pdev->dev, 0, priv->cells, nr, NULL, 0, NULL);
+}
+
+static int flexcard_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct flexcard_device *priv;
+ union {
+ struct fc_version ver;
+ u32 reg;
+ } fw_ver, hw_ver;
+
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ pci_set_drvdata(pdev, priv);
+ priv->pdev = pdev;
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to enable device: %d\n", ret);
+ return ret;
+ }
+
+ pci_set_master(pdev);
+ ret = pci_request_regions(pdev, "flexcard");
+ if (ret) {
+ dev_err(&pdev->dev, "unable to request regions: %d\n", ret);
+ goto out_disable;
+ }
+
+ priv->bar0 = pci_ioremap_bar(pdev, 0);
+ if (!priv->bar0) {
+ dev_err(&pdev->dev, "unable to remap bar0 regs\n");
+ ret = -ENOMEM;
+ goto out_release;
+ }
+ fw_ver.reg = readl(&priv->bar0->conf.fc_fw_ver);
+ hw_ver.reg = readl(&priv->bar0->conf.fc_hw_ver);
+
+ ret = flexcard_tiny_probe(priv);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to probe tinys: %d", ret);
+ goto out_unmap;
+ }
+
+ dev_info(&pdev->dev, "HW %02x.%02x.%02x FW %02x.%02x.%02x\n",
+ hw_ver.ver.maj, hw_ver.ver.min, hw_ver.ver.dev,
+ fw_ver.ver.maj, fw_ver.ver.min, fw_ver.ver.dev);
+
+ return 0;
+
+out_unmap:
+ iounmap(priv->bar0);
+out_release:
+ pci_release_regions(pdev);
+out_disable:
+ pci_disable_device(pdev);
+
+ return ret;
+}
+
+static void flexcard_remove(struct pci_dev *pdev)
+{
+ struct flexcard_device *priv = pci_get_drvdata(pdev);
+
+ mfd_remove_devices(&pdev->dev);
+ iounmap(priv->bar0);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+#define PCI_VENDOR_ID_EBEL 0x1974
+
+static const struct pci_device_id flexcard_pci_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_EBEL, 0x0009), },
+ { }
+};
+MODULE_DEVICE_TABLE(pci, flexcard_pci_ids);
+
+static struct pci_driver flexcard_driver = {
+ .name = "flexcard",
+ .id_table = flexcard_pci_ids,
+ .probe = flexcard_probe,
+ .remove = flexcard_remove,
+};
+
+module_pci_driver(flexcard_driver);
+
+MODULE_AUTHOR("Holger Dengler <dengler@linutronix.de>");
+MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>");
+MODULE_DESCRIPTION("Eberspaecher Flexcard PMC II Carrier Board Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/flexcard.h b/include/linux/mfd/flexcard.h
new file mode 100644
index 0000000..362b909
--- /dev/null
+++ b/include/linux/mfd/flexcard.h
@@ -0,0 +1,103 @@
+/*
+ * Eberspächer Flexcard PMC II Carrier Board PCI Driver - device attributes
+ *
+ * Copyright (c) 2014 - 2016, Linutronix GmbH
+ * Author: Benedikt Spranger <b.spranger@linutronix.de>
+ * Holger Dengler <dengler@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_MFD_FLEXCARD_H
+#define _LINUX_MFD_FLEXCARD_H
+
+#include <uapi/linux/flexcard.h>
+
+/* PCI BAR 0: Flexcard DMA register */
+struct fc_bar0_dma {
+ __u32 dma_ctrl; /* 500 */
+ __u32 dma_stat; /* 504 */
+ __u32 r16[2]; /* 508 */
+ __u64 dma_cba; /* 510 */
+ __u32 dma_cbs; /* 518 */
+ __u32 dma_txr; /* 51c */
+ __u32 dma_irer; /* 520 */
+ __u32 dma_irsr; /* 524 */
+ __u32 r17[10]; /* 528 */
+ __u32 dma_cbcr; /* 550 */
+ __u32 dma_cblr; /* 554 */
+ __u32 r18[2]; /* 558 */
+ __u32 dma_itcr; /* 560 */
+ __u32 dma_itr; /* 564 */
+ __u32 r19[2]; /* 568 */
+ __u32 dma_wptr; /* 570 */
+ __u32 dma_rptr; /* 574 */
+} __packed;
+
+/* PCI BAR 0: Flexcard clock register */
+struct fc_bar0_time {
+ __u32 ts_high; /* 700 */
+ __u32 ts_low; /* 704 */
+ __u32 r21[2]; /* 708 */
+ __u32 clk_src; /* 710 */
+} __packed;
+
+struct fc_bar0_nf {
+ __u32 fc_nfctrl; /* 170 */
+ __u32 nf_cnt; /* 174 */
+} __packed;
+
+/* PCI BAR 0: Flexcard register */
+struct fc_bar0 {
+ struct fc_bar0_conf conf; /* 000-13c */
+ __u32 fc_ts; /* 140 */
+ __u32 fc_reset; /* 144 */
+ __u32 trig_sc_ctrl; /* 148 */
+ __u32 trig_ctrl; /* 14c */
+ __u32 r12; /* 150 */
+ __u32 tirqir; /* 154 */
+ __u32 pccr1; /* 158 */
+ __u32 pccr2; /* 15c */
+ __u32 r13[4]; /* 160 */
+ struct fc_bar0_nf nf; /* 170-174 */
+ __u32 r14; /* 178 */
+ struct fc_bar0_dma dma; /* 500-574 */
+ __u32 r20[0x62]; /* 578 */
+ struct fc_bar0_time time; /* 700-710 */
+ __u32 r22[0x7b]; /* 714 */
+ __u32 faddr; /* 900 */
+ __u32 fwdat; /* 904 */
+ __u32 fctrl; /* 908 */
+ __u32 frdat; /* 90c */
+ __u32 bwdat[16]; /* 910 */
+ __u32 brdat[16]; /* 950 */
+ __u32 r23[28]; /* 990 */
+ __u32 fwmode; /* a00 */
+ __u32 recond; /* a04 */
+ __u32 wdtctrl; /* a08 */
+ __u32 imgsel; /* a0c */
+ __u32 actimg; /* a10 */
+ __u32 updimginf; /* a14 */
+ __u32 r24[0x32]; /* a18 */
+ __u32 factory_image_info[8]; /* ae0 */
+ __u32 app_image0_info[8]; /* b00 */
+ __u32 app_image1_info[8]; /* b20 */
+ __u32 app_image2_info[8]; /* b40 */
+ __u32 app_image3_info[8]; /* b60 */
+ __u32 app_image4_info[8]; /* b80 */
+ __u32 app_image5_info[8]; /* ba0 */
+ __u32 app_image6_info[8]; /* bc0 */
+ __u32 app_image7_info[8]; /* be0 */
+ __u32 r25[0x100]; /* c00 */
+} __packed;
+
+struct flexcard_device {
+ struct pci_dev *pdev;
+ struct fc_bar0 __iomem *bar0;
+ struct mfd_cell *cells;
+ struct resource *res;
+};
+
+#endif /* _LINUX_FLEXCARD_H */
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index cd2be1c..46dc3c1 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -131,6 +131,7 @@ header-y += filter.h
header-y += firewire-cdev.h
header-y += firewire-constants.h
header-y += flat.h
+header-y += flexcard.h
header-y += fou.h
header-y += fs.h
header-y += fsl_hypervisor.h
diff --git a/include/uapi/linux/flexcard.h b/include/uapi/linux/flexcard.h
new file mode 100644
index 0000000..4e9f07b4
--- /dev/null
+++ b/include/uapi/linux/flexcard.h
@@ -0,0 +1,64 @@
+/*
+ * Eberspächer Flexcard PMC II Carrier Board PCI Driver - device attributes
+ *
+ * Copyright (c) 2014,2016 Linutronix GmbH
+ * Author: Benedikt Spranger <b.spranger@linutronix.de>
+ * Holger Dengler <dengler@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _UAPI_LINUX_FLEXCARD_H
+#define _UAPI_LINUX_FLEXCARD_H
+
+#include <linux/types.h>
+
+struct fc_version {
+ __u8 dev;
+ __u8 min;
+ __u8 maj;
+ __u8 reserved;
+} __packed;
+
+/* PCI BAR 0: Flexcard configuration */
+struct fc_bar0_conf {
+ __u32 r1; /* 000 */
+ struct fc_version fc_fw_ver; /* 004 */
+ struct fc_version fc_hw_ver; /* 008 */
+ __u32 r2[3]; /* 00c */
+ __u64 fc_sn; /* 018 */
+ __u32 fc_uid; /* 020 */
+ __u32 r3[7]; /* 024 */
+ __u32 fc_lic[6]; /* 040 */
+ __u32 fc_slic[6]; /* 058 */
+ __u32 trig_ctrl1; /* 070 */
+ __u32 r4; /* 074 */
+ __u32 trig_ctrl2; /* 078 */
+ __u32 r5[22]; /* 07c */
+ __u32 amreg; /* 0d4 */
+ __u32 tiny_stat; /* 0d8 */
+ __u32 r6[5]; /* 0dc */
+ __u32 can_dat_cnt; /* 0f0 */
+ __u32 can_err_cnt; /* 0f4 */
+ __u32 fc_data_cnt; /* 0f8 */
+ __u32 r7; /* 0fc */
+ __u32 fc_rocr; /* 100 */
+ __u32 r8; /* 104 */
+ __u32 pg_ctrl; /* 108 */
+ __u32 pg_term; /* 10c */
+ __u32 r9; /* 110 */
+ __u32 irs; /* 114 */
+ __u32 fr_tx_cnt; /* 118 */
+ __u32 irc; /* 11c */
+ __u64 pcnt; /* 120 */
+ __u32 r10; /* 128 */
+ __u32 nmv_cnt; /* 12c */
+ __u32 info_cnt; /* 130 */
+ __u32 stat_trg_cnt; /* 134 */
+ __u32 r11; /* 138 */
+ __u32 fr_rx_cnt; /* 13c */
+} __packed;
+
+#endif /* _UAPI_LINUX_FLEXCARD_H */
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 02/12] mfd: flexcard: add flexcard misc mfd-cell
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
2016-12-14 0:11 ` [PATCH 01/12] mfd: Eberspaecher Flexcard PMC II Carrier Board support Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 0:11 ` [PATCH 03/12] mfd: flexcard: add posix clock mfd-cell Holger Dengler
` (10 subsequent siblings)
12 siblings, 0 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Flexcard PCI BAR0 contain registers for configuration and
informational purpose. Add an appropriate MFD-cell for these registers.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/flexcard_core.c | 58 +++++++++++++++++++++++++++++++++++++++++++-
include/linux/mfd/flexcard.h | 1 +
2 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/drivers/mfd/flexcard_core.c b/drivers/mfd/flexcard_core.c
index e580971..2ee9089 100644
--- a/drivers/mfd/flexcard_core.c
+++ b/drivers/mfd/flexcard_core.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
+#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -25,11 +26,48 @@
#define FLEXCARD_FR_OFFSET 0x4000
#define FLEXCARD_FR_SIZE 0x2000
+#define FLEXCARD_CONF_START 0x000
+#define FLEXCARD_CONF_SIZE 0x13F
+#define FLEXCARD_NF_START 0x170
+#define FLEXCARD_NF_SIZE 0x7
+
+static DEFINE_IDA(flexcard_ida);
+
+static struct resource flexcard_misc_res[] = {
+ DEFINE_RES_MEM_NAMED(FLEXCARD_CONF_START,
+ FLEXCARD_CONF_SIZE,
+ "flexcard-conf"),
+ DEFINE_RES_MEM_NAMED(FLEXCARD_NF_START,
+ FLEXCARD_NF_SIZE,
+ "flexcard-nf"),
+};
+
+static struct mfd_cell flexcard_misc_dev[] = {
+ {
+ .name = "flexcard-misc",
+ .num_resources = ARRAY_SIZE(flexcard_misc_res),
+ .resources = flexcard_misc_res,
+ },
+};
+
enum flexcard_cell_id {
FLEXCARD_CELL_CAN,
FLEXCARD_CELL_FLEXRAY,
};
+static int flexcard_misc_setup(struct flexcard_device *priv)
+{
+ struct pci_dev *pdev = priv->pdev;
+
+ flexcard_misc_dev[0].id = priv->cardnr;
+ flexcard_misc_res[0].parent = &pdev->resource[0];
+ flexcard_misc_res[1].parent = &pdev->resource[0];
+
+ return mfd_add_devices(&pdev->dev, 0, flexcard_misc_dev,
+ ARRAY_SIZE(flexcard_misc_dev),
+ &pdev->resource[0], 0, NULL);
+}
+
static int flexcard_tiny_can(struct flexcard_device *priv,
int idx, int id, u32 offset)
{
@@ -163,10 +201,23 @@ static int flexcard_probe(struct pci_dev *pdev,
fw_ver.reg = readl(&priv->bar0->conf.fc_fw_ver);
hw_ver.reg = readl(&priv->bar0->conf.fc_hw_ver);
+ ret = ida_simple_get(&flexcard_ida, 0, 0, GFP_KERNEL);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "could not get new Flexcard id:%d\n", ret);
+ goto out_unmap;
+ }
+ priv->cardnr = ret;
+
ret = flexcard_tiny_probe(priv);
if (ret) {
dev_err(&pdev->dev, "unable to probe tinys: %d", ret);
- goto out_unmap;
+ goto out_ida;
+ }
+
+ ret = flexcard_misc_setup(priv);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to probe tinys: %d", ret);
+ goto out_mfd_dev_remove;
}
dev_info(&pdev->dev, "HW %02x.%02x.%02x FW %02x.%02x.%02x\n",
@@ -175,6 +226,10 @@ static int flexcard_probe(struct pci_dev *pdev,
return 0;
+out_mfd_dev_remove:
+ mfd_remove_devices(&pdev->dev);
+out_ida:
+ ida_simple_remove(&flexcard_ida, priv->cardnr);
out_unmap:
iounmap(priv->bar0);
out_release:
@@ -190,6 +245,7 @@ static void flexcard_remove(struct pci_dev *pdev)
struct flexcard_device *priv = pci_get_drvdata(pdev);
mfd_remove_devices(&pdev->dev);
+ ida_simple_remove(&flexcard_ida, priv->cardnr);
iounmap(priv->bar0);
pci_release_regions(pdev);
pci_disable_device(pdev);
diff --git a/include/linux/mfd/flexcard.h b/include/linux/mfd/flexcard.h
index 362b909..4116305 100644
--- a/include/linux/mfd/flexcard.h
+++ b/include/linux/mfd/flexcard.h
@@ -94,6 +94,7 @@ struct fc_bar0 {
} __packed;
struct flexcard_device {
+ unsigned int cardnr;
struct pci_dev *pdev;
struct fc_bar0 __iomem *bar0;
struct mfd_cell *cells;
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 03/12] mfd: flexcard: add posix clock mfd-cell
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
2016-12-14 0:11 ` [PATCH 01/12] mfd: Eberspaecher Flexcard PMC II Carrier Board support Holger Dengler
2016-12-14 0:11 ` [PATCH 02/12] mfd: flexcard: add flexcard misc mfd-cell Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 0:11 ` [PATCH 04/12] mfd: flexcard: add interrupt support Holger Dengler
` (9 subsequent siblings)
12 siblings, 0 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Flexcard offers a Flexray network synchronized counter with a
selectable resolution of 1us, 100ns or 10ns. Add an appropriate MFD-cell
to use the counter.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/flexcard_core.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/mfd/flexcard_core.c b/drivers/mfd/flexcard_core.c
index 2ee9089..73eb726 100644
--- a/drivers/mfd/flexcard_core.c
+++ b/drivers/mfd/flexcard_core.c
@@ -28,11 +28,32 @@
#define FLEXCARD_CONF_START 0x000
#define FLEXCARD_CONF_SIZE 0x13F
+#define FLEXCARD_CLKRST_START 0x144
+#define FLEXCARD_CLKRST_SIZE 0x3
#define FLEXCARD_NF_START 0x170
#define FLEXCARD_NF_SIZE 0x7
+#define FLEXCARD_CLK_START 0x700
+#define FLEXCARD_CLK_SIZE 0x13
static DEFINE_IDA(flexcard_ida);
+static struct resource flexcard_clk_res[] = {
+ DEFINE_RES_MEM_NAMED(FLEXCARD_CLK_START,
+ FLEXCARD_CLK_SIZE,
+ "flexcard-clock"),
+ DEFINE_RES_MEM_NAMED(FLEXCARD_CLKRST_START,
+ FLEXCARD_CLKRST_SIZE,
+ "flexcard-clock-reset"),
+};
+
+static struct mfd_cell flexcard_clk_dev[] = {
+ {
+ .name = "flexcard-clock",
+ .num_resources = ARRAY_SIZE(flexcard_clk_res),
+ .resources = flexcard_clk_res,
+ },
+};
+
static struct resource flexcard_misc_res[] = {
DEFINE_RES_MEM_NAMED(FLEXCARD_CONF_START,
FLEXCARD_CONF_SIZE,
@@ -55,6 +76,19 @@ enum flexcard_cell_id {
FLEXCARD_CELL_FLEXRAY,
};
+static int flexcard_clk_setup(struct flexcard_device *priv)
+{
+ struct pci_dev *pdev = priv->pdev;
+
+ flexcard_clk_dev[0].id = priv->cardnr;
+ flexcard_clk_res[0].parent = &pdev->resource[0];
+ flexcard_clk_res[1].parent = &pdev->resource[0];
+
+ return mfd_add_devices(&pdev->dev, 0, flexcard_clk_dev,
+ ARRAY_SIZE(flexcard_clk_dev),
+ &pdev->resource[0], 0, NULL);
+}
+
static int flexcard_misc_setup(struct flexcard_device *priv)
{
struct pci_dev *pdev = priv->pdev;
@@ -220,6 +254,12 @@ static int flexcard_probe(struct pci_dev *pdev,
goto out_mfd_dev_remove;
}
+ ret = flexcard_clk_setup(priv);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to register clksrc: %d\n", ret);
+ goto out_mfd_dev_remove;
+ }
+
dev_info(&pdev->dev, "HW %02x.%02x.%02x FW %02x.%02x.%02x\n",
hw_ver.ver.maj, hw_ver.ver.min, hw_ver.ver.dev,
fw_ver.ver.maj, fw_ver.ver.min, fw_ver.ver.dev);
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 04/12] mfd: flexcard: add interrupt support
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (2 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 03/12] mfd: flexcard: add posix clock mfd-cell Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 2:47 ` kbuild test robot
2016-12-14 3:37 ` kbuild test robot
2016-12-14 0:11 ` [PATCH 05/12] mfd: flexcard: add DMA interrupts Holger Dengler
` (8 subsequent siblings)
12 siblings, 2 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Flexcard comprise an interrupt controller for the attached
tinys, timer, a Flexray related trigger and a second one for DMA.
Both controllers share a single IRQ line.
Add an interrupt domain for the non-DMA interrupts.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/Kconfig | 1 +
drivers/mfd/Makefile | 1 +
drivers/mfd/flexcard_core.c | 14 ++-
drivers/mfd/flexcard_irq.c | 238 +++++++++++++++++++++++++++++++++++++++++++
include/linux/mfd/flexcard.h | 6 ++
5 files changed, 258 insertions(+), 2 deletions(-)
create mode 100644 drivers/mfd/flexcard_irq.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a5a12da..85fedf6 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -302,6 +302,7 @@ config MFD_EXYNOS_LPASS
config MFD_FLEXCARD
tristate "Eberspaecher Flexcard PMC II Carrier Board"
select MFD_CORE
+ select IRQ_DOMAIN
depends on PCI
help
This is the core driver for the Eberspaecher Flexcard
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 843e57c..7d9feb4 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -212,4 +212,5 @@ obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
flexcard-objs := flexcard_core.o
+flexcard-objs := flexcard_core.o flexcard_irq.o
obj-$(CONFIG_MFD_FLEXCARD) += flexcard.o
diff --git a/drivers/mfd/flexcard_core.c b/drivers/mfd/flexcard_core.c
index 73eb726..b7aead5 100644
--- a/drivers/mfd/flexcard_core.c
+++ b/drivers/mfd/flexcard_core.c
@@ -192,7 +192,8 @@ static int flexcard_tiny_probe(struct flexcard_device *priv)
offset += FLEXCARD_CAN_OFFSET;
}
- return mfd_add_devices(&pdev->dev, 0, priv->cells, nr, NULL, 0, NULL);
+ return mfd_add_devices(&pdev->dev, 0, priv->cells, nr, NULL,
+ 0, priv->irq_domain);
}
static int flexcard_probe(struct pci_dev *pdev,
@@ -242,10 +243,16 @@ static int flexcard_probe(struct pci_dev *pdev,
}
priv->cardnr = ret;
+ ret = flexcard_setup_irq(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to setup irq controller: %d", ret);
+ goto out_ida;
+ }
+
ret = flexcard_tiny_probe(priv);
if (ret) {
dev_err(&pdev->dev, "unable to probe tinys: %d", ret);
- goto out_ida;
+ goto out_remove_irq;
}
ret = flexcard_misc_setup(priv);
@@ -268,6 +275,8 @@ static int flexcard_probe(struct pci_dev *pdev,
out_mfd_dev_remove:
mfd_remove_devices(&pdev->dev);
+out_remove_irq:
+ flexcard_remove_irq(pdev);
out_ida:
ida_simple_remove(&flexcard_ida, priv->cardnr);
out_unmap:
@@ -285,6 +294,7 @@ static void flexcard_remove(struct pci_dev *pdev)
struct flexcard_device *priv = pci_get_drvdata(pdev);
mfd_remove_devices(&pdev->dev);
+ flexcard_remove_irq(pdev);
ida_simple_remove(&flexcard_ida, priv->cardnr);
iounmap(priv->bar0);
pci_release_regions(pdev);
diff --git a/drivers/mfd/flexcard_irq.c b/drivers/mfd/flexcard_irq.c
new file mode 100644
index 0000000..fa2063f
--- /dev/null
+++ b/drivers/mfd/flexcard_irq.c
@@ -0,0 +1,238 @@
+/*
+ * Eberspächer Flexcard PMC II Carrier Board PCI Driver - Interrupt controller
+ *
+ * Copyright (c) 2014 - 2016, Linutronix GmbH
+ * Author: Benedikt Spranger <b.spranger@linutronix.de>
+ * Holger Dengler <dengler@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/export.h>
+#include <linux/flexcard.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/pci.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/flexcard.h>
+
+struct fc_irq_tab {
+ u32 mskcache;
+ u32 mskoffs;
+ u32 msk;
+ u32 ackoffs;
+ u32 ack;
+};
+
+#define to_irq_tab_ack(statbit, cofs, mskofs, mskbit, ackofs, ackbit) \
+ [statbit] = { \
+ .mskcache = cofs, \
+ .mskoffs = mskofs, \
+ .msk = (1U << mskbit), \
+ .ackoffs = ackofs, \
+ .ack = (1U << ackbit) }
+
+#define to_irq_tab(statbit, cofs, mskofs, mskbit) \
+ [statbit] = { \
+ .mskcache = cofs, \
+ .mskoffs = mskofs, \
+ .msk = (1U << mskbit) }
+
+#define DEVMSK_OFFS offsetof(struct fc_bar0, conf.irc)
+#define DEVACK_OFFS offsetof(struct fc_bar0, conf.irs)
+#define DEVMSK_CACHE offsetof(struct flexcard_device, dev_irqmsk)
+
+#define dev_to_irq_tab_ack(s, m, a) \
+ to_irq_tab_ack(s, DEVMSK_CACHE, DEVMSK_OFFS, m, \
+ DEVACK_OFFS, a)
+
+#define dev_to_irq_tab(s, m) \
+ to_irq_tab(s, DEVMSK_CACHE, DEVMSK_OFFS, m)
+
+static const struct fc_irq_tab flexcard_irq_tab[] = {
+ /* Device Interrupts */
+ dev_to_irq_tab_ack(28, 28, 0), /* TIMER */
+ dev_to_irq_tab_ack(29, 29, 1), /* CC1CYS */
+ dev_to_irq_tab_ack(21, 30, 10), /* CC2CYS */
+ dev_to_irq_tab_ack(30, 18, 2), /* CC3CYS */
+ dev_to_irq_tab_ack(25, 19, 6), /* CC4CYS */
+ dev_to_irq_tab_ack(26, 26, 4), /* WAKE1A */
+ dev_to_irq_tab_ack(27, 27, 5), /* WAKE1B */
+ dev_to_irq_tab_ack(23, 24, 8), /* WAKE2A */
+ dev_to_irq_tab_ack(22, 25, 9), /* WAKE2B */
+ dev_to_irq_tab_ack(19, 22, 12), /* WAKE3A */
+ dev_to_irq_tab_ack(18, 23, 13), /* WAKE3B */
+ dev_to_irq_tab_ack(17, 20, 14), /* WAKE4A */
+ dev_to_irq_tab_ack(16, 21, 15), /* WAKE4B */
+ dev_to_irq_tab(31, 15), /* CC1T0 */
+ dev_to_irq_tab(3, 14), /* CC2T0 */
+ dev_to_irq_tab(24, 16), /* CC3T0 */
+ dev_to_irq_tab(20, 17), /* CC4T0 */
+};
+
+#define NR_FLEXCARD_IRQ ARRAY_SIZE(flexcard_irq_tab)
+
+#define VALID_DEVIRQ_MSK ((1U << 28) | \
+ (1U << 29) | \
+ (1U << 21) | \
+ (1U << 30) | \
+ (1U << 25) | \
+ (1U << 26) | \
+ (1U << 27) | \
+ (1U << 23) | \
+ (1U << 22) | \
+ (1U << 19) | \
+ (1U << 18) | \
+ (1U << 17) | \
+ (1U << 16) | \
+ (1U << 31) | \
+ (1U << 3) | \
+ (1U << 24) | \
+ (1U << 20))
+
+static irqreturn_t flexcard_demux(int irq, void *data)
+{
+ struct flexcard_device *priv = data;
+ irqreturn_t ret = IRQ_NONE;
+ unsigned int slot, cur, stat;
+
+ stat = readl(&priv->bar0->conf.irs) & VALID_DEVIRQ_MSK;
+ while (stat) {
+ slot = __ffs(stat);
+ stat &= (1 << slot);
+ cur = irq_linear_revmap(priv->irq_domain, slot);
+ generic_handle_irq(cur);
+ ret = IRQ_HANDLED;
+ }
+ return ret;
+}
+
+static void flexcard_irq_ack(struct irq_data *d)
+{
+ struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
+ const struct fc_irq_tab *tp = &flexcard_irq_tab[d->hwirq];
+ void __iomem *p = (void __iomem *)priv->bar0 + tp->ackoffs;
+
+ writel(tp->ack, p);
+}
+
+static void flexcard_irq_mask(struct irq_data *d)
+{
+ struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
+ const struct fc_irq_tab *tp = &flexcard_irq_tab[d->hwirq];
+ void __iomem *p = (void __iomem *)priv->bar0 + tp->mskoffs;
+ u32 *msk = (void *)priv + tp->mskcache;
+
+ raw_spin_lock(&priv->irq_lock);
+ *msk &= ~tp->msk;
+ writel(*msk, p);
+ raw_spin_unlock(&priv->irq_lock);
+}
+
+static void flexcard_irq_unmask(struct irq_data *d)
+{
+ struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
+ const struct fc_irq_tab *tp = &flexcard_irq_tab[d->hwirq];
+ void __iomem *p = (void __iomem *)priv->bar0 + tp->mskoffs;
+ u32 *msk = (void *)priv + tp->mskcache;
+
+ raw_spin_lock(&priv->irq_lock);
+ *msk |= tp->msk;
+ writel(*msk, p);
+ raw_spin_unlock(&priv->irq_lock);
+}
+
+static int flexcard_req_irq(struct pci_dev *pdev)
+{
+ struct flexcard_device *priv = pci_get_drvdata(pdev);
+ int ret;
+
+ ret = pci_enable_msi(pdev);
+ if (ret) {
+ dev_warn(&pdev->dev, "could not enable MSI\n");
+ /* shared PCI irq fallback */
+ return request_irq(pdev->irq, flexcard_demux,
+ IRQF_NO_THREAD | IRQF_SHARED,
+ "flexcard", priv);
+ }
+ dev_info(&pdev->dev, "MSI enabled\n");
+
+ ret = request_irq(pdev->irq, flexcard_demux, IRQF_NO_THREAD,
+ "flexcard", priv);
+ if (ret)
+ pci_disable_msi(pdev);
+
+ return ret;
+}
+
+static struct irq_chip flexcard_irq_chip = {
+ .name = "flexcard_irq",
+ .irq_ack = flexcard_irq_ack,
+ .irq_mask = flexcard_irq_mask,
+ .irq_unmask = flexcard_irq_unmask,
+};
+
+static int flexcard_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct flexcard_device *priv = d->host_data;
+
+ irq_set_chip_and_handler_name(irq, &flexcard_irq_chip,
+ handle_level_irq, "flexcard");
+ irq_set_chip_data(irq, priv);
+ irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
+
+ return 0;
+}
+
+static const struct irq_domain_ops flexcard_irq_domain_ops = {
+ .map = flexcard_irq_domain_map,
+};
+
+int flexcard_setup_irq(struct pci_dev *pdev)
+{
+ struct flexcard_device *priv = pci_get_drvdata(pdev);
+ struct irq_domain *domain;
+ int ret;
+
+ /* Make sure none of the subirqs is enabled */
+ writel(0, &priv->bar0->conf.irc);
+ writel(0, &priv->bar0->dma.dma_irer);
+
+ raw_spin_lock_init(&priv->irq_lock);
+
+ domain = irq_domain_add_linear(NULL, NR_FLEXCARD_IRQ,
+ &flexcard_irq_domain_ops, priv);
+ if (!domain) {
+ dev_err(&pdev->dev, "could not request irq domain\n");
+ return -ENODEV;
+ }
+
+ priv->irq_domain = domain;
+
+ ret = flexcard_req_irq(pdev);
+ if (ret)
+ irq_domain_remove(priv->irq_domain);
+
+ return ret;
+}
+
+void flexcard_remove_irq(struct pci_dev *pdev)
+{
+ struct flexcard_device *priv = pci_get_drvdata(pdev);
+
+ /* Disable all subirqs */
+ writel(0, &priv->bar0->conf.irc);
+ writel(0, &priv->bar0->dma.dma_irer);
+
+ free_irq(pdev->irq, priv);
+ pci_disable_msi(pdev);
+ irq_domain_remove(priv->irq_domain);
+}
diff --git a/include/linux/mfd/flexcard.h b/include/linux/mfd/flexcard.h
index 4116305..6cb8ad0 100644
--- a/include/linux/mfd/flexcard.h
+++ b/include/linux/mfd/flexcard.h
@@ -96,9 +96,15 @@ struct fc_bar0 {
struct flexcard_device {
unsigned int cardnr;
struct pci_dev *pdev;
+ raw_spinlock_t irq_lock;
+ struct irq_domain *irq_domain;
struct fc_bar0 __iomem *bar0;
struct mfd_cell *cells;
struct resource *res;
+ u32 dev_irqmsk;
};
+int flexcard_setup_irq(struct pci_dev *pdev);
+void flexcard_remove_irq(struct pci_dev *pdev);
+
#endif /* _LINUX_FLEXCARD_H */
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 05/12] mfd: flexcard: add DMA interrupts
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (3 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 04/12] mfd: flexcard: add interrupt support Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 3:08 ` kbuild test robot
2016-12-14 0:11 ` [PATCH 06/12] mfd: flexcard: add DMA device Holger Dengler
` (7 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Flexcard comprise an interrupt controller for the attached
tinys, timer, a Flexray related trigger and a second one for DMA.
Both controllers share a single IRQ line.
Add the DMA Controller interrupts.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/flexcard_irq.c | 71 ++++++++++++++++++++++++++++++++++++++++++--
include/linux/mfd/flexcard.h | 2 ++
2 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/drivers/mfd/flexcard_irq.c b/drivers/mfd/flexcard_irq.c
index fa2063f..15acd18 100644
--- a/drivers/mfd/flexcard_irq.c
+++ b/drivers/mfd/flexcard_irq.c
@@ -23,6 +23,12 @@
#include <linux/mfd/core.h>
#include <linux/mfd/flexcard.h>
+/*
+ * Bit 31 in dma interrupt register:
+ * DMA interrupt enable. Must be 1 to enable the DMA interrupts
+ */
+#define FLEXCARD_DMA_IRER_DIRE (1U << 31)
+
struct fc_irq_tab {
u32 mskcache;
u32 mskoffs;
@@ -49,6 +55,10 @@ struct fc_irq_tab {
#define DEVACK_OFFS offsetof(struct fc_bar0, conf.irs)
#define DEVMSK_CACHE offsetof(struct flexcard_device, dev_irqmsk)
+#define DMAMSK_OFFS offsetof(struct fc_bar0, dma.dma_irer)
+#define DMAACK_OFFS offsetof(struct fc_bar0, dma.dma_irsr)
+#define DMAMSK_CACHE offsetof(struct flexcard_device, dma_irqmsk)
+
#define dev_to_irq_tab_ack(s, m, a) \
to_irq_tab_ack(s, DEVMSK_CACHE, DEVMSK_OFFS, m, \
DEVACK_OFFS, a)
@@ -56,6 +66,10 @@ struct fc_irq_tab {
#define dev_to_irq_tab(s, m) \
to_irq_tab(s, DEVMSK_CACHE, DEVMSK_OFFS, m)
+#define dma_to_irq_tab_ack(s, m, a) \
+ to_irq_tab_ack(s, DMAMSK_CACHE, DMAMSK_OFFS, m, \
+ DMAACK_OFFS, a)
+
static const struct fc_irq_tab flexcard_irq_tab[] = {
/* Device Interrupts */
dev_to_irq_tab_ack(28, 28, 0), /* TIMER */
@@ -75,6 +89,11 @@ static const struct fc_irq_tab flexcard_irq_tab[] = {
dev_to_irq_tab(3, 14), /* CC2T0 */
dev_to_irq_tab(24, 16), /* CC3T0 */
dev_to_irq_tab(20, 17), /* CC4T0 */
+ /* DMA Interrupts */
+ dma_to_irq_tab_ack(0, 0, 0), /* DMA_C0 */
+ dma_to_irq_tab_ack(1, 1, 1), /* DMA_TE */
+ dma_to_irq_tab_ack(4, 4, 4), /* DMA_TI */
+ dma_to_irq_tab_ack(5, 5, 5), /* DMA_CBL */
};
#define NR_FLEXCARD_IRQ ARRAY_SIZE(flexcard_irq_tab)
@@ -96,6 +115,10 @@ static const struct fc_irq_tab flexcard_irq_tab[] = {
(1U << 3) | \
(1U << 24) | \
(1U << 20))
+#define VALID_DMAIRQ_MSK ((1U << 0) | \
+ (1U << 1) | \
+ (1U << 4) | \
+ (1U << 5))
static irqreturn_t flexcard_demux(int irq, void *data)
{
@@ -104,6 +127,7 @@ static irqreturn_t flexcard_demux(int irq, void *data)
unsigned int slot, cur, stat;
stat = readl(&priv->bar0->conf.irs) & VALID_DEVIRQ_MSK;
+ stat |= readl(&priv->bar0->dma.dma_irsr) & VALID_DMAIRQ_MSK;
while (stat) {
slot = __ffs(stat);
stat &= (1 << slot);
@@ -196,6 +220,30 @@ static const struct irq_domain_ops flexcard_irq_domain_ops = {
.map = flexcard_irq_domain_map,
};
+static struct irq_chip flexcard_dma_irq_chip = {
+ .name = "flexcard_dma_irq",
+ .irq_ack = flexcard_irq_ack,
+ .irq_mask = flexcard_irq_mask,
+ .irq_unmask = flexcard_irq_unmask,
+};
+
+static int flexcard_dma_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct flexcard_device *priv = d->host_data;
+
+ irq_set_chip_and_handler_name(irq, &flexcard_dma_irq_chip,
+ handle_level_irq, "flexcard-dma");
+ irq_set_chip_data(irq, priv);
+ irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
+
+ return 0;
+}
+
+static const struct irq_domain_ops flexcard_dma_irq_domain_ops = {
+ .map = flexcard_dma_irq_domain_map,
+};
+
int flexcard_setup_irq(struct pci_dev *pdev)
{
struct flexcard_device *priv = pci_get_drvdata(pdev);
@@ -217,9 +265,27 @@ int flexcard_setup_irq(struct pci_dev *pdev)
priv->irq_domain = domain;
+ domain = irq_domain_add_linear(NULL, NR_FLEXCARD_IRQ,
+ &flexcard_dma_irq_domain_ops, priv);
+ if (!domain) {
+ dev_err(&pdev->dev, "could not request dma irq domain\n");
+ ret = -ENODEV;
+ goto out_irq;
+ }
+ priv->dma_domain = domain;
+
+ /* DMA IRQs must be device-globally enabled by setting bit 31 to 1 */
+ writel(FLEXCARD_DMA_IRER_DIRE, &priv->bar0->dma.dma_irer);
+
ret = flexcard_req_irq(pdev);
if (ret)
- irq_domain_remove(priv->irq_domain);
+ goto out_dma;
+
+ return 0;
+out_dma:
+ irq_domain_remove(priv->dma_domain);
+out_irq:
+ irq_domain_remove(priv->irq_domain);
return ret;
}
@@ -228,11 +294,12 @@ void flexcard_remove_irq(struct pci_dev *pdev)
{
struct flexcard_device *priv = pci_get_drvdata(pdev);
- /* Disable all subirqs */
+ /* Disable all subirqs (including global DMA-IRQ bit 31) */
writel(0, &priv->bar0->conf.irc);
writel(0, &priv->bar0->dma.dma_irer);
free_irq(pdev->irq, priv);
pci_disable_msi(pdev);
+ irq_domain_remove(priv->dma_domain);
irq_domain_remove(priv->irq_domain);
}
diff --git a/include/linux/mfd/flexcard.h b/include/linux/mfd/flexcard.h
index 6cb8ad0..819c6ef 100644
--- a/include/linux/mfd/flexcard.h
+++ b/include/linux/mfd/flexcard.h
@@ -98,10 +98,12 @@ struct flexcard_device {
struct pci_dev *pdev;
raw_spinlock_t irq_lock;
struct irq_domain *irq_domain;
+ struct irq_domain *dma_domain;
struct fc_bar0 __iomem *bar0;
struct mfd_cell *cells;
struct resource *res;
u32 dev_irqmsk;
+ u32 dma_irqmsk;
};
int flexcard_setup_irq(struct pci_dev *pdev);
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 06/12] mfd: flexcard: add DMA device
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (4 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 05/12] mfd: flexcard: add DMA interrupts Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 0:11 ` [PATCH 07/12] mfd: flexcard: add UIO IRQ devices Holger Dengler
` (6 subsequent siblings)
12 siblings, 0 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Flexcard interface design split packet receive and transmit. All
received packets and card status information are multiplexed with a
Flexcard specific protocol and handled through a DMA capable ringbuffer.
The TX path has to poke each available component separate.
Add a platform device for the DMA receive channel.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/flexcard_core.c | 67 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/drivers/mfd/flexcard_core.c b/drivers/mfd/flexcard_core.c
index b7aead5..55bcfec 100644
--- a/drivers/mfd/flexcard_core.c
+++ b/drivers/mfd/flexcard_core.c
@@ -32,11 +32,41 @@
#define FLEXCARD_CLKRST_SIZE 0x3
#define FLEXCARD_NF_START 0x170
#define FLEXCARD_NF_SIZE 0x7
+#define FLEXCARD_DMA_START 0x500
+#define FLEXCARD_DMA_SIZE 0x80
#define FLEXCARD_CLK_START 0x700
#define FLEXCARD_CLK_SIZE 0x13
+#define FLEXCARD_DMA_IRQ_CO 0
+#define FLEXCARD_DMA_IRQ_TE 1
+#define FLEXCARD_DMA_IRQ_TI 2
+#define FLEXCARD_DMA_IRQ_CBL 3
+
+/* The first FW Version supporting DMA is 6.4.0 */
+#define DMA_MIN_FW_MAJOR 6
+#define DMA_MIN_FW_MINOR 4
+#define DMA_MIN_FW_UPDATE 0
+
static DEFINE_IDA(flexcard_ida);
+static struct resource flexcard_dma_res[] = {
+ DEFINE_RES_MEM_NAMED(FLEXCARD_DMA_START,
+ FLEXCARD_DMA_SIZE,
+ "flexcard-dma"),
+ DEFINE_RES_IRQ_NAMED(FLEXCARD_DMA_IRQ_CBL,
+ "flexcard-dma-cbl"),
+ DEFINE_RES_IRQ_NAMED(FLEXCARD_DMA_IRQ_CO,
+ "flexcard-dma-co"),
+};
+
+static struct mfd_cell flexcard_dma_dev[] = {
+ {
+ .name = "flexcard-dma",
+ .num_resources = ARRAY_SIZE(flexcard_dma_res),
+ .resources = flexcard_dma_res,
+ },
+};
+
static struct resource flexcard_clk_res[] = {
DEFINE_RES_MEM_NAMED(FLEXCARD_CLK_START,
FLEXCARD_CLK_SIZE,
@@ -102,6 +132,37 @@ static int flexcard_misc_setup(struct flexcard_device *priv)
&pdev->resource[0], 0, NULL);
}
+static int flexcard_add_dma(struct flexcard_device *priv)
+{
+ struct pci_dev *pdev = priv->pdev;
+ union {
+ struct fc_version ver;
+ u32 reg;
+ } fw_ver;
+
+ /* check for a DMA capable firmware version*/
+ fw_ver.reg = readl(&priv->bar0->conf.fc_fw_ver);
+ if (fw_ver.ver.maj < DMA_MIN_FW_MAJOR)
+ goto out;
+
+ if (fw_ver.ver.maj == DMA_MIN_FW_MAJOR) {
+ if (fw_ver.ver.min < DMA_MIN_FW_MINOR)
+ goto out;
+ if ((fw_ver.ver.min == DMA_MIN_FW_MINOR) &&
+ (fw_ver.ver.dev < DMA_MIN_FW_UPDATE))
+ goto out;
+ }
+
+ return mfd_add_devices(&pdev->dev, 0, flexcard_dma_dev,
+ ARRAY_SIZE(flexcard_dma_dev),
+ &pdev->resource[0], 0, priv->dma_domain);
+
+out:
+ dev_info(&pdev->dev, "Firmware is not DMA capable\n");
+
+ return 0;
+}
+
static int flexcard_tiny_can(struct flexcard_device *priv,
int idx, int id, u32 offset)
{
@@ -267,6 +328,12 @@ static int flexcard_probe(struct pci_dev *pdev,
goto out_mfd_dev_remove;
}
+ ret = flexcard_add_dma(priv);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to add DMA device: %d", ret);
+ goto out_mfd_dev_remove;
+ }
+
dev_info(&pdev->dev, "HW %02x.%02x.%02x FW %02x.%02x.%02x\n",
hw_ver.ver.maj, hw_ver.ver.min, hw_ver.ver.dev,
fw_ver.ver.maj, fw_ver.ver.min, fw_ver.ver.dev);
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 07/12] mfd: flexcard: add UIO IRQ devices
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (5 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 06/12] mfd: flexcard: add DMA device Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 0:11 ` [PATCH 08/12] misc: Flexcard misc device support Holger Dengler
` (5 subsequent siblings)
12 siblings, 0 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
Add an UIO device for each Flexcard Flexray related trigger. The trigger
devide into:
- Flexray cycle start (CCYS)
- Flexray timer 0 (CCxT0)
- Bus wakeup (WAKE)
The UIO IRQ devices can be used to synchronize an application
with these events.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/flexcard_core.c | 85 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/drivers/mfd/flexcard_core.c b/drivers/mfd/flexcard_core.c
index 55bcfec..fc5b033 100644
--- a/drivers/mfd/flexcard_core.c
+++ b/drivers/mfd/flexcard_core.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
#include <linux/mfd/core.h>
#include <linux/mfd/flexcard.h>
@@ -47,6 +48,46 @@
#define DMA_MIN_FW_MINOR 4
#define DMA_MIN_FW_UPDATE 0
+#define FLEXCARD_IRQ_CC1CCYS_OFF 0
+#define FLEXCARD_IRQ_CC2CCYS_OFF 1
+#define FLEXCARD_IRQ_CC3CCYS_OFF 2
+#define FLEXCARD_IRQ_CC4CCYS_OFF 3
+#define FLEXCARD_IRQ_WAKE4A_OFF 4
+#define FLEXCARD_IRQ_WAKE4B_OFF 5
+#define FLEXCARD_IRQ_WAKE3A_OFF 6
+#define FLEXCARD_IRQ_WAKE3B_OFF 7
+#define FLEXCARD_IRQ_WAKE2A_OFF 8
+#define FLEXCARD_IRQ_WAKE2B_OFF 9
+#define FLEXCARD_IRQ_WAKE1A_OFF 10
+#define FLEXCARD_IRQ_WAKE1B_OFF 11
+#define FLEXCARD_IRQ_CC1T0_OFF 12
+#define FLEXCARD_IRQ_CC2T0_OFF 13
+#define FLEXCARD_IRQ_CC3T0_OFF 14
+#define FLEXCARD_IRQ_CC4T0_OFF 15
+
+#define flexcard_irq_resource(irq_name) \
+ static struct resource flexcard_irq_res_##irq_name = { \
+ .name = __stringify(fc_irq_##irq_name##_off), \
+ .start = FLEXCARD_IRQ_##irq_name##_OFF, \
+ .end = FLEXCARD_IRQ_##irq_name##_OFF, \
+ .flags = IORESOURCE_IRQ, \
+ }; \
+ \
+ static struct uio_info flexcard_irq_pdata_##irq_name = { \
+ .name = __stringify(irq_name), \
+ .version = "0", \
+ }
+
+#define flexcard_irq_cell(irq_name, irq_id) \
+ { \
+ .id = irq_id, \
+ .name = "uio_pdrv_genirq", \
+ .platform_data = &flexcard_irq_pdata_##irq_name, \
+ .pdata_size = sizeof(flexcard_irq_pdata_##irq_name), \
+ .num_resources = 1, \
+ .resources = &flexcard_irq_res_##irq_name \
+ }
+
static DEFINE_IDA(flexcard_ida);
static struct resource flexcard_dma_res[] = {
@@ -163,6 +204,42 @@ static int flexcard_add_dma(struct flexcard_device *priv)
return 0;
}
+flexcard_irq_resource(CC1CCYS);
+flexcard_irq_resource(CC2CCYS);
+flexcard_irq_resource(CC3CCYS);
+flexcard_irq_resource(CC4CCYS);
+flexcard_irq_resource(WAKE4A);
+flexcard_irq_resource(WAKE4B);
+flexcard_irq_resource(WAKE3A);
+flexcard_irq_resource(WAKE3B);
+flexcard_irq_resource(WAKE2A);
+flexcard_irq_resource(WAKE2B);
+flexcard_irq_resource(WAKE1A);
+flexcard_irq_resource(WAKE1B);
+flexcard_irq_resource(CC1T0);
+flexcard_irq_resource(CC2T0);
+flexcard_irq_resource(CC3T0);
+flexcard_irq_resource(CC4T0);
+
+static struct mfd_cell flexcard_uio_dev[] = {
+ flexcard_irq_cell(CC3CCYS, 0),
+ flexcard_irq_cell(CC4CCYS, 1),
+ flexcard_irq_cell(WAKE4A, 2),
+ flexcard_irq_cell(WAKE4B, 3),
+ flexcard_irq_cell(WAKE3A, 4),
+ flexcard_irq_cell(WAKE3B, 5),
+ flexcard_irq_cell(WAKE2A, 6),
+ flexcard_irq_cell(WAKE2B, 7),
+ flexcard_irq_cell(WAKE1A, 8),
+ flexcard_irq_cell(WAKE1B, 9),
+ flexcard_irq_cell(CC1CCYS, 10),
+ flexcard_irq_cell(CC2CCYS, 11),
+ flexcard_irq_cell(CC1T0, 12),
+ flexcard_irq_cell(CC2T0, 13),
+ flexcard_irq_cell(CC3T0, 14),
+ flexcard_irq_cell(CC4T0, 15),
+};
+
static int flexcard_tiny_can(struct flexcard_device *priv,
int idx, int id, u32 offset)
{
@@ -334,6 +411,14 @@ static int flexcard_probe(struct pci_dev *pdev,
goto out_mfd_dev_remove;
}
+ ret = mfd_add_devices(&pdev->dev, 0, flexcard_uio_dev,
+ ARRAY_SIZE(flexcard_uio_dev),
+ NULL, 0, priv->irq_domain);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to add irq UIO devices: %d", ret);
+ goto out_mfd_dev_remove;
+ }
+
dev_info(&pdev->dev, "HW %02x.%02x.%02x FW %02x.%02x.%02x\n",
hw_ver.ver.maj, hw_ver.ver.min, hw_ver.ver.dev,
fw_ver.ver.maj, fw_ver.ver.min, fw_ver.ver.dev);
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 08/12] misc: Flexcard misc device support
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (6 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 07/12] mfd: flexcard: add UIO IRQ devices Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 8:42 ` Arnd Bergmann
2016-12-14 0:11 ` [PATCH 09/12] misc: flexcard: add device attributes Holger Dengler
` (4 subsequent siblings)
12 siblings, 1 reply; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Flexcard PCI BAR0 contain registers for configuration but also
for informational purpose like error counter, statistical information
and some timestamps. The read-only mmap of the misc device offers the
userspace a fast access to these registers.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Arnd Bergmann <arnd@arndb.de>
cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mfd/Kconfig | 1 +
drivers/misc/Kconfig | 6 ++
drivers/misc/Makefile | 1 +
drivers/misc/flexcard_misc.c | 165 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 173 insertions(+)
create mode 100644 drivers/misc/flexcard_misc.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 85fedf6..580f521 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -303,6 +303,7 @@ config MFD_FLEXCARD
tristate "Eberspaecher Flexcard PMC II Carrier Board"
select MFD_CORE
select IRQ_DOMAIN
+ select FLEXCARD_MISC
depends on PCI
help
This is the core driver for the Eberspaecher Flexcard
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 64971ba..3f54b58 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -766,6 +766,12 @@ config PANEL_BOOT_MESSAGE
An empty message will only clear the display at driver init time. Any other
printf()-formatted message is valid with newline and escape codes.
+config FLEXCARD_MISC
+ tristate "Flexcard Misc Device driver"
+ depends on MFD_FLEXCARD
+ help
+ Misc driver for Flexcard PMC II.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 3198336..08a1729 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_ECHO) += echo/
obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
obj-$(CONFIG_CXL_BASE) += cxl/
obj-$(CONFIG_PANEL) += panel.o
+obj-$(CONFIG_FLEXCARD_MISC) += flexcard_misc.o
lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
diff --git a/drivers/misc/flexcard_misc.c b/drivers/misc/flexcard_misc.c
new file mode 100644
index 0000000..93c951c
--- /dev/null
+++ b/drivers/misc/flexcard_misc.c
@@ -0,0 +1,165 @@
+/*
+ * Eberspächer Flexcard PMC II Misc Device
+ *
+ * Copyright (c) 2014 - 2016, Linutronix GmbH
+ * Author: Benedikt Spranger <b.spranger@linutronix.de>
+ * Holger Dengler <dengler@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/kref.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/flexcard.h>
+
+#define FLEXCARD_MAX_NAME 16
+
+struct flexcard_misc {
+ char name[FLEXCARD_MAX_NAME];
+ struct miscdevice dev;
+ struct platform_device *pdev;
+ struct fc_bar0_conf __iomem *conf;
+ struct fc_bar0_nf __iomem *nf;
+};
+
+static int flexcard_misc_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned long offset, vsize, psize, addr;
+ struct flexcard_misc *priv;
+ struct resource *res;
+
+ priv = container_of(filp->private_data, struct flexcard_misc, dev);
+ if (!priv)
+ return -EINVAL;
+
+ if (vma->vm_flags & (VM_WRITE | VM_EXEC))
+ return -EPERM;
+
+ res = platform_get_resource(priv->pdev, IORESOURCE_MEM, 0);
+ offset = vma->vm_pgoff << PAGE_SHIFT;
+ if (offset > resource_size(res)) {
+ dev_err(&priv->pdev->dev,
+ "mmap offset out of resource range\n");
+ return -EINVAL;
+ }
+
+ vsize = vma->vm_end - vma->vm_start;
+ psize = round_up(resource_size(res) - offset, PAGE_SIZE);
+ addr = (res->start + offset) >> PAGE_SHIFT;
+ if (vsize > psize) {
+ dev_err(&priv->pdev->dev,
+ "requested mmap mapping too large\n");
+ return -EINVAL;
+ }
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return io_remap_pfn_range(vma, vma->vm_start, addr, vsize,
+ vma->vm_page_prot);
+}
+
+static const struct file_operations flexcard_misc_fops = {
+ .owner = THIS_MODULE,
+ .open = nonseekable_open,
+ .mmap = flexcard_misc_mmap,
+ .llseek = no_llseek,
+};
+
+static int flexcard_misc_iomap(struct platform_device *pdev)
+{
+ struct flexcard_misc *priv = platform_get_drvdata(pdev);
+ struct resource *res;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENXIO;
+
+ priv->conf = ioremap_nocache(res->start, resource_size(res));
+ if (!priv->conf)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ priv->nf = ioremap_nocache(res->start, resource_size(res));
+ if (!priv->nf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ return 0;
+out:
+ iounmap(priv->conf);
+ return ret;
+}
+
+static int flexcard_misc_probe(struct platform_device *pdev)
+{
+ struct flexcard_misc *priv;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, priv);
+
+ ret = flexcard_misc_iomap(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to map resource: %d\n", ret);
+ return ret;
+ }
+
+ snprintf(priv->name, sizeof(priv->name),
+ "flexcard%d", pdev->id);
+ priv->dev.name = priv->name;
+ priv->dev.minor = MISC_DYNAMIC_MINOR;
+ priv->dev.fops = &flexcard_misc_fops;
+ priv->dev.parent = &pdev->dev;
+ priv->pdev = pdev;
+
+ ret = misc_register(&priv->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to register miscdevice: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int flexcard_misc_remove(struct platform_device *pdev)
+{
+ struct flexcard_misc *priv = platform_get_drvdata(pdev);
+
+ misc_deregister(&priv->dev);
+
+ return 0;
+}
+
+static struct platform_driver flexcard_misc_driver = {
+ .probe = flexcard_misc_probe,
+ .remove = flexcard_misc_remove,
+ .driver = {
+ .name = "flexcard-misc",
+ },
+};
+
+module_platform_driver(flexcard_misc_driver);
+
+MODULE_AUTHOR("Holger Dengler <dengler@linutronix.de>");
+MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>");
+MODULE_DESCRIPTION("Eberspaecher Flexcard PMC II Misc Driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 09/12] misc: flexcard: add device attributes
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (7 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 08/12] misc: Flexcard misc device support Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 1:33 ` kbuild test robot
2017-01-10 16:58 ` Greg Kroah-Hartman
2016-12-14 0:11 ` [PATCH 10/12] misc: Flexcard basic timestamp counter support Holger Dengler
` (3 subsequent siblings)
12 siblings, 2 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
Add device attributes for common flexcard information access. The
attribiutes are read-only execpt "uid" (user ID register).
The "uid" attribute can also be used to change the user-defined ID of a
Flexcard.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Arnd Bergmann <arnd@arndb.de>
cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/misc/flexcard_misc.c | 196 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 196 insertions(+)
diff --git a/drivers/misc/flexcard_misc.c b/drivers/misc/flexcard_misc.c
index 93c951c..2a5c006 100644
--- a/drivers/misc/flexcard_misc.c
+++ b/drivers/misc/flexcard_misc.c
@@ -31,6 +31,183 @@ struct flexcard_misc {
struct fc_bar0_nf __iomem *nf;
};
+static ssize_t fw_version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+ union {
+ struct fc_version ver;
+ u32 reg;
+ } fw_ver;
+
+ fw_ver.reg = readl(&priv->conf->fc_fw_ver);
+ return sprintf(buf, "%02x.%02x.%02x\n",
+ fw_ver.ver.maj, fw_ver.ver.min, fw_ver.ver.dev);
+}
+static DEVICE_ATTR_RO(fw_version);
+
+static ssize_t hw_version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+ union {
+ struct fc_version ver;
+ u32 reg;
+ } hw_ver;
+
+ hw_ver.reg = readl(&priv->conf->fc_hw_ver);
+ return sprintf(buf, "%02x.%02x.%02x\n",
+ hw_ver.ver.maj, hw_ver.ver.min, hw_ver.ver.dev);
+}
+static DEVICE_ATTR_RO(hw_version);
+
+static ssize_t serialno_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+ u64 fc_sn;
+
+ fc_sn = readq(&priv->conf->fc_sn);
+ return sprintf(buf, "%lld\n", fc_sn);
+}
+static DEVICE_ATTR_RO(serialno);
+
+static ssize_t tiny_stat_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "0x%x\n", readl(&priv->conf->tiny_stat));
+}
+static DEVICE_ATTR_RO(tiny_stat);
+
+static ssize_t can_dat_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", readl(&priv->conf->can_dat_cnt));
+}
+static DEVICE_ATTR_RO(can_dat);
+
+static ssize_t can_err_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", readl(&priv->conf->can_err_cnt));
+}
+static DEVICE_ATTR_RO(can_err);
+
+static ssize_t fc_data_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", readl(&priv->conf->fc_data_cnt));
+}
+static DEVICE_ATTR_RO(fc_data);
+
+static ssize_t fr_rx_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", readl(&priv->conf->fr_rx_cnt));
+}
+static DEVICE_ATTR_RO(fr_rx);
+
+static ssize_t fr_tx_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", readl(&priv->conf->fr_tx_cnt));
+}
+static DEVICE_ATTR_RO(fr_tx);
+
+static ssize_t nmv_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", readl(&priv->conf->nmv_cnt));
+}
+static DEVICE_ATTR_RO(nmv);
+
+static ssize_t info_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", readl(&priv->conf->info_cnt));
+}
+static DEVICE_ATTR_RO(info);
+
+static ssize_t stat_trg_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", readl(&priv->conf->stat_trg_cnt));
+}
+static DEVICE_ATTR_RO(stat_trg);
+
+static ssize_t nf_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", readl(&priv->nf->nf_cnt));
+}
+static DEVICE_ATTR_RO(nf);
+
+static ssize_t uid_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+ u32 uid;
+ int ret;
+
+ ret = kstrtou32(buf, 0, &uid);
+ if (ret)
+ return ret;
+
+ writel(uid, &priv->conf->fc_uid);
+ return count;
+}
+
+static ssize_t uid_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct flexcard_misc *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", readl(&priv->conf->fc_uid));
+}
+static DEVICE_ATTR(uid, 0644, uid_show, uid_store);
+
+static struct attribute *flexcard_misc_dev_attrs[] = {
+ &dev_attr_fw_version.attr,
+ &dev_attr_hw_version.attr,
+ &dev_attr_serialno.attr,
+ &dev_attr_tiny_stat.attr,
+ &dev_attr_can_dat.attr,
+ &dev_attr_can_err.attr,
+ &dev_attr_fc_data.attr,
+ &dev_attr_fr_rx.attr,
+ &dev_attr_fr_tx.attr,
+ &dev_attr_nmv.attr,
+ &dev_attr_info.attr,
+ &dev_attr_stat_trg.attr,
+ &dev_attr_nf.attr,
+ &dev_attr_uid.attr,
+ NULL,
+};
+
+static const struct attribute_group flexcard_misc_dev_group = {
+ .attrs = flexcard_misc_dev_attrs,
+};
+
static int flexcard_misc_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long offset, vsize, psize, addr;
@@ -109,6 +286,7 @@ static int flexcard_misc_iomap(struct platform_device *pdev)
static int flexcard_misc_probe(struct platform_device *pdev)
{
struct flexcard_misc *priv;
+ struct device *this_device;
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -137,13 +315,31 @@ static int flexcard_misc_probe(struct platform_device *pdev)
return ret;
}
+ this_device = priv->dev.this_device;
+ dev_set_drvdata(this_device, priv);
+
+ ret = sysfs_create_group(&this_device->kobj,
+ &flexcard_misc_dev_group);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to create sysfs attributes: %d\n", ret);
+ goto out;
+ }
+
return 0;
+
+out:
+ misc_deregister(&priv->dev);
+ return ret;
}
static int flexcard_misc_remove(struct platform_device *pdev)
{
struct flexcard_misc *priv = platform_get_drvdata(pdev);
+ struct device *this_device = priv->dev.this_device;
+ sysfs_remove_group(&this_device->kobj,
+ &flexcard_misc_dev_group);
misc_deregister(&priv->dev);
return 0;
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 10/12] misc: Flexcard basic timestamp counter support
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (8 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 09/12] misc: flexcard: add device attributes Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 3:28 ` kbuild test robot
2016-12-14 8:46 ` Arnd Bergmann
2016-12-14 0:11 ` [PATCH 11/12] misc: flexcard: Support timestamp trigger selection Holger Dengler
` (2 subsequent siblings)
12 siblings, 2 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Eberspaecher Flexcard PMC II offers a Flexray network synchronized
counter with a selectable resolution of 1us, 100ns or 10ns. Add basic
support for the timestamp counter with 1us resolution, which is the
standard Flexray bus resolution.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Arnd Bergmann <arnd@arndb.de>
cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mfd/Kconfig | 1 +
drivers/misc/Kconfig | 9 ++
drivers/misc/Makefile | 1 +
drivers/misc/flexcard_posixclock.c | 240 +++++++++++++++++++++++++++++++++++++
4 files changed, 251 insertions(+)
create mode 100644 drivers/misc/flexcard_posixclock.c
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 580f521..490b435 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -304,6 +304,7 @@ config MFD_FLEXCARD
select MFD_CORE
select IRQ_DOMAIN
select FLEXCARD_MISC
+ select FLEXCARD_PCLOCK
depends on PCI
help
This is the core driver for the Eberspaecher Flexcard
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 3f54b58..658a6df 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -772,6 +772,15 @@ config FLEXCARD_MISC
help
Misc driver for Flexcard PMC II.
+config FLEXCARD_PCLOCK
+ tristate "Flexcard posix clock Function driver"
+ depends on MFD_FLEXCARD
+ help
+ This is the posix clock function driver for the
+ Eberspaecher Flexcard PMC II carrier board. The
+ Flexcard provide a Flexray synchronized counter
+ configurable at 1, 10 or 100MHz.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 08a1729..df655bb 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
obj-$(CONFIG_CXL_BASE) += cxl/
obj-$(CONFIG_PANEL) += panel.o
obj-$(CONFIG_FLEXCARD_MISC) += flexcard_misc.o
+obj-$(CONFIG_FLEXCARD_PCLOCK) += flexcard_posixclock.o
lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
diff --git a/drivers/misc/flexcard_posixclock.c b/drivers/misc/flexcard_posixclock.c
new file mode 100644
index 0000000..146f0f3
--- /dev/null
+++ b/drivers/misc/flexcard_posixclock.c
@@ -0,0 +1,240 @@
+/*
+ * Eberspächer Flexcard PMC II - posix clock driver
+ *
+ * Copyright (c) 2014 - 2016, Linutronix GmbH
+ * Author: Benedikt Spranger <b.spranger@linutronix.de>
+ * Holger Dengler <dengler@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/posix-clock.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/flexcard.h>
+
+#define MAX_CLOCKS 16
+#define CLKSEL_OFF 0x10
+
+#define FLEXCARD_RST_TS 0x8000
+
+#define FLEXCARD_CLK_1MHZ 0
+
+static dev_t flexcard_clk_devt;
+static struct class *flexcard_clk_class;
+
+struct flexcard_clk {
+ struct posix_clock clock;
+ dev_t devid;
+ struct device *dev;
+ void __iomem *ts64;
+ void __iomem *reset;
+};
+
+static int flexcard_clk_getres(struct posix_clock *pc, struct timespec *tp)
+{
+ tp->tv_sec = 0;
+ tp->tv_nsec = 1000;
+
+ return 0;
+}
+
+static int flexcard_clk_gettime(struct posix_clock *pc, struct timespec *tp)
+{
+ struct flexcard_clk *clk = container_of(pc, struct flexcard_clk, clock);
+ u64 now;
+ u32 upper, rem;
+
+retry:
+ upper = readl(clk->ts64);
+ now = ((u64) upper << 32) | readl(clk->ts64 + 4);
+ if (upper != readl(clk->ts64))
+ goto retry;
+
+ tp->tv_sec = div_u64_rem(now, 1000000, &rem);
+ tp->tv_nsec = rem * 1000;
+
+ return 0;
+}
+
+static int flexcard_clk_settime(struct posix_clock *pc,
+ const struct timespec *tp)
+{
+ struct flexcard_clk *clk = container_of(pc, struct flexcard_clk, clock);
+
+ /* The FlexCard posix clock could only be reset to 0 and not set */
+ if (tp->tv_sec || tp->tv_nsec)
+ return -EINVAL;
+
+ writel(FLEXCARD_RST_TS, clk->reset);
+
+ return 0;
+}
+
+static struct posix_clock_operations flexcard_clk_ops = {
+ .owner = THIS_MODULE,
+ .clock_getres = flexcard_clk_getres,
+ .clock_gettime = flexcard_clk_gettime,
+ .clock_settime = flexcard_clk_settime,
+};
+
+static int flexcard_clk_iomap(struct platform_device *pdev)
+{
+ struct flexcard_clk *clk = platform_get_drvdata(pdev);
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENXIO;
+
+ clk->ts64 = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!clk->ts64)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res)
+ return -ENXIO;
+
+ clk->reset = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!clk->reset)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int flexcard_clk_probe(struct platform_device *pdev)
+{
+ const struct mfd_cell *cell;
+ struct flexcard_clk *clk;
+ int major, ret;
+
+ cell = mfd_get_cell(pdev);
+ if (!cell)
+ return -ENODEV;
+
+ if (cell->id >= MAX_CLOCKS) {
+ dev_err(&pdev->dev, "all flexcard posix clocks in use: %d\n",
+ cell->id);
+ return -EBUSY;
+ }
+
+ clk = devm_kzalloc(&pdev->dev, sizeof(*clk), GFP_KERNEL);
+ if (!clk)
+ return -ENOMEM;
+
+ major = MAJOR(flexcard_clk_devt);
+ platform_set_drvdata(pdev, clk);
+
+ ret = flexcard_clk_iomap(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to map resources: %d\n", ret);
+ goto out;
+ }
+
+ clk->devid = MKDEV(major, cell->id);
+ clk->clock.ops = flexcard_clk_ops;
+
+ writel(FLEXCARD_CLK_1MHZ, clk->ts64 + CLKSEL_OFF);
+ writel(FLEXCARD_RST_TS, clk->reset);
+
+ clk->dev = device_create(flexcard_clk_class, &pdev->dev, clk->devid,
+ clk, "flexcard_clock%d", cell->id);
+ if (IS_ERR(clk->dev)) {
+ ret = PTR_ERR(clk->dev);
+ goto out;
+ }
+
+ ret = posix_clock_register(&clk->clock, clk->devid);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to register flexcard posix clock: %d\n", ret);
+ goto out_destroy;
+ }
+
+ dev_info(&pdev->dev, "flexcard posix clock %d registered", cell->id);
+
+ return 0;
+
+out_destroy:
+ device_destroy(flexcard_clk_class, clk->devid);
+out:
+ return ret;
+}
+
+static int flexcard_clk_remove(struct platform_device *pdev)
+{
+ struct flexcard_clk *clk = platform_get_drvdata(pdev);
+
+ posix_clock_unregister(&clk->clock);
+ device_destroy(flexcard_clk_class, clk->devid);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static const struct platform_device_id flexcard_clk_id_table[] = {
+ { "flexcard-clock", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, flexcard_clk_id_table);
+
+static struct platform_driver flexcard_clk_driver = {
+ .probe = flexcard_clk_probe,
+ .remove = flexcard_clk_remove,
+ .driver = {
+ .name = "flexcard-clock",
+ },
+ .id_table = flexcard_clk_id_table,
+};
+
+static int __init flexcard_clk_init(void)
+{
+ int ret;
+
+ flexcard_clk_class = class_create(THIS_MODULE, "flexcard_clock");
+ if (IS_ERR(flexcard_clk_class)) {
+ pr_err("flexcard_clock: failed to allocate class\n");
+ return PTR_ERR(flexcard_clk_class);
+ }
+
+ ret = alloc_chrdev_region(&flexcard_clk_devt, 0, MAX_CLOCKS,
+ "flexcard_clock");
+ if (ret < 0) {
+ pr_err("failed to allocate device region\n");
+ goto out;
+ }
+
+ ret = platform_driver_register(&flexcard_clk_driver);
+ if (ret < 0)
+ goto out_unregister;
+
+ return 0;
+
+out_unregister:
+ unregister_chrdev_region(flexcard_clk_devt, MAX_CLOCKS);
+out:
+ class_destroy(flexcard_clk_class);
+
+ return ret;
+}
+
+static void __exit flexcard_clk_exit(void)
+{
+ platform_driver_unregister(&flexcard_clk_driver);
+ unregister_chrdev_region(flexcard_clk_devt, MAX_CLOCKS);
+ class_destroy(flexcard_clk_class);
+}
+
+module_init(flexcard_clk_init);
+module_exit(flexcard_clk_exit);
+
+MODULE_AUTHOR("Holger Dengler <dengler@linutronix.de>");
+MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>");
+MODULE_DESCRIPTION("Eberspaecher Flexcard PMC II posix clock driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 11/12] misc: flexcard: Support timestamp trigger selection
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (9 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 10/12] misc: Flexcard basic timestamp counter support Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 0:11 ` [PATCH 12/12] dma: Flexcard DMA ringbuffer demux driver Holger Dengler
2017-01-04 9:43 ` [PATCH 00/12] Eberspaecher Flexcard PMC II base support Lee Jones
12 siblings, 0 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Flexcard timestamp counter can be triggered from two external
trigger inputs or an internal clock at 1 MHz, 10 Mhz or 100 MHz.
Add support for timestamp trigger selection.
Signed-off-by: Holger Dengler <dengler@linutronix.de>
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
cc: Arnd Bergmann <arnd@arndb.de>
cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/misc/flexcard_posixclock.c | 63 +++++++++++++++++++++++++++++++++++---
include/uapi/linux/flexcard.h | 16 ++++++++++
2 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/flexcard_posixclock.c b/drivers/misc/flexcard_posixclock.c
index 146f0f3..b4cb38e 100644
--- a/drivers/misc/flexcard_posixclock.c
+++ b/drivers/misc/flexcard_posixclock.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/flexcard.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
@@ -35,12 +36,15 @@ struct flexcard_clk {
struct device *dev;
void __iomem *ts64;
void __iomem *reset;
+ u32 mul;
+ struct flexcard_clk_desc desc;
};
static int flexcard_clk_getres(struct posix_clock *pc, struct timespec *tp)
{
+ struct flexcard_clk *clk = container_of(pc, struct flexcard_clk, clock);
tp->tv_sec = 0;
- tp->tv_nsec = 1000;
+ tp->tv_nsec = clk->mul;
return 0;
}
@@ -57,8 +61,8 @@ static int flexcard_clk_gettime(struct posix_clock *pc, struct timespec *tp)
if (upper != readl(clk->ts64))
goto retry;
- tp->tv_sec = div_u64_rem(now, 1000000, &rem);
- tp->tv_nsec = rem * 1000;
+ tp->tv_sec = div_u64_rem(now, clk->desc.freq, &rem);
+ tp->tv_nsec = rem * clk->mul;
return 0;
}
@@ -77,11 +81,59 @@ static int flexcard_clk_settime(struct posix_clock *pc,
return 0;
}
+static long flexcard_clk_ioctl(struct posix_clock *pc, unsigned int cmd,
+ unsigned long arg)
+{
+ struct flexcard_clk *clk = container_of(pc, struct flexcard_clk, clock);
+ struct flexcard_clk_desc desc;
+
+ switch (cmd) {
+ case FCSCLKSRC:
+ if (copy_from_user(&desc, (void __user *)arg, sizeof(desc)))
+ return -EFAULT;
+
+ switch (desc.type) {
+ case FLEXCARD_CLK_1MHZ:
+ desc.freq = 1000000;
+ break;
+ case FLEXCARD_CLK_10MHZ:
+ desc.freq = 10000000;
+ break;
+ case FLEXCARD_CLK_100MHZ:
+ desc.freq = 100000000;
+ break;
+ case FLEXCARD_CLK_EXT1:
+ case FLEXCARD_CLK_EXT2:
+ if (desc.freq < 1 || desc.freq > NSEC_PER_SEC)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ clk->desc = desc;
+ clk->mul = NSEC_PER_SEC/desc.freq;
+ writel(clk->desc.type, clk->ts64 + CLKSEL_OFF);
+ writel(FLEXCARD_RST_TS, clk->reset);
+
+ break;
+ case FCGCLKSRC:
+ if (copy_to_user((void __user *)arg, &clk->desc, sizeof(desc)))
+ return -EFAULT;
+ break;
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
static struct posix_clock_operations flexcard_clk_ops = {
.owner = THIS_MODULE,
.clock_getres = flexcard_clk_getres,
.clock_gettime = flexcard_clk_gettime,
.clock_settime = flexcard_clk_settime,
+ .ioctl = flexcard_clk_ioctl,
};
static int flexcard_clk_iomap(struct platform_device *pdev)
@@ -139,8 +191,11 @@ static int flexcard_clk_probe(struct platform_device *pdev)
clk->devid = MKDEV(major, cell->id);
clk->clock.ops = flexcard_clk_ops;
+ clk->desc.type = FLEXCARD_CLK_1MHZ;
+ clk->desc.freq = 1000000;
+ clk->mul = 1000;
- writel(FLEXCARD_CLK_1MHZ, clk->ts64 + CLKSEL_OFF);
+ writel(clk->desc.type, clk->ts64 + CLKSEL_OFF);
writel(FLEXCARD_RST_TS, clk->reset);
clk->dev = device_create(flexcard_clk_class, &pdev->dev, clk->devid,
diff --git a/include/uapi/linux/flexcard.h b/include/uapi/linux/flexcard.h
index 4e9f07b4..3ad0bf4 100644
--- a/include/uapi/linux/flexcard.h
+++ b/include/uapi/linux/flexcard.h
@@ -15,6 +15,22 @@
#include <linux/types.h>
+enum flexcard_clk_type {
+ FLEXCARD_CLK_1MHZ = 0x0,
+ FLEXCARD_CLK_10MHZ = 0x1,
+ FLEXCARD_CLK_100MHZ = 0x2,
+ FLEXCARD_CLK_EXT1 = 0x11,
+ FLEXCARD_CLK_EXT2 = 0x12,
+};
+
+struct flexcard_clk_desc {
+ enum flexcard_clk_type type;
+ __u32 freq;
+};
+
+#define FCGCLKSRC _IOR(0xeb, 0, struct flexcard_clk_desc)
+#define FCSCLKSRC _IOW(0xeb, 1, struct flexcard_clk_desc)
+
struct fc_version {
__u8 dev;
__u8 min;
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 12/12] dma: Flexcard DMA ringbuffer demux driver
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (10 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 11/12] misc: flexcard: Support timestamp trigger selection Holger Dengler
@ 2016-12-14 0:11 ` Holger Dengler
2016-12-14 1:54 ` kbuild test robot
2016-12-15 4:38 ` Vinod Koul
2017-01-04 9:43 ` [PATCH 00/12] Eberspaecher Flexcard PMC II base support Lee Jones
12 siblings, 2 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 0:11 UTC (permalink / raw)
To: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul
Cc: linux-kernel, dmaengine, Thomas Gleixner, Sebastian Siewior,
Juergen Bubeck, Peter Mahler, Holger Dengler, Benedikt Spranger
The Flexcard interface design split packet receive and transmit. All
received packets and card status information are multiplexed with a
Flexcard specific protocol and handled through a DMA capable ringbuffer.
The TX path has to poke each available component separate.
Add a Flexcard DMA ringbuffer driver and packet demultiplexer.
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
cc: Vinod Koul <vinod.koul@intel.com>
---
drivers/dma/Kconfig | 9 ++
drivers/dma/Makefile | 1 +
drivers/dma/flexcard/Makefile | 2 +
drivers/dma/flexcard/core.c | 292 ++++++++++++++++++++++++++++++++++++
drivers/dma/flexcard/flexcard-dma.h | 218 +++++++++++++++++++++++++++
drivers/dma/flexcard/parser.c | 227 ++++++++++++++++++++++++++++
drivers/mfd/Kconfig | 1 +
include/linux/mfd/flexcard.h | 4 +
8 files changed, 754 insertions(+)
create mode 100644 drivers/dma/flexcard/Makefile
create mode 100644 drivers/dma/flexcard/core.c
create mode 100644 drivers/dma/flexcard/flexcard-dma.h
create mode 100644 drivers/dma/flexcard/parser.c
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 141aefb..b158544 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -40,6 +40,15 @@ config ASYNC_TX_ENABLE_CHANNEL_SWITCH
config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
bool
+config FLEXCARD_DMA
+ tristate "DMA support for Eberspaecher Flexcard PMC II Carrier Board"
+ depends on MFD_FLEXCARD
+ help
+ The Eberspaecher Flexcard PMC (PCI Mezzanine Card) II carrier
+ board support one DMA capable receive ringbuffer for all devices.
+ A card specific protocol is used to multiplex the received packets
+ through the ringbuffer. Enable DMA and Packet parser.
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index e4dc9ca..a9a5b3f 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_DMA_SUN4I) += sun4i-dma.o
obj-$(CONFIG_DMA_SUN6I) += sun6i-dma.o
obj-$(CONFIG_DW_DMAC_CORE) += dw/
obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
+obj-$(CONFIG_FLEXCARD_DMA) += flexcard/
obj-$(CONFIG_FSL_DMA) += fsldma.o
obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
obj-$(CONFIG_FSL_RAID) += fsl_raid.o
diff --git a/drivers/dma/flexcard/Makefile b/drivers/dma/flexcard/Makefile
new file mode 100644
index 0000000..62ae627
--- /dev/null
+++ b/drivers/dma/flexcard/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_FLEXCARD_DMA) += flexcard_dma.o
+flexcard_dma-objs := core.o parser.o
diff --git a/drivers/dma/flexcard/core.c b/drivers/dma/flexcard/core.c
new file mode 100644
index 0000000..6809840
--- /dev/null
+++ b/drivers/dma/flexcard/core.c
@@ -0,0 +1,292 @@
+/*
+ * Eberspächer Flexcard PMC II Carrier Board PCI Driver - DMA controller
+ *
+ * Copyright (c) 2014 - 2016, Linutronix GmbH
+ * Author: Benedikt Spranger <b.spranger@linutronix.de>
+ * Holger Dengler <dengler@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/flexcard.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/flexcard.h>
+
+#include "flexcard-dma.h"
+
+/*
+ * Allocate twice the size of FLEXCARD_DMA_BUF_SIZE for the receiving
+ * ring buffer to easily handle wrap-arounds.
+ */
+#define DMA_TOTAL_BUF_SIZE (2*FLEXCARD_DMA_BUF_SIZE)
+
+static int flexcard_dma_stop(struct flexcard_dma *dma)
+{
+ u32 __iomem *dma_ctrl = &dma->reg->dma_ctrl;
+ u32 __iomem *dma_stat = &dma->reg->dma_stat;
+ int retry;
+
+ writel(FLEXCARD_DMA_CTRL_STOP_REQ, dma_ctrl);
+
+ /*
+ * DMA_IDLE bit reads 1 when the DMA state machine is in idle state
+ * after a stop request, otherwise 0. DMA stop should complete in at
+ * least 200us.
+ */
+ retry = 200;
+ while (!(readl(dma_ctrl) & FLEXCARD_DMA_CTRL_DMA_IDLE) && retry--)
+ udelay(1);
+ if (!retry)
+ return -EBUSY;
+
+ /*
+ * Check for max. 200us, if there are DMA jobs in progress.
+ */
+ retry = 200;
+ while ((readl(dma_stat) & FLEXCARD_DMA_STAT_BUSY) && retry--)
+ udelay(1);
+
+ return retry ? 0 : -EBUSY;
+}
+
+static int flexcard_dma_reset(struct flexcard_dma *dma)
+{
+ u32 __iomem *dma_ctrl = &dma->reg->dma_ctrl;
+ int retry = 500;
+
+ writel(FLEXCARD_DMA_CTRL_RST_DMA, dma_ctrl);
+
+ /*
+ * DMA_IDLE bit reads 1 when the DMA state machine is in idle state
+ * after a reset request, otherwise 0. DMA reset should complete in
+ * at least 5ms.
+ */
+ while (!(readl(dma_ctrl) & FLEXCARD_DMA_CTRL_DMA_IDLE) && retry--)
+ udelay(10);
+
+ return retry ? 0 : -EIO;
+}
+
+static int flexcard_dma_setup(struct flexcard_dma *dma)
+{
+ int ret;
+
+ ret = flexcard_dma_reset(dma);
+ if (ret)
+ return ret;
+
+ writel(0x0, &dma->reg->dma_rptr);
+ writel(0x0, &dma->reg->dma_wptr);
+ writel(0x0, &dma->reg->dma_ctrl);
+
+ writeq(dma->phys, &dma->reg->dma_cba);
+ writel(FLEXCARD_DMA_BUF_SIZE, &dma->reg->dma_cbs);
+
+ return ret;
+}
+
+static irqreturn_t flexcard_dma_isr(int irq, void *dev_id)
+{
+ struct platform_device *pdev = dev_id;
+ struct flexcard_dma *dma = platform_get_drvdata(pdev);
+ u32 avail, parsed, rptr = dma->rptr;
+
+ avail = readl(&dma->reg->dma_cblr);
+ if (!avail)
+ return IRQ_NONE;
+
+ do {
+ u32 tocp = rptr + FLEXCARD_MAX_PAKET_SIZE;
+ /*
+ * For simplicity the parser always looks at contiguous
+ * buffer space.
+ *
+ * We ensure that by copying the eventually wrapped
+ * bytes of the next message from the bottom of the
+ * dma buffer to the space right after the dma buffer
+ * which has been allocated just for that reason.
+ */
+ if (tocp > FLEXCARD_DMA_BUF_SIZE) {
+ tocp &= FLEXCARD_DMA_BUF_MASK;
+ memcpy(dma->buf + FLEXCARD_DMA_BUF_SIZE,
+ dma->buf, tocp);
+ }
+
+ parsed = flexcard_parse_packet(dma->buf + rptr, avail, dma);
+ if (parsed > avail) {
+ dev_err(&pdev->dev, "Parser overrun\n");
+ rptr = (rptr + parsed) & FLEXCARD_DMA_BUF_MASK;
+ break;
+ }
+ avail -= parsed;
+ rptr = (rptr + parsed) & FLEXCARD_DMA_BUF_MASK;
+ } while (parsed && avail);
+
+ /* Update the read pointer in the device if we processed data */
+ if (dma->rptr != rptr) {
+ dma->rptr = rptr;
+ writel(rptr, &dma->reg->dma_rptr);
+ } else {
+ /* This may happen if no packets has been parsed */
+ dev_err_ratelimited(&pdev->dev, "rptr unchanged\n");
+ return IRQ_NONE;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t flexcard_dma_ovr(int irq, void *dev_id)
+{
+ struct platform_device *pdev = dev_id;
+ struct flexcard_dma *dma = platform_get_drvdata(pdev);
+ u32 stat;
+
+ /* check overflow flag */
+ stat = readl(&dma->reg->dma_stat);
+ if (!(stat & FLEXCARD_DMA_STAT_OFL))
+ return IRQ_NONE;
+
+ dev_err(&pdev->dev, "DMA buffer overflow\n");
+
+ writel(0x0, &dma->reg->dma_rptr);
+
+ /* reset overflow flag */
+ writel(FLEXCARD_DMA_STAT_OFL, &dma->reg->dma_stat);
+
+ return IRQ_HANDLED;
+}
+
+static int flexcard_dma_resource(struct platform_device *pdev)
+{
+ struct flexcard_dma *dma = platform_get_drvdata(pdev);
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENXIO;
+
+ dma->reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!dma->reg) {
+ dev_err(&pdev->dev, "failed to map DMA register\n");
+ return -ENOMEM;
+ }
+
+ dma->irq = platform_get_irq(pdev, 0);
+ if (dma->irq < 0) {
+ dev_err(&pdev->dev, "failed to get CBL IRQ\n");
+ return -ENXIO;
+ }
+
+ dma->irq_ovr = platform_get_irq(pdev, 1);
+ if (dma->irq_ovr < 0) {
+ dev_err(&pdev->dev, "failed to get CO IRQ\n");
+ return -ENXIO;
+ }
+ return 0;
+}
+
+static int flexcard_dma_probe(struct platform_device *pdev)
+{
+ const struct mfd_cell *cell;
+ struct flexcard_dma *dma;
+ int ret;
+
+ cell = mfd_get_cell(pdev);
+ if (!cell)
+ return -ENODEV;
+
+ dma = devm_kzalloc(&pdev->dev, sizeof(*dma), GFP_KERNEL);
+ if (!dma)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, dma);
+
+ dma->buf = dma_alloc_coherent(&pdev->dev, DMA_TOTAL_BUF_SIZE,
+ &dma->phys, GFP_KERNEL);
+ if (!dma->buf) {
+ dev_err(&pdev->dev, "could not allocate DMA memory\n");
+ return -ENOMEM;
+ }
+
+ ret = flexcard_dma_resource(pdev);
+ if (ret)
+ goto out_free_buf;
+
+ ret = flexcard_dma_setup(dma);
+ if (ret) {
+ dev_err(&pdev->dev, "could not setup Flexcard DMA: %d\n", ret);
+ goto out_free_buf;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, dma->irq, NULL,
+ flexcard_dma_isr, IRQF_ONESHOT,
+ "flexcard-CBL", pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "could not request Flexcard DMA CBL IRQ\n");
+ goto out_free_buf;
+ }
+
+ ret = devm_request_irq(&pdev->dev, dma->irq_ovr, flexcard_dma_ovr, 0,
+ "flexcard-CO", pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "could not request Flexcard DMA CO IRQ\n");
+ goto out_free_irq;
+ }
+
+ writel(FLEXCARD_DMA_CTRL_DMA_ENA, &dma->reg->dma_ctrl);
+ writel(0x300, &dma->reg->dma_cbcr);
+
+ dev_info(&pdev->dev, "Flexcard DMA registered");
+
+ return 0;
+
+out_free_irq:
+ writel(0x0, &dma->reg->dma_ctrl);
+out_free_buf:
+ dma_free_coherent(&pdev->dev, DMA_TOTAL_BUF_SIZE,
+ dma->buf, dma->phys);
+ return ret;
+}
+
+static int flexcard_dma_remove(struct platform_device *pdev)
+{
+ struct flexcard_dma *dma = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = flexcard_dma_stop(dma);
+ if (ret) {
+ dev_err(&pdev->dev, "could not stop DMA state machine\n");
+ return ret;
+ }
+
+ dma_free_coherent(&pdev->dev, DMA_TOTAL_BUF_SIZE,
+ dma->buf, dma->phys);
+
+ return ret;
+}
+
+static struct platform_driver flexcard_dma_driver = {
+ .probe = flexcard_dma_probe,
+ .remove = flexcard_dma_remove,
+ .driver = {
+ .name = "flexcard-dma",
+ }
+};
+
+module_platform_driver(flexcard_dma_driver);
+
+MODULE_AUTHOR("Holger Dengler <dengler@linutronix.de>");
+MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>");
+MODULE_DESCRIPTION("Eberspaecher Flexcard PMC II DMA Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:flexcard-dma");
diff --git a/drivers/dma/flexcard/flexcard-dma.h b/drivers/dma/flexcard/flexcard-dma.h
new file mode 100644
index 0000000..6fc4ccf
--- /dev/null
+++ b/drivers/dma/flexcard/flexcard-dma.h
@@ -0,0 +1,218 @@
+/*
+ * Eberspächer Flexcard PMC II Carrier Board PCI Driver - DMA controller
+ *
+ * Copyright (c) 2014 - 2016, Linutronix GmbH
+ * Author: Benedikt Spranger <b.spranger@linutronix.de>
+ * Holger Dengler <dengler@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+#ifndef __FLEXCARD_DMA_H
+#define __FLEXCARD_DMA_H
+
+#define FLEXCARD_DMA_BUF_SIZE 0x200000
+#define FLEXCARD_DMA_BUF_MASK (FLEXCARD_DMA_BUF_SIZE - 1)
+
+#define FLEXCARD_DMA_CTRL_DMA_ENA (1 << 0)
+#define FLEXCARD_DMA_CTRL_MAN_ENA (1 << 1)
+#define FLEXCARD_DMA_CTRL_STOP_REQ (1 << 16)
+#define FLEXCARD_DMA_CTRL_DMA_IDLE (1 << 17)
+#define FLEXCARD_DMA_CTRL_RST_DMA (1 << 31)
+
+#define FLEXCARD_DMA_STAT_BUSY (1 << 15)
+#define FLEXCARD_DMA_STAT_OFL (1 << 31)
+
+#define FLEXCARD_MAX_PAKET_SIZE 0x200
+
+#define FLEXCARD_BUF_HEADER_LEN_SHIFT 15
+#define FLEXCARD_BUF_HEADER_LEN_MASK 0xfe
+
+#define FLEXCARD_CANIF_OFFSET 0x20
+
+struct flexcard_dma_reg {
+ u32 dma_ctrl;
+ u32 dma_stat;
+ u32 r1[2];
+ u64 dma_cba;
+ u32 dma_cbs;
+ u32 dma_txr;
+ u32 dma_irer;
+ u32 dma_irsr;
+ u32 r2[10];
+ u32 dma_cbcr;
+ u32 dma_cblr;
+ u32 r3[2];
+ u32 dma_itcr;
+ u32 dma_itr;
+ u32 r4[2];
+ u32 dma_wptr;
+ u32 dma_rptr;
+ u32 r5[2];
+} __packed;
+
+struct flexcard_dma {
+ int irq;
+ int irq_ovr;
+ u32 rptr;
+ void *buf;
+ dma_addr_t phys;
+ int nr_eray;
+ struct flexcard_dma_reg __iomem *reg;
+};
+
+enum fc_packet_type {
+ FC_PACKET_TYPE_INFO = 1,
+ FC_PACKET_TYPE_FLEXRAY_FRAME = 2,
+ FC_PACKET_TYPE_ERROR = 3,
+ FC_PACKET_TYPE_STATUS = 4,
+ FC_PACKET_TYPE_TRIGGER = 5,
+ FC_PACKET_TYPE_TX_ACK = 6,
+ FC_PACKET_TYPE_NMV_VECTOR = 7,
+ FC_PACKET_TYPE_NOTIFICATION = 8,
+ FC_PACKET_TYPE_TRIGGER_EX = 9,
+ FC_PACKET_TYPE_CAN = 10,
+ FC_PACKET_TYPE_CAN_ERROR = 11,
+};
+
+struct fc_packet {
+ __u32 type;
+ __u32 p_packet;
+ __u32 p_next_packet;
+} __packed;
+
+struct fc_info_packet {
+ __u32 current_cycle;
+ __u32 timestamp;
+ __u32 offset_rate_correction;
+ __u32 pta_ccf_count;
+ __u32 cc;
+} __packed;
+
+struct fc_flexray_frame {
+ __u32 header;
+ __u32 header_crc;
+ __u32 pdata;
+ __u32 channel;
+ __u32 frame_crc;
+ __u32 timestamp;
+ __u32 cc;
+} __packed;
+
+struct fc_error_packet {
+ __u32 flag;
+ __u32 timestamp;
+ __u32 cycle_count;
+ __u64 additional_info;
+ __u32 cc;
+ __u32 reserved;
+} __packed;
+
+struct fc_status_packet {
+ __u32 flag;
+ __u32 timestamp;
+ __u32 cycle_count;
+ __u32 additional_info;
+ __u32 cc;
+ __u32 reserved[2];
+} __packed;
+
+struct fc_tx_ack_packet {
+ __u32 bufferid;
+ __u32 timestamp;
+ __u32 cycle_count;
+ __u32 header;
+ __u32 header_crc;
+ __u32 pdata;
+ __u32 channel;
+ __u32 cc;
+} __packed;
+
+struct fc_nm_vector_packet {
+ __u32 timestamp;
+ __u32 cycle_count;
+ __u32 nmv_vector_length;
+ __u32 nmv_vector[3];
+ __u32 cc;
+ __u32 reserved;
+} __packed;
+
+struct fc_notification_packet {
+ __u32 timestamp;
+ __u32 sequence_count;
+ __u32 reserved;
+} __packed;
+
+struct fc_trigger_ex_info_packet {
+ __u32 condition;
+ __u32 timestamp;
+ __u32 sequence_count;
+ __u32 reserved1;
+ __u64 performance_counter;
+ __u32 edge;
+ __u32 trigger_line;
+ __u32 reserved[4];
+} __packed;
+
+struct fc_can_packet {
+ __u32 id;
+ __u32 timestamp;
+ __u32 flags;
+ __u32 reserved;
+ __u32 cc;
+ __u8 data[8];
+} __packed;
+
+struct fc_can_error_packet {
+ __u32 type;
+ __u32 state;
+ __u32 timestamp;
+ __u32 rx_error_counter;
+ __u32 tx_error_counter;
+ __u32 cc;
+ __u32 reserved[2];
+} __packed;
+
+enum fc_can_cc_state {
+ fc_can_state_unknown = 0,
+ fc_can_state_config,
+ fc_can_state_normalActive,
+ fc_can_state_warning,
+ fc_can_state_error_passive,
+ fc_can_state_bus_off,
+};
+
+enum fc_can_error_type {
+ fc_can_error_none = 0,
+ fc_can_error_stuff,
+ fc_can_error_form,
+ fc_can_error_acknowledge,
+ fc_can_error_bit1,
+ fc_can_error_bit0,
+ fc_can_error_crc,
+ fc_can_error_parity,
+};
+
+union fc_packet_types {
+ struct fc_info_packet info_packet;
+ struct fc_flexray_frame flexray_frame;
+ struct fc_error_packet error_packet;
+ struct fc_status_packet status_packet;
+ struct fc_tx_ack_packet tx_ack_packet;
+ struct fc_nm_vector_packet nm_vector_packet;
+ struct fc_notification_packet notification_packet;
+ struct fc_trigger_ex_info_packet ex_info_packet;
+ struct fc_can_packet can_packet;
+ struct fc_can_error_packet can_error_packet;
+};
+
+struct fc_packet_buf {
+ struct fc_packet header;
+ union fc_packet_types packet;
+} __packed;
+
+u32 flexcard_parse_packet(struct fc_packet_buf *pb, u32 avail,
+ struct flexcard_dma *dma);
+
+#endif /* __FLEXCARD_DMA_H */
diff --git a/drivers/dma/flexcard/parser.c b/drivers/dma/flexcard/parser.c
new file mode 100644
index 0000000..2450229
--- /dev/null
+++ b/drivers/dma/flexcard/parser.c
@@ -0,0 +1,227 @@
+/*
+ * Eberspächer Flexcard PMC II Carrier Board PCI Driver - packet parser/mux
+ *
+ * Copyright (c) 2014 - 2016, Linutronix GmbH
+ * Author: Benedikt Spranger <b.spranger@linutronix.de>
+ * Holger Dengler <dengler@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <linux/mfd/flexcard.h>
+#include "flexcard-dma.h"
+
+static LIST_HEAD(rx_cb_list);
+static DEFINE_SPINLOCK(rx_cb_lock);
+
+struct fc_rx_cb {
+ struct list_head list;
+ int (*rx_cb)(void *priv, void *data, size_t len);
+ int cc;
+ void *priv;
+};
+
+/**
+ * flexcard_register_rx_cb() - Registers a callback for received packages
+ * @cc: communication controller id
+ * @priv: pointer to private data of the cc
+ * @rx_cp: pionter to the receive callback
+ *
+ * Registers a callback for a communication controller specific handling for
+ * received packages. The callback is called by the generic parser, if the
+ * communication controller id inside of the received package matches the cc
+ * of the callback owner.
+ *
+ * Return: 0 is returned on success and a negative errno code for failure.
+ */
+int flexcard_register_rx_cb(int cc, void *priv,
+ int (*rx_cb)(void *priv, void *data, size_t len))
+{
+ unsigned long flags;
+ struct fc_rx_cb *cb, *next;
+
+ if (!rx_cb)
+ return -EINVAL;
+
+ cb = kmalloc(sizeof(*cb), GFP_KERNEL);
+ if (!cb)
+ return -ENOMEM;
+
+ cb->cc = cc;
+ cb->priv = priv;
+ cb->rx_cb = rx_cb;
+
+ spin_lock_irqsave(&rx_cb_lock, flags);
+ list_for_each_entry(next, &rx_cb_list, list)
+ if (next->cc == cc)
+ goto out;
+
+ list_add_tail(&cb->list, &rx_cb_list);
+ spin_unlock_irqrestore(&rx_cb_lock, flags);
+
+ return 0;
+out:
+ spin_unlock_irqrestore(&rx_cb_lock, flags);
+ kfree(cb);
+
+ return -EBUSY;
+}
+EXPORT_SYMBOL_GPL(flexcard_register_rx_cb);
+
+/**
+ * flexcard_unregister_rx_cb() - Unregisters a callback for received packages
+ * @cc: communication controller id
+ *
+ * Unregisters a callback for a communication controller specific handling for
+ * received packages.
+ *
+ * Return: 0 is returned on success and a negative errno code for failure.
+ */
+void flexcard_unregister_rx_cb(int cc)
+{
+ unsigned long flags;
+ struct fc_rx_cb *cur, *next;
+ int found = 0;
+
+ spin_lock_irqsave(&rx_cb_lock, flags);
+ list_for_each_entry_safe(cur, next, &rx_cb_list, list) {
+ if (cur->cc == cc) {
+ list_del(&cur->list);
+ kfree(cur);
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ pr_err("no callback registered for cc %d\n", cc);
+
+ spin_unlock_irqrestore(&rx_cb_lock, flags);
+}
+EXPORT_SYMBOL_GPL(flexcard_unregister_rx_cb);
+
+static int flexcard_queue_rx(int cc, void *buf, size_t len)
+{
+ struct fc_rx_cb *next;
+ unsigned long flags;
+ int ret = -ENODEV;
+
+ spin_lock_irqsave(&rx_cb_lock, flags);
+ list_for_each_entry(next, &rx_cb_list, list)
+ if (next->cc == cc)
+ ret = next->rx_cb(next->priv, buf, len);
+ spin_unlock_irqrestore(&rx_cb_lock, flags);
+
+ return ret;
+}
+
+static u32 flexcard_get_packet_len(u32 header)
+{
+ u32 len;
+
+ /*
+ * header contains the number of transmitted 16bit words in bits 30-16.
+ * if the number is odd the DMA engine padded with zero to 32bit.
+ * calculate the number of transmitted bytes.
+ */
+
+ len = le32_to_cpu(header);
+
+ len >>= FLEXCARD_BUF_HEADER_LEN_SHIFT;
+ len &= FLEXCARD_BUF_HEADER_LEN_MASK;
+
+ len = roundup(len, 4);
+
+ return len;
+}
+
+/**
+ * selfsync_cc - adjust the cc number for self-sync packages
+ * @dma: pointer to dma structure
+ * @cc: package cc
+ *
+ * Some Flexcards has support for self-synci bus configurations. With this
+ * feature it is possible to get a synchronized bus configuration with a
+ * single card.
+ * Indication for a self-sync package is eray_nr == 1 and cc == 1. The
+ * packages are always handled by communication controller 0.
+ */
+static inline u32 selfsync_cc(struct flexcard_dma *dma, u32 cc)
+{
+ if ((dma->nr_eray == 1) && (cc == 1))
+ return 0;
+ return cc;
+}
+
+u32 flexcard_parse_packet(struct fc_packet_buf *pb, u32 avail,
+ struct flexcard_dma *dma)
+{
+ u32 l, cc, len = sizeof(struct fc_packet);
+ union fc_packet_types *pt = &pb->packet;
+
+ switch (le32_to_cpu(pb->header.type)) {
+ case FC_PACKET_TYPE_INFO:
+ len += sizeof(struct fc_info_packet);
+ cc = pt->info_packet.cc;
+ break;
+ case FC_PACKET_TYPE_ERROR:
+ len += sizeof(struct fc_error_packet);
+ cc = pt->error_packet.cc;
+ break;
+ case FC_PACKET_TYPE_STATUS:
+ len += sizeof(struct fc_status_packet);
+ cc = selfsync_cc(dma, pt->status_packet.cc);
+ break;
+ case FC_PACKET_TYPE_NMV_VECTOR:
+ len += sizeof(struct fc_nm_vector_packet);
+ cc = pt->nm_vector_packet.cc;
+ break;
+ case FC_PACKET_TYPE_NOTIFICATION:
+ len += sizeof(struct fc_notification_packet);
+ cc = 0;
+ break;
+ case FC_PACKET_TYPE_TRIGGER_EX:
+ len += sizeof(struct fc_trigger_ex_info_packet);
+ cc = 0;
+ break;
+ case FC_PACKET_TYPE_CAN:
+ len += sizeof(struct fc_can_packet);
+ cc = FLEXCARD_CANIF_OFFSET + pt->can_packet.cc;
+ break;
+ case FC_PACKET_TYPE_CAN_ERROR:
+ len += sizeof(struct fc_can_error_packet);
+ cc = FLEXCARD_CANIF_OFFSET + pt->can_error_packet.cc;
+ break;
+ case FC_PACKET_TYPE_FLEXRAY_FRAME:
+ len += sizeof(struct fc_flexray_frame);
+ pt->flexray_frame.pdata = len;
+ l = flexcard_get_packet_len(pt->flexray_frame.header);
+ len += l;
+ cc = pt->flexray_frame.cc;
+ break;
+ case FC_PACKET_TYPE_TX_ACK:
+ len += sizeof(struct fc_tx_ack_packet);
+ pt->tx_ack_packet.pdata = len;
+ l = flexcard_get_packet_len(pt->tx_ack_packet.header);
+ len += l;
+ cc = selfsync_cc(dma, pt->tx_ack_packet.cc);
+ break;
+ case FC_PACKET_TYPE_TRIGGER:
+ default:
+ pr_debug("pkt->type = %08x\n", pb->header.type);
+ return 0;
+ }
+
+ if (len > avail)
+ return 0;
+
+ flexcard_queue_rx(cc, pb, len);
+
+ return len;
+}
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 490b435..cb87c27 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -303,6 +303,7 @@ config MFD_FLEXCARD
tristate "Eberspaecher Flexcard PMC II Carrier Board"
select MFD_CORE
select IRQ_DOMAIN
+ select FLEXCARD_DMA
select FLEXCARD_MISC
select FLEXCARD_PCLOCK
depends on PCI
diff --git a/include/linux/mfd/flexcard.h b/include/linux/mfd/flexcard.h
index 819c6ef..eeabc9e 100644
--- a/include/linux/mfd/flexcard.h
+++ b/include/linux/mfd/flexcard.h
@@ -109,4 +109,8 @@ struct flexcard_device {
int flexcard_setup_irq(struct pci_dev *pdev);
void flexcard_remove_irq(struct pci_dev *pdev);
+int flexcard_register_rx_cb(int cc, void *priv,
+ int (*rx_cb)(void *priv, void *data, size_t len));
+void flexcard_unregister_rx_cb(int cc);
+
#endif /* _LINUX_FLEXCARD_H */
--
2.1.4
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH 09/12] misc: flexcard: add device attributes
2016-12-14 0:11 ` [PATCH 09/12] misc: flexcard: add device attributes Holger Dengler
@ 2016-12-14 1:33 ` kbuild test robot
2017-01-10 16:58 ` Greg Kroah-Hartman
1 sibling, 0 replies; 30+ messages in thread
From: kbuild test robot @ 2016-12-14 1:33 UTC (permalink / raw)
To: Holger Dengler
Cc: kbuild-all, Lee Jones, Arnd Bergmann, Greg Kroah-Hartman,
Vinod Koul, linux-kernel, dmaengine, Thomas Gleixner,
Sebastian Siewior, Juergen Bubeck, Peter Mahler, Holger Dengler,
Benedikt Spranger
[-- Attachment #1: Type: text/plain, Size: 1452 bytes --]
Hi Holger,
[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on v4.9]
[cannot apply to ljones-mfd/for-mfd-next next-20161213]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Holger-Dengler/Eberspaecher-Flexcard-PMC-II-base-support/20161214-082350
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
drivers/misc/flexcard_misc.c: In function 'serialno_show':
>> drivers/misc/flexcard_misc.c:70:10: error: implicit declaration of function 'readq' [-Werror=implicit-function-declaration]
fc_sn = readq(&priv->conf->fc_sn);
^~~~~
cc1: some warnings being treated as errors
vim +/readq +70 drivers/misc/flexcard_misc.c
64 static ssize_t serialno_show(struct device *dev,
65 struct device_attribute *attr, char *buf)
66 {
67 struct flexcard_misc *priv = dev_get_drvdata(dev);
68 u64 fc_sn;
69
> 70 fc_sn = readq(&priv->conf->fc_sn);
71 return sprintf(buf, "%lld\n", fc_sn);
72 }
73 static DEVICE_ATTR_RO(serialno);
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 56970 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 12/12] dma: Flexcard DMA ringbuffer demux driver
2016-12-14 0:11 ` [PATCH 12/12] dma: Flexcard DMA ringbuffer demux driver Holger Dengler
@ 2016-12-14 1:54 ` kbuild test robot
2016-12-15 4:38 ` Vinod Koul
1 sibling, 0 replies; 30+ messages in thread
From: kbuild test robot @ 2016-12-14 1:54 UTC (permalink / raw)
To: Holger Dengler
Cc: kbuild-all, Lee Jones, Arnd Bergmann, Greg Kroah-Hartman,
Vinod Koul, linux-kernel, dmaengine, Thomas Gleixner,
Sebastian Siewior, Juergen Bubeck, Peter Mahler, Holger Dengler,
Benedikt Spranger
[-- Attachment #1: Type: text/plain, Size: 1403 bytes --]
Hi Holger,
[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on v4.9]
[cannot apply to ljones-mfd/for-mfd-next next-20161213]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Holger-Dengler/Eberspaecher-Flexcard-PMC-II-base-support/20161214-082350
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
drivers/dma/flexcard/core.c: In function 'flexcard_dma_setup':
>> drivers/dma/flexcard/core.c:92:2: error: implicit declaration of function 'writeq' [-Werror=implicit-function-declaration]
writeq(dma->phys, &dma->reg->dma_cba);
^~~~~~
cc1: some warnings being treated as errors
vim +/writeq +92 drivers/dma/flexcard/core.c
86 return ret;
87
88 writel(0x0, &dma->reg->dma_rptr);
89 writel(0x0, &dma->reg->dma_wptr);
90 writel(0x0, &dma->reg->dma_ctrl);
91
> 92 writeq(dma->phys, &dma->reg->dma_cba);
93 writel(FLEXCARD_DMA_BUF_SIZE, &dma->reg->dma_cbs);
94
95 return ret;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 57027 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 04/12] mfd: flexcard: add interrupt support
2016-12-14 0:11 ` [PATCH 04/12] mfd: flexcard: add interrupt support Holger Dengler
@ 2016-12-14 2:47 ` kbuild test robot
2016-12-14 3:37 ` kbuild test robot
1 sibling, 0 replies; 30+ messages in thread
From: kbuild test robot @ 2016-12-14 2:47 UTC (permalink / raw)
To: Holger Dengler
Cc: kbuild-all, Lee Jones, Arnd Bergmann, Greg Kroah-Hartman,
Vinod Koul, linux-kernel, dmaengine, Thomas Gleixner,
Sebastian Siewior, Juergen Bubeck, Peter Mahler, Holger Dengler,
Benedikt Spranger
[-- Attachment #1: Type: text/plain, Size: 9301 bytes --]
Hi Holger,
[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on v4.9]
[cannot apply to ljones-mfd/for-mfd-next next-20161213]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Holger-Dengler/Eberspaecher-Flexcard-PMC-II-base-support/20161214-082350
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm
All error/warnings (new ones prefixed by >>):
drivers/mfd/flexcard_irq.c: In function 'flexcard_demux':
>> drivers/mfd/flexcard_irq.c:111:3: error: implicit declaration of function 'generic_handle_irq' [-Werror=implicit-function-declaration]
generic_handle_irq(cur);
^~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_ack':
>> drivers/mfd/flexcard_irq.c:119:33: error: implicit declaration of function 'irq_data_get_irq_chip_data' [-Werror=implicit-function-declaration]
struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/mfd/flexcard_irq.c:119:33: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
>> drivers/mfd/flexcard_irq.c:120:51: error: dereferencing pointer to incomplete type 'struct irq_data'
const struct fc_irq_tab *tp = &flexcard_irq_tab[d->hwirq];
^~
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_mask':
drivers/mfd/flexcard_irq.c:128:33: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_unmask':
drivers/mfd/flexcard_irq.c:141:33: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c: At top level:
>> drivers/mfd/flexcard_irq.c:175:15: error: variable 'flexcard_irq_chip' has initializer but incomplete type
static struct irq_chip flexcard_irq_chip = {
^~~~~~~~
>> drivers/mfd/flexcard_irq.c:176:2: error: unknown field 'name' specified in initializer
.name = "flexcard_irq",
^
>> drivers/mfd/flexcard_irq.c:176:11: warning: excess elements in struct initializer
.name = "flexcard_irq",
^~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:176:11: note: (near initialization for 'flexcard_irq_chip')
>> drivers/mfd/flexcard_irq.c:177:2: error: unknown field 'irq_ack' specified in initializer
.irq_ack = flexcard_irq_ack,
^
drivers/mfd/flexcard_irq.c:177:13: warning: excess elements in struct initializer
.irq_ack = flexcard_irq_ack,
^~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:177:13: note: (near initialization for 'flexcard_irq_chip')
>> drivers/mfd/flexcard_irq.c:178:2: error: unknown field 'irq_mask' specified in initializer
.irq_mask = flexcard_irq_mask,
^
drivers/mfd/flexcard_irq.c:178:14: warning: excess elements in struct initializer
.irq_mask = flexcard_irq_mask,
^~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:178:14: note: (near initialization for 'flexcard_irq_chip')
>> drivers/mfd/flexcard_irq.c:179:2: error: unknown field 'irq_unmask' specified in initializer
.irq_unmask = flexcard_irq_unmask,
^
drivers/mfd/flexcard_irq.c:179:16: warning: excess elements in struct initializer
.irq_unmask = flexcard_irq_unmask,
^~~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:179:16: note: (near initialization for 'flexcard_irq_chip')
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_domain_map':
>> drivers/mfd/flexcard_irq.c:187:2: error: implicit declaration of function 'irq_set_chip_and_handler_name' [-Werror=implicit-function-declaration]
irq_set_chip_and_handler_name(irq, &flexcard_irq_chip,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/mfd/flexcard_irq.c:188:11: error: 'handle_level_irq' undeclared (first use in this function)
handle_level_irq, "flexcard");
^~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:188:11: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/mfd/flexcard_irq.c:189:2: error: implicit declaration of function 'irq_set_chip_data' [-Werror=implicit-function-declaration]
irq_set_chip_data(irq, priv);
^~~~~~~~~~~~~~~~~
>> drivers/mfd/flexcard_irq.c:190:2: error: implicit declaration of function 'irq_modify_status' [-Werror=implicit-function-declaration]
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~~~~~~~
>> drivers/mfd/flexcard_irq.c:190:25: error: 'IRQ_NOREQUEST' undeclared (first use in this function)
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~~~
>> drivers/mfd/flexcard_irq.c:190:41: error: 'IRQ_NOAUTOEN' undeclared (first use in this function)
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~~
>> drivers/mfd/flexcard_irq.c:190:55: error: 'IRQ_NOPROBE' undeclared (first use in this function)
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~
drivers/mfd/flexcard_irq.c: At top level:
>> drivers/mfd/flexcard_irq.c:175:24: error: storage size of 'flexcard_irq_chip' isn't known
static struct irq_chip flexcard_irq_chip = {
^~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/generic_handle_irq +111 drivers/mfd/flexcard_irq.c
105
106 stat = readl(&priv->bar0->conf.irs) & VALID_DEVIRQ_MSK;
107 while (stat) {
108 slot = __ffs(stat);
109 stat &= (1 << slot);
110 cur = irq_linear_revmap(priv->irq_domain, slot);
> 111 generic_handle_irq(cur);
112 ret = IRQ_HANDLED;
113 }
114 return ret;
115 }
116
117 static void flexcard_irq_ack(struct irq_data *d)
118 {
> 119 struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
> 120 const struct fc_irq_tab *tp = &flexcard_irq_tab[d->hwirq];
121 void __iomem *p = (void __iomem *)priv->bar0 + tp->ackoffs;
122
123 writel(tp->ack, p);
124 }
125
126 static void flexcard_irq_mask(struct irq_data *d)
127 {
> 128 struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
129 const struct fc_irq_tab *tp = &flexcard_irq_tab[d->hwirq];
130 void __iomem *p = (void __iomem *)priv->bar0 + tp->mskoffs;
131 u32 *msk = (void *)priv + tp->mskcache;
132
133 raw_spin_lock(&priv->irq_lock);
134 *msk &= ~tp->msk;
135 writel(*msk, p);
136 raw_spin_unlock(&priv->irq_lock);
137 }
138
139 static void flexcard_irq_unmask(struct irq_data *d)
140 {
> 141 struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
142 const struct fc_irq_tab *tp = &flexcard_irq_tab[d->hwirq];
143 void __iomem *p = (void __iomem *)priv->bar0 + tp->mskoffs;
144 u32 *msk = (void *)priv + tp->mskcache;
145
146 raw_spin_lock(&priv->irq_lock);
147 *msk |= tp->msk;
148 writel(*msk, p);
149 raw_spin_unlock(&priv->irq_lock);
150 }
151
152 static int flexcard_req_irq(struct pci_dev *pdev)
153 {
154 struct flexcard_device *priv = pci_get_drvdata(pdev);
155 int ret;
156
157 ret = pci_enable_msi(pdev);
158 if (ret) {
159 dev_warn(&pdev->dev, "could not enable MSI\n");
160 /* shared PCI irq fallback */
161 return request_irq(pdev->irq, flexcard_demux,
162 IRQF_NO_THREAD | IRQF_SHARED,
163 "flexcard", priv);
164 }
165 dev_info(&pdev->dev, "MSI enabled\n");
166
167 ret = request_irq(pdev->irq, flexcard_demux, IRQF_NO_THREAD,
168 "flexcard", priv);
169 if (ret)
170 pci_disable_msi(pdev);
171
172 return ret;
173 }
174
> 175 static struct irq_chip flexcard_irq_chip = {
> 176 .name = "flexcard_irq",
> 177 .irq_ack = flexcard_irq_ack,
> 178 .irq_mask = flexcard_irq_mask,
> 179 .irq_unmask = flexcard_irq_unmask,
180 };
181
182 static int flexcard_irq_domain_map(struct irq_domain *d, unsigned int irq,
183 irq_hw_number_t hw)
184 {
185 struct flexcard_device *priv = d->host_data;
186
> 187 irq_set_chip_and_handler_name(irq, &flexcard_irq_chip,
> 188 handle_level_irq, "flexcard");
> 189 irq_set_chip_data(irq, priv);
> 190 irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
191
192 return 0;
193 }
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 59495 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 05/12] mfd: flexcard: add DMA interrupts
2016-12-14 0:11 ` [PATCH 05/12] mfd: flexcard: add DMA interrupts Holger Dengler
@ 2016-12-14 3:08 ` kbuild test robot
0 siblings, 0 replies; 30+ messages in thread
From: kbuild test robot @ 2016-12-14 3:08 UTC (permalink / raw)
To: Holger Dengler
Cc: kbuild-all, Lee Jones, Arnd Bergmann, Greg Kroah-Hartman,
Vinod Koul, linux-kernel, dmaengine, Thomas Gleixner,
Sebastian Siewior, Juergen Bubeck, Peter Mahler, Holger Dengler,
Benedikt Spranger
[-- Attachment #1: Type: text/plain, Size: 10417 bytes --]
Hi Holger,
[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on v4.9]
[cannot apply to ljones-mfd/for-mfd-next next-20161213]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Holger-Dengler/Eberspaecher-Flexcard-PMC-II-base-support/20161214-082350
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm
All errors (new ones prefixed by >>):
drivers/mfd/flexcard_irq.c: In function 'flexcard_demux':
drivers/mfd/flexcard_irq.c:135:3: error: implicit declaration of function 'generic_handle_irq' [-Werror=implicit-function-declaration]
generic_handle_irq(cur);
^~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_ack':
drivers/mfd/flexcard_irq.c:143:33: error: implicit declaration of function 'irq_data_get_irq_chip_data' [-Werror=implicit-function-declaration]
struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:143:33: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
drivers/mfd/flexcard_irq.c:144:51: error: dereferencing pointer to incomplete type 'struct irq_data'
const struct fc_irq_tab *tp = &flexcard_irq_tab[d->hwirq];
^~
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_mask':
drivers/mfd/flexcard_irq.c:152:33: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_unmask':
drivers/mfd/flexcard_irq.c:165:33: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c: At top level:
drivers/mfd/flexcard_irq.c:199:15: error: variable 'flexcard_irq_chip' has initializer but incomplete type
static struct irq_chip flexcard_irq_chip = {
^~~~~~~~
drivers/mfd/flexcard_irq.c:200:2: error: unknown field 'name' specified in initializer
.name = "flexcard_irq",
^
drivers/mfd/flexcard_irq.c:200:11: warning: excess elements in struct initializer
.name = "flexcard_irq",
^~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:200:11: note: (near initialization for 'flexcard_irq_chip')
drivers/mfd/flexcard_irq.c:201:2: error: unknown field 'irq_ack' specified in initializer
.irq_ack = flexcard_irq_ack,
^
drivers/mfd/flexcard_irq.c:201:13: warning: excess elements in struct initializer
.irq_ack = flexcard_irq_ack,
^~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:201:13: note: (near initialization for 'flexcard_irq_chip')
drivers/mfd/flexcard_irq.c:202:2: error: unknown field 'irq_mask' specified in initializer
.irq_mask = flexcard_irq_mask,
^
drivers/mfd/flexcard_irq.c:202:14: warning: excess elements in struct initializer
.irq_mask = flexcard_irq_mask,
^~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:202:14: note: (near initialization for 'flexcard_irq_chip')
drivers/mfd/flexcard_irq.c:203:2: error: unknown field 'irq_unmask' specified in initializer
.irq_unmask = flexcard_irq_unmask,
^
drivers/mfd/flexcard_irq.c:203:16: warning: excess elements in struct initializer
.irq_unmask = flexcard_irq_unmask,
^~~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:203:16: note: (near initialization for 'flexcard_irq_chip')
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_domain_map':
drivers/mfd/flexcard_irq.c:211:2: error: implicit declaration of function 'irq_set_chip_and_handler_name' [-Werror=implicit-function-declaration]
irq_set_chip_and_handler_name(irq, &flexcard_irq_chip,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:212:11: error: 'handle_level_irq' undeclared (first use in this function)
handle_level_irq, "flexcard");
^~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:212:11: note: each undeclared identifier is reported only once for each function it appears in
drivers/mfd/flexcard_irq.c:213:2: error: implicit declaration of function 'irq_set_chip_data' [-Werror=implicit-function-declaration]
irq_set_chip_data(irq, priv);
^~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:214:2: error: implicit declaration of function 'irq_modify_status' [-Werror=implicit-function-declaration]
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:214:25: error: 'IRQ_NOREQUEST' undeclared (first use in this function)
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:214:41: error: 'IRQ_NOAUTOEN' undeclared (first use in this function)
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:214:55: error: 'IRQ_NOPROBE' undeclared (first use in this function)
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~
drivers/mfd/flexcard_irq.c: At top level:
>> drivers/mfd/flexcard_irq.c:223:15: error: variable 'flexcard_dma_irq_chip' has initializer but incomplete type
static struct irq_chip flexcard_dma_irq_chip = {
^~~~~~~~
drivers/mfd/flexcard_irq.c:224:2: error: unknown field 'name' specified in initializer
.name = "flexcard_dma_irq",
^
drivers/mfd/flexcard_irq.c:224:11: warning: excess elements in struct initializer
.name = "flexcard_dma_irq",
^~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:224:11: note: (near initialization for 'flexcard_dma_irq_chip')
drivers/mfd/flexcard_irq.c:225:2: error: unknown field 'irq_ack' specified in initializer
.irq_ack = flexcard_irq_ack,
^
drivers/mfd/flexcard_irq.c:225:13: warning: excess elements in struct initializer
.irq_ack = flexcard_irq_ack,
^~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:225:13: note: (near initialization for 'flexcard_dma_irq_chip')
drivers/mfd/flexcard_irq.c:226:2: error: unknown field 'irq_mask' specified in initializer
.irq_mask = flexcard_irq_mask,
^
drivers/mfd/flexcard_irq.c:226:14: warning: excess elements in struct initializer
.irq_mask = flexcard_irq_mask,
^~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:226:14: note: (near initialization for 'flexcard_dma_irq_chip')
drivers/mfd/flexcard_irq.c:227:2: error: unknown field 'irq_unmask' specified in initializer
.irq_unmask = flexcard_irq_unmask,
^
drivers/mfd/flexcard_irq.c:227:16: warning: excess elements in struct initializer
.irq_unmask = flexcard_irq_unmask,
^~~~~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:227:16: note: (near initialization for 'flexcard_dma_irq_chip')
drivers/mfd/flexcard_irq.c: In function 'flexcard_dma_irq_domain_map':
drivers/mfd/flexcard_irq.c:236:11: error: 'handle_level_irq' undeclared (first use in this function)
handle_level_irq, "flexcard-dma");
^~~~~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:238:25: error: 'IRQ_NOREQUEST' undeclared (first use in this function)
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:238:41: error: 'IRQ_NOAUTOEN' undeclared (first use in this function)
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~~
drivers/mfd/flexcard_irq.c:238:55: error: 'IRQ_NOPROBE' undeclared (first use in this function)
irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
^~~~~~~~~~~
drivers/mfd/flexcard_irq.c: At top level:
drivers/mfd/flexcard_irq.c:199:24: error: storage size of 'flexcard_irq_chip' isn't known
static struct irq_chip flexcard_irq_chip = {
^~~~~~~~~~~~~~~~~
>> drivers/mfd/flexcard_irq.c:223:24: error: storage size of 'flexcard_dma_irq_chip' isn't known
static struct irq_chip flexcard_dma_irq_chip = {
^~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/flexcard_dma_irq_chip +223 drivers/mfd/flexcard_irq.c
208 {
209 struct flexcard_device *priv = d->host_data;
210
211 irq_set_chip_and_handler_name(irq, &flexcard_irq_chip,
212 handle_level_irq, "flexcard");
213 irq_set_chip_data(irq, priv);
> 214 irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
215
216 return 0;
217 }
218
219 static const struct irq_domain_ops flexcard_irq_domain_ops = {
220 .map = flexcard_irq_domain_map,
221 };
222
> 223 static struct irq_chip flexcard_dma_irq_chip = {
224 .name = "flexcard_dma_irq",
225 .irq_ack = flexcard_irq_ack,
226 .irq_mask = flexcard_irq_mask,
227 .irq_unmask = flexcard_irq_unmask,
228 };
229
230 static int flexcard_dma_irq_domain_map(struct irq_domain *d, unsigned int irq,
231 irq_hw_number_t hw)
232 {
233 struct flexcard_device *priv = d->host_data;
234
235 irq_set_chip_and_handler_name(irq, &flexcard_dma_irq_chip,
236 handle_level_irq, "flexcard-dma");
237 irq_set_chip_data(irq, priv);
> 238 irq_modify_status(irq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
239
240 return 0;
241 }
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 59495 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/12] misc: Flexcard basic timestamp counter support
2016-12-14 0:11 ` [PATCH 10/12] misc: Flexcard basic timestamp counter support Holger Dengler
@ 2016-12-14 3:28 ` kbuild test robot
2016-12-14 8:46 ` Arnd Bergmann
1 sibling, 0 replies; 30+ messages in thread
From: kbuild test robot @ 2016-12-14 3:28 UTC (permalink / raw)
To: Holger Dengler
Cc: kbuild-all, Lee Jones, Arnd Bergmann, Greg Kroah-Hartman,
Vinod Koul, linux-kernel, dmaengine, Thomas Gleixner,
Sebastian Siewior, Juergen Bubeck, Peter Mahler, Holger Dengler,
Benedikt Spranger
[-- Attachment #1: Type: text/plain, Size: 3879 bytes --]
Hi Holger,
[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on v4.9]
[cannot apply to ljones-mfd/for-mfd-next next-20161213]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Holger-Dengler/Eberspaecher-Flexcard-PMC-II-base-support/20161214-082350
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm
All error/warnings (new ones prefixed by >>):
drivers/misc/flexcard_posixclock.c: In function 'flexcard_clk_gettime':
>> drivers/misc/flexcard_posixclock.c:55:10: error: implicit declaration of function 'readl' [-Werror=implicit-function-declaration]
upper = readl(clk->ts64);
^~~~~
drivers/misc/flexcard_posixclock.c: In function 'flexcard_clk_settime':
>> drivers/misc/flexcard_posixclock.c:75:2: error: implicit declaration of function 'writel' [-Werror=implicit-function-declaration]
writel(FLEXCARD_RST_TS, clk->reset);
^~~~~~
drivers/misc/flexcard_posixclock.c: In function 'flexcard_clk_iomap':
>> drivers/misc/flexcard_posixclock.c:96:14: error: implicit declaration of function 'devm_ioremap' [-Werror=implicit-function-declaration]
clk->ts64 = devm_ioremap(&pdev->dev, res->start, resource_size(res));
^~~~~~~~~~~~
>> drivers/misc/flexcard_posixclock.c:96:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
clk->ts64 = devm_ioremap(&pdev->dev, res->start, resource_size(res));
^
drivers/misc/flexcard_posixclock.c:104:13: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
clk->reset = devm_ioremap(&pdev->dev, res->start, resource_size(res));
^
cc1: some warnings being treated as errors
vim +/readl +55 drivers/misc/flexcard_posixclock.c
49 {
50 struct flexcard_clk *clk = container_of(pc, struct flexcard_clk, clock);
51 u64 now;
52 u32 upper, rem;
53
54 retry:
> 55 upper = readl(clk->ts64);
56 now = ((u64) upper << 32) | readl(clk->ts64 + 4);
57 if (upper != readl(clk->ts64))
58 goto retry;
59
60 tp->tv_sec = div_u64_rem(now, 1000000, &rem);
61 tp->tv_nsec = rem * 1000;
62
63 return 0;
64 }
65
66 static int flexcard_clk_settime(struct posix_clock *pc,
67 const struct timespec *tp)
68 {
69 struct flexcard_clk *clk = container_of(pc, struct flexcard_clk, clock);
70
71 /* The FlexCard posix clock could only be reset to 0 and not set */
72 if (tp->tv_sec || tp->tv_nsec)
73 return -EINVAL;
74
> 75 writel(FLEXCARD_RST_TS, clk->reset);
76
77 return 0;
78 }
79
80 static struct posix_clock_operations flexcard_clk_ops = {
81 .owner = THIS_MODULE,
82 .clock_getres = flexcard_clk_getres,
83 .clock_gettime = flexcard_clk_gettime,
84 .clock_settime = flexcard_clk_settime,
85 };
86
87 static int flexcard_clk_iomap(struct platform_device *pdev)
88 {
89 struct flexcard_clk *clk = platform_get_drvdata(pdev);
90 struct resource *res;
91
92 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
93 if (!res)
94 return -ENXIO;
95
> 96 clk->ts64 = devm_ioremap(&pdev->dev, res->start, resource_size(res));
97 if (!clk->ts64)
98 return -ENOMEM;
99
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 59509 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 04/12] mfd: flexcard: add interrupt support
2016-12-14 0:11 ` [PATCH 04/12] mfd: flexcard: add interrupt support Holger Dengler
2016-12-14 2:47 ` kbuild test robot
@ 2016-12-14 3:37 ` kbuild test robot
1 sibling, 0 replies; 30+ messages in thread
From: kbuild test robot @ 2016-12-14 3:37 UTC (permalink / raw)
To: Holger Dengler
Cc: kbuild-all, Lee Jones, Arnd Bergmann, Greg Kroah-Hartman,
Vinod Koul, linux-kernel, dmaengine, Thomas Gleixner,
Sebastian Siewior, Juergen Bubeck, Peter Mahler, Holger Dengler,
Benedikt Spranger
[-- Attachment #1: Type: text/plain, Size: 5018 bytes --]
Hi Holger,
[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on v4.9]
[cannot apply to ljones-mfd/for-mfd-next next-20161213]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Holger-Dengler/Eberspaecher-Flexcard-PMC-II-base-support/20161214-082350
config: tile-allyesconfig (attached as .config)
compiler: tilegx-linux-gcc (GCC) 4.6.2
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=tile
All errors (new ones prefixed by >>):
drivers/mfd/flexcard_irq.c: In function 'flexcard_demux':
drivers/mfd/flexcard_irq.c:111:3: error: implicit declaration of function 'generic_handle_irq'
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_ack':
drivers/mfd/flexcard_irq.c:119:9: error: implicit declaration of function 'irq_data_get_irq_chip_data'
drivers/mfd/flexcard_irq.c:119:33: warning: initialization makes pointer from integer without a cast [enabled by default]
>> drivers/mfd/flexcard_irq.c:120:51: error: dereferencing pointer to incomplete type
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_mask':
drivers/mfd/flexcard_irq.c:128:33: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/mfd/flexcard_irq.c:129:51: error: dereferencing pointer to incomplete type
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_unmask':
drivers/mfd/flexcard_irq.c:141:33: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/mfd/flexcard_irq.c:142:51: error: dereferencing pointer to incomplete type
drivers/mfd/flexcard_irq.c: At top level:
drivers/mfd/flexcard_irq.c:175:15: error: variable 'flexcard_irq_chip' has initializer but incomplete type
drivers/mfd/flexcard_irq.c:176:2: error: unknown field 'name' specified in initializer
drivers/mfd/flexcard_irq.c:176:2: warning: excess elements in struct initializer [enabled by default]
drivers/mfd/flexcard_irq.c:176:2: warning: (near initialization for 'flexcard_irq_chip') [enabled by default]
drivers/mfd/flexcard_irq.c:177:2: error: unknown field 'irq_ack' specified in initializer
drivers/mfd/flexcard_irq.c:177:2: warning: excess elements in struct initializer [enabled by default]
drivers/mfd/flexcard_irq.c:177:2: warning: (near initialization for 'flexcard_irq_chip') [enabled by default]
drivers/mfd/flexcard_irq.c:178:2: error: unknown field 'irq_mask' specified in initializer
drivers/mfd/flexcard_irq.c:178:2: warning: excess elements in struct initializer [enabled by default]
drivers/mfd/flexcard_irq.c:178:2: warning: (near initialization for 'flexcard_irq_chip') [enabled by default]
drivers/mfd/flexcard_irq.c:179:2: error: unknown field 'irq_unmask' specified in initializer
drivers/mfd/flexcard_irq.c:179:2: warning: excess elements in struct initializer [enabled by default]
drivers/mfd/flexcard_irq.c:179:2: warning: (near initialization for 'flexcard_irq_chip') [enabled by default]
drivers/mfd/flexcard_irq.c: In function 'flexcard_irq_domain_map':
drivers/mfd/flexcard_irq.c:187:2: error: implicit declaration of function 'irq_set_chip_and_handler_name'
drivers/mfd/flexcard_irq.c:188:11: error: 'handle_level_irq' undeclared (first use in this function)
drivers/mfd/flexcard_irq.c:188:11: note: each undeclared identifier is reported only once for each function it appears in
drivers/mfd/flexcard_irq.c:189:2: error: implicit declaration of function 'irq_set_chip_data'
drivers/mfd/flexcard_irq.c:190:2: error: implicit declaration of function 'irq_modify_status'
drivers/mfd/flexcard_irq.c:190:25: error: 'IRQ_NOREQUEST' undeclared (first use in this function)
drivers/mfd/flexcard_irq.c:190:41: error: 'IRQ_NOAUTOEN' undeclared (first use in this function)
drivers/mfd/flexcard_irq.c:190:55: error: 'IRQ_NOPROBE' undeclared (first use in this function)
cc1: some warnings being treated as errors
vim +120 drivers/mfd/flexcard_irq.c
105
106 stat = readl(&priv->bar0->conf.irs) & VALID_DEVIRQ_MSK;
107 while (stat) {
108 slot = __ffs(stat);
109 stat &= (1 << slot);
110 cur = irq_linear_revmap(priv->irq_domain, slot);
> 111 generic_handle_irq(cur);
112 ret = IRQ_HANDLED;
113 }
114 return ret;
115 }
116
117 static void flexcard_irq_ack(struct irq_data *d)
118 {
119 struct flexcard_device *priv = irq_data_get_irq_chip_data(d);
> 120 const struct fc_irq_tab *tp = &flexcard_irq_tab[d->hwirq];
121 void __iomem *p = (void __iomem *)priv->bar0 + tp->ackoffs;
122
123 writel(tp->ack, p);
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 46516 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 01/12] mfd: Eberspaecher Flexcard PMC II Carrier Board support
2016-12-14 0:11 ` [PATCH 01/12] mfd: Eberspaecher Flexcard PMC II Carrier Board support Holger Dengler
@ 2016-12-14 8:38 ` Arnd Bergmann
2017-01-05 13:52 ` Holger Dengler
0 siblings, 1 reply; 30+ messages in thread
From: Arnd Bergmann @ 2016-12-14 8:38 UTC (permalink / raw)
To: Holger Dengler
Cc: Lee Jones, Greg Kroah-Hartman, Vinod Koul, linux-kernel,
dmaengine, Thomas Gleixner, Sebastian Siewior, Juergen Bubeck,
Peter Mahler, Benedikt Spranger
On Wednesday, December 14, 2016 1:11:42 AM CET Holger Dengler wrote:
>
> diff --git a/include/uapi/linux/flexcard.h b/include/uapi/linux/flexcard.h
> new file mode 100644
> index 0000000..4e9f07b4
> --- /dev/null
> +++ b/include/uapi/linux/flexcard.h
> @@ -0,0 +1,64 @@
Why is this exported to user space?
> +
> +#include <linux/types.h>
> +
> +struct fc_version {
> + __u8 dev;
> + __u8 min;
> + __u8 maj;
> + __u8 reserved;
> +} __packed;
The __packed attribute is redundant here as all members
are just one byte anyway.
> +/* PCI BAR 0: Flexcard configuration */
> +struct fc_bar0_conf {
> + __u32 r1; /* 000 */
> + struct fc_version fc_fw_ver; /* 004 */
> + struct fc_version fc_hw_ver; /* 008 */
> + __u32 r2[3]; /* 00c */
> + __u64 fc_sn; /* 018 */
> + __u32 fc_uid; /* 020 */
> + __u32 r3[7]; /* 024 */
> + __u32 fc_lic[6]; /* 040 */
> + __u32 fc_slic[6]; /* 058 */
> + __u32 trig_ctrl1; /* 070 */
> + __u32 r4; /* 074 */
> + __u32 trig_ctrl2; /* 078 */
> + __u32 r5[22]; /* 07c */
> + __u32 amreg; /* 0d4 */
> + __u32 tiny_stat; /* 0d8 */
> + __u32 r6[5]; /* 0dc */
> + __u32 can_dat_cnt; /* 0f0 */
> + __u32 can_err_cnt; /* 0f4 */
> + __u32 fc_data_cnt; /* 0f8 */
> + __u32 r7; /* 0fc */
> + __u32 fc_rocr; /* 100 */
> + __u32 r8; /* 104 */
> + __u32 pg_ctrl; /* 108 */
> + __u32 pg_term; /* 10c */
> + __u32 r9; /* 110 */
> + __u32 irs; /* 114 */
> + __u32 fr_tx_cnt; /* 118 */
> + __u32 irc; /* 11c */
> + __u64 pcnt; /* 120 */
> + __u32 r10; /* 128 */
> + __u32 nmv_cnt; /* 12c */
> + __u32 info_cnt; /* 130 */
> + __u32 stat_trg_cnt; /* 134 */
> + __u32 r11; /* 138 */
> + __u32 fr_rx_cnt; /* 13c */
> +} __packed;
Here the __packed attribute is probably harmful, it prevents you
from accessing the members using 32-bit sized accesses and forces
bytewise accesses on some architectures, which tends to do the
wrong thing on MMIO.
Arnd
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/12] misc: Flexcard misc device support
2016-12-14 0:11 ` [PATCH 08/12] misc: Flexcard misc device support Holger Dengler
@ 2016-12-14 8:42 ` Arnd Bergmann
2016-12-14 9:28 ` Holger Dengler
0 siblings, 1 reply; 30+ messages in thread
From: Arnd Bergmann @ 2016-12-14 8:42 UTC (permalink / raw)
To: Holger Dengler
Cc: Lee Jones, Greg Kroah-Hartman, Vinod Koul, linux-kernel,
dmaengine, Thomas Gleixner, Sebastian Siewior, Juergen Bubeck,
Peter Mahler, Benedikt Spranger
On Wednesday, December 14, 2016 1:11:49 AM CET Holger Dengler wrote:
> The Flexcard PCI BAR0 contain registers for configuration but also
> for informational purpose like error counter, statistical information
> and some timestamps. The read-only mmap of the misc device offers the
> userspace a fast access to these registers.
>
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> Signed-off-by: Holger Dengler <dengler@linutronix.de>
> cc: Arnd Bergmann <arnd@arndb.de>
> cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
> drivers/mfd/Kconfig | 1 +
> drivers/misc/Kconfig | 6 ++
> drivers/misc/Makefile | 1 +
> drivers/misc/flexcard_misc.c | 165 +++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 173 insertions(+)
> create mode 100644 drivers/misc/flexcard_misc.c
>
Maybe this could fit better in drivers/uio/ than drivers/misc? It
seems to only export a memory mapped device.
Arnd
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/12] misc: Flexcard basic timestamp counter support
2016-12-14 0:11 ` [PATCH 10/12] misc: Flexcard basic timestamp counter support Holger Dengler
2016-12-14 3:28 ` kbuild test robot
@ 2016-12-14 8:46 ` Arnd Bergmann
2016-12-14 9:16 ` Thomas Gleixner
1 sibling, 1 reply; 30+ messages in thread
From: Arnd Bergmann @ 2016-12-14 8:46 UTC (permalink / raw)
To: Holger Dengler
Cc: Lee Jones, Greg Kroah-Hartman, Vinod Koul, linux-kernel,
dmaengine, Thomas Gleixner, Sebastian Siewior, Juergen Bubeck,
Peter Mahler, Benedikt Spranger
On Wednesday, December 14, 2016 1:11:51 AM CET Holger Dengler wrote:
> The Eberspaecher Flexcard PMC II offers a Flexray network synchronized
> counter with a selectable resolution of 1us, 100ns or 10ns. Add basic
> support for the timestamp counter with 1us resolution, which is the
> standard Flexray bus resolution.
>
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> Signed-off-by: Holger Dengler <dengler@linutronix.de>
> cc: Arnd Bergmann <arnd@arndb.de>
> cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>
Have you tried fitting this in the drivers/ptp/ framework rather
than having your own posix clock for it?
No idea if that works, it's just a thought I had.
Arnd
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 10/12] misc: Flexcard basic timestamp counter support
2016-12-14 8:46 ` Arnd Bergmann
@ 2016-12-14 9:16 ` Thomas Gleixner
0 siblings, 0 replies; 30+ messages in thread
From: Thomas Gleixner @ 2016-12-14 9:16 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Holger Dengler, Lee Jones, Greg Kroah-Hartman, Vinod Koul,
linux-kernel, dmaengine, Sebastian Siewior, Juergen Bubeck,
Peter Mahler, Benedikt Spranger
On Wed, 14 Dec 2016, Arnd Bergmann wrote:
> On Wednesday, December 14, 2016 1:11:51 AM CET Holger Dengler wrote:
> > The Eberspaecher Flexcard PMC II offers a Flexray network synchronized
> > counter with a selectable resolution of 1us, 100ns or 10ns. Add basic
> > support for the timestamp counter with 1us resolution, which is the
> > standard Flexray bus resolution.
> >
> > Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> > Signed-off-by: Holger Dengler <dengler@linutronix.de>
> > cc: Arnd Bergmann <arnd@arndb.de>
> > cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> >
>
> Have you tried fitting this in the drivers/ptp/ framework rather
> than having your own posix clock for it?
It has nothing to do with PTP. It's a completely seperate clock and cannot
be used for PTP style time synchronization.
Thanks,
tglx
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/12] misc: Flexcard misc device support
2016-12-14 8:42 ` Arnd Bergmann
@ 2016-12-14 9:28 ` Holger Dengler
2017-01-10 16:59 ` Greg Kroah-Hartman
0 siblings, 1 reply; 30+ messages in thread
From: Holger Dengler @ 2016-12-14 9:28 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, Greg Kroah-Hartman, Vinod Koul, linux-kernel,
dmaengine, Thomas Gleixner, Sebastian Siewior, Juergen Bubeck,
Peter Mahler, Benedikt Spranger
[-- Attachment #1: Type: text/plain, Size: 1318 bytes --]
On 12/14/2016 09:42 AM, Arnd Bergmann wrote:
> On Wednesday, December 14, 2016 1:11:49 AM CET Holger Dengler wrote:
>> The Flexcard PCI BAR0 contain registers for configuration but also
>> for informational purpose like error counter, statistical information
>> and some timestamps. The read-only mmap of the misc device offers the
>> userspace a fast access to these registers.
>>
>> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
>> Signed-off-by: Holger Dengler <dengler@linutronix.de>
>> cc: Arnd Bergmann <arnd@arndb.de>
>> cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> ---
>> drivers/mfd/Kconfig | 1 +
>> drivers/misc/Kconfig | 6 ++
>> drivers/misc/Makefile | 1 +
>> drivers/misc/flexcard_misc.c | 165 +++++++++++++++++++++++++++++++++++++++++++
>> 4 files changed, 173 insertions(+)
>> create mode 100644 drivers/misc/flexcard_misc.c
>>
>
> Maybe this could fit better in drivers/uio/ than drivers/misc? It
> seems to only export a memory mapped device.
You're right, this patch only introduce the memory mapping. But the next patch in series add also some attributes to the device, therfore we put it in drivers/misc.
>
> Arnd
>
--
Gruß,
Holger Dengler
--
phone: +49 7556 25 999 14; fax: +49 7556 25 999 99
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 12/12] dma: Flexcard DMA ringbuffer demux driver
2016-12-14 0:11 ` [PATCH 12/12] dma: Flexcard DMA ringbuffer demux driver Holger Dengler
2016-12-14 1:54 ` kbuild test robot
@ 2016-12-15 4:38 ` Vinod Koul
2016-12-19 10:54 ` Holger Dengler
1 sibling, 1 reply; 30+ messages in thread
From: Vinod Koul @ 2016-12-15 4:38 UTC (permalink / raw)
To: Holger Dengler
Cc: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, linux-kernel,
dmaengine, Thomas Gleixner, Sebastian Siewior, Juergen Bubeck,
Peter Mahler, Benedikt Spranger
On Wed, Dec 14, 2016 at 01:11:53AM +0100, Holger Dengler wrote:
> The Flexcard interface design split packet receive and transmit. All
> received packets and card status information are multiplexed with a
> Flexcard specific protocol and handled through a DMA capable ringbuffer.
> The TX path has to poke each available component separate.
>
> Add a Flexcard DMA ringbuffer driver and packet demultiplexer.
so the dma driver should only provide service and not do demuxing...
> +config FLEXCARD_DMA
> + tristate "DMA support for Eberspaecher Flexcard PMC II Carrier Board"
> + depends on MFD_FLEXCARD
> + help
> + The Eberspaecher Flexcard PMC (PCI Mezzanine Card) II carrier
> + board support one DMA capable receive ringbuffer for all devices.
> + A card specific protocol is used to multiplex the received packets
> + through the ringbuffer. Enable DMA and Packet parser.
> +
This file is sorted alphabetically, so please add it it relavant place
> +#define DMA_TOTAL_BUF_SIZE (2*FLEXCARD_DMA_BUF_SIZE)
space around * pls
> +#define FLEXCARD_DMA_BUF_SIZE 0x200000
> +#define FLEXCARD_DMA_BUF_MASK (FLEXCARD_DMA_BUF_SIZE - 1)
> +
> +#define FLEXCARD_DMA_CTRL_DMA_ENA (1 << 0)
> +#define FLEXCARD_DMA_CTRL_MAN_ENA (1 << 1)
> +#define FLEXCARD_DMA_CTRL_STOP_REQ (1 << 16)
> +#define FLEXCARD_DMA_CTRL_DMA_IDLE (1 << 17)
> +#define FLEXCARD_DMA_CTRL_RST_DMA (1 << 31)
BIT() and friends please
> +
> +#define FLEXCARD_DMA_STAT_BUSY (1 << 15)
> +#define FLEXCARD_DMA_STAT_OFL (1 << 31)
> +
> +#define FLEXCARD_MAX_PAKET_SIZE 0x200
> +
> +#define FLEXCARD_BUF_HEADER_LEN_SHIFT 15
> +#define FLEXCARD_BUF_HEADER_LEN_MASK 0xfe
> +
> +#define FLEXCARD_CANIF_OFFSET 0x20
Okay I have skipped over the parser and other stuff and still looking for
the dmaengine APIs.
This driver _doesn't_ do that, and am not sure why.
Anyway, if this driver doesnt need dmaengine APIs it doesnt belong in
drivers/dma/. Otherwise please port to dmanegine APIs, possibly use parser
as a client. You cna use virt-channels as well for managing the transfers.
So I am not considering this submission
Thanks
--
~Vinod
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 12/12] dma: Flexcard DMA ringbuffer demux driver
2016-12-15 4:38 ` Vinod Koul
@ 2016-12-19 10:54 ` Holger Dengler
0 siblings, 0 replies; 30+ messages in thread
From: Holger Dengler @ 2016-12-19 10:54 UTC (permalink / raw)
To: Vinod Koul
Cc: Lee Jones, Arnd Bergmann, Greg Kroah-Hartman, linux-kernel,
dmaengine, Thomas Gleixner, Sebastian Siewior, Juergen Bubeck,
Peter Mahler, Benedikt Spranger
[-- Attachment #1: Type: text/plain, Size: 3102 bytes --]
On 12/15/2016 05:38 AM, Vinod Koul wrote:
> On Wed, Dec 14, 2016 at 01:11:53AM +0100, Holger Dengler wrote:
>> The Flexcard interface design split packet receive and transmit. All
>> received packets and card status information are multiplexed with a
>> Flexcard specific protocol and handled through a DMA capable ringbuffer.
>> The TX path has to poke each available component separate.
>>
>> Add a Flexcard DMA ringbuffer driver and packet demultiplexer.
>
> so the dma driver should only provide service and not do demuxing...
The Flexcard can be equipped with multiple functional modules (so called Tinys). Unfortunately, the RX traffic of all Tinys is handled by the base card in a single DMA-ringbuffer. No separate channels, no scatter-gather-lists. So RX-demuxing must be done by one single instance per base card. The TX-path is _not_ handled via DMA, the data goes directly to the Tiny registers.
>> +#define FLEXCARD_DMA_STAT_BUSY (1 << 15)
>> +#define FLEXCARD_DMA_STAT_OFL (1 << 31)
>> +
>> +#define FLEXCARD_MAX_PAKET_SIZE 0x200
>> +
>> +#define FLEXCARD_BUF_HEADER_LEN_SHIFT 15
>> +#define FLEXCARD_BUF_HEADER_LEN_MASK 0xfe
>> +
>> +#define FLEXCARD_CANIF_OFFSET 0x20
>
> Okay I have skipped over the parser and other stuff and still looking for
> the dmaengine APIs.
>
> This driver _doesn't_ do that, and am not sure why.
The main reason, why we do not used the dmaengine interfaces, is, that the Flexcard DMA engine is not as flexible as normal DMA engines are. It is only used for the receive path, it does not support separate channels per Tiny and it uses a single ring-buffer instead of scatter-gather-lists. If we would use the dmaengine interfaces, we would end up with a solution, that accepts only one client per card, and the client must always be the parser (because of the demuxing). Therefore, I do not see any advantage in using the dmaengine interfaces.
> Anyway, if this driver doesnt need dmaengine APIs it doesnt belong in
> drivers/dma/. Otherwise please port to dmanegine APIs, possibly use parser
> as a client. You cna use virt-channels as well for managing the transfers.
Ok, I can follow your argumentation, that the driver for the Flexcard "DMA" does not belong to drivers/dma. In our second post [1], we had it in drivers/mfd, but Lee mentioned, that it is not a mfd driver and asked us to move it to drivers/dma [2]. But if it is neither a mfd nor a dmaengine driver, what kind of driver is it? What is the right place for this driver? (Maybe the naming of the driver is too confusing. Although the Flexcard use DMA (from a technically point of view), this function is more a RX-demux-engine...)
@Lee:
with Vinods comments, the information above and (optionally) a renaming, do you see any possibility to re-include it in drivers/mfd?
[1] http://www.spinics.net/lists/kernel/msg1954282.html
[2] http://www.spinics.net/lists/kernel/msg1957525.html
>
> So I am not considering this submission
>
> Thanks
>
--
Gruß,
Holger Dengler
--
phone: +49 7556 25 999 14; fax: +49 7556 25 999 99
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 00/12] Eberspaecher Flexcard PMC II base support
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
` (11 preceding siblings ...)
2016-12-14 0:11 ` [PATCH 12/12] dma: Flexcard DMA ringbuffer demux driver Holger Dengler
@ 2017-01-04 9:43 ` Lee Jones
12 siblings, 0 replies; 30+ messages in thread
From: Lee Jones @ 2017-01-04 9:43 UTC (permalink / raw)
To: Holger Dengler
Cc: Arnd Bergmann, Greg Kroah-Hartman, Vinod Koul, linux-kernel,
dmaengine, Thomas Gleixner, Sebastian Siewior, Juergen Bubeck,
Peter Mahler
On Wed, 14 Dec 2016, Holger Dengler wrote:
>
> The Eberspaecher Flexcard PMC II is a PMC (PCI Mezzanine Card) II
> carrier board. The carrier board can take up to 4 exchangeable physical
> layer boards for CAN, FlexRay or Ethernet.
> This patchset adds support for the common infrastructure of the carrier
> board.
>
> This patch series apply on v4.9.
>
> First post: http://www.spinics.net/lists/netdev/msg246290.html
> Second post: http://www.spinics.net/lists/kernel/msg1954275.html
>
> According to the comments regarding our first posting, the MFD driver
> patchset has been split up into separate functional parts.
>
> According to the comments regarding our second port, we moved the
> separated driver to their particular subsystems. All other comments
> are also reflected.
>
> The timer functionality was wrongly named as clocksource in the second post,
> although it is a posix_clock. We renamed it and moved it together with the
> misc_device funtions to drivers/misc/. If someone know a better place for
> the posix_clock, please let me know.
>
> The irq part of the mfd driver has been mainly reworked (thanks to Thomas
> and Sebastian for their input). The irq-demux is now implementet without a
> loop and the irq_chips share the irq-table and functions.
>
> Holger Dengler (12):
> mfd: Eberspaecher Flexcard PMC II Carrier Board support
> mfd: flexcard: add flexcard misc mfd-cell
> mfd: flexcard: add posix clock mfd-cell
> mfd: flexcard: add interrupt support
> mfd: flexcard: add DMA interrupts
> mfd: flexcard: add DMA device
> mfd: flexcard: add UIO IRQ devices
> misc: Flexcard misc device support
> misc: flexcard: add device attributes
> misc: Flexcard basic timestamp counter support
> misc: flexcard: Support timestamp trigger selection
> dma: Flexcard DMA ringbuffer demux driver
>
> drivers/dma/Kconfig | 9 +
> drivers/dma/Makefile | 1 +
> drivers/dma/flexcard/Makefile | 2 +
> drivers/dma/flexcard/core.c | 292 ++++++++++++++++++++++
> drivers/dma/flexcard/flexcard-dma.h | 218 +++++++++++++++++
> drivers/dma/flexcard/parser.c | 227 +++++++++++++++++
> drivers/mfd/Kconfig | 14 ++
> drivers/mfd/Makefile | 3 +
> drivers/mfd/flexcard_core.c | 476 ++++++++++++++++++++++++++++++++++++
> drivers/mfd/flexcard_irq.c | 305 +++++++++++++++++++++++
> include/linux/mfd/flexcard.h | 116 +++++++++
Place all of this in one patch to aid review.
> drivers/misc/Kconfig | 15 ++
> drivers/misc/Makefile | 2 +
> drivers/misc/flexcard_misc.c | 361 +++++++++++++++++++++++++++
> drivers/misc/flexcard_posixclock.c | 295 ++++++++++++++++++++++
> include/uapi/linux/Kbuild | 1 +
> include/uapi/linux/flexcard.h | 80 ++++++
> 17 files changed, 2417 insertions(+)
> create mode 100644 drivers/dma/flexcard/Makefile
> create mode 100644 drivers/dma/flexcard/core.c
> create mode 100644 drivers/dma/flexcard/flexcard-dma.h
> create mode 100644 drivers/dma/flexcard/parser.c
> create mode 100644 drivers/mfd/flexcard_core.c
> create mode 100644 drivers/mfd/flexcard_irq.c
> create mode 100644 drivers/misc/flexcard_misc.c
> create mode 100644 drivers/misc/flexcard_posixclock.c
> create mode 100644 include/linux/mfd/flexcard.h
> create mode 100644 include/uapi/linux/flexcard.h
>
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 01/12] mfd: Eberspaecher Flexcard PMC II Carrier Board support
2016-12-14 8:38 ` Arnd Bergmann
@ 2017-01-05 13:52 ` Holger Dengler
0 siblings, 0 replies; 30+ messages in thread
From: Holger Dengler @ 2017-01-05 13:52 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Lee Jones, Greg Kroah-Hartman, Vinod Koul, linux-kernel,
dmaengine, Thomas Gleixner, Sebastian Siewior, Juergen Bubeck,
Peter Mahler, Benedikt Spranger
[-- Attachment #1.1: Type: text/plain, Size: 2868 bytes --]
On 12/14/2016 09:38 AM, Arnd Bergmann wrote:
> On Wednesday, December 14, 2016 1:11:42 AM CET Holger Dengler wrote:
>>
>> diff --git a/include/uapi/linux/flexcard.h b/include/uapi/linux/flexcard.h
>> new file mode 100644
>> index 0000000..4e9f07b4
>> --- /dev/null
>> +++ b/include/uapi/linux/flexcard.h
>> @@ -0,0 +1,64 @@
>
> Why is this exported to user space?
The registers of bar0 can be accessed from userspace via mmap and the structures in this header file describe the register layout in bar0.
>> +
>> +#include <linux/types.h>
>> +
>> +struct fc_version {
>> + __u8 dev;
>> + __u8 min;
>> + __u8 maj;
>> + __u8 reserved;
>> +} __packed;
>
> The __packed attribute is redundant here as all members
> are just one byte anyway.
Both structures (struct fc_version and struct fc_bar0_conf) describe the layout of the registers in bar0. Therefore it must be guaranteed (on all architectures) that the compiler don't insert any spare-parts in the structures. My current understanding is, that the __packed attribute has to be used exactly for such a case. But I will check this again and if it is not required, I'll remove it.
>
>> +/* PCI BAR 0: Flexcard configuration */
>> +struct fc_bar0_conf {
>> + __u32 r1; /* 000 */
>> + struct fc_version fc_fw_ver; /* 004 */
>> + struct fc_version fc_hw_ver; /* 008 */
>> + __u32 r2[3]; /* 00c */
>> + __u64 fc_sn; /* 018 */
>> + __u32 fc_uid; /* 020 */
>> + __u32 r3[7]; /* 024 */
>> + __u32 fc_lic[6]; /* 040 */
>> + __u32 fc_slic[6]; /* 058 */
>> + __u32 trig_ctrl1; /* 070 */
>> + __u32 r4; /* 074 */
>> + __u32 trig_ctrl2; /* 078 */
>> + __u32 r5[22]; /* 07c */
>> + __u32 amreg; /* 0d4 */
>> + __u32 tiny_stat; /* 0d8 */
>> + __u32 r6[5]; /* 0dc */
>> + __u32 can_dat_cnt; /* 0f0 */
>> + __u32 can_err_cnt; /* 0f4 */
>> + __u32 fc_data_cnt; /* 0f8 */
>> + __u32 r7; /* 0fc */
>> + __u32 fc_rocr; /* 100 */
>> + __u32 r8; /* 104 */
>> + __u32 pg_ctrl; /* 108 */
>> + __u32 pg_term; /* 10c */
>> + __u32 r9; /* 110 */
>> + __u32 irs; /* 114 */
>> + __u32 fr_tx_cnt; /* 118 */
>> + __u32 irc; /* 11c */
>> + __u64 pcnt; /* 120 */
>> + __u32 r10; /* 128 */
>> + __u32 nmv_cnt; /* 12c */
>> + __u32 info_cnt; /* 130 */
>> + __u32 stat_trg_cnt; /* 134 */
>> + __u32 r11; /* 138 */
>> + __u32 fr_rx_cnt; /* 13c */
>> +} __packed;
>
> Here the __packed attribute is probably harmful, it prevents you
> from accessing the members using 32-bit sized accesses and forces
> bytewise accesses on some architectures, which tends to do the
> wrong thing on MMIO.
Is this also true, if the base address for this struct is always 32bit-alligned (because it is the base address of bar0)?
>
> Arnd
>
--
Gruß,
Holger Dengler
--
phone: +49 7556 25 999 14; fax: +49 7556 25 999 99
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 09/12] misc: flexcard: add device attributes
2016-12-14 0:11 ` [PATCH 09/12] misc: flexcard: add device attributes Holger Dengler
2016-12-14 1:33 ` kbuild test robot
@ 2017-01-10 16:58 ` Greg Kroah-Hartman
1 sibling, 0 replies; 30+ messages in thread
From: Greg Kroah-Hartman @ 2017-01-10 16:58 UTC (permalink / raw)
To: Holger Dengler
Cc: Lee Jones, Arnd Bergmann, Vinod Koul, linux-kernel, dmaengine,
Thomas Gleixner, Sebastian Siewior, Juergen Bubeck, Peter Mahler,
Benedikt Spranger
On Wed, Dec 14, 2016 at 01:11:50AM +0100, Holger Dengler wrote:
> Add device attributes for common flexcard information access. The
> attribiutes are read-only execpt "uid" (user ID register).
> The "uid" attribute can also be used to change the user-defined ID of a
> Flexcard.
>
> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> Signed-off-by: Holger Dengler <dengler@linutronix.de>
> cc: Arnd Bergmann <arnd@arndb.de>
> cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
> drivers/misc/flexcard_misc.c | 196 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 196 insertions(+)
You didn't document your new sysfs files in Documentation/ABI/ ?
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 08/12] misc: Flexcard misc device support
2016-12-14 9:28 ` Holger Dengler
@ 2017-01-10 16:59 ` Greg Kroah-Hartman
0 siblings, 0 replies; 30+ messages in thread
From: Greg Kroah-Hartman @ 2017-01-10 16:59 UTC (permalink / raw)
To: Holger Dengler
Cc: Arnd Bergmann, Lee Jones, Vinod Koul, linux-kernel, dmaengine,
Thomas Gleixner, Sebastian Siewior, Juergen Bubeck, Peter Mahler,
Benedikt Spranger
On Wed, Dec 14, 2016 at 10:28:25AM +0100, Holger Dengler wrote:
> On 12/14/2016 09:42 AM, Arnd Bergmann wrote:
> > On Wednesday, December 14, 2016 1:11:49 AM CET Holger Dengler wrote:
> >> The Flexcard PCI BAR0 contain registers for configuration but also
> >> for informational purpose like error counter, statistical information
> >> and some timestamps. The read-only mmap of the misc device offers the
> >> userspace a fast access to these registers.
> >>
> >> Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
> >> Signed-off-by: Holger Dengler <dengler@linutronix.de>
> >> cc: Arnd Bergmann <arnd@arndb.de>
> >> cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> >> ---
> >> drivers/mfd/Kconfig | 1 +
> >> drivers/misc/Kconfig | 6 ++
> >> drivers/misc/Makefile | 1 +
> >> drivers/misc/flexcard_misc.c | 165 +++++++++++++++++++++++++++++++++++++++++++
> >> 4 files changed, 173 insertions(+)
> >> create mode 100644 drivers/misc/flexcard_misc.c
> >>
> >
> > Maybe this could fit better in drivers/uio/ than drivers/misc? It
> > seems to only export a memory mapped device.
>
> You're right, this patch only introduce the memory mapping. But the
> next patch in series add also some attributes to the device, therfore
> we put it in drivers/misc.
That's fine, it should still be a uio driver as that's what it does.
You can have sysfs files for a UIO device, right?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2017-01-10 16:58 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-14 0:11 [PATCH 00/12] Eberspaecher Flexcard PMC II base support Holger Dengler
2016-12-14 0:11 ` [PATCH 01/12] mfd: Eberspaecher Flexcard PMC II Carrier Board support Holger Dengler
2016-12-14 8:38 ` Arnd Bergmann
2017-01-05 13:52 ` Holger Dengler
2016-12-14 0:11 ` [PATCH 02/12] mfd: flexcard: add flexcard misc mfd-cell Holger Dengler
2016-12-14 0:11 ` [PATCH 03/12] mfd: flexcard: add posix clock mfd-cell Holger Dengler
2016-12-14 0:11 ` [PATCH 04/12] mfd: flexcard: add interrupt support Holger Dengler
2016-12-14 2:47 ` kbuild test robot
2016-12-14 3:37 ` kbuild test robot
2016-12-14 0:11 ` [PATCH 05/12] mfd: flexcard: add DMA interrupts Holger Dengler
2016-12-14 3:08 ` kbuild test robot
2016-12-14 0:11 ` [PATCH 06/12] mfd: flexcard: add DMA device Holger Dengler
2016-12-14 0:11 ` [PATCH 07/12] mfd: flexcard: add UIO IRQ devices Holger Dengler
2016-12-14 0:11 ` [PATCH 08/12] misc: Flexcard misc device support Holger Dengler
2016-12-14 8:42 ` Arnd Bergmann
2016-12-14 9:28 ` Holger Dengler
2017-01-10 16:59 ` Greg Kroah-Hartman
2016-12-14 0:11 ` [PATCH 09/12] misc: flexcard: add device attributes Holger Dengler
2016-12-14 1:33 ` kbuild test robot
2017-01-10 16:58 ` Greg Kroah-Hartman
2016-12-14 0:11 ` [PATCH 10/12] misc: Flexcard basic timestamp counter support Holger Dengler
2016-12-14 3:28 ` kbuild test robot
2016-12-14 8:46 ` Arnd Bergmann
2016-12-14 9:16 ` Thomas Gleixner
2016-12-14 0:11 ` [PATCH 11/12] misc: flexcard: Support timestamp trigger selection Holger Dengler
2016-12-14 0:11 ` [PATCH 12/12] dma: Flexcard DMA ringbuffer demux driver Holger Dengler
2016-12-14 1:54 ` kbuild test robot
2016-12-15 4:38 ` Vinod Koul
2016-12-19 10:54 ` Holger Dengler
2017-01-04 9:43 ` [PATCH 00/12] Eberspaecher Flexcard PMC II base support Lee Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).