All of lore.kernel.org
 help / color / mirror / Atom feed
From: Holger Dengler <dengler@linutronix.de>
To: linux-kernel@vger.kernel.org
Cc: Peter Mahler <mahler@xkrug.com>,
	Juergen Bubeck <bubeck@xkrug.com>,
	Benedikt Spranger <b.spranger@linutronix.de>,
	Holger Dengler <dengler@linutronix.de>,
	Samuel Ortiz <sameo@linux.intel.com>,
	Lee Jones <lee.jones@linaro.org>
Subject: [PATCH 01/11] mfd: Eberspaecher Flexcard PMC II Carrier Board support
Date: Wed, 25 Mar 2015 10:51:50 +0100	[thread overview]
Message-ID: <1427277120-16924-2-git-send-email-dengler@linutronix.de> (raw)
In-Reply-To: <1427277120-16924-1-git-send-email-dengler@linutronix.de>

From: Benedikt Spranger <b.spranger@linutronix.de>

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: Holger Dengler <dengler@linutronix.de>
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/Kconfig           |  10 +++
 drivers/mfd/Makefile          |   2 +
 drivers/mfd/flexcard/Makefile |   2 +
 drivers/mfd/flexcard/core.c   | 193 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/flexcard.h  |  34 ++++++++
 include/uapi/linux/flexcard.h | 125 +++++++++++++++++++++++++++
 6 files changed, 366 insertions(+)
 create mode 100644 drivers/mfd/flexcard/Makefile
 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 38356e3..3765707 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -217,6 +217,16 @@ config MFD_DLN2
 	  etc. must be enabled in order to use the functionality of
 	  the device.
 
+config MFD_FLEXCARD
+	tristate "Support for 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 19f3d74..d7d5432 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -181,3 +181,5 @@ obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
 
 intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
