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: <1449001186-24743-1-git-send-email-martyn.welch@collabora.co.uk>
Date:	Tue,  1 Dec 2015 20:19:46 +0000
From:	Martyn Welch <martyn.welch@...labora.co.uk>
To:	Olof Johansson <olof@...om.net>
Cc:	linux-kernel@...r.kernel.org,
	Martyn Welch <martyn.welch@...labora.co.uk>
Subject: [PATCH v2] Add support for monitoring Chrome OS firmware signals

Select Chromebooks have gpio attached to signals used to cause the firmware
to enter alternative modes of operation and/or control other device
characteristics (such as write protection on flash devices). This patch
adds a driver that exposes a read-only interface to allow these signals to
be read from user space.

Signed-off-by: Martyn Welch <martyn.welch@...labora.co.uk>
---

v2:
 - Added missing call to remove sysfs link. 

 drivers/platform/chrome/Kconfig             |  13 +++
 drivers/platform/chrome/Makefile            |   1 +
 drivers/platform/chrome/chromeos_firmware.c | 166 ++++++++++++++++++++++++++++
 3 files changed, 180 insertions(+)
 create mode 100644 drivers/platform/chrome/chromeos_firmware.c

diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index d03df4a..d55ceef 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -38,6 +38,19 @@ config CHROMEOS_PSTORE
 	  If you have a supported Chromebook, choose Y or M here.
 	  The module will be called chromeos_pstore.
 
+config CHROMEOS_FIRMWARE
+	tristate "Chrome OS firmware signal monitoring"
+	depends on GPIO_SYSFS
+	---help---
+	 Many chromebooks have gpio attached to signals used to cause the
+	 firmware to enter alternative modes of operation and/or control other
+	 device characteristics (such as write protection on flash devices).
+	 This driver exposes a read-only interface to allow these signals to be
+	 read from user space.
+
+	 If you have a supported Chromebook, choose Y or M here.
+	 The module will be called chromeos_firmware.
+
 config CROS_EC_CHARDEV
         tristate "Chrome OS Embedded Controller userspace device interface"
         depends on MFD_CROS_EC
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile
index bc498bd..2453adf 100644
--- a/drivers/platform/chrome/Makefile
+++ b/drivers/platform/chrome/Makefile
@@ -1,6 +1,7 @@
 
 obj-$(CONFIG_CHROMEOS_LAPTOP)	+= chromeos_laptop.o
 obj-$(CONFIG_CHROMEOS_PSTORE)	+= chromeos_pstore.o
+obj-$(CONFIG_CHROMEOS_FIRMWARE)	+= chromeos_firmware.o
 cros_ec_devs-objs		:= cros_ec_dev.o cros_ec_sysfs.o \
 				   cros_ec_lightbar.o cros_ec_vbc.o
 obj-$(CONFIG_CROS_EC_CHARDEV)   += cros_ec_devs.o
diff --git a/drivers/platform/chrome/chromeos_firmware.c b/drivers/platform/chrome/chromeos_firmware.c
new file mode 100644
index 0000000..a08cb57
--- /dev/null
+++ b/drivers/platform/chrome/chromeos_firmware.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2015 Collabora Ltd.
+ *
+ * based on vendor driver,
+ *
+ * Copyright (C) 2011 The Chromium OS Authors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/bcd.h>
+#include <linux/gpio.h>
+#include <linux/notifier.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct chromeos_firmware_gpio_info {
+	int gpio;
+	const char *link;
+};
+
+struct chromeos_firmware_data {
+	struct chromeos_firmware_gpio_info wp;
+	struct chromeos_firmware_gpio_info rec;
+	struct chromeos_firmware_gpio_info dev;
+};
+
+static int dt_gpio_init(struct platform_device *pdev, const char *of_list_name,
+			const char *gpio_desc_name, const char *sysfs_name,
+			struct chromeos_firmware_gpio_info *gpio)
+{
+	int err;
+	enum of_gpio_flags of_flags;
+	unsigned long flags = GPIOF_DIR_IN | GPIOF_EXPORT;
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *cnp;
+
+	cnp = of_get_child_by_name(np, of_list_name);
+	if (!cnp)
+		/*
+		 * We don't necessarily expect to find all of the devices, so
+		 * return without generating an error.
+		 */
+		return 0;
+
+	gpio->gpio = of_get_named_gpio_flags(cnp, "gpios", 0, &of_flags);
+	if (!gpio_is_valid(gpio->gpio)) {
+		err = -EINVAL;
+		goto err_prop;
+	}
+
+	if (of_flags & OF_GPIO_ACTIVE_LOW)
+		flags |= GPIOF_ACTIVE_LOW;
+
+	err = gpio_request_one(gpio->gpio, flags, gpio_desc_name);
+	if (err)
+		goto err_prop;
+
+	err = gpio_export_link(&pdev->dev, sysfs_name, gpio->gpio);
+	if (err)
+		goto err_gpio;
+
+	gpio->link = sysfs_name;
+
+	return 0;
+
+err_gpio:
+	gpio_free(gpio->gpio);
+err_prop:
+	of_node_put(cnp);
+
+	return err;
+}
+
+static void chromeos_firmware_rem(struct device *dev,
+				  struct chromeos_firmware_gpio_info *gpio)
+{
+	sysfs_remove_link(&dev->kobj, gpio->link);
+
+	gpio_unexport(gpio->gpio);
+
+	gpio_free(gpio->gpio);
+}
+
+static int chromeos_firmware_probe(struct platform_device *pdev)
+{
+	int err;
+	struct chromeos_firmware_data *gpios;
+
+	gpios = devm_kmalloc(&pdev->dev, sizeof(gpios), GFP_KERNEL);
+	if (!gpios)
+		return -ENOMEM;
+
+	err = dt_gpio_init(pdev, "write-protect", "firmware-write-protect",
+			   "write-protect", &gpios->wp);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to init write-protect.\n");
+		goto err_wp;
+	}
+
+	err = dt_gpio_init(pdev, "recovery-switch", "firmware-recovery-switch",
+			   "recovery-switch", &gpios->rec);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to init recovery-switch.\n");
+		goto err_rec;
+	}
+
+	err = dt_gpio_init(pdev, "developer-switch",
+			   "firmware-developer-switch", "developer-switch",
+			   &gpios->dev);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to init developer-switch.\n");
+		goto err_dev;
+	}
+
+	platform_set_drvdata(pdev, gpios);
+
+	return 0;
+
+err_dev:
+	chromeos_firmware_rem(&pdev->dev, &gpios->rec);
+
+err_rec:
+	chromeos_firmware_rem(&pdev->dev, &gpios->wp);
+err_wp:
+	return err;
+}
+
+static int chromeos_firmware_remove(struct platform_device *pdev)
+{
+	struct chromeos_firmware_data *gpios = platform_get_drvdata(pdev);
+
+	chromeos_firmware_rem(&pdev->dev, &gpios->dev);
+	chromeos_firmware_rem(&pdev->dev, &gpios->rec);
+	chromeos_firmware_rem(&pdev->dev, &gpios->wp);
+
+	return 0;
+}
+
+static const struct of_device_id chromeos_firmware_of_match[] = {
+	{ .compatible = "google,gpio-firmware" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, chromeos_firmware_of_match);
+
+static struct platform_driver chromeos_firmware_driver = {
+	.probe = chromeos_firmware_probe,
+	.remove = chromeos_firmware_remove,
+	.driver = {
+		.name = "chromeos_firmware",
+		.of_match_table = chromeos_firmware_of_match,
+	},
+};
+module_platform_driver(chromeos_firmware_driver);
+
+MODULE_LICENSE("GPL");
-- 
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