[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/kernel/linux/v4.14/drivers/sbus/char/display7seg.c b/src/kernel/linux/v4.14/drivers/sbus/char/display7seg.c
new file mode 100644
index 0000000..db761ac
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/sbus/char/display7seg.c
@@ -0,0 +1,273 @@
+/* display7seg.c - Driver implementation for the 7-segment display
+ *                 present on Sun Microsystems CP1400 and CP1500
+ *
+ * Copyright (c) 2000 Eric Brower (ebrower@usa.net)
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>		/* request_region */
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/atomic.h>
+#include <linux/uaccess.h>		/* put_/get_user			*/
+#include <asm/io.h>
+
+#include <asm/display7seg.h>
+
+#define D7S_MINOR	193
+#define DRIVER_NAME	"d7s"
+#define PFX		DRIVER_NAME ": "
+
+static DEFINE_MUTEX(d7s_mutex);
+static int sol_compat = 0;		/* Solaris compatibility mode	*/
+
+/* Solaris compatibility flag -
+ * The Solaris implementation omits support for several
+ * documented driver features (ref Sun doc 806-0180-03).  
+ * By default, this module supports the documented driver 
+ * abilities, rather than the Solaris implementation:
+ *
+ * 	1) Device ALWAYS reverts to OBP-specified FLIPPED mode
+ * 	   upon closure of device or module unload.
+ * 	2) Device ioctls D7SIOCRD/D7SIOCWR honor toggling of
+ * 	   FLIP bit
+ *
+ * If you wish the device to operate as under Solaris,
+ * omitting above features, set this parameter to non-zero.
+ */
+module_param(sol_compat, int, 0);
+MODULE_PARM_DESC(sol_compat, 
+		 "Disables documented functionality omitted from Solaris driver");
+
+MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
+MODULE_DESCRIPTION("7-Segment Display driver for Sun Microsystems CP1400/1500");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("d7s");
+
+struct d7s {
+	void __iomem	*regs;
+	bool		flipped;
+};
+struct d7s *d7s_device;
+
+/*
+ * Register block address- see header for details
+ * -----------------------------------------
+ * | DP | ALARM | FLIP | 4 | 3 | 2 | 1 | 0 |
+ * -----------------------------------------
+ *
+ * DP 		- Toggles decimal point on/off 
+ * ALARM	- Toggles "Alarm" LED green/red
+ * FLIP		- Inverts display for upside-down mounted board
+ * bits 0-4	- 7-segment display contents
+ */
+static atomic_t d7s_users = ATOMIC_INIT(0);
+
+static int d7s_open(struct inode *inode, struct file *f)
+{
+	if (D7S_MINOR != iminor(inode))
+		return -ENODEV;
+	atomic_inc(&d7s_users);
+	return 0;
+}
+
+static int d7s_release(struct inode *inode, struct file *f)
+{
+	/* Reset flipped state to OBP default only if
+	 * no other users have the device open and we
+	 * are not operating in solaris-compat mode
+	 */
+	if (atomic_dec_and_test(&d7s_users) && !sol_compat) {
+		struct d7s *p = d7s_device;
+		u8 regval = 0;
+
+		regval = readb(p->regs);
+		if (p->flipped)
+			regval |= D7S_FLIP;
+		else
+			regval &= ~D7S_FLIP;
+		writeb(regval, p->regs);
+	}
+
+	return 0;
+}
+
+static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct d7s *p = d7s_device;
+	u8 regs = readb(p->regs);
+	int error = 0;
+	u8 ireg = 0;
+
+	if (D7S_MINOR != iminor(file_inode(file)))
+		return -ENODEV;
+
+	mutex_lock(&d7s_mutex);
+	switch (cmd) {
+	case D7SIOCWR:
+		/* assign device register values we mask-out D7S_FLIP
+		 * if in sol_compat mode
+		 */
+		if (get_user(ireg, (int __user *) arg)) {
+			error = -EFAULT;
+			break;
+		}
+		if (sol_compat) {
+			if (regs & D7S_FLIP)
+				ireg |= D7S_FLIP;
+			else
+				ireg &= ~D7S_FLIP;
+		}
+		writeb(ireg, p->regs);
+		break;
+
+	case D7SIOCRD:
+		/* retrieve device register values
+		 * NOTE: Solaris implementation returns D7S_FLIP bit
+		 * as toggled by user, even though it does not honor it.
+		 * This driver will not misinform you about the state
+		 * of your hardware while in sol_compat mode
+		 */
+		if (put_user(regs, (int __user *) arg)) {
+			error = -EFAULT;
+			break;
+		}
+		break;
+
+	case D7SIOCTM:
+		/* toggle device mode-- flip display orientation */
+		regs ^= D7S_FLIP;
+		writeb(regs, p->regs);
+		break;
+	}
+	mutex_unlock(&d7s_mutex);
+
+	return error;
+}
+
+static const struct file_operations d7s_fops = {
+	.owner =		THIS_MODULE,
+	.unlocked_ioctl =	d7s_ioctl,
+	.compat_ioctl =		d7s_ioctl,
+	.open =			d7s_open,
+	.release =		d7s_release,
+	.llseek = noop_llseek,
+};
+
+static struct miscdevice d7s_miscdev = {
+	.minor		= D7S_MINOR,
+	.name		= DRIVER_NAME,
+	.fops		= &d7s_fops
+};
+
+static int d7s_probe(struct platform_device *op)
+{
+	struct device_node *opts;
+	int err = -EINVAL;
+	struct d7s *p;
+	u8 regs;
+
+	if (d7s_device)
+		goto out;
+
+	p = devm_kzalloc(&op->dev, sizeof(*p), GFP_KERNEL);
+	err = -ENOMEM;
+	if (!p)
+		goto out;
+
+	p->regs = of_ioremap(&op->resource[0], 0, sizeof(u8), "d7s");
+	if (!p->regs) {
+		printk(KERN_ERR PFX "Cannot map chip registers\n");
+		goto out_free;
+	}
+
+	err = misc_register(&d7s_miscdev);
+	if (err) {
+		printk(KERN_ERR PFX "Unable to acquire miscdevice minor %i\n",
+		       D7S_MINOR);
+		goto out_iounmap;
+	}
+
+	/* OBP option "d7s-flipped?" is honored as default for the
+	 * device, and reset default when detached
+	 */
+	regs = readb(p->regs);
+	opts = of_find_node_by_path("/options");
+	if (opts &&
+	    of_get_property(opts, "d7s-flipped?", NULL))
+		p->flipped = true;
+
+	if (p->flipped)
+		regs |= D7S_FLIP;
+	else
+		regs &= ~D7S_FLIP;
+
+	writeb(regs,  p->regs);
+
+	printk(KERN_INFO PFX "7-Segment Display%pOF at [%s:0x%llx] %s\n",
+	       op->dev.of_node,
+	       (regs & D7S_FLIP) ? " (FLIPPED)" : "",
+	       op->resource[0].start,
+	       sol_compat ? "in sol_compat mode" : "");
+
+	dev_set_drvdata(&op->dev, p);
+	d7s_device = p;
+	err = 0;
+	of_node_put(opts);
+
+out:
+	return err;
+
+out_iounmap:
+	of_iounmap(&op->resource[0], p->regs, sizeof(u8));
+
+out_free:
+	goto out;
+}
+
+static int d7s_remove(struct platform_device *op)
+{
+	struct d7s *p = dev_get_drvdata(&op->dev);
+	u8 regs = readb(p->regs);
+
+	/* Honor OBP d7s-flipped? unless operating in solaris-compat mode */
+	if (sol_compat) {
+		if (p->flipped)
+			regs |= D7S_FLIP;
+		else
+			regs &= ~D7S_FLIP;
+		writeb(regs, p->regs);
+	}
+
+	misc_deregister(&d7s_miscdev);
+	of_iounmap(&op->resource[0], p->regs, sizeof(u8));
+
+	return 0;
+}
+
+static const struct of_device_id d7s_match[] = {
+	{
+		.name = "display7seg",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, d7s_match);
+
+static struct platform_driver d7s_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.of_match_table = d7s_match,
+	},
+	.probe		= d7s_probe,
+	.remove		= d7s_remove,
+};
+
+module_platform_driver(d7s_driver);