+
+obj-$(CONFIG_MFD_FLEXCARD)	+= flexcard/
diff --git a/drivers/mfd/flexcard/Makefile b/drivers/mfd/flexcard/Makefile
new file mode 100644
index 0000000..6606ebb
--- /dev/null
+++ b/drivers/mfd/flexcard/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MFD_FLEXCARD)	+= flexcard.o
+flexcard-objs			:= core.o
diff --git a/drivers/mfd/flexcard/core.c b/drivers/mfd/flexcard/core.c
new file mode 100644
index 0000000..99df3d5
--- /dev/null
+++ b/drivers/mfd/flexcard/core.c
@@ -0,0 +1,193 @@
+/*
+ * Eberspaecher Flexcard PMC II Carrier Board PCI Driver
+ *
+ * Copyright (c) 2014,2015 Linutronix GmbH
+ * Author: Holger Dengler
+ *         Benedikt Spranger
+ *
+ * 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/flexcard.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/flexcard.h>
+
+static const char drv_name[] = "flexcard";
+
+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;
+
+	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;
+
+	return 0;
+}
+
+static int flexcard_tiny_probe(struct flexcard_device *priv)
+{
+	u32 fc_slic0 = priv->conf->fc_slic[0];
+	struct pci_dev *pdev = priv->pdev;
+	u8 nr_can, nr_fr, nr;
+	u32 offset = 0;
+	int i, ret;
+
+	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;
+	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, drv_name);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to request regions: %d\n", ret);
+		goto out_disable;
+	}
+
+	priv->conf = pci_ioremap_bar(pdev, 0);
+	if (!priv->conf) {
+		dev_err(&pdev->dev, "unable to remap configuration regs\n");
+		ret = -ENOMEM;
+		goto out_release;
+	}
+
+	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",
+		 priv->conf->fc_hw_ver.maj, priv->conf->fc_hw_ver.min,
+		 priv->conf->fc_hw_ver.dev, priv->conf->fc_fw_ver.maj,
+		 priv->conf->fc_fw_ver.min, priv->conf->fc_fw_ver.dev);
+
+	return 0;
+
+out_unmap:
+	iounmap(priv->conf);
+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->conf);
+	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     = drv_name,
+	.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..20d0f40
--- /dev/null
+++ b/include/linux/mfd/flexcard.h
@@ -0,0 +1,34 @@
+/*
+ * Common Definitions for Eberspaecher Flexcard PMC II
+ *
+ * Copyright (c) 2014,2015 Linutronix GmbH
+ * Author: Holger Dengler
+ *         Benedikt Spranger
+ *
+ * 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_H
+#define FLEXCARD_H
+
+#define FLEXCARD_CAN_OFFSET	0x2000
+#define FLEXCARD_CAN_SIZE	0x2000
+
+#define FLEXCARD_FR_OFFSET	0x4000
+#define FLEXCARD_FR_SIZE	0x2000
+
+struct flexcard_device {
+	struct pci_dev *pdev;
+	struct fc_conf_bar __iomem *conf;
+	struct mfd_cell *cells;
+	struct resource *res;
+};
+
+enum flexcard_cell_id {
+	FLEXCARD_CELL_CAN,
+	FLEXCARD_CELL_FLEXRAY,
+};
+
+#endif /* FLEXCARD_H */
diff --git a/include/uapi/linux/flexcard.h b/include/uapi/linux/flexcard.h
new file mode 100644
index 0000000..9b73d8d
--- /dev/null
+++ b/include/uapi/linux/flexcard.h
@@ -0,0 +1,125 @@
+/*
+ * Eberspaecher Flexcard PMC II Carrier Board PCI Driver - device attributes
+ *
+ * Copyright (c) 2014,2015 Linutronix GmbH
+ * Author: Holger Dengler
+ *         Benedikt Spranger
+ *
+ * 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_FLEXCARD_H
+#define _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_conf_bar {
+	__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 */
+	__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 */
+	__u32 fc_nfctrl;		/* 170 */
+	__u32 nf_cnt;			/* 174 */
+	__u32 r14;			/* 178 */
+	__u32 pl_ctrl;			/* 17c */
+	__u32 r15[0xe0];		/* 180 */
+	__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 */
+	__u32 r20[0x62];		/* 578 */
+	__u32 ts_high;			/* 700 */
+	__u32 ts_low;			/* 704 */
+	__u32 r21[2];			/* 708 */
+	__u32 clk_src;			/* 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;
+
+#endif /* _LINUX_FLEXCARD_H */
-- 
2.1.4


  reply	other threads:[~2015-03-25  9:55 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-25  9:51 [PATCH 00/11] Eberspaecher Flexcard PMC II base support Holger Dengler
2015-03-25  9:51 ` Holger Dengler [this message]
2015-03-30  7:57   ` [PATCH 01/11] mfd: Eberspaecher Flexcard PMC II Carrier Board support Lee Jones
2015-03-25  9:51 ` [PATCH 02/11] mfd: flexcard: add flexcard core device Holger Dengler
2015-03-30  8:06   ` Lee Jones
2015-03-25  9:51 ` [PATCH 03/11] mfd: flexcard: add device attributes Holger Dengler
2015-03-30  8:15   ` Lee Jones
2015-03-25  9:51 ` [PATCH 04/11] mfd: flexcard: add clocksrc device Holger Dengler
2015-03-30  8:30   ` Lee Jones
2015-03-25  9:51 ` [PATCH 05/11] mfd: flexcard: add interrupt support Holger Dengler
2015-03-30  8:46   ` Lee Jones
2015-03-25  9:51 ` [PATCH 06/11] mfd: flexcard: add DMA interrupt domain Holger Dengler
2015-03-30  8:50   ` Lee Jones
2015-03-25  9:51 ` [PATCH 07/11] mfd: flexcard: add UIO IRQ devices Holger Dengler
2015-03-30  8:57   ` Lee Jones
2015-03-25  9:51 ` [PATCH 08/11] mfd: flexcard: add DMA device Holger Dengler
2015-03-30  8:59   ` Lee Jones
2015-03-25  9:51 ` [PATCH 09/11] mfd: flexcard: add DMA ringbuffer demux driver Holger Dengler
2015-03-30  9:02   ` Lee Jones
2015-03-25  9:51 ` [PATCH 10/11] clocksource: flexcard: Add basic timestamp counter support Holger Dengler
2015-03-26  9:41   ` Daniel Lezcano
2015-03-26 11:01     ` Holger Dengler
2015-03-26 16:34       ` John Stultz
2015-03-27 12:27         ` Holger Dengler
2015-03-25  9:52 ` [PATCH 11/11] clocksource: flexcard: Support timestamp trigger selection Holger Dengler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1427277120-16924-2-git-send-email-dengler@linutronix.de \
    --to=dengler@linutronix.de \
    --cc=b.spranger@linutronix.de \
    --cc=bubeck@xkrug.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mahler@xkrug.com \
    --cc=sameo@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.