lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1427277120-16924-2-git-send-email-dengler@linutronix.de>
Date:	Wed, 25 Mar 2015 10:51:50 +0100
From:	Holger Dengler <dengler@...utronix.de>
To:	linux-kernel@...r.kernel.org
Cc:	Peter Mahler <mahler@...ug.com>, Juergen Bubeck <bubeck@...ug.com>,
	Benedikt Spranger <b.spranger@...utronix.de>,
	Holger Dengler <dengler@...utronix.de>,
	Samuel Ortiz <sameo@...ux.intel.com>,
	Lee Jones <lee.jones@...aro.org>
Subject: [PATCH 01/11] mfd: Eberspaecher Flexcard PMC II Carrier Board support

From: Benedikt Spranger <b.spranger@...utronix.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@...utronix.de>
Signed-off-by: Benedikt Spranger <b.spranger@...utronix.de>
cc: Samuel Ortiz <sameo@...ux.intel.com>
cc: Lee Jones <lee.jones@...aro.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@...utronix.de>");
+MODULE_AUTHOR("Benedikt Spranger <b.spranger@...utronix.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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