All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/6] Add Advantech iManager MFD core driver
@ 2016-01-10  9:10   ` richard.dorsch
  0 siblings, 0 replies; 44+ messages in thread
From: richard.dorsch-Re5JQEeQqe8AvxtiuMwx3w @ 2016-01-10  9:10 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, jdelvare-IBi9RG/b67k,
	linux-0h96xk9xTtrk1uMJSBkQmQ, wim-IQzOog9fTRqzQB+pC5nmwQ,
	jo.sunga-ELdSlb/RfAS1Z/+hSey0Gg, Richard Vidal-Dorsch

From: Richard Vidal-Dorsch <richard.dorsch-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

This patch adds Advantech iManager Embedded Controller MFD core driver.
This mfd core dirver provides an interface to GPIO, I2C, HWmon,
Watchdog, and Backlight/Brightness control.

Signed-off-by: Richard Vidal-Dorsch <richard.dorsch-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 Documentation/devicetree/bindings/mfd/imanager.txt |   33 +
 MAINTAINERS                                        |   13 +
 drivers/mfd/Kconfig                                |   20 +
 drivers/mfd/Makefile                               |    2 +
 drivers/mfd/imanager-core.c                        |  288 +++++
 drivers/mfd/imanager-ec.c                          | 1345 ++++++++++++++++++++
 include/linux/mfd/imanager/core.h                  |   31 +
 include/linux/mfd/imanager/ec.h                    |  210 +++
 8 files changed, 1942 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/imanager.txt
 create mode 100644 drivers/mfd/imanager-core.c
 create mode 100644 drivers/mfd/imanager-ec.c
 create mode 100644 include/linux/mfd/imanager/core.h
 create mode 100644 include/linux/mfd/imanager/ec.h

diff --git a/Documentation/devicetree/bindings/mfd/imanager.txt b/Documentation/devicetree/bindings/mfd/imanager.txt
new file mode 100644
index 0000000..bf58a96
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/imanager.txt
@@ -0,0 +1,33 @@
+Note
+====
+
+This is a set of platform drivers which provide support for multiple
+embedded features such as GPIO, I2C/SMBus, Hardware Monitoring, Watchdog,
+and Backlight/Brightness control. Those features are available on Advantech
+Embedded boards such as SOM, MIO, AIMB, and PCM.
+Datasheets of each product line can be downloaded from www.advantech.com
+
+Author:
+	Richard Vidal-Dorsch <richard.dorsch-ELdSlb/RfAS1Z/+hSey0Gg@public.gmane.org>
+
+
+Kernel driver imanager
+======================
+
+This driver provides a communication layer to the Advantech iManager EC
+firmware which is factory loaded onto ITE IT8518/28 chips. The type of
+communication is message based. Clients (gpio, i2c, hwmon etc. drivers)
+request data from Advantech iManager (polling, not interrupt driven). If
+a response is been received within a time frame, the data is been extracted
+from the message and then passed to the caller (clients).
+
+  Supported chips:
+  * Advantech EC based on ITE IT8518
+    Prefix: imanager
+    Addresses: 0x029e/0x029f
+    Datasheet: Available from ITE upon request
+  * Advantech EC based on ITE IT8528
+    Prefix: imanager
+    Addresses: 0x0299/0x29a
+    Datasheet: Available from ITE upon request
+
diff --git a/MAINTAINERS b/MAINTAINERS
index 233f834..8d25fdc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5391,6 +5391,19 @@ M:	Stanislaw Gruszka <stf_xl-5tc4TXWwyLM@public.gmane.org>
 S:	Maintained
 F:	drivers/usb/atm/ueagle-atm.c
 
+IMANAGER ADVANTECH EC DRIVER
+M:	Richard Vidal-Dorsch <richard.dorsch-ELdSlb/RfAS1Z/+hSey0Gg@public.gmane.org>
+S:	Maintained
+F:	Documentation/devicetree/bindings/mfd/imanager.txt
+F:	Documentation/hwmon/imanager
+F:	Documentation/i2c/busses/i2c-imanager
+F:	drivers/mfd/imanager-core.c
+F:	drivers/gpio/imanager-gpio.c
+F:	drivers/hwmon/imanager-hwmon.c
+F:	drivers/i2c/busses/imanager-i2c.c
+F:	drivers/video/backlight/imanager-bl.c
+F:	drivers/watchdog/imanager-wdt.c
+
 INA209 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
 L:	lm-sensors-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 4d92df6..4dc7c13 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -322,6 +322,26 @@ config MFD_INTEL_QUARK_I2C_GPIO
 	  their respective IO driver.
 	  The GPIO exports a total amount of 8 interrupt-capable GPIOs.
 
+config MFD_IMANAGER
+	tristate "Advantech iManager Embedded Controller"
+	depends on PCI
+	depends on X86
+	select MFD_CORE
+	help
+	  This is the core driver for Advantech iManager EC as found on some
+	  Advantech SOM, MIO, AIMB, and PCM modules/boards. The EC may provide
+	  functions like GPIO, I2C interface, HW monitoring, Watchdog, and
+	  backlight/brightness control.
+
+	  The following Advantech boards are supported:
+		* All SOM modules newer than SOM-5788
+		* MIO-5250/5251/5270/5271 and newer
+		* PCM-9388
+		* AIMB-274/231
+
+	  This driver can also be built as a module. If so, the module
+	  will be called imanager.
+
 config LPC_ICH
 	tristate "Intel ICH LPC"
 	depends on PCI
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a8b76b8..c9c63d9 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -142,6 +142,8 @@ obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500-prcmu.o
 obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
 obj-$(CONFIG_MFD_TIMBERDALE)    += timberdale.o
 obj-$(CONFIG_PMIC_ADP5520)	+= adp5520.o
+imanager-objs			:= imanager-core.o imanager-ec.o
+obj-$(CONFIG_MFD_IMANAGER)	+= imanager.o
 obj-$(CONFIG_MFD_KEMPLD)	+= kempld-core.o
 obj-$(CONFIG_MFD_INTEL_QUARK_I2C_GPIO)	+= intel_quark_i2c_gpio.o
 obj-$(CONFIG_LPC_SCH)		+= lpc_sch.o
diff --git a/drivers/mfd/imanager-core.c b/drivers/mfd/imanager-core.c
new file mode 100644
index 0000000..9697c144
--- /dev/null
+++ b/drivers/mfd/imanager-core.c
@@ -0,0 +1,288 @@
+/*
+ * Advantech iManager MFD core driver
+ *
+ * Copyright (C) 2016 Advantech Co., Ltd., Irvine, CA, USA
+ * Author: Richard Vidal-Dorsch <richard.dorsch-ELdSlb/RfAS1Z/+hSey0Gg@public.gmane.org>
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/imanager/core.h>
+#include <linux/mfd/imanager/ec.h>
+
+static struct platform_device *pdev;
+
+enum imanager_cells {
+	IMANAGER_BL,
+	IMANAGER_GPIO,
+	IMANAGER_HWMON,
+	IMANAGER_I2C,
+	IMANAGER_WDT,
+};
+
+static const char * const chip_names[] = {
+	"it8516",
+	"it8518",
+	"it8528",
+	NULL
+};
+
+static struct resource imanager_ioresource = {
+	.start  = IT8516_DAT_PORT,
+	.end    = IT8518_DAT_PORT,
+	.flags  = IORESOURCE_IO,
+};
+
+/*
+ * Devices which are part of the iManager and are available via firmware.
+ */
+static struct mfd_cell imanager_devs[] = {
+	[IMANAGER_BL] = {
+		.name = "imanager_backlight",
+	},
+	[IMANAGER_GPIO] = {
+		.name = "imanager_gpio",
+	},
+	[IMANAGER_HWMON] = {
+		.name = "imanager_hwmon",
+	},
+	[IMANAGER_I2C] = {
+		.name = "imanager_i2c",
+	},
+	[IMANAGER_WDT] = {
+		.name = "imanager_wdt",
+	},
+};
+
+const char *project_type_to_str(int type)
+{
+	const char *version_type;
+
+	switch (type) {
+	case 'V':
+		version_type = "Release";
+		break;
+	case 'X':
+		version_type = "Engineering Sample";
+		break;
+	case 'A' ... 'U':
+		version_type = "Custom";
+		break;
+	default:
+		version_type = "Unknown";
+		break;
+	}
+
+	return version_type;
+}
+
+static ssize_t imanager_name_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	const struct ec_info *info = &pdata->dev->info;
+
+	return scnprintf(buf, PAGE_SIZE, "%s\n", info->pcb_name);
+}
+
+static ssize_t imanager_kversion_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	const struct ec_info *info = &pdata->dev->info;
+
+	return scnprintf(buf, PAGE_SIZE, "%d.%d\n",
+			 info->version.kernel_major,
+			 info->version.kernel_minor);
+}
+
+static ssize_t imanager_fwversion_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	const struct ec_info *info = &pdata->dev->info;
+
+	return scnprintf(buf, PAGE_SIZE, "%d.%d\n",
+			 info->version.firmware_major,
+			 info->version.firmware_minor);
+}
+
+static ssize_t imanager_type_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	const struct ec_info *info = &pdata->dev->info;
+
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			project_type_to_str(info->version.type));
+}
+
+static ssize_t imanager_chip_name_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%s\n", pdata->chip_name);
+}
+
+static DEVICE_ATTR(imanager_name, S_IRUGO, imanager_name_show, NULL);
+static DEVICE_ATTR(imanager_kversion, S_IRUGO, imanager_kversion_show, NULL);
+static DEVICE_ATTR(imanager_fwversion, S_IRUGO, imanager_fwversion_show, NULL);
+static DEVICE_ATTR(imanager_type, S_IRUGO, imanager_type_show, NULL);
+static DEVICE_ATTR(imanager_chip_name, S_IRUGO, imanager_chip_name_show, NULL);
+
+static struct attribute *imanager_core_attributes[] = {
+	&dev_attr_imanager_name.attr,
+	&dev_attr_imanager_kversion.attr,
+	&dev_attr_imanager_fwversion.attr,
+	&dev_attr_imanager_type.attr,
+	&dev_attr_imanager_chip_name.attr,
+	NULL
+};
+
+static const struct attribute_group imanager_core_attr_group = {
+	.attrs = imanager_core_attributes,
+};
+
+static int imanager_platform_create(void)
+{
+	struct device *dev;
+	struct imanager_platform_data platdata;
+	int err;
+
+	pdev = platform_device_alloc("imanager-core", -1);
+	if (!pdev)
+		return -ENOMEM;
+
+	dev = &pdev->dev;
+
+	err = platform_device_add_data(pdev, &platdata, sizeof(platdata));
+	if (err)
+		goto exit_device_put;
+
+	err = platform_device_add_resources(pdev, &imanager_ioresource, 1);
+	if (err)
+		goto exit_device_put;
+
+	err = platform_device_add(pdev);
+	if (err)
+		goto exit_device_put;
+
+	err = mfd_add_devices(dev, pdev->id, imanager_devs,
+		ARRAY_SIZE(imanager_devs), NULL, -1, NULL);
+	if (err)
+		goto exit_device_unregister;
+
+	return 0;
+
+exit_device_unregister:
+	platform_device_unregister(pdev);
+exit_device_put:
+	platform_device_put(pdev);
+
+	return err;
+}
+
+static int imanager_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	struct imanager_device_data *imanager;
+	int ret;
+
+	if (!pdev)
+		return -EINVAL;
+
+	imanager = devm_kzalloc(dev, sizeof(*imanager), GFP_KERNEL);
+	if (!imanager)
+		return -ENOMEM;
+
+	imanager->dev = dev;
+	mutex_init(&imanager->lock);
+
+	platform_set_drvdata(pdev, imanager);
+
+	pdata->dev = imanager_get_ec_device();
+	pdata->chip_name = chip_names[pdata->dev->id];
+
+	dev_info(dev, "Found Advantech iManager %s - %s %d.%d/%d.%d (%s)\n",
+		 pdata->chip_name,
+		 pdata->dev->info.pcb_name,
+		 pdata->dev->info.version.kernel_major,
+		 pdata->dev->info.version.kernel_minor,
+		 pdata->dev->info.version.firmware_major,
+		 pdata->dev->info.version.firmware_minor,
+		 project_type_to_str(pdata->dev->info.version.type));
+
+	ret = sysfs_create_group(&dev->kobj, &imanager_core_attr_group);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int imanager_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	sysfs_remove_group(&dev->kobj, &imanager_core_attr_group);
+
+	mfd_remove_devices(dev);
+
+	return 0;
+}
+
+static struct platform_driver imanager_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name  = "imanager-core",
+	},
+	.probe	= imanager_probe,
+	.remove	= imanager_remove,
+};
+
+static int __init imanager_init(void)
+{
+	int ret;
+
+	ret = imanager_ec_probe();
+	if (ret < 0)
+		return ret;
+
+	ret = imanager_platform_create();
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&imanager_driver);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void __exit imanager_exit(void)
+{
+	if (pdev)
+		platform_device_unregister(pdev);
+
+	platform_driver_unregister(&imanager_driver);
+}
+
+module_init(imanager_init);
+module_exit(imanager_exit);
+
+MODULE_DESCRIPTION("Advantech iManager Core Driver");
+MODULE_AUTHOR("Richard Vidal-Dorsch <richard.dorsch at advantech.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imanager-core");
diff --git a/drivers/mfd/imanager-ec.c b/drivers/mfd/imanager-ec.c
new file mode 100644
index 0000000..be554ba
--- /dev/null
+++ b/drivers/mfd/imanager-ec.c
@@ -0,0 +1,1345 @@
+/*
+ * Advantech iManager Core - Firmware Interface
+ *
+ * Copyright (C) 2016 Advantech Co., Ltd., Irvine, CA, USA
+ * Author: Richard Vidal-Dorsch <richard.dorsch-ELdSlb/RfAS1Z/+hSey0Gg@public.gmane.org>
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/byteorder/generic.h>
+#include <linux/module.h>
+#include <linux/swab.h>
+#include <linux/mfd/imanager/ec.h>
+
+/**
+ * This is the delay time between two EC transactions.
+ * Values lower than 200us are not encouraged and may
+ * cause I/O errors
+ */
+#define EC_MICRO_DELAY			200
+#define EC_MAX_RETRY			1000
+
+#define EC_MSG_OFFSET_CMD		0UL
+#define EC_MSG_OFFSET_STATUS		1UL
+#define EC_MSG_OFFSET_PARAM		2UL
+#define EC_MSG_OFFSET_DATA(N)		(3UL + N)
+#define EC_MSG_OFFSET_PAYLOAD(N)	(7UL + N)
+
+/* The Device ID registers - 16 bit */
+#define DEVID_REG_MSB			0x20
+#define DEVID_REG_LSB			0x21
+
+/*
+ * IT8528 based firmware require a read/write command offset.
+ */
+#define EC_CMD_OFFSET_READ		0xA0UL
+#define EC_CMD_OFFSET_WRITE		0x50UL
+
+#define EC_STATUS_SUCCESS		BIT(0)
+#define EC_STATUS_CMD_COMPLETE		BIT(7)
+
+#define PCB_NAME_MAX_SIZE		8UL
+#define EC_I2C_BLOCK_SIZE		32
+#define EC_MAX_DID			32UL
+
+#define DID_LABEL_SIZE			24UL
+#define DID_DESC_SIZE			32UL
+
+#define EC_KERNEL_MINOR(x)		(LOBYTE16(x))
+#define EC_KERNEL_MAJOR(x) ({		\
+	typeof(x) __x = (HIBYTE16(x));	\
+	((__x >> 4) * 10 + (__x & 0x000f)); })
+#define EC_FIRMWARE_MINOR(x)		(LOBYTE16(x))
+#define EC_FIRMWARE_MAJOR(x)		EC_KERNEL_MAJOR(x)
+#define EC_PROJECT_CODE(x)		((char)(LOBYTE16(x)))
+
+enum ec_device_type {
+	ADC = 1,
+	DAC,
+	GPIO,
+	IRQ,
+	PWM,
+	SMB,
+	TACH
+};
+
+enum ec_device_id {
+	/* GPIO */
+	ALTGPIO0	= 0x10,
+	ALTGPIO1,
+	ALTGPIO2,
+	ALTGPIO3,
+	ALTGPIO4,
+	ALTGPIO5,
+	ALTGPIO6,
+	ALTGPIO7,
+	/* Button (GPIO) */
+	BUTTON0,
+	BUTTON1,
+	BUTTON2,
+	BUTTON3,
+	BUTTON4,
+	BUTTON5,
+	BUTTON6,
+	BUTTON7,
+	/* FAN */
+	CPUFAN_2P,
+	CPUFAN_4P,
+	SYSFAN1_2P,
+	SYSFAN1_4P,
+	SYSFAN2_2P,
+	SYSFAN2_4P,
+	/* Brightness Control */
+	BRIGHTNESS,
+	/* System Speaker */
+	PCBEEP,
+	/* SMBus */
+	SMBOEM0,
+	SMBOEM1,
+	SMBOEM2,
+	SMBEEPROM,
+	SMBTHERMAL0,
+	SMBTHERMAL1,
+	SMBSECEEP,
+	I2COEM,
+	/* Speaker */
+	SPEAKER		= 0x30,
+	/* SMBus */
+	SMBEEP2K	= 0x38,
+	OEMEEP,
+	OEMEEP2K,
+	PECI,
+	SMBOEM3,
+	SMLINK,
+	SMBSLV,
+	/* LED */
+	POWERLED	= 0x40,
+	BATLEDG,
+	OEMLED0,
+	OEMLED1,
+	OEMLED2,
+	BATLEDR,
+	/* Smart Battery */
+	SMARTBAT1	= 0x48,
+	SMARTBAT2,
+	/* ADC */
+	CMOSBAT		= 0x50,
+	CMOSBATx2,
+	CMOSBATx10,
+	LIBAT,
+	LIBATx2,
+	LIBATx10,
+	ADC5VS0,
+	ADC5VS0x2,
+	ADC5VS0x10,
+	ADC5VS5,
+	ADC5VS5x2,
+	ADC5VS5x10,
+	ADC33VS0,
+	ADC33VS0x2,
+	ADC33VS0x10,
+	ADC33VS5,
+	ADC33VS5x2,	/* 0x60 */
+	ADC33VS5x10,
+	ADC12VS0,
+	ADC12VS0x2,
+	ADC12VS0x10,
+	VCOREA,
+	VCOREAx2,
+	VCOREAx10,
+	VCOREB,
+	VCOREBx2,
+	VCOREBx10,
+	ADCDC,
+	ADCDCx2,
+	ADCDCx10,
+	VSTBY,
+	VSTBYx2,
+	VSTBYx10,	/* 0x70 */
+	VAUX,
+	VAUXx2,
+	VAUXx10,
+	CURRENT,
+	/* Watchdog */
+	WDIRQ		= 0x78,
+	WDNMI,
+	/* FAN Tacho */
+	TACHO0		= 0x80,
+	TACHO1,
+	TACHO2,
+	/* Brightness/Backlight Control */
+	BRIGHTNESS2	= 0x88,
+	BACKLIGHT1,
+	BACKLIGHT2
+};
+
+enum ec_dynamic_table_type {
+	EC_DYN_DID,
+	EC_DYN_HWP,
+	EC_DYN_POL
+};
+
+struct ec_devtbl {
+	int id;
+	int type;
+	int scale;
+	const char label[DID_LABEL_SIZE];
+	const char description[DID_DESC_SIZE];
+};
+
+struct ec_dyn_devtbl {
+	int did;	/* Device ID */
+	int hwp;	/* Hardware Pin */
+	int pol;	/* Polarity */
+	const struct ec_devtbl *devtbl; /* Device table Entry */
+};
+
+struct imanager_data {
+	int (*read)(int cmd);
+	int (*write)(int cmd, int value);
+
+	struct ec_dyn_devtbl dyn[EC_MAX_DID];
+
+	struct imanager_ec_device		dev;
+	struct imanager_hwmon_device		sensors;
+	struct imanager_gpio_device		gpio;
+	struct imanager_i2c_device		i2c;
+	struct imanager_watchdog_device		wdt;
+	struct imanager_backlight_device	blc;
+};
+
+struct ec_version_raw {
+	u16	kernel,
+		chipid,
+		project_code,
+		firmware;
+};
+
+enum ec_ram_type {
+	EC_RAM_ACPI = 1,
+	EC_RAM_HW,
+	EC_RAM_EXT
+};
+
+static struct imanager_data ec;
+
+static const struct ec_devtbl devtbl[] = {
+	{ ALTGPIO0,	GPIO,	-1,	"gpio0" },
+	{ ALTGPIO1,	GPIO,	-1,	"gpio1" },
+	{ ALTGPIO2,	GPIO,	-1,	"gpio2" },
+	{ ALTGPIO3,	GPIO,	-1,	"gpio3" },
+	{ ALTGPIO4,	GPIO,	-1,	"gpio4" },
+	{ ALTGPIO5,	GPIO,	-1,	"gpio5" },
+	{ ALTGPIO6,	GPIO,	-1,	"gpio6" },
+	{ ALTGPIO7,	GPIO,	-1,	"gpio7" },
+	{ BUTTON0,	GPIO,	-1,	"button0" },
+	{ BUTTON1,	GPIO,	-1,	"button1" },
+	{ BUTTON2,	GPIO,	-1,	"button2" },
+	{ BUTTON3,	GPIO,	-1,	"button3" },
+	{ BUTTON4,	GPIO,	-1,	"button4" },
+	{ BUTTON5,	GPIO,	-1,	"button4" },
+	{ BUTTON6,	GPIO,	-1,	"button4" },
+	{ BUTTON7,	GPIO,	-1,	"button4" },
+	{ CPUFAN_2P,	PWM,	2,	"FAN CPU" },
+	{ CPUFAN_4P,	PWM,	4,	"FAN CPU" },
+	{ SYSFAN1_2P,	PWM,	2,	"FAN SYS1" },
+	{ SYSFAN1_4P,	PWM,	4,	"FAN SYS1" },
+	{ SYSFAN2_2P,	PWM,	2,	"FAN SYS2" },
+	{ SYSFAN2_4P,	PWM,	4,	"FAN SYS2" },
+	{ BRIGHTNESS,	PWM,	-1,	"Brightness1" },
+	{ PCBEEP,	PWM,	-1,	"Beep" },
+	{ SMBOEM0,	SMB,	-1,	"SMB1" },
+	{ SMBOEM1,	SMB,	-1,	"SMB2" },
+	{ SMBOEM2,	SMB,	-1,	"SMB3" },
+	{ SMBEEPROM,	SMB,	-1,	"SMBEEP" },
+	{ SMBTHERMAL0,	SMB,	-1,	"SMBTHERM0" },
+	{ SMBTHERMAL1,	SMB,	-1,	"SMBTHERM1" },
+	{ SMBSECEEP,	SMB,	-1,	"SMBSECEEP" },
+	{ I2COEM,	SMB,	-1,	"I2COEM" },
+	{ SPEAKER,	DAC,	-1,	"Speaker" },
+	{ SMBEEP2K,	SMB,	-1,	"SMBEEP2K" },
+	{ OEMEEP,	SMB,	-1,	"OEMEEP" },
+	{ OEMEEP2K,	SMB,	-1,	"OEMEEP2K" },
+	{ PECI,		SMB,	-1,	"SMB_PECI" },
+	{ SMBOEM3,	SMB,	-1,	"SMBOEM3" },
+	{ SMLINK,	SMB,	-1,	"SMLINK" },
+	{ SMBSLV,	SMB,	-1,	"SMBSLV" },
+	{ POWERLED,	GPIO,	-1,	"Power LED" },
+	{ BATLEDG,	GPIO,	-1,	"BATLEDG" },
+	{ OEMLED0,	GPIO,	-1,	"OEMLED0" },
+	{ OEMLED1,	GPIO,	-1,	"OEMLED1" },
+	{ OEMLED2,	GPIO,	-1,	"OEMLED2" },
+	{ BATLEDR,	GPIO,	-1,	"OEMLEDR" },
+	{ SMARTBAT1,	SMB,	-1,	"SmartBat1" },
+	{ SMARTBAT2,	SMB,	-1,	"SmartBat2" },
+	{ CMOSBAT,	ADC,	1,	"VBat" },
+	{ CMOSBATx2,	ADC,	2,	"VBat" },
+	{ CMOSBATx10,	ADC,	10,	"VBat" },
+	{ LIBAT,	ADC,	1,	"VBat2" },
+	{ LIBATx2,	ADC,	2,	"VBat2" },
+	{ LIBATx10,	ADC,	10,	"VBat2" },
+	{ ADC5VS0,	ADC,	1,	"+5V" },
+	{ ADC5VS0x2,	ADC,	2,	"+5V" },
+	{ ADC5VS0x10,	ADC,	10,	"+5V" },
+	{ ADC5VS5,	ADC,	1,	"+5V" },
+	{ ADC5VS5x2,	ADC,	2,	"+5V" },
+	{ ADC5VS5x10,	ADC,	10,	"+5V" },
+	{ ADC33VS0,	ADC,	1,	"+3.3V" },
+	{ ADC33VS0x2,	ADC,	2,	"+3.3V" },
+	{ ADC33VS0x10,	ADC,	10,	"+3.3V" },
+	{ ADC33VS5,	ADC,	1,	"+3.3V" },
+	{ ADC33VS5x2,	ADC,	2,	"+3.3V" },
+	{ ADC33VS5x10,	ADC,	10,	"+3.3V" },
+	{ ADC12VS0,	ADC,	1,	"+12V" },
+	{ ADC12VS0x2,	ADC,	2,	"+12V" },
+	{ ADC12VS0x10,	ADC,	10,	"+12V" },
+	{ VCOREA,	ADC,	1,	"VCore" },
+	{ VCOREAx2,	ADC,	2,	"VCore" },
+	{ VCOREAx10,	ADC,	10,	"VCore" },
+	{ VCOREB,	ADC,	1,	"VCore2" },
+	{ VCOREBx2,	ADC,	2,	"VCore2" },
+	{ VCOREBx10,	ADC,	10,	"VCore2" },
+	{ ADCDC,	ADC,	1,	"ADCDC" },
+	{ ADCDCx2,	ADC,	2,	"ADCDCx2" },
+	{ ADCDCx10,	ADC,	10,	"ADCDCx10" },
+	{ VSTBY,	ADC,	1,	"Vsb" },
+	{ VSTBYx2,	ADC,	2,	"Vsb" },
+	{ VSTBYx10,	ADC,	10,	"Vsb" },
+	{ VAUX,		ADC,	1,	"VAUX" },
+	{ VAUXx2,	ADC,	2,	"VAUX" },
+	{ VAUXx10,	ADC,	10,	"VAUX" },
+	{ CURRENT,	ADC,	1,	"Imon" },
+	{ WDIRQ,	IRQ,	-1,	"WDIRQ" },
+	{ WDNMI,	GPIO,	-1,	"WDNMI" },
+	{ TACHO0,	TACH,	-1,	"Tacho1" },
+	{ TACHO1,	TACH,	-1,	"Tacho2" },
+	{ TACHO2,	TACH,	-1,	"Tacho3" },
+	{ BRIGHTNESS2,	PWM,	-1,	"Brightness2" },
+	{ BACKLIGHT1,	GPIO,	-1,	"Backlight1" },
+	{ BACKLIGHT2,	GPIO,	-1,	"Backlight2" },
+	{ 0, 0, 0, "" }
+};
+
+/**
+ * EC I/O
+ */
+
+static inline void imanager_delay(void)
+{
+	udelay(EC_MICRO_DELAY);
+}
+
+static int wait_ibf_cleared(void)
+{
+	int i = 0;
+
+	do {
+		if (!(inb(IT8516_CMD_PORT) & BIT(1)))
+			return 0;
+		imanager_delay();
+	} while (i++ < EC_MAX_RETRY);
+
+	return -ETIME;
+}
+
+static int wait_obf_set(void)
+{
+	int i = 0;
+
+	do {
+		if (inb(IT8516_CMD_PORT) & BIT(0))
+			return 0;
+		imanager_delay();
+	} while (i++ < EC_MAX_RETRY);
+
+	return -ETIME;
+}
+
+static inline int ec_inb(int addr, int reg)
+{
+	outb(reg, addr);
+	return inb(addr + 1);
+}
+
+static inline void ec_outb(int addr, int reg, int val)
+{
+	outb(reg, addr);
+	outb(val, addr + 1);
+}
+
+static inline int ec_io28_inb(int addr, int reg)
+{
+	int ret;
+
+	ret = wait_ibf_cleared();
+	if (ret)
+		return ret;
+
+	/* clear data to prevent lock */
+	inb(addr - 1);
+
+	outb(reg, addr);
+
+	ret = wait_obf_set();
+	if (ret)
+		return ret;
+
+	return inb(addr - 1);
+}
+
+static inline int ec_io28_outb(int addr, int reg, int val)
+{
+	int ret;
+
+	ret = wait_ibf_cleared();
+	if (ret)
+		return ret;
+
+	outb(reg, addr);
+
+	ret = wait_ibf_cleared();
+	if (ret)
+		return ret;
+
+	outb(val, addr - 1);
+
+	return 0;
+}
+
+static int ec_io18_read(int cmd)
+{
+	return ec_inb(IT8518_CMD_PORT, cmd);
+}
+
+static int ec_io18_write(int cmd, int value)
+{
+	ec_outb(IT8518_CMD_PORT, cmd, value);
+
+	return 0;
+}
+
+static int ec_io28_read(int cmd)
+{
+	return ec_io28_inb(IT8516_CMD_PORT, cmd + EC_CMD_OFFSET_READ);
+}
+
+static int ec_io28_write(int cmd, int value)
+{
+	return ec_io28_outb(IT8516_CMD_PORT, cmd + EC_CMD_OFFSET_WRITE, value);
+}
+
+/* Prevent FW lock */
+static void ec_clear_ports(void)
+{
+	inb(IT8516_DAT_PORT);
+	inb(IT8518_DAT_PORT);
+}
+
+static inline u16 ec_read_chipid(u16 addr)
+{
+	return (ec_inb(addr, DEVID_REG_MSB) << 8 |
+		ec_inb(addr, DEVID_REG_LSB));
+}
+
+static int ec_wait_cmd_clear(void)
+{
+	int i = 0;
+
+	do {
+		if (!ec.read(0))
+			return 0;
+		imanager_delay();
+	} while (i++ < EC_MAX_RETRY);
+
+	pr_err("No respons from EC (timeout)\n");
+
+	return -ETIME;
+}
+
+static int ec_read_ram(u8 bank, u8 offset, u8 len, u8 *buf, u8 bufsz)
+{
+	int i;
+	int ret;
+
+	if (WARN_ON(!buf))
+		return -EINVAL;
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ec.write(EC_MSG_OFFSET_PARAM, bank);
+	ec.write(EC_MSG_OFFSET_DATA(0), offset);
+	ec.write(EC_MSG_OFFSET_DATA(0x2C), len);
+	ec.write(EC_MSG_OFFSET_CMD, EC_CMD_RAM_RD);
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ret = ec.read(EC_MSG_OFFSET_STATUS);
+	if (ret != EC_STATUS_SUCCESS)
+		return -EIO;
+
+	for (i = 0; (i < len) && (len < EC_MSG_SIZE) && (len <= bufsz); i++)
+		buf[i] = ec.read(EC_MSG_OFFSET_DATA(i + 1));
+
+	return 0;
+}
+
+static int ec_write_ram(u8 bank, u8 offset, u8 len, u8 *buf)
+{
+	int i;
+	int ret;
+
+	if (WARN_ON(!buf))
+		return -EINVAL;
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ec.write(EC_MSG_OFFSET_PARAM, bank);
+	ec.write(EC_MSG_OFFSET_DATA(0), offset);
+	ec.write(EC_MSG_OFFSET_DATA(0x2C), len);
+
+	for (i = 0; (i < len) && (len < EC_MSG_SIZE); i++)
+		ec.write(EC_MSG_OFFSET_DATA(i + 1), buf[i]);
+
+	ec.write(EC_MSG_OFFSET_CMD, EC_CMD_RAM_WR);
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ret = ec.read(EC_MSG_OFFSET_STATUS);
+	if (ret != EC_STATUS_SUCCESS)
+		return -EIO;
+
+	return 0;
+}
+
+static int ec_read_dynamic_devtbl(struct imanager_data *ec)
+{
+	u32 i, j;
+	int ret;
+	struct ec_message did = {
+		.rlen = EC_MAX_DID,
+		.wlen = 0,
+	};
+	struct ec_message hwp = {
+		.rlen = EC_MAX_DID,
+		.wlen = 0,
+	};
+	struct ec_message pol = {
+		.rlen = EC_MAX_DID,
+		.wlen = 0,
+	};
+	struct ec_dyn_devtbl *dyn;
+
+	memset(ec->dyn, 0, sizeof(ec->dyn));
+
+	ret = imanager_msg_read(EC_CMD_DYN_TBL_RD, EC_DYN_DID, &did);
+	if (ret)
+		return -EIO;
+
+	ret = imanager_msg_read(EC_CMD_DYN_TBL_RD, EC_DYN_HWP, &hwp);
+	if (ret)
+		return -EIO;
+
+	ret = imanager_msg_read(EC_CMD_DYN_TBL_RD, EC_DYN_POL, &pol);
+	if (ret)
+		return -EIO;
+
+	for (i = 0; (i < EC_MAX_DID) && did.u.data[i]; i++) {
+		dyn = &ec->dyn[i];
+		for (j = 0; j < ARRAY_SIZE(devtbl); j++) {
+			if (devtbl[j].id == did.u.data[i]) {
+				dyn->did = did.u.data[i];
+				dyn->hwp = hwp.u.data[i];
+				dyn->pol = pol.u.data[i];
+				dyn->devtbl = &devtbl[j];
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int ec_read_buffer(u8 *data, int rlen)
+{
+	int ret, i, j;
+	int pages = rlen % EC_I2C_BLOCK_SIZE;
+	int rem = rlen / EC_I2C_BLOCK_SIZE;
+
+	/* pre-condition: rlen <= 256 */
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	for (i = 0; i < pages; i++) {
+		ec.write(EC_MSG_OFFSET_PARAM, i);
+		ec.write(EC_MSG_OFFSET_CMD, EC_CMD_BUF_RD);
+
+		ret = ec_wait_cmd_clear();
+		if (ret)
+			return ret;
+
+		ret = ec.read(EC_MSG_OFFSET_STATUS);
+		if (ret != EC_STATUS_SUCCESS)
+			return -EIO;
+
+		for (j = 0; j < EC_I2C_BLOCK_SIZE; j++)
+			data[i * EC_I2C_BLOCK_SIZE + j] =
+				ec.read(EC_MSG_OFFSET_DATA(j));
+	}
+
+	if (rem) {
+		ec.write(EC_MSG_OFFSET_PARAM, pages);
+		ec.write(EC_MSG_OFFSET_CMD, EC_CMD_BUF_RD);
+
+		ret = ec_wait_cmd_clear();
+		if (ret)
+			return ret;
+
+		ret = ec.read(EC_MSG_OFFSET_STATUS);
+		if (ret != EC_STATUS_SUCCESS)
+			return -EIO;
+
+		for (j = 0; j < rem; j++)
+			data[pages * EC_I2C_BLOCK_SIZE + j] =
+				ec.read(EC_MSG_OFFSET_DATA(j));
+	}
+
+	return 0;
+}
+
+static int
+imanager_msg_trans(u8 cmd, u8 param, struct ec_message *msg, bool payload)
+{
+	int ret, i, len;
+	u32 offset;
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ec.write(EC_MSG_OFFSET_PARAM, param);
+
+	if (msg && msg->wlen) {
+		if (!msg->data) {
+			for (i = 0; i < msg->wlen; i++)
+				ec.write(EC_MSG_OFFSET_DATA(i),
+					msg->u.data[i]);
+		} else {
+			for (i = 0; i < msg->wlen; i++)
+				ec.write(EC_MSG_OFFSET_DATA(i), msg->data[i]);
+			ec.write(EC_MSG_OFFSET_DATA(0x2c), msg->wlen);
+		}
+	}
+
+	ec.write(EC_MSG_OFFSET_CMD, cmd);
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	/* GPIO and I2C have different success return values */
+	ret = ec.read(EC_MSG_OFFSET_STATUS);
+	if ((ret != EC_STATUS_SUCCESS) && !(ret & EC_STATUS_CMD_COMPLETE))
+		return -EIO;
+	/*
+	 * EC I2C may return an error code which we need to hand-off
+	 * to the caller
+	 */
+	else if (ret & 0x07e)
+		return ret;
+
+	if (msg && msg->data) {
+		ret = ec_read_buffer(msg->data, msg->rlen);
+		if (ret < 0)
+			return ret;
+	} else if (msg && msg->rlen) {
+		if (msg->rlen == 0xff)
+			/* Use alternate message body for hwmon */
+			len = ec.read(EC_MSG_OFFSET_DATA(0x2C));
+		else
+			len = (msg->rlen > EC_MSG_SIZE ? EC_MSG_SIZE :
+				msg->rlen);
+		offset = payload ? EC_MSG_OFFSET_PAYLOAD(0) :
+				EC_MSG_OFFSET_DATA(0);
+		for (i = 0; i < len; i++)
+			msg->u.data[i] = ec.read(offset + i);
+	}
+
+	return 0;
+}
+
+int imanager_msg_read(u8 cmd, u8 param, struct ec_message *msg)
+{
+	return imanager_msg_trans(cmd, param, msg, false);
+}
+EXPORT_SYMBOL_GPL(imanager_msg_read);
+
+int imanager_msg_write(u8 cmd, u8 param, struct ec_message *msg)
+{
+	return imanager_msg_trans(cmd, param, msg, true);
+}
+EXPORT_SYMBOL_GPL(imanager_msg_write);
+
+int imanager_read_byte(u8 cmd, u8 param)
+{
+	int ret;
+	struct ec_message msg = {
+		.rlen = 1,
+		.wlen = 0,
+	};
+
+	ret = imanager_msg_read(cmd, param, &msg);
+	if (ret)
+		return ret;
+
+	return msg.u.data[0];
+}
+EXPORT_SYMBOL_GPL(imanager_read_byte);
+
+int imanager_read_word(u8 cmd, u8 param)
+{
+	int ret;
+	struct ec_message msg = {
+		.rlen = 2,
+		.wlen = 0,
+	};
+
+	ret = imanager_msg_read(cmd, param, &msg);
+	if (ret)
+		return ret;
+
+	return (msg.u.data[0] << 8 | msg.u.data[1]);
+}
+EXPORT_SYMBOL_GPL(imanager_read_word);
+
+int imanager_write_byte(u8 cmd, u8 param, u8 byte)
+{
+	struct ec_message msg = {
+		.rlen = 0,
+		.wlen = 1,
+		.u = {
+			.data = { byte, 0 },
+		},
+	};
+
+	return imanager_msg_write(cmd, param, &msg);
+}
+EXPORT_SYMBOL_GPL(imanager_write_byte);
+
+int imanager_write_word(u8 cmd, u8 param, u16 word)
+{
+	struct ec_message msg = {
+		.rlen = 0,
+		.wlen = 2,
+		.u = {
+			.data = { HIBYTE16(word), LOBYTE16(word), 0 },
+		},
+	};
+
+	return imanager_msg_write(cmd, param, &msg);
+}
+EXPORT_SYMBOL_GPL(imanager_write_word);
+
+static int ec_hwram_read_byte(u8 offset)
+{
+	int ret;
+	u8 val;
+
+	ret = ec_read_ram(EC_RAM_HW, offset, sizeof(val), &val, sizeof(val));
+	if (ret < 0) {
+		pr_err("Failed to read from HWRAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return val;
+}
+
+int imanager_acpiram_read_byte(u8 offset)
+{
+	int ret;
+	u8 value;
+
+	ret = ec_read_ram(EC_RAM_ACPI, offset, sizeof(value), (u8 *)&value,
+			  sizeof(value));
+	if (ret < 0) {
+		pr_err("Failed to read from ACPI RAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return value;
+}
+EXPORT_SYMBOL_GPL(imanager_acpiram_read_byte);
+
+int imanager_acpiram_write_byte(u8 offset, u8 value)
+{
+	int ret;
+
+	ret = ec_write_ram(EC_RAM_ACPI, offset, sizeof(value), &value);
+	if (ret) {
+		pr_err("Failed to write to ACPI RAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(imanager_acpiram_write_byte);
+
+int imanager_acpiram_read_block(u8 offset, u8 *buf, u8 len)
+{
+	int ret;
+
+	ret = ec_read_ram(EC_RAM_ACPI, offset, len, buf, len);
+	if (ret < 0) {
+		pr_err("Failed to read from ACPI RAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(imanager_acpiram_read_block);
+
+int imanager_acpiram_write_block(u8 offset, u8 *buf, u8 len)
+{
+	int ret;
+
+	ret = ec_write_ram(EC_RAM_ACPI, offset, len, buf);
+	if (ret) {
+		pr_err("Failed to write to ACPI RAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(imanager_acpiram_write_block);
+
+int imanager_wait_proc_complete(u8 offset, int cond)
+{
+	int ret, i;
+
+	for (i = 0; i < EC_MAX_RETRY; i++) {
+		ret = ec_hwram_read_byte(offset);
+		if (ret < 0)
+			return ret;
+
+		if (ret == cond)
+			return 0;
+
+		imanager_delay();
+	}
+
+	return -EIO;
+}
+EXPORT_SYMBOL_GPL(imanager_wait_proc_complete);
+
+static inline void ec_get_dev_attr(struct ec_dev_attr *attr,
+				   const struct ec_dyn_devtbl *tbl)
+{
+	attr->did = tbl->did;
+	attr->hwp = tbl->hwp;
+	attr->pol = tbl->pol;
+	attr->scale = tbl->devtbl->scale;
+	attr->label = tbl->devtbl->label;
+}
+
+static int ec_get_dev_gpio(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct imanager_gpio_device *gpio = &ec->gpio;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == GPIO)) {
+			switch (dyn->did) {
+			case ALTGPIO0:
+				ec_get_dev_attr(&gpio->attr[0], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO1:
+				ec_get_dev_attr(&gpio->attr[1], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO2:
+				ec_get_dev_attr(&gpio->attr[2], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO3:
+				ec_get_dev_attr(&gpio->attr[3], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO4:
+				ec_get_dev_attr(&gpio->attr[4], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO5:
+				ec_get_dev_attr(&gpio->attr[5], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO6:
+				ec_get_dev_attr(&gpio->attr[6], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO7:
+				ec_get_dev_attr(&gpio->attr[7], dyn);
+				gpio->num++;
+				break;
+			case BUTTON0:
+			case BUTTON1:
+			case BUTTON2:
+			case BUTTON3:
+			case BUTTON4:
+			case BUTTON5:
+			case BUTTON6:
+			case BUTTON7:
+			case POWERLED:
+			case BATLEDG:
+			case OEMLED0:
+			case OEMLED1:
+			case OEMLED2:
+			case BATLEDR:
+			case WDNMI:
+			case BACKLIGHT1:
+			case BACKLIGHT2:
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	gpio->info = &ec->dev.info;
+
+	return 0;
+}
+
+static int ec_get_dev_adc(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct dev_adc *adc = &ec->sensors.adc;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == ADC)) {
+			switch (dyn->did) {
+			case ADC12VS0:
+			case ADC12VS0x2:
+			case ADC12VS0x10:
+				ec_get_dev_attr(&adc->attr[0], dyn);
+				adc->num++;
+				break;
+			case ADC5VS5:
+			case ADC5VS5x2:
+			case ADC5VS5x10:
+				ec_get_dev_attr(&adc->attr[1], dyn);
+				adc->num++;
+				break;
+			case CMOSBAT:
+			case CMOSBATx2:
+			case CMOSBATx10:
+				ec_get_dev_attr(&adc->attr[2], dyn);
+				adc->num++;
+				break;
+			case VCOREA:
+			case ADC5VS0:
+			case ADC5VS0x2:
+			case ADC5VS0x10:
+				ec_get_dev_attr(&adc->attr[3], dyn);
+				adc->num++;
+				break;
+			case CURRENT:
+			case ADC33VS0:
+			case ADC33VS0x2:
+			case ADC33VS0x10:
+				ec_get_dev_attr(&adc->attr[4], dyn);
+				adc->num++;
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int ec_get_dev_fan(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct dev_fan *fan = &ec->sensors.fan;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && ((dyn->devtbl->type == TACH) ||
+				 (dyn->devtbl->type == PWM))) {
+			switch (dyn->did) {
+			case CPUFAN_2P:
+			case CPUFAN_4P:
+				ec_get_dev_attr(&fan->attr[0], dyn);
+				fan->num++;
+				fan->active |= 1 << 0;
+				break;
+			case SYSFAN1_2P:
+			case SYSFAN1_4P:
+				ec_get_dev_attr(&fan->attr[1], dyn);
+				fan->num++;
+				fan->active |= 1 << 1;
+				break;
+			case SYSFAN2_2P:
+			case SYSFAN2_4P:
+				ec_get_dev_attr(&fan->attr[2], dyn);
+				fan->num++;
+				fan->active |= 1 << 2;
+				break;
+			case TACHO0:
+			case TACHO1:
+			case TACHO2:
+			case BRIGHTNESS:
+			case BRIGHTNESS2:
+			case PCBEEP:
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int ec_get_dev_hwmon(struct imanager_data *ec)
+{
+	int ret;
+
+	ret = ec_get_dev_adc(ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_fan(ec);
+	if (ret < 0)
+		return ret;
+
+	ec->sensors.ecdev = &ec->dev;
+
+	return 0;
+}
+
+static int ec_get_dev_i2c(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct imanager_i2c_device *i2c = &ec->i2c;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == SMB)) {
+			switch (dyn->did) {
+			case SMBEEPROM:
+				ec_get_dev_attr(&i2c->attr[0], dyn);
+				i2c->eeprom = &i2c->attr[0];
+				i2c->num++;
+				break;
+			case I2COEM:
+				ec_get_dev_attr(&i2c->attr[1], dyn);
+				i2c->i2coem = &i2c->attr[1];
+				i2c->num++;
+				break;
+			case SMBOEM0:
+			case SMBOEM1:
+			case SMBOEM2:
+			case SMBTHERMAL0:
+			case SMBTHERMAL1:
+			case SMBSECEEP:
+			case SMBEEP2K:
+			case OEMEEP:
+			case OEMEEP2K:
+			case PECI:
+			case SMBOEM3:
+			case SMLINK:
+			case SMBSLV:
+			case SMARTBAT1:
+			case SMARTBAT2:
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	i2c->ecdev = &ec->dev;
+
+	return 0;
+}
+
+static int ec_get_dev_blc(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct imanager_backlight_device *blc = &ec->blc;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == PWM)) {
+			switch (dyn->did) {
+			case BRIGHTNESS:
+				ec_get_dev_attr(&blc->attr[0], dyn);
+				blc->brightness[0] = EC_ACPIRAM_BRIGHTNESS1;
+				blc->num++;
+				break;
+			case BRIGHTNESS2:
+				ec_get_dev_attr(&blc->attr[1], dyn);
+				blc->brightness[1] = EC_ACPIRAM_BRIGHTNESS2;
+				blc->num++;
+				break;
+			case CPUFAN_2P:
+			case CPUFAN_4P:
+			case SYSFAN1_2P:
+			case SYSFAN1_4P:
+			case SYSFAN2_2P:
+			case SYSFAN2_4P:
+			case PCBEEP:
+			case TACHO0:
+			case TACHO1:
+			case TACHO2:
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	blc->info = &ec->dev.info;
+
+	return 0;
+}
+
+static int ec_get_dev_wdt(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct imanager_watchdog_device *wdt = &ec->wdt;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == IRQ)) {
+			switch (dyn->did) {
+			case WDIRQ:
+				ec_get_dev_attr(&wdt->attr[0], dyn);
+				wdt->irq = &wdt->attr[0];
+				wdt->num++;
+				break;
+			case WDNMI:
+				ec_get_dev_attr(&wdt->attr[1], dyn);
+				wdt->nmi = &wdt->attr[1];
+				wdt->num++;
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	wdt->info = &ec->dev.info;
+
+	return 0;
+}
+
+const struct imanager_ec_device *imanager_get_ec_device(void)
+{
+	return &ec.dev;
+};
+EXPORT_SYMBOL_GPL(imanager_get_ec_device);
+
+const struct imanager_hwmon_device *imanager_get_hwmon_device(void)
+{
+	return &ec.sensors;
+}
+EXPORT_SYMBOL_GPL(imanager_get_hwmon_device);
+
+const struct imanager_gpio_device *imanager_get_gpio_device(void)
+{
+	return &ec.gpio;
+}
+EXPORT_SYMBOL_GPL(imanager_get_gpio_device);
+
+const struct imanager_i2c_device *imanager_get_i2c_device(void)
+{
+	return &ec.i2c;
+}
+EXPORT_SYMBOL_GPL(imanager_get_i2c_device);
+
+const struct imanager_backlight_device *imanager_get_backlight_device(void)
+{
+	return &ec.blc;
+}
+EXPORT_SYMBOL_GPL(imanager_get_backlight_device);
+
+const struct imanager_watchdog_device *imanager_get_watchdog_device(void)
+{
+	return &ec.wdt;
+}
+EXPORT_SYMBOL_GPL(imanager_get_watchdog_device);
+
+static int ec_get_version(struct ec_version *version)
+{
+	int ret;
+	u16 raw;
+	struct ec_version_raw ver;
+
+	if (WARN_ON(!version))
+		return -EINVAL;
+
+	ret = ec_read_ram(EC_RAM_ACPI, EC_ACPIRAM_FW_RELEASE_RD, sizeof(ver),
+			 (u8 *)&ver, sizeof(ver));
+	if (ret < 0)
+		return ret;
+
+	raw = swab16(ver.kernel);
+	version->kernel_major = EC_KERNEL_MAJOR(raw);
+	version->kernel_minor = EC_KERNEL_MINOR(raw);
+
+	raw = swab16(ver.firmware);
+	version->firmware_major = EC_FIRMWARE_MAJOR(raw);
+	version->firmware_minor = EC_FIRMWARE_MINOR(raw);
+
+	raw = swab16(ver.project_code);
+	version->type = EC_PROJECT_CODE(raw);
+
+	return 0;
+}
+
+static int ec_get_pcb_name(struct ec_info *info)
+{
+	int ret;
+	struct ec_message msg = {
+		.rlen = ARRAY_SIZE(info->pcb_name),
+		.wlen = 0,
+	};
+
+	if (WARN_ON(!info))
+		return -EINVAL;
+
+	ret = imanager_msg_read(EC_CMD_FW_INFO_RD, 0, &msg);
+	if (ret)
+		return ret;
+
+	/*
+	 * Sadly, the string is not Null-terminated so we will need to read a
+	 * fixed amount of chars. There is, apparently, no exact definition
+	 * of board name (SOM6867 vs. MIO-5271).
+	 */
+	memset(info->pcb_name, 0, ARRAY_SIZE(info->pcb_name));
+	strncpy(info->pcb_name, (const char *)msg.u.data, PCB_NAME_MAX_SIZE);
+
+	if (strchr(info->pcb_name, '-') == NULL)
+		info->pcb_name[PCB_NAME_MAX_SIZE - 1] = '\0';
+
+	return 0;
+}
+
+static int ec_get_fw_info(struct ec_info *info)
+{
+	int ret;
+
+	if (WARN_ON(!info))
+		return -EINVAL;
+
+	ret = ec_get_version(&info->version);
+	if (ret)
+		return ret;
+
+	return ec_get_pcb_name(info);
+}
+
+static int ec_init(void)
+{
+	int ret;
+
+	ec_clear_ports();
+
+	ret = ec_read_dynamic_devtbl(&ec);
+	if (ret)
+		return ret;
+
+	ret = ec_get_fw_info(&ec.dev.info);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_gpio(&ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_hwmon(&ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_i2c(&ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_blc(&ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_wdt(&ec);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int imanager_ec_probe(void)
+{
+	int chipid = ec_read_chipid(EC_BASE_ADDR);
+
+	memset((void *)&ec, 0, sizeof(ec));
+
+	switch (chipid) {
+	case EC_DEVID_IT8516:
+		pr_err("EC IT8516 not supported\n");
+		ec.dev.id = IT8516;
+		return -ENODEV;
+	case EC_DEVID_IT8518:
+		ec.read = ec_io18_read;
+		ec.write = ec_io18_write;
+		ec.dev.id = IT8518;
+		break;
+	case EC_DEVID_IT8528:
+		ec.read = ec_io28_read;
+		ec.write = ec_io28_write;
+		ec.dev.id = IT8528;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	ec.dev.addr = EC_BASE_ADDR;
+
+	return ec_init();
+}
+
diff --git a/include/linux/mfd/imanager/core.h b/include/linux/mfd/imanager/core.h
new file mode 100644
index 0000000..05c77fa
--- /dev/null
+++ b/include/linux/mfd/imanager/core.h
@@ -0,0 +1,31 @@
+/*
+ * Advantech iManager MFD core
+ *
+ * Copyright (C) 2016 Advantech Co., Ltd., Irvine, CA, USA
+ * Author: Richard Vidal-Dorsch <richard.dorsch-ELdSlb/RfAS1Z/+hSey0Gg@public.gmane.org>
+ *
+ * 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.
+ */
+
+#ifndef __CORE_H__
+#define __CORE_H__
+
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/mfd/imanager/ec.h>
+
+struct imanager_platform_data {
+	const struct imanager_ec_device *dev;
+	const char *chip_name;
+};
+
+struct imanager_device_data {
+	struct device *dev;
+	struct mutex  lock;
+};
+
+#endif
diff --git a/include/linux/mfd/imanager/ec.h b/include/linux/mfd/imanager/ec.h
new file mode 100644
index 0000000..783f268
--- /dev/null
+++ b/include/linux/mfd/imanager/ec.h
@@ -0,0 +1,210 @@
+/*
+ * Advantech iManager core - firmware interface
+ *
+ * Copyright (C) 2016 Advantech Co., Ltd., Irvine, CA, USA
+ * Author: Richard Vidal-Dorsch <richard.dorsch-ELdSlb/RfAS1Z/+hSey0Gg@public.gmane.org>
+ *
+ * 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.
+ */
+
+#ifndef __EC_H__
+#define __EC_H__
+
+#include <linux/types.h>
+
+#define EC_DEVID_IT8516			0x8516
+#define EC_DEVID_IT8518			0x8518
+#define EC_DEVID_IT8528			0x8528
+
+#define EC_BASE_ADDR			0x029C
+
+#define IT8516_CMD_PORT			0x029A /* it8528 */
+#define IT8516_DAT_PORT			0x0299
+
+#define IT8518_CMD_PORT			0x029E /* it8518 */
+#define IT8518_DAT_PORT			0x029F
+
+#define EC_GPIO_MAX_NUM			8
+#define EC_HWM_MAX_ADC			5
+#define EC_HWM_MAX_FAN			3
+#define EC_BLC_MAX_NUM			2
+#define EC_SMB_MAX_NUM			4
+#define EC_WDT_MAX_NUM			2
+
+#define PCB_NAME_SIZE			32
+#define EC_PAYLOAD_SIZE			40
+#define EC_MSG_SIZE			sizeof(struct ec_smb_message)
+
+#define LOBYTE16(x)			(x & 0x00FF)
+#define HIBYTE16(x)			(LOBYTE16(x >> 8))
+#define LOADDR16(x)			LOBYTE16(x)
+#define HIADDR16(x)			(x >= 0xF000 ? LOBYTE16(x >> 8) : 0)
+
+/*
+ * iManager commands
+ */
+#define EC_CMD_HWP_RD			0x11UL
+#define EC_CMD_HWP_WR			0x12UL
+#define EC_CMD_GPIO_DIR_RD		0x30UL
+#define EC_CMD_GPIO_DIR_WR		0x31UL
+#define EC_CMD_PWM_FREQ_RD		0x36UL
+#define EC_CMD_PWM_FREQ_WR		0x32UL
+#define EC_CMD_PWM_POL_RD		0x37UL
+#define EC_CMD_PWM_POL_WR		0x33UL
+#define EC_CMD_SMB_FREQ_RD		0x34UL
+#define EC_CMD_SMB_FREQ_WR		0x35UL
+#define EC_CMD_FAN_CTL_RD		0x40UL
+#define EC_CMD_FAN_CTL_WR		0x41UL
+#define EC_CMD_THZ_RD			0x42UL
+#define EC_CMD_DYN_TBL_RD		0x20UL
+#define EC_CMD_FW_INFO_RD		0xF0UL
+#define EC_CMD_BUF_CLR			0xC0UL
+#define EC_CMD_BUF_RD			0xC1UL
+#define EC_CMD_BUF_WR			0xC2UL
+#define EC_CMD_RAM_RD			0x1EUL
+#define EC_CMD_RAM_WR			0x1FUL
+#define EC_CMD_I2C_RW			0x0EUL
+#define EC_CMD_I2C_WR			0x0FUL
+#define EC_CMD_WDT_CTRL			0x28UL
+
+/*
+ * ACPI and HW RAM offsets
+ */
+#define EC_ACPIRAM_FAN_ALERT		0x6FUL
+#define EC_ACPIRAM_FAN_SPEED_LIMIT	0x76UL
+#define EC_ACPIRAM_BRIGHTNESS1		0x50UL
+#define EC_ACPIRAM_BRIGHTNESS2		0x52UL
+#define EC_ACPIRAM_BLC_CTRL		0x99UL
+#define EC_ACPIRAM_FW_RELEASE_RD	0xF8UL
+
+enum chips { IT8516, IT8518, IT8528 };
+
+struct ec_message_header {
+	u8 addr_low;	/* SMB low-byte address or data low-byte */
+			/* of byte-/word-transaction */
+	u8 addr_high;	/* SMB high-byte address or data high-byte */
+			/* of word-transaction */
+	u8 rlen;	/* SMB read length */
+	u8 wlen;	/* SMB write length */
+	u8 cmd;		/* SMB command */
+};
+
+struct ec_smb_message {
+	struct ec_message_header hdr;
+	u8 data[EC_PAYLOAD_SIZE];
+};
+
+struct ec_message {
+	u8 rlen;	/* EC message read length */
+	u8 wlen;	/* EC message write length */
+	union {
+		struct ec_smb_message smb;
+		u8 data[EC_MSG_SIZE];
+	} u;
+
+	u8 *data;
+};
+
+struct ec_version {
+	u32 kernel_major;
+	u32 kernel_minor;
+	u32 firmware_major;
+	u32 firmware_minor;
+	u32 type;
+};
+
+struct ec_info {
+	struct ec_version version;
+	char pcb_name[PCB_NAME_SIZE];
+};
+
+struct imanager_ec_device {
+	int		id; /* enum chip */
+	u16		addr;
+	struct ec_info	info;
+};
+
+struct ec_dev_attr {
+	int did;	/* Device ID */
+	int hwp;	/* Hardware Pin number */
+	int pol;	/* Polarity */
+	int scale;	/* Scaling factor */
+	const char *label;
+};
+
+struct imanager_gpio_device {
+	u32			num;
+	struct ec_dev_attr	attr[EC_GPIO_MAX_NUM];
+	struct ec_info		*info;
+};
+
+struct dev_adc {
+	u32			num;
+	struct ec_dev_attr	attr[EC_HWM_MAX_ADC];
+};
+
+struct dev_fan {
+	u32			num;
+	u32			active;
+	struct ec_dev_attr	attr[EC_HWM_MAX_FAN];
+};
+
+struct imanager_hwmon_device {
+	struct dev_adc		adc;
+	struct dev_fan		fan;
+	struct imanager_ec_device *ecdev;
+};
+
+struct imanager_i2c_device {
+	u32			num;
+	struct ec_dev_attr	attr[EC_SMB_MAX_NUM];
+	struct ec_dev_attr	*eeprom;
+	struct ec_dev_attr	*i2coem;
+	struct imanager_ec_device *ecdev;
+};
+
+struct imanager_backlight_device {
+	u32			num;
+	struct ec_dev_attr	attr[EC_BLC_MAX_NUM];
+	u8			brightness[EC_BLC_MAX_NUM];
+	struct ec_info		*info;
+};
+
+struct imanager_watchdog_device {
+	u32			num;
+	struct ec_dev_attr	attr[EC_WDT_MAX_NUM];
+	struct ec_dev_attr	*irq;
+	struct ec_dev_attr	*nmi;
+	struct ec_info		*info;
+};
+
+/* Must be called first, obviously */
+int imanager_ec_probe(void);
+
+int imanager_msg_write(u8 cmd, u8 param, struct ec_message *msg);
+int imanager_msg_read(u8 cmd, u8 param, struct ec_message *msg);
+
+int imanager_read_byte(u8 cmd, u8 param);
+int imanager_read_word(u8 cmd, u8 param);
+
+int imanager_write_byte(u8 cmd, u8 param, u8 byte);
+int imanager_write_word(u8 cmd, u8 param, u16 word);
+
+int imanager_acpiram_read_byte(u8 offset);
+int imanager_acpiram_write_byte(u8 offset, u8 value);
+int imanager_acpiram_read_block(u8 offset, u8 *buf, u8 len);
+int imanager_acpiram_write_block(u8 offset, u8 *buf, u8 len);
+
+int imanager_wait_proc_complete(u8 offset, int cond);
+
+const struct imanager_ec_device *imanager_get_ec_device(void);
+const struct imanager_hwmon_device *imanager_get_hwmon_device(void);
+const struct imanager_gpio_device *imanager_get_gpio_device(void);
+const struct imanager_i2c_device *imanager_get_i2c_device(void);
+const struct imanager_watchdog_device *imanager_get_watchdog_device(void);
+const struct imanager_backlight_device *imanager_get_backlight_device(void);
+
+#endif
-- 
2.6.4

--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH v2 1/6] Add Advantech iManager MFD core driver
@ 2016-01-10  9:10   ` richard.dorsch
  0 siblings, 0 replies; 44+ messages in thread
From: richard.dorsch @ 2016-01-10  9:10 UTC (permalink / raw)
  To: linux-kernel
  Cc: lm-sensors, linux-i2c, linux-watchdog, linux-gpio, lee.jones,
	jdelvare, linux, wim, jo.sunga, Richard Vidal-Dorsch

From: Richard Vidal-Dorsch <richard.dorsch@gmail.com>

This patch adds Advantech iManager Embedded Controller MFD core driver.
This mfd core dirver provides an interface to GPIO, I2C, HWmon,
Watchdog, and Backlight/Brightness control.

Signed-off-by: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
---
 Documentation/devicetree/bindings/mfd/imanager.txt |   33 +
 MAINTAINERS                                        |   13 +
 drivers/mfd/Kconfig                                |   20 +
 drivers/mfd/Makefile                               |    2 +
 drivers/mfd/imanager-core.c                        |  288 +++++
 drivers/mfd/imanager-ec.c                          | 1345 ++++++++++++++++++++
 include/linux/mfd/imanager/core.h                  |   31 +
 include/linux/mfd/imanager/ec.h                    |  210 +++
 8 files changed, 1942 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/imanager.txt
 create mode 100644 drivers/mfd/imanager-core.c
 create mode 100644 drivers/mfd/imanager-ec.c
 create mode 100644 include/linux/mfd/imanager/core.h
 create mode 100644 include/linux/mfd/imanager/ec.h

diff --git a/Documentation/devicetree/bindings/mfd/imanager.txt b/Documentation/devicetree/bindings/mfd/imanager.txt
new file mode 100644
index 0000000..bf58a96
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/imanager.txt
@@ -0,0 +1,33 @@
+Note
+====
+
+This is a set of platform drivers which provide support for multiple
+embedded features such as GPIO, I2C/SMBus, Hardware Monitoring, Watchdog,
+and Backlight/Brightness control. Those features are available on Advantech
+Embedded boards such as SOM, MIO, AIMB, and PCM.
+Datasheets of each product line can be downloaded from www.advantech.com
+
+Author:
+	Richard Vidal-Dorsch <richard.dorsch@advantech.com>
+
+
+Kernel driver imanager
+======================
+
+This driver provides a communication layer to the Advantech iManager EC
+firmware which is factory loaded onto ITE IT8518/28 chips. The type of
+communication is message based. Clients (gpio, i2c, hwmon etc. drivers)
+request data from Advantech iManager (polling, not interrupt driven). If
+a response is been received within a time frame, the data is been extracted
+from the message and then passed to the caller (clients).
+
+  Supported chips:
+  * Advantech EC based on ITE IT8518
+    Prefix: imanager
+    Addresses: 0x029e/0x029f
+    Datasheet: Available from ITE upon request
+  * Advantech EC based on ITE IT8528
+    Prefix: imanager
+    Addresses: 0x0299/0x29a
+    Datasheet: Available from ITE upon request
+
diff --git a/MAINTAINERS b/MAINTAINERS
index 233f834..8d25fdc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5391,6 +5391,19 @@ M:	Stanislaw Gruszka <stf_xl@wp.pl>
 S:	Maintained
 F:	drivers/usb/atm/ueagle-atm.c
 
+IMANAGER ADVANTECH EC DRIVER
+M:	Richard Vidal-Dorsch <richard.dorsch@advantech.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/mfd/imanager.txt
+F:	Documentation/hwmon/imanager
+F:	Documentation/i2c/busses/i2c-imanager
+F:	drivers/mfd/imanager-core.c
+F:	drivers/gpio/imanager-gpio.c
+F:	drivers/hwmon/imanager-hwmon.c
+F:	drivers/i2c/busses/imanager-i2c.c
+F:	drivers/video/backlight/imanager-bl.c
+F:	drivers/watchdog/imanager-wdt.c
+
 INA209 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
 L:	lm-sensors@lm-sensors.org
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 4d92df6..4dc7c13 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -322,6 +322,26 @@ config MFD_INTEL_QUARK_I2C_GPIO
 	  their respective IO driver.
 	  The GPIO exports a total amount of 8 interrupt-capable GPIOs.
 
+config MFD_IMANAGER
+	tristate "Advantech iManager Embedded Controller"
+	depends on PCI
+	depends on X86
+	select MFD_CORE
+	help
+	  This is the core driver for Advantech iManager EC as found on some
+	  Advantech SOM, MIO, AIMB, and PCM modules/boards. The EC may provide
+	  functions like GPIO, I2C interface, HW monitoring, Watchdog, and
+	  backlight/brightness control.
+
+	  The following Advantech boards are supported:
+		* All SOM modules newer than SOM-5788
+		* MIO-5250/5251/5270/5271 and newer
+		* PCM-9388
+		* AIMB-274/231
+
+	  This driver can also be built as a module. If so, the module
+	  will be called imanager.
+
 config LPC_ICH
 	tristate "Intel ICH LPC"
 	depends on PCI
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a8b76b8..c9c63d9 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -142,6 +142,8 @@ obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500-prcmu.o
 obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
 obj-$(CONFIG_MFD_TIMBERDALE)    += timberdale.o
 obj-$(CONFIG_PMIC_ADP5520)	+= adp5520.o
+imanager-objs			:= imanager-core.o imanager-ec.o
+obj-$(CONFIG_MFD_IMANAGER)	+= imanager.o
 obj-$(CONFIG_MFD_KEMPLD)	+= kempld-core.o
 obj-$(CONFIG_MFD_INTEL_QUARK_I2C_GPIO)	+= intel_quark_i2c_gpio.o
 obj-$(CONFIG_LPC_SCH)		+= lpc_sch.o
diff --git a/drivers/mfd/imanager-core.c b/drivers/mfd/imanager-core.c
new file mode 100644
index 0000000..9697c144
--- /dev/null
+++ b/drivers/mfd/imanager-core.c
@@ -0,0 +1,288 @@
+/*
+ * Advantech iManager MFD core driver
+ *
+ * Copyright (C) 2016 Advantech Co., Ltd., Irvine, CA, USA
+ * Author: Richard Vidal-Dorsch <richard.dorsch@advantech.com>
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/imanager/core.h>
+#include <linux/mfd/imanager/ec.h>
+
+static struct platform_device *pdev;
+
+enum imanager_cells {
+	IMANAGER_BL,
+	IMANAGER_GPIO,
+	IMANAGER_HWMON,
+	IMANAGER_I2C,
+	IMANAGER_WDT,
+};
+
+static const char * const chip_names[] = {
+	"it8516",
+	"it8518",
+	"it8528",
+	NULL
+};
+
+static struct resource imanager_ioresource = {
+	.start  = IT8516_DAT_PORT,
+	.end    = IT8518_DAT_PORT,
+	.flags  = IORESOURCE_IO,
+};
+
+/*
+ * Devices which are part of the iManager and are available via firmware.
+ */
+static struct mfd_cell imanager_devs[] = {
+	[IMANAGER_BL] = {
+		.name = "imanager_backlight",
+	},
+	[IMANAGER_GPIO] = {
+		.name = "imanager_gpio",
+	},
+	[IMANAGER_HWMON] = {
+		.name = "imanager_hwmon",
+	},
+	[IMANAGER_I2C] = {
+		.name = "imanager_i2c",
+	},
+	[IMANAGER_WDT] = {
+		.name = "imanager_wdt",
+	},
+};
+
+const char *project_type_to_str(int type)
+{
+	const char *version_type;
+
+	switch (type) {
+	case 'V':
+		version_type = "Release";
+		break;
+	case 'X':
+		version_type = "Engineering Sample";
+		break;
+	case 'A' ... 'U':
+		version_type = "Custom";
+		break;
+	default:
+		version_type = "Unknown";
+		break;
+	}
+
+	return version_type;
+}
+
+static ssize_t imanager_name_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	const struct ec_info *info = &pdata->dev->info;
+
+	return scnprintf(buf, PAGE_SIZE, "%s\n", info->pcb_name);
+}
+
+static ssize_t imanager_kversion_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	const struct ec_info *info = &pdata->dev->info;
+
+	return scnprintf(buf, PAGE_SIZE, "%d.%d\n",
+			 info->version.kernel_major,
+			 info->version.kernel_minor);
+}
+
+static ssize_t imanager_fwversion_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	const struct ec_info *info = &pdata->dev->info;
+
+	return scnprintf(buf, PAGE_SIZE, "%d.%d\n",
+			 info->version.firmware_major,
+			 info->version.firmware_minor);
+}
+
+static ssize_t imanager_type_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	const struct ec_info *info = &pdata->dev->info;
+
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			project_type_to_str(info->version.type));
+}
+
+static ssize_t imanager_chip_name_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%s\n", pdata->chip_name);
+}
+
+static DEVICE_ATTR(imanager_name, S_IRUGO, imanager_name_show, NULL);
+static DEVICE_ATTR(imanager_kversion, S_IRUGO, imanager_kversion_show, NULL);
+static DEVICE_ATTR(imanager_fwversion, S_IRUGO, imanager_fwversion_show, NULL);
+static DEVICE_ATTR(imanager_type, S_IRUGO, imanager_type_show, NULL);
+static DEVICE_ATTR(imanager_chip_name, S_IRUGO, imanager_chip_name_show, NULL);
+
+static struct attribute *imanager_core_attributes[] = {
+	&dev_attr_imanager_name.attr,
+	&dev_attr_imanager_kversion.attr,
+	&dev_attr_imanager_fwversion.attr,
+	&dev_attr_imanager_type.attr,
+	&dev_attr_imanager_chip_name.attr,
+	NULL
+};
+
+static const struct attribute_group imanager_core_attr_group = {
+	.attrs = imanager_core_attributes,
+};
+
+static int imanager_platform_create(void)
+{
+	struct device *dev;
+	struct imanager_platform_data platdata;
+	int err;
+
+	pdev = platform_device_alloc("imanager-core", -1);
+	if (!pdev)
+		return -ENOMEM;
+
+	dev = &pdev->dev;
+
+	err = platform_device_add_data(pdev, &platdata, sizeof(platdata));
+	if (err)
+		goto exit_device_put;
+
+	err = platform_device_add_resources(pdev, &imanager_ioresource, 1);
+	if (err)
+		goto exit_device_put;
+
+	err = platform_device_add(pdev);
+	if (err)
+		goto exit_device_put;
+
+	err = mfd_add_devices(dev, pdev->id, imanager_devs,
+		ARRAY_SIZE(imanager_devs), NULL, -1, NULL);
+	if (err)
+		goto exit_device_unregister;
+
+	return 0;
+
+exit_device_unregister:
+	platform_device_unregister(pdev);
+exit_device_put:
+	platform_device_put(pdev);
+
+	return err;
+}
+
+static int imanager_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct imanager_platform_data *pdata = dev_get_platdata(dev);
+	struct imanager_device_data *imanager;
+	int ret;
+
+	if (!pdev)
+		return -EINVAL;
+
+	imanager = devm_kzalloc(dev, sizeof(*imanager), GFP_KERNEL);
+	if (!imanager)
+		return -ENOMEM;
+
+	imanager->dev = dev;
+	mutex_init(&imanager->lock);
+
+	platform_set_drvdata(pdev, imanager);
+
+	pdata->dev = imanager_get_ec_device();
+	pdata->chip_name = chip_names[pdata->dev->id];
+
+	dev_info(dev, "Found Advantech iManager %s - %s %d.%d/%d.%d (%s)\n",
+		 pdata->chip_name,
+		 pdata->dev->info.pcb_name,
+		 pdata->dev->info.version.kernel_major,
+		 pdata->dev->info.version.kernel_minor,
+		 pdata->dev->info.version.firmware_major,
+		 pdata->dev->info.version.firmware_minor,
+		 project_type_to_str(pdata->dev->info.version.type));
+
+	ret = sysfs_create_group(&dev->kobj, &imanager_core_attr_group);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int imanager_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	sysfs_remove_group(&dev->kobj, &imanager_core_attr_group);
+
+	mfd_remove_devices(dev);
+
+	return 0;
+}
+
+static struct platform_driver imanager_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name  = "imanager-core",
+	},
+	.probe	= imanager_probe,
+	.remove	= imanager_remove,
+};
+
+static int __init imanager_init(void)
+{
+	int ret;
+
+	ret = imanager_ec_probe();
+	if (ret < 0)
+		return ret;
+
+	ret = imanager_platform_create();
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&imanager_driver);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void __exit imanager_exit(void)
+{
+	if (pdev)
+		platform_device_unregister(pdev);
+
+	platform_driver_unregister(&imanager_driver);
+}
+
+module_init(imanager_init);
+module_exit(imanager_exit);
+
+MODULE_DESCRIPTION("Advantech iManager Core Driver");
+MODULE_AUTHOR("Richard Vidal-Dorsch <richard.dorsch at advantech.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imanager-core");
diff --git a/drivers/mfd/imanager-ec.c b/drivers/mfd/imanager-ec.c
new file mode 100644
index 0000000..be554ba
--- /dev/null
+++ b/drivers/mfd/imanager-ec.c
@@ -0,0 +1,1345 @@
+/*
+ * Advantech iManager Core - Firmware Interface
+ *
+ * Copyright (C) 2016 Advantech Co., Ltd., Irvine, CA, USA
+ * Author: Richard Vidal-Dorsch <richard.dorsch@advantech.com>
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/bug.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/byteorder/generic.h>
+#include <linux/module.h>
+#include <linux/swab.h>
+#include <linux/mfd/imanager/ec.h>
+
+/**
+ * This is the delay time between two EC transactions.
+ * Values lower than 200us are not encouraged and may
+ * cause I/O errors
+ */
+#define EC_MICRO_DELAY			200
+#define EC_MAX_RETRY			1000
+
+#define EC_MSG_OFFSET_CMD		0UL
+#define EC_MSG_OFFSET_STATUS		1UL
+#define EC_MSG_OFFSET_PARAM		2UL
+#define EC_MSG_OFFSET_DATA(N)		(3UL + N)
+#define EC_MSG_OFFSET_PAYLOAD(N)	(7UL + N)
+
+/* The Device ID registers - 16 bit */
+#define DEVID_REG_MSB			0x20
+#define DEVID_REG_LSB			0x21
+
+/*
+ * IT8528 based firmware require a read/write command offset.
+ */
+#define EC_CMD_OFFSET_READ		0xA0UL
+#define EC_CMD_OFFSET_WRITE		0x50UL
+
+#define EC_STATUS_SUCCESS		BIT(0)
+#define EC_STATUS_CMD_COMPLETE		BIT(7)
+
+#define PCB_NAME_MAX_SIZE		8UL
+#define EC_I2C_BLOCK_SIZE		32
+#define EC_MAX_DID			32UL
+
+#define DID_LABEL_SIZE			24UL
+#define DID_DESC_SIZE			32UL
+
+#define EC_KERNEL_MINOR(x)		(LOBYTE16(x))
+#define EC_KERNEL_MAJOR(x) ({		\
+	typeof(x) __x = (HIBYTE16(x));	\
+	((__x >> 4) * 10 + (__x & 0x000f)); })
+#define EC_FIRMWARE_MINOR(x)		(LOBYTE16(x))
+#define EC_FIRMWARE_MAJOR(x)		EC_KERNEL_MAJOR(x)
+#define EC_PROJECT_CODE(x)		((char)(LOBYTE16(x)))
+
+enum ec_device_type {
+	ADC = 1,
+	DAC,
+	GPIO,
+	IRQ,
+	PWM,
+	SMB,
+	TACH
+};
+
+enum ec_device_id {
+	/* GPIO */
+	ALTGPIO0	= 0x10,
+	ALTGPIO1,
+	ALTGPIO2,
+	ALTGPIO3,
+	ALTGPIO4,
+	ALTGPIO5,
+	ALTGPIO6,
+	ALTGPIO7,
+	/* Button (GPIO) */
+	BUTTON0,
+	BUTTON1,
+	BUTTON2,
+	BUTTON3,
+	BUTTON4,
+	BUTTON5,
+	BUTTON6,
+	BUTTON7,
+	/* FAN */
+	CPUFAN_2P,
+	CPUFAN_4P,
+	SYSFAN1_2P,
+	SYSFAN1_4P,
+	SYSFAN2_2P,
+	SYSFAN2_4P,
+	/* Brightness Control */
+	BRIGHTNESS,
+	/* System Speaker */
+	PCBEEP,
+	/* SMBus */
+	SMBOEM0,
+	SMBOEM1,
+	SMBOEM2,
+	SMBEEPROM,
+	SMBTHERMAL0,
+	SMBTHERMAL1,
+	SMBSECEEP,
+	I2COEM,
+	/* Speaker */
+	SPEAKER		= 0x30,
+	/* SMBus */
+	SMBEEP2K	= 0x38,
+	OEMEEP,
+	OEMEEP2K,
+	PECI,
+	SMBOEM3,
+	SMLINK,
+	SMBSLV,
+	/* LED */
+	POWERLED	= 0x40,
+	BATLEDG,
+	OEMLED0,
+	OEMLED1,
+	OEMLED2,
+	BATLEDR,
+	/* Smart Battery */
+	SMARTBAT1	= 0x48,
+	SMARTBAT2,
+	/* ADC */
+	CMOSBAT		= 0x50,
+	CMOSBATx2,
+	CMOSBATx10,
+	LIBAT,
+	LIBATx2,
+	LIBATx10,
+	ADC5VS0,
+	ADC5VS0x2,
+	ADC5VS0x10,
+	ADC5VS5,
+	ADC5VS5x2,
+	ADC5VS5x10,
+	ADC33VS0,
+	ADC33VS0x2,
+	ADC33VS0x10,
+	ADC33VS5,
+	ADC33VS5x2,	/* 0x60 */
+	ADC33VS5x10,
+	ADC12VS0,
+	ADC12VS0x2,
+	ADC12VS0x10,
+	VCOREA,
+	VCOREAx2,
+	VCOREAx10,
+	VCOREB,
+	VCOREBx2,
+	VCOREBx10,
+	ADCDC,
+	ADCDCx2,
+	ADCDCx10,
+	VSTBY,
+	VSTBYx2,
+	VSTBYx10,	/* 0x70 */
+	VAUX,
+	VAUXx2,
+	VAUXx10,
+	CURRENT,
+	/* Watchdog */
+	WDIRQ		= 0x78,
+	WDNMI,
+	/* FAN Tacho */
+	TACHO0		= 0x80,
+	TACHO1,
+	TACHO2,
+	/* Brightness/Backlight Control */
+	BRIGHTNESS2	= 0x88,
+	BACKLIGHT1,
+	BACKLIGHT2
+};
+
+enum ec_dynamic_table_type {
+	EC_DYN_DID,
+	EC_DYN_HWP,
+	EC_DYN_POL
+};
+
+struct ec_devtbl {
+	int id;
+	int type;
+	int scale;
+	const char label[DID_LABEL_SIZE];
+	const char description[DID_DESC_SIZE];
+};
+
+struct ec_dyn_devtbl {
+	int did;	/* Device ID */
+	int hwp;	/* Hardware Pin */
+	int pol;	/* Polarity */
+	const struct ec_devtbl *devtbl; /* Device table Entry */
+};
+
+struct imanager_data {
+	int (*read)(int cmd);
+	int (*write)(int cmd, int value);
+
+	struct ec_dyn_devtbl dyn[EC_MAX_DID];
+
+	struct imanager_ec_device		dev;
+	struct imanager_hwmon_device		sensors;
+	struct imanager_gpio_device		gpio;
+	struct imanager_i2c_device		i2c;
+	struct imanager_watchdog_device		wdt;
+	struct imanager_backlight_device	blc;
+};
+
+struct ec_version_raw {
+	u16	kernel,
+		chipid,
+		project_code,
+		firmware;
+};
+
+enum ec_ram_type {
+	EC_RAM_ACPI = 1,
+	EC_RAM_HW,
+	EC_RAM_EXT
+};
+
+static struct imanager_data ec;
+
+static const struct ec_devtbl devtbl[] = {
+	{ ALTGPIO0,	GPIO,	-1,	"gpio0" },
+	{ ALTGPIO1,	GPIO,	-1,	"gpio1" },
+	{ ALTGPIO2,	GPIO,	-1,	"gpio2" },
+	{ ALTGPIO3,	GPIO,	-1,	"gpio3" },
+	{ ALTGPIO4,	GPIO,	-1,	"gpio4" },
+	{ ALTGPIO5,	GPIO,	-1,	"gpio5" },
+	{ ALTGPIO6,	GPIO,	-1,	"gpio6" },
+	{ ALTGPIO7,	GPIO,	-1,	"gpio7" },
+	{ BUTTON0,	GPIO,	-1,	"button0" },
+	{ BUTTON1,	GPIO,	-1,	"button1" },
+	{ BUTTON2,	GPIO,	-1,	"button2" },
+	{ BUTTON3,	GPIO,	-1,	"button3" },
+	{ BUTTON4,	GPIO,	-1,	"button4" },
+	{ BUTTON5,	GPIO,	-1,	"button4" },
+	{ BUTTON6,	GPIO,	-1,	"button4" },
+	{ BUTTON7,	GPIO,	-1,	"button4" },
+	{ CPUFAN_2P,	PWM,	2,	"FAN CPU" },
+	{ CPUFAN_4P,	PWM,	4,	"FAN CPU" },
+	{ SYSFAN1_2P,	PWM,	2,	"FAN SYS1" },
+	{ SYSFAN1_4P,	PWM,	4,	"FAN SYS1" },
+	{ SYSFAN2_2P,	PWM,	2,	"FAN SYS2" },
+	{ SYSFAN2_4P,	PWM,	4,	"FAN SYS2" },
+	{ BRIGHTNESS,	PWM,	-1,	"Brightness1" },
+	{ PCBEEP,	PWM,	-1,	"Beep" },
+	{ SMBOEM0,	SMB,	-1,	"SMB1" },
+	{ SMBOEM1,	SMB,	-1,	"SMB2" },
+	{ SMBOEM2,	SMB,	-1,	"SMB3" },
+	{ SMBEEPROM,	SMB,	-1,	"SMBEEP" },
+	{ SMBTHERMAL0,	SMB,	-1,	"SMBTHERM0" },
+	{ SMBTHERMAL1,	SMB,	-1,	"SMBTHERM1" },
+	{ SMBSECEEP,	SMB,	-1,	"SMBSECEEP" },
+	{ I2COEM,	SMB,	-1,	"I2COEM" },
+	{ SPEAKER,	DAC,	-1,	"Speaker" },
+	{ SMBEEP2K,	SMB,	-1,	"SMBEEP2K" },
+	{ OEMEEP,	SMB,	-1,	"OEMEEP" },
+	{ OEMEEP2K,	SMB,	-1,	"OEMEEP2K" },
+	{ PECI,		SMB,	-1,	"SMB_PECI" },
+	{ SMBOEM3,	SMB,	-1,	"SMBOEM3" },
+	{ SMLINK,	SMB,	-1,	"SMLINK" },
+	{ SMBSLV,	SMB,	-1,	"SMBSLV" },
+	{ POWERLED,	GPIO,	-1,	"Power LED" },
+	{ BATLEDG,	GPIO,	-1,	"BATLEDG" },
+	{ OEMLED0,	GPIO,	-1,	"OEMLED0" },
+	{ OEMLED1,	GPIO,	-1,	"OEMLED1" },
+	{ OEMLED2,	GPIO,	-1,	"OEMLED2" },
+	{ BATLEDR,	GPIO,	-1,	"OEMLEDR" },
+	{ SMARTBAT1,	SMB,	-1,	"SmartBat1" },
+	{ SMARTBAT2,	SMB,	-1,	"SmartBat2" },
+	{ CMOSBAT,	ADC,	1,	"VBat" },
+	{ CMOSBATx2,	ADC,	2,	"VBat" },
+	{ CMOSBATx10,	ADC,	10,	"VBat" },
+	{ LIBAT,	ADC,	1,	"VBat2" },
+	{ LIBATx2,	ADC,	2,	"VBat2" },
+	{ LIBATx10,	ADC,	10,	"VBat2" },
+	{ ADC5VS0,	ADC,	1,	"+5V" },
+	{ ADC5VS0x2,	ADC,	2,	"+5V" },
+	{ ADC5VS0x10,	ADC,	10,	"+5V" },
+	{ ADC5VS5,	ADC,	1,	"+5V" },
+	{ ADC5VS5x2,	ADC,	2,	"+5V" },
+	{ ADC5VS5x10,	ADC,	10,	"+5V" },
+	{ ADC33VS0,	ADC,	1,	"+3.3V" },
+	{ ADC33VS0x2,	ADC,	2,	"+3.3V" },
+	{ ADC33VS0x10,	ADC,	10,	"+3.3V" },
+	{ ADC33VS5,	ADC,	1,	"+3.3V" },
+	{ ADC33VS5x2,	ADC,	2,	"+3.3V" },
+	{ ADC33VS5x10,	ADC,	10,	"+3.3V" },
+	{ ADC12VS0,	ADC,	1,	"+12V" },
+	{ ADC12VS0x2,	ADC,	2,	"+12V" },
+	{ ADC12VS0x10,	ADC,	10,	"+12V" },
+	{ VCOREA,	ADC,	1,	"VCore" },
+	{ VCOREAx2,	ADC,	2,	"VCore" },
+	{ VCOREAx10,	ADC,	10,	"VCore" },
+	{ VCOREB,	ADC,	1,	"VCore2" },
+	{ VCOREBx2,	ADC,	2,	"VCore2" },
+	{ VCOREBx10,	ADC,	10,	"VCore2" },
+	{ ADCDC,	ADC,	1,	"ADCDC" },
+	{ ADCDCx2,	ADC,	2,	"ADCDCx2" },
+	{ ADCDCx10,	ADC,	10,	"ADCDCx10" },
+	{ VSTBY,	ADC,	1,	"Vsb" },
+	{ VSTBYx2,	ADC,	2,	"Vsb" },
+	{ VSTBYx10,	ADC,	10,	"Vsb" },
+	{ VAUX,		ADC,	1,	"VAUX" },
+	{ VAUXx2,	ADC,	2,	"VAUX" },
+	{ VAUXx10,	ADC,	10,	"VAUX" },
+	{ CURRENT,	ADC,	1,	"Imon" },
+	{ WDIRQ,	IRQ,	-1,	"WDIRQ" },
+	{ WDNMI,	GPIO,	-1,	"WDNMI" },
+	{ TACHO0,	TACH,	-1,	"Tacho1" },
+	{ TACHO1,	TACH,	-1,	"Tacho2" },
+	{ TACHO2,	TACH,	-1,	"Tacho3" },
+	{ BRIGHTNESS2,	PWM,	-1,	"Brightness2" },
+	{ BACKLIGHT1,	GPIO,	-1,	"Backlight1" },
+	{ BACKLIGHT2,	GPIO,	-1,	"Backlight2" },
+	{ 0, 0, 0, "" }
+};
+
+/**
+ * EC I/O
+ */
+
+static inline void imanager_delay(void)
+{
+	udelay(EC_MICRO_DELAY);
+}
+
+static int wait_ibf_cleared(void)
+{
+	int i = 0;
+
+	do {
+		if (!(inb(IT8516_CMD_PORT) & BIT(1)))
+			return 0;
+		imanager_delay();
+	} while (i++ < EC_MAX_RETRY);
+
+	return -ETIME;
+}
+
+static int wait_obf_set(void)
+{
+	int i = 0;
+
+	do {
+		if (inb(IT8516_CMD_PORT) & BIT(0))
+			return 0;
+		imanager_delay();
+	} while (i++ < EC_MAX_RETRY);
+
+	return -ETIME;
+}
+
+static inline int ec_inb(int addr, int reg)
+{
+	outb(reg, addr);
+	return inb(addr + 1);
+}
+
+static inline void ec_outb(int addr, int reg, int val)
+{
+	outb(reg, addr);
+	outb(val, addr + 1);
+}
+
+static inline int ec_io28_inb(int addr, int reg)
+{
+	int ret;
+
+	ret = wait_ibf_cleared();
+	if (ret)
+		return ret;
+
+	/* clear data to prevent lock */
+	inb(addr - 1);
+
+	outb(reg, addr);
+
+	ret = wait_obf_set();
+	if (ret)
+		return ret;
+
+	return inb(addr - 1);
+}
+
+static inline int ec_io28_outb(int addr, int reg, int val)
+{
+	int ret;
+
+	ret = wait_ibf_cleared();
+	if (ret)
+		return ret;
+
+	outb(reg, addr);
+
+	ret = wait_ibf_cleared();
+	if (ret)
+		return ret;
+
+	outb(val, addr - 1);
+
+	return 0;
+}
+
+static int ec_io18_read(int cmd)
+{
+	return ec_inb(IT8518_CMD_PORT, cmd);
+}
+
+static int ec_io18_write(int cmd, int value)
+{
+	ec_outb(IT8518_CMD_PORT, cmd, value);
+
+	return 0;
+}
+
+static int ec_io28_read(int cmd)
+{
+	return ec_io28_inb(IT8516_CMD_PORT, cmd + EC_CMD_OFFSET_READ);
+}
+
+static int ec_io28_write(int cmd, int value)
+{
+	return ec_io28_outb(IT8516_CMD_PORT, cmd + EC_CMD_OFFSET_WRITE, value);
+}
+
+/* Prevent FW lock */
+static void ec_clear_ports(void)
+{
+	inb(IT8516_DAT_PORT);
+	inb(IT8518_DAT_PORT);
+}
+
+static inline u16 ec_read_chipid(u16 addr)
+{
+	return (ec_inb(addr, DEVID_REG_MSB) << 8 |
+		ec_inb(addr, DEVID_REG_LSB));
+}
+
+static int ec_wait_cmd_clear(void)
+{
+	int i = 0;
+
+	do {
+		if (!ec.read(0))
+			return 0;
+		imanager_delay();
+	} while (i++ < EC_MAX_RETRY);
+
+	pr_err("No respons from EC (timeout)\n");
+
+	return -ETIME;
+}
+
+static int ec_read_ram(u8 bank, u8 offset, u8 len, u8 *buf, u8 bufsz)
+{
+	int i;
+	int ret;
+
+	if (WARN_ON(!buf))
+		return -EINVAL;
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ec.write(EC_MSG_OFFSET_PARAM, bank);
+	ec.write(EC_MSG_OFFSET_DATA(0), offset);
+	ec.write(EC_MSG_OFFSET_DATA(0x2C), len);
+	ec.write(EC_MSG_OFFSET_CMD, EC_CMD_RAM_RD);
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ret = ec.read(EC_MSG_OFFSET_STATUS);
+	if (ret != EC_STATUS_SUCCESS)
+		return -EIO;
+
+	for (i = 0; (i < len) && (len < EC_MSG_SIZE) && (len <= bufsz); i++)
+		buf[i] = ec.read(EC_MSG_OFFSET_DATA(i + 1));
+
+	return 0;
+}
+
+static int ec_write_ram(u8 bank, u8 offset, u8 len, u8 *buf)
+{
+	int i;
+	int ret;
+
+	if (WARN_ON(!buf))
+		return -EINVAL;
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ec.write(EC_MSG_OFFSET_PARAM, bank);
+	ec.write(EC_MSG_OFFSET_DATA(0), offset);
+	ec.write(EC_MSG_OFFSET_DATA(0x2C), len);
+
+	for (i = 0; (i < len) && (len < EC_MSG_SIZE); i++)
+		ec.write(EC_MSG_OFFSET_DATA(i + 1), buf[i]);
+
+	ec.write(EC_MSG_OFFSET_CMD, EC_CMD_RAM_WR);
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ret = ec.read(EC_MSG_OFFSET_STATUS);
+	if (ret != EC_STATUS_SUCCESS)
+		return -EIO;
+
+	return 0;
+}
+
+static int ec_read_dynamic_devtbl(struct imanager_data *ec)
+{
+	u32 i, j;
+	int ret;
+	struct ec_message did = {
+		.rlen = EC_MAX_DID,
+		.wlen = 0,
+	};
+	struct ec_message hwp = {
+		.rlen = EC_MAX_DID,
+		.wlen = 0,
+	};
+	struct ec_message pol = {
+		.rlen = EC_MAX_DID,
+		.wlen = 0,
+	};
+	struct ec_dyn_devtbl *dyn;
+
+	memset(ec->dyn, 0, sizeof(ec->dyn));
+
+	ret = imanager_msg_read(EC_CMD_DYN_TBL_RD, EC_DYN_DID, &did);
+	if (ret)
+		return -EIO;
+
+	ret = imanager_msg_read(EC_CMD_DYN_TBL_RD, EC_DYN_HWP, &hwp);
+	if (ret)
+		return -EIO;
+
+	ret = imanager_msg_read(EC_CMD_DYN_TBL_RD, EC_DYN_POL, &pol);
+	if (ret)
+		return -EIO;
+
+	for (i = 0; (i < EC_MAX_DID) && did.u.data[i]; i++) {
+		dyn = &ec->dyn[i];
+		for (j = 0; j < ARRAY_SIZE(devtbl); j++) {
+			if (devtbl[j].id == did.u.data[i]) {
+				dyn->did = did.u.data[i];
+				dyn->hwp = hwp.u.data[i];
+				dyn->pol = pol.u.data[i];
+				dyn->devtbl = &devtbl[j];
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int ec_read_buffer(u8 *data, int rlen)
+{
+	int ret, i, j;
+	int pages = rlen % EC_I2C_BLOCK_SIZE;
+	int rem = rlen / EC_I2C_BLOCK_SIZE;
+
+	/* pre-condition: rlen <= 256 */
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	for (i = 0; i < pages; i++) {
+		ec.write(EC_MSG_OFFSET_PARAM, i);
+		ec.write(EC_MSG_OFFSET_CMD, EC_CMD_BUF_RD);
+
+		ret = ec_wait_cmd_clear();
+		if (ret)
+			return ret;
+
+		ret = ec.read(EC_MSG_OFFSET_STATUS);
+		if (ret != EC_STATUS_SUCCESS)
+			return -EIO;
+
+		for (j = 0; j < EC_I2C_BLOCK_SIZE; j++)
+			data[i * EC_I2C_BLOCK_SIZE + j] =
+				ec.read(EC_MSG_OFFSET_DATA(j));
+	}
+
+	if (rem) {
+		ec.write(EC_MSG_OFFSET_PARAM, pages);
+		ec.write(EC_MSG_OFFSET_CMD, EC_CMD_BUF_RD);
+
+		ret = ec_wait_cmd_clear();
+		if (ret)
+			return ret;
+
+		ret = ec.read(EC_MSG_OFFSET_STATUS);
+		if (ret != EC_STATUS_SUCCESS)
+			return -EIO;
+
+		for (j = 0; j < rem; j++)
+			data[pages * EC_I2C_BLOCK_SIZE + j] =
+				ec.read(EC_MSG_OFFSET_DATA(j));
+	}
+
+	return 0;
+}
+
+static int
+imanager_msg_trans(u8 cmd, u8 param, struct ec_message *msg, bool payload)
+{
+	int ret, i, len;
+	u32 offset;
+
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	ec.write(EC_MSG_OFFSET_PARAM, param);
+
+	if (msg && msg->wlen) {
+		if (!msg->data) {
+			for (i = 0; i < msg->wlen; i++)
+				ec.write(EC_MSG_OFFSET_DATA(i),
+					msg->u.data[i]);
+		} else {
+			for (i = 0; i < msg->wlen; i++)
+				ec.write(EC_MSG_OFFSET_DATA(i), msg->data[i]);
+			ec.write(EC_MSG_OFFSET_DATA(0x2c), msg->wlen);
+		}
+	}
+
+	ec.write(EC_MSG_OFFSET_CMD, cmd);
+	ret = ec_wait_cmd_clear();
+	if (ret)
+		return ret;
+
+	/* GPIO and I2C have different success return values */
+	ret = ec.read(EC_MSG_OFFSET_STATUS);
+	if ((ret != EC_STATUS_SUCCESS) && !(ret & EC_STATUS_CMD_COMPLETE))
+		return -EIO;
+	/*
+	 * EC I2C may return an error code which we need to hand-off
+	 * to the caller
+	 */
+	else if (ret & 0x07e)
+		return ret;
+
+	if (msg && msg->data) {
+		ret = ec_read_buffer(msg->data, msg->rlen);
+		if (ret < 0)
+			return ret;
+	} else if (msg && msg->rlen) {
+		if (msg->rlen == 0xff)
+			/* Use alternate message body for hwmon */
+			len = ec.read(EC_MSG_OFFSET_DATA(0x2C));
+		else
+			len = (msg->rlen > EC_MSG_SIZE ? EC_MSG_SIZE :
+				msg->rlen);
+		offset = payload ? EC_MSG_OFFSET_PAYLOAD(0) :
+				EC_MSG_OFFSET_DATA(0);
+		for (i = 0; i < len; i++)
+			msg->u.data[i] = ec.read(offset + i);
+	}
+
+	return 0;
+}
+
+int imanager_msg_read(u8 cmd, u8 param, struct ec_message *msg)
+{
+	return imanager_msg_trans(cmd, param, msg, false);
+}
+EXPORT_SYMBOL_GPL(imanager_msg_read);
+
+int imanager_msg_write(u8 cmd, u8 param, struct ec_message *msg)
+{
+	return imanager_msg_trans(cmd, param, msg, true);
+}
+EXPORT_SYMBOL_GPL(imanager_msg_write);
+
+int imanager_read_byte(u8 cmd, u8 param)
+{
+	int ret;
+	struct ec_message msg = {
+		.rlen = 1,
+		.wlen = 0,
+	};
+
+	ret = imanager_msg_read(cmd, param, &msg);
+	if (ret)
+		return ret;
+
+	return msg.u.data[0];
+}
+EXPORT_SYMBOL_GPL(imanager_read_byte);
+
+int imanager_read_word(u8 cmd, u8 param)
+{
+	int ret;
+	struct ec_message msg = {
+		.rlen = 2,
+		.wlen = 0,
+	};
+
+	ret = imanager_msg_read(cmd, param, &msg);
+	if (ret)
+		return ret;
+
+	return (msg.u.data[0] << 8 | msg.u.data[1]);
+}
+EXPORT_SYMBOL_GPL(imanager_read_word);
+
+int imanager_write_byte(u8 cmd, u8 param, u8 byte)
+{
+	struct ec_message msg = {
+		.rlen = 0,
+		.wlen = 1,
+		.u = {
+			.data = { byte, 0 },
+		},
+	};
+
+	return imanager_msg_write(cmd, param, &msg);
+}
+EXPORT_SYMBOL_GPL(imanager_write_byte);
+
+int imanager_write_word(u8 cmd, u8 param, u16 word)
+{
+	struct ec_message msg = {
+		.rlen = 0,
+		.wlen = 2,
+		.u = {
+			.data = { HIBYTE16(word), LOBYTE16(word), 0 },
+		},
+	};
+
+	return imanager_msg_write(cmd, param, &msg);
+}
+EXPORT_SYMBOL_GPL(imanager_write_word);
+
+static int ec_hwram_read_byte(u8 offset)
+{
+	int ret;
+	u8 val;
+
+	ret = ec_read_ram(EC_RAM_HW, offset, sizeof(val), &val, sizeof(val));
+	if (ret < 0) {
+		pr_err("Failed to read from HWRAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return val;
+}
+
+int imanager_acpiram_read_byte(u8 offset)
+{
+	int ret;
+	u8 value;
+
+	ret = ec_read_ram(EC_RAM_ACPI, offset, sizeof(value), (u8 *)&value,
+			  sizeof(value));
+	if (ret < 0) {
+		pr_err("Failed to read from ACPI RAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return value;
+}
+EXPORT_SYMBOL_GPL(imanager_acpiram_read_byte);
+
+int imanager_acpiram_write_byte(u8 offset, u8 value)
+{
+	int ret;
+
+	ret = ec_write_ram(EC_RAM_ACPI, offset, sizeof(value), &value);
+	if (ret) {
+		pr_err("Failed to write to ACPI RAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(imanager_acpiram_write_byte);
+
+int imanager_acpiram_read_block(u8 offset, u8 *buf, u8 len)
+{
+	int ret;
+
+	ret = ec_read_ram(EC_RAM_ACPI, offset, len, buf, len);
+	if (ret < 0) {
+		pr_err("Failed to read from ACPI RAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(imanager_acpiram_read_block);
+
+int imanager_acpiram_write_block(u8 offset, u8 *buf, u8 len)
+{
+	int ret;
+
+	ret = ec_write_ram(EC_RAM_ACPI, offset, len, buf);
+	if (ret) {
+		pr_err("Failed to write to ACPI RAM @ 0x%02X\n", offset);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(imanager_acpiram_write_block);
+
+int imanager_wait_proc_complete(u8 offset, int cond)
+{
+	int ret, i;
+
+	for (i = 0; i < EC_MAX_RETRY; i++) {
+		ret = ec_hwram_read_byte(offset);
+		if (ret < 0)
+			return ret;
+
+		if (ret == cond)
+			return 0;
+
+		imanager_delay();
+	}
+
+	return -EIO;
+}
+EXPORT_SYMBOL_GPL(imanager_wait_proc_complete);
+
+static inline void ec_get_dev_attr(struct ec_dev_attr *attr,
+				   const struct ec_dyn_devtbl *tbl)
+{
+	attr->did = tbl->did;
+	attr->hwp = tbl->hwp;
+	attr->pol = tbl->pol;
+	attr->scale = tbl->devtbl->scale;
+	attr->label = tbl->devtbl->label;
+}
+
+static int ec_get_dev_gpio(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct imanager_gpio_device *gpio = &ec->gpio;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == GPIO)) {
+			switch (dyn->did) {
+			case ALTGPIO0:
+				ec_get_dev_attr(&gpio->attr[0], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO1:
+				ec_get_dev_attr(&gpio->attr[1], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO2:
+				ec_get_dev_attr(&gpio->attr[2], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO3:
+				ec_get_dev_attr(&gpio->attr[3], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO4:
+				ec_get_dev_attr(&gpio->attr[4], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO5:
+				ec_get_dev_attr(&gpio->attr[5], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO6:
+				ec_get_dev_attr(&gpio->attr[6], dyn);
+				gpio->num++;
+				break;
+			case ALTGPIO7:
+				ec_get_dev_attr(&gpio->attr[7], dyn);
+				gpio->num++;
+				break;
+			case BUTTON0:
+			case BUTTON1:
+			case BUTTON2:
+			case BUTTON3:
+			case BUTTON4:
+			case BUTTON5:
+			case BUTTON6:
+			case BUTTON7:
+			case POWERLED:
+			case BATLEDG:
+			case OEMLED0:
+			case OEMLED1:
+			case OEMLED2:
+			case BATLEDR:
+			case WDNMI:
+			case BACKLIGHT1:
+			case BACKLIGHT2:
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	gpio->info = &ec->dev.info;
+
+	return 0;
+}
+
+static int ec_get_dev_adc(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct dev_adc *adc = &ec->sensors.adc;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == ADC)) {
+			switch (dyn->did) {
+			case ADC12VS0:
+			case ADC12VS0x2:
+			case ADC12VS0x10:
+				ec_get_dev_attr(&adc->attr[0], dyn);
+				adc->num++;
+				break;
+			case ADC5VS5:
+			case ADC5VS5x2:
+			case ADC5VS5x10:
+				ec_get_dev_attr(&adc->attr[1], dyn);
+				adc->num++;
+				break;
+			case CMOSBAT:
+			case CMOSBATx2:
+			case CMOSBATx10:
+				ec_get_dev_attr(&adc->attr[2], dyn);
+				adc->num++;
+				break;
+			case VCOREA:
+			case ADC5VS0:
+			case ADC5VS0x2:
+			case ADC5VS0x10:
+				ec_get_dev_attr(&adc->attr[3], dyn);
+				adc->num++;
+				break;
+			case CURRENT:
+			case ADC33VS0:
+			case ADC33VS0x2:
+			case ADC33VS0x10:
+				ec_get_dev_attr(&adc->attr[4], dyn);
+				adc->num++;
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int ec_get_dev_fan(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct dev_fan *fan = &ec->sensors.fan;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && ((dyn->devtbl->type == TACH) ||
+				 (dyn->devtbl->type == PWM))) {
+			switch (dyn->did) {
+			case CPUFAN_2P:
+			case CPUFAN_4P:
+				ec_get_dev_attr(&fan->attr[0], dyn);
+				fan->num++;
+				fan->active |= 1 << 0;
+				break;
+			case SYSFAN1_2P:
+			case SYSFAN1_4P:
+				ec_get_dev_attr(&fan->attr[1], dyn);
+				fan->num++;
+				fan->active |= 1 << 1;
+				break;
+			case SYSFAN2_2P:
+			case SYSFAN2_4P:
+				ec_get_dev_attr(&fan->attr[2], dyn);
+				fan->num++;
+				fan->active |= 1 << 2;
+				break;
+			case TACHO0:
+			case TACHO1:
+			case TACHO2:
+			case BRIGHTNESS:
+			case BRIGHTNESS2:
+			case PCBEEP:
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int ec_get_dev_hwmon(struct imanager_data *ec)
+{
+	int ret;
+
+	ret = ec_get_dev_adc(ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_fan(ec);
+	if (ret < 0)
+		return ret;
+
+	ec->sensors.ecdev = &ec->dev;
+
+	return 0;
+}
+
+static int ec_get_dev_i2c(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct imanager_i2c_device *i2c = &ec->i2c;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == SMB)) {
+			switch (dyn->did) {
+			case SMBEEPROM:
+				ec_get_dev_attr(&i2c->attr[0], dyn);
+				i2c->eeprom = &i2c->attr[0];
+				i2c->num++;
+				break;
+			case I2COEM:
+				ec_get_dev_attr(&i2c->attr[1], dyn);
+				i2c->i2coem = &i2c->attr[1];
+				i2c->num++;
+				break;
+			case SMBOEM0:
+			case SMBOEM1:
+			case SMBOEM2:
+			case SMBTHERMAL0:
+			case SMBTHERMAL1:
+			case SMBSECEEP:
+			case SMBEEP2K:
+			case OEMEEP:
+			case OEMEEP2K:
+			case PECI:
+			case SMBOEM3:
+			case SMLINK:
+			case SMBSLV:
+			case SMARTBAT1:
+			case SMARTBAT2:
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	i2c->ecdev = &ec->dev;
+
+	return 0;
+}
+
+static int ec_get_dev_blc(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct imanager_backlight_device *blc = &ec->blc;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == PWM)) {
+			switch (dyn->did) {
+			case BRIGHTNESS:
+				ec_get_dev_attr(&blc->attr[0], dyn);
+				blc->brightness[0] = EC_ACPIRAM_BRIGHTNESS1;
+				blc->num++;
+				break;
+			case BRIGHTNESS2:
+				ec_get_dev_attr(&blc->attr[1], dyn);
+				blc->brightness[1] = EC_ACPIRAM_BRIGHTNESS2;
+				blc->num++;
+				break;
+			case CPUFAN_2P:
+			case CPUFAN_4P:
+			case SYSFAN1_2P:
+			case SYSFAN1_4P:
+			case SYSFAN2_2P:
+			case SYSFAN2_4P:
+			case PCBEEP:
+			case TACHO0:
+			case TACHO1:
+			case TACHO2:
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	blc->info = &ec->dev.info;
+
+	return 0;
+}
+
+static int ec_get_dev_wdt(struct imanager_data *ec)
+{
+	size_t i;
+	struct ec_dyn_devtbl *dyn;
+	struct imanager_watchdog_device *wdt = &ec->wdt;
+
+	for (i = 0; i < ARRAY_SIZE(ec->dyn); i++) {
+		dyn = &ec->dyn[i];
+		if (dyn->did && (dyn->devtbl->type == IRQ)) {
+			switch (dyn->did) {
+			case WDIRQ:
+				ec_get_dev_attr(&wdt->attr[0], dyn);
+				wdt->irq = &wdt->attr[0];
+				wdt->num++;
+				break;
+			case WDNMI:
+				ec_get_dev_attr(&wdt->attr[1], dyn);
+				wdt->nmi = &wdt->attr[1];
+				wdt->num++;
+				break;
+			default:
+				pr_err("DID 0x%02X not handled\n", dyn->did);
+				return -EINVAL;
+			}
+		}
+	}
+
+	wdt->info = &ec->dev.info;
+
+	return 0;
+}
+
+const struct imanager_ec_device *imanager_get_ec_device(void)
+{
+	return &ec.dev;
+};
+EXPORT_SYMBOL_GPL(imanager_get_ec_device);
+
+const struct imanager_hwmon_device *imanager_get_hwmon_device(void)
+{
+	return &ec.sensors;
+}
+EXPORT_SYMBOL_GPL(imanager_get_hwmon_device);
+
+const struct imanager_gpio_device *imanager_get_gpio_device(void)
+{
+	return &ec.gpio;
+}
+EXPORT_SYMBOL_GPL(imanager_get_gpio_device);
+
+const struct imanager_i2c_device *imanager_get_i2c_device(void)
+{
+	return &ec.i2c;
+}
+EXPORT_SYMBOL_GPL(imanager_get_i2c_device);
+
+const struct imanager_backlight_device *imanager_get_backlight_device(void)
+{
+	return &ec.blc;
+}
+EXPORT_SYMBOL_GPL(imanager_get_backlight_device);
+
+const struct imanager_watchdog_device *imanager_get_watchdog_device(void)
+{
+	return &ec.wdt;
+}
+EXPORT_SYMBOL_GPL(imanager_get_watchdog_device);
+
+static int ec_get_version(struct ec_version *version)
+{
+	int ret;
+	u16 raw;
+	struct ec_version_raw ver;
+
+	if (WARN_ON(!version))
+		return -EINVAL;
+
+	ret = ec_read_ram(EC_RAM_ACPI, EC_ACPIRAM_FW_RELEASE_RD, sizeof(ver),
+			 (u8 *)&ver, sizeof(ver));
+	if (ret < 0)
+		return ret;
+
+	raw = swab16(ver.kernel);
+	version->kernel_major = EC_KERNEL_MAJOR(raw);
+	version->kernel_minor = EC_KERNEL_MINOR(raw);
+
+	raw = swab16(ver.firmware);
+	version->firmware_major = EC_FIRMWARE_MAJOR(raw);
+	version->firmware_minor = EC_FIRMWARE_MINOR(raw);
+
+	raw = swab16(ver.project_code);
+	version->type = EC_PROJECT_CODE(raw);
+
+	return 0;
+}
+
+static int ec_get_pcb_name(struct ec_info *info)
+{
+	int ret;
+	struct ec_message msg = {
+		.rlen = ARRAY_SIZE(info->pcb_name),
+		.wlen = 0,
+	};
+
+	if (WARN_ON(!info))
+		return -EINVAL;
+
+	ret = imanager_msg_read(EC_CMD_FW_INFO_RD, 0, &msg);
+	if (ret)
+		return ret;
+
+	/*
+	 * Sadly, the string is not Null-terminated so we will need to read a
+	 * fixed amount of chars. There is, apparently, no exact definition
+	 * of board name (SOM6867 vs. MIO-5271).
+	 */
+	memset(info->pcb_name, 0, ARRAY_SIZE(info->pcb_name));
+	strncpy(info->pcb_name, (const char *)msg.u.data, PCB_NAME_MAX_SIZE);
+
+	if (strchr(info->pcb_name, '-') == NULL)
+		info->pcb_name[PCB_NAME_MAX_SIZE - 1] = '\0';
+
+	return 0;
+}
+
+static int ec_get_fw_info(struct ec_info *info)
+{
+	int ret;
+
+	if (WARN_ON(!info))
+		return -EINVAL;
+
+	ret = ec_get_version(&info->version);
+	if (ret)
+		return ret;
+
+	return ec_get_pcb_name(info);
+}
+
+static int ec_init(void)
+{
+	int ret;
+
+	ec_clear_ports();
+
+	ret = ec_read_dynamic_devtbl(&ec);
+	if (ret)
+		return ret;
+
+	ret = ec_get_fw_info(&ec.dev.info);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_gpio(&ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_hwmon(&ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_i2c(&ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_blc(&ec);
+	if (ret < 0)
+		return ret;
+
+	ret = ec_get_dev_wdt(&ec);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int imanager_ec_probe(void)
+{
+	int chipid = ec_read_chipid(EC_BASE_ADDR);
+
+	memset((void *)&ec, 0, sizeof(ec));
+
+	switch (chipid) {
+	case EC_DEVID_IT8516:
+		pr_err("EC IT8516 not supported\n");
+		ec.dev.id = IT8516;
+		return -ENODEV;
+	case EC_DEVID_IT8518:
+		ec.read = ec_io18_read;
+		ec.write = ec_io18_write;
+		ec.dev.id = IT8518;
+		break;
+	case EC_DEVID_IT8528:
+		ec.read = ec_io28_read;
+		ec.write = ec_io28_write;
+		ec.dev.id = IT8528;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	ec.dev.addr = EC_BASE_ADDR;
+
+	return ec_init();
+}
+
diff --git a/include/linux/mfd/imanager/core.h b/include/linux/mfd/imanager/core.h
new file mode 100644
index 0000000..05c77fa
--- /dev/null
+++ b/include/linux/mfd/imanager/core.h
@@ -0,0 +1,31 @@
+/*
+ * Advantech iManager MFD core
+ *
+ * Copyright (C) 2016 Advantech Co., Ltd., Irvine, CA, USA
+ * Author: Richard Vidal-Dorsch <richard.dorsch@advantech.com>
+ *
+ * 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.
+ */
+
+#ifndef __CORE_H__
+#define __CORE_H__
+
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/mfd/imanager/ec.h>
+
+struct imanager_platform_data {
+	const struct imanager_ec_device *dev;
+	const char *chip_name;
+};
+
+struct imanager_device_data {
+	struct device *dev;
+	struct mutex  lock;
+};
+
+#endif
diff --git a/include/linux/mfd/imanager/ec.h b/include/linux/mfd/imanager/ec.h
new file mode 100644
index 0000000..783f268
--- /dev/null
+++ b/include/linux/mfd/imanager/ec.h
@@ -0,0 +1,210 @@
+/*
+ * Advantech iManager core - firmware interface
+ *
+ * Copyright (C) 2016 Advantech Co., Ltd., Irvine, CA, USA
+ * Author: Richard Vidal-Dorsch <richard.dorsch@advantech.com>
+ *
+ * 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.
+ */
+
+#ifndef __EC_H__
+#define __EC_H__
+
+#include <linux/types.h>
+
+#define EC_DEVID_IT8516			0x8516
+#define EC_DEVID_IT8518			0x8518
+#define EC_DEVID_IT8528			0x8528
+
+#define EC_BASE_ADDR			0x029C
+
+#define IT8516_CMD_PORT			0x029A /* it8528 */
+#define IT8516_DAT_PORT			0x0299
+
+#define IT8518_CMD_PORT			0x029E /* it8518 */
+#define IT8518_DAT_PORT			0x029F
+
+#define EC_GPIO_MAX_NUM			8
+#define EC_HWM_MAX_ADC			5
+#define EC_HWM_MAX_FAN			3
+#define EC_BLC_MAX_NUM			2
+#define EC_SMB_MAX_NUM			4
+#define EC_WDT_MAX_NUM			2
+
+#define PCB_NAME_SIZE			32
+#define EC_PAYLOAD_SIZE			40
+#define EC_MSG_SIZE			sizeof(struct ec_smb_message)
+
+#define LOBYTE16(x)			(x & 0x00FF)
+#define HIBYTE16(x)			(LOBYTE16(x >> 8))
+#define LOADDR16(x)			LOBYTE16(x)
+#define HIADDR16(x)			(x >= 0xF000 ? LOBYTE16(x >> 8) : 0)
+
+/*
+ * iManager commands
+ */
+#define EC_CMD_HWP_RD			0x11UL
+#define EC_CMD_HWP_WR			0x12UL
+#define EC_CMD_GPIO_DIR_RD		0x30UL
+#define EC_CMD_GPIO_DIR_WR		0x31UL
+#define EC_CMD_PWM_FREQ_RD		0x36UL
+#define EC_CMD_PWM_FREQ_WR		0x32UL
+#define EC_CMD_PWM_POL_RD		0x37UL
+#define EC_CMD_PWM_POL_WR		0x33UL
+#define EC_CMD_SMB_FREQ_RD		0x34UL
+#define EC_CMD_SMB_FREQ_WR		0x35UL
+#define EC_CMD_FAN_CTL_RD		0x40UL
+#define EC_CMD_FAN_CTL_WR		0x41UL
+#define EC_CMD_THZ_RD			0x42UL
+#define EC_CMD_DYN_TBL_RD		0x20UL
+#define EC_CMD_FW_INFO_RD		0xF0UL
+#define EC_CMD_BUF_CLR			0xC0UL
+#define EC_CMD_BUF_RD			0xC1UL
+#define EC_CMD_BUF_WR			0xC2UL
+#define EC_CMD_RAM_RD			0x1EUL
+#define EC_CMD_RAM_WR			0x1FUL
+#define EC_CMD_I2C_RW			0x0EUL
+#define EC_CMD_I2C_WR			0x0FUL
+#define EC_CMD_WDT_CTRL			0x28UL
+
+/*
+ * ACPI and HW RAM offsets
+ */
+#define EC_ACPIRAM_FAN_ALERT		0x6FUL
+#define EC_ACPIRAM_FAN_SPEED_LIMIT	0x76UL
+#define EC_ACPIRAM_BRIGHTNESS1		0x50UL
+#define EC_ACPIRAM_BRIGHTNESS2		0x52UL
+#define EC_ACPIRAM_BLC_CTRL		0x99UL
+#define EC_ACPIRAM_FW_RELEASE_RD	0xF8UL
+
+enum chips { IT8516, IT8518, IT8528 };
+
+struct ec_message_header {
+	u8 addr_low;	/* SMB low-byte address or data low-byte */
+			/* of byte-/word-transaction */
+	u8 addr_high;	/* SMB high-byte address or data high-byte */
+			/* of word-transaction */
+	u8 rlen;	/* SMB read length */
+	u8 wlen;	/* SMB write length */
+	u8 cmd;		/* SMB command */
+};
+
+struct ec_smb_message {
+	struct ec_message_header hdr;
+	u8 data[EC_PAYLOAD_SIZE];
+};
+
+struct ec_message {
+	u8 rlen;	/* EC message read length */
+	u8 wlen;	/* EC message write length */
+	union {
+		struct ec_smb_message smb;
+		u8 data[EC_MSG_SIZE];
+	} u;
+
+	u8 *data;
+};
+
+struct ec_version {
+	u32 kernel_major;
+	u32 kernel_minor;
+	u32 firmware_major;
+	u32 firmware_minor;
+	u32 type;
+};
+
+struct ec_info {
+	struct ec_version version;
+	char pcb_name[PCB_NAME_SIZE];
+};
+
+struct imanager_ec_device {
+	int		id; /* enum chip */
+	u16		addr;
+	struct ec_info	info;
+};
+
+struct ec_dev_attr {
+	int did;	/* Device ID */
+	int hwp;	/* Hardware Pin number */
+	int pol;	/* Polarity */
+	int scale;	/* Scaling factor */
+	const char *label;
+};
+
+struct imanager_gpio_device {
+	u32			num;
+	struct ec_dev_attr	attr[EC_GPIO_MAX_NUM];
+	struct ec_info		*info;
+};
+
+struct dev_adc {
+	u32			num;
+	struct ec_dev_attr	attr[EC_HWM_MAX_ADC];
+};
+
+struct dev_fan {
+	u32			num;
+	u32			active;
+	struct ec_dev_attr	attr[EC_HWM_MAX_FAN];
+};
+
+struct imanager_hwmon_device {
+	struct dev_adc		adc;
+	struct dev_fan		fan;
+	struct imanager_ec_device *ecdev;
+};
+
+struct imanager_i2c_device {
+	u32			num;
+	struct ec_dev_attr	attr[EC_SMB_MAX_NUM];
+	struct ec_dev_attr	*eeprom;
+	struct ec_dev_attr	*i2coem;
+	struct imanager_ec_device *ecdev;
+};
+
+struct imanager_backlight_device {
+	u32			num;
+	struct ec_dev_attr	attr[EC_BLC_MAX_NUM];
+	u8			brightness[EC_BLC_MAX_NUM];
+	struct ec_info		*info;
+};
+
+struct imanager_watchdog_device {
+	u32			num;
+	struct ec_dev_attr	attr[EC_WDT_MAX_NUM];
+	struct ec_dev_attr	*irq;
+	struct ec_dev_attr	*nmi;
+	struct ec_info		*info;
+};
+
+/* Must be called first, obviously */
+int imanager_ec_probe(void);
+
+int imanager_msg_write(u8 cmd, u8 param, struct ec_message *msg);
+int imanager_msg_read(u8 cmd, u8 param, struct ec_message *msg);
+
+int imanager_read_byte(u8 cmd, u8 param);
+int imanager_read_word(u8 cmd, u8 param);
+
+int imanager_write_byte(u8 cmd, u8 param, u8 byte);
+int imanager_write_word(u8 cmd, u8 param, u16 word);
+
+int imanager_acpiram_read_byte(u8 offset);
+int imanager_acpiram_write_byte(u8 offset, u8 value);
+int imanager_acpiram_read_block(u8 offset, u8 *buf, u8 len);
+int imanager_acpiram_write_block(u8 offset, u8 *buf, u8 len);
+
+int imanager_wait_proc_complete(u8 offset, int cond);
+
+const struct imanager_ec_device *imanager_get_ec_device(void);
+const struct imanager_hwmon_device *imanager_get_hwmon_device(void);
+const struct imanager_gpio_device *imanager_get_gpio_device(void);
+const struct imanager_i2c_device *imanager_get_i2c_device(void);
+const struct imanager_watchdog_device *imanager_get_watchdog_device(void);
+const struct imanager_backlight_device *imanager_get_backlight_device(void);
+
+#endif
-- 
2.6.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2016-01-10  9:10   ` richard.dorsch
@ 2016-01-10 10:11     ` kbuild test robot
  -1 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:11 UTC (permalink / raw)
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/mfd/imanager-core.c:248:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-core.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/mfd/imanager-core.c
+++ b/drivers/mfd/imanager-core.c
@@ -245,7 +245,6 @@ static int imanager_remove(struct platfo
 
 static struct platform_driver imanager_driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name  = "imanager-core",
 	},
 	.probe	= imanager_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 1/6] Add Advantech iManager MFD core driver
  2016-01-10  9:10   ` richard.dorsch
@ 2016-01-10 10:11 ` kbuild test robot
  -1 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:11 UTC (permalink / raw)
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

Hi Richard,

[auto build test WARNING on hwmon/hwmon-next]
[also build test WARNING on v4.4-rc8 next-20160108]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/richard-dorsch-gmail-com/Add-Advantech-iManager-EC-driver-set/20160110-171635
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next


coccinelle warnings: (new ones prefixed by >>)

>> drivers/mfd/imanager-core.c:248:3-8: No need to set .owner here. The core will do it.

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-01-10 10:11     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:11 UTC (permalink / raw)
  To: richard.dorsch
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/mfd/imanager-core.c:248:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-core.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/mfd/imanager-core.c
+++ b/drivers/mfd/imanager-core.c
@@ -245,7 +245,6 @@ static int imanager_remove(struct platfo
 
 static struct platform_driver imanager_driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name  = "imanager-core",
 	},
 	.probe	= imanager_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH v2 1/6] Add Advantech iManager MFD core driver
@ 2016-01-10 10:11 ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:11 UTC (permalink / raw)
  To: richard.dorsch
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

Hi Richard,

[auto build test WARNING on hwmon/hwmon-next]
[also build test WARNING on v4.4-rc8 next-20160108]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/richard-dorsch-gmail-com/Add-Advantech-iManager-EC-driver-set/20160110-171635
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next


coccinelle warnings: (new ones prefixed by >>)

>> drivers/mfd/imanager-core.c:248:3-8: No need to set .owner here. The core will do it.

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
       [not found] <201906240241.S3kwAGar%lkp@intel.com>
@ 2019-06-23 18:50 ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2019-06-23 18:50 UTC (permalink / raw)
  To: Asmaa Mnebhi
  Cc: kbuild-all, Corey Minyard, Arnd Bergmann, Greg Kroah-Hartman,
	openipmi-developer, linux-kernel

From: kbuild test robot <lkp@intel.com>

drivers/char/ipmi/ipmb_dev_int.c:352:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

Fixes: 51bd6f291583 ("Add support for IPMB driver")
CC: Asmaa Mnebhi <Asmaa@mellanox.com>
Signed-off-by: kbuild test robot <lkp@intel.com>
---

tree:   https://github.com/cminyard/linux-ipmi for-next
head:   21feadd024e747123bc0aaba8d8cbef2b5eda058
commit: 51bd6f291583684f495ea498984dfc22049d7fd2 [5/7] Add support for IPMB driver

 ipmb_dev_int.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/char/ipmi/ipmb_dev_int.c
+++ b/drivers/char/ipmi/ipmb_dev_int.c
@@ -349,7 +349,6 @@ MODULE_DEVICE_TABLE(acpi, acpi_ipmb_id);
 
 static struct i2c_driver ipmb_driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name = "ipmb-dev",
 		.acpi_match_table = ACPI_PTR(acpi_ipmb_id),
 	},

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2018-12-30  5:10 [nomadik:ixp4 4/9] drivers/gpio/gw_i2c_pld.c:25:10: fatal error: linux/i2c/gw_i2c_pld.h: No such file or directory kbuild test robot
@ 2018-12-30  5:10 ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2018-12-30  5:10 UTC (permalink / raw)
  To: Linus Walleij; +Cc: kbuild-all, linux-arm-kernel

From: kbuild test robot <fengguang.wu@intel.com>

drivers/gpio/gw_i2c_pld.c:351:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

Fixes: 443f1c782cc7 ("GW i2c PLF GPIO")
Signed-off-by: kbuild test robot <fengguang.wu@intel.com>
---

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4
head:   fd04bd59327ab42cfa79c1a5aaa3160fc4821402
commit: 443f1c782cc742e40a1ef4cb2bca0afa2fea9baf [4/9] GW i2c PLF GPIO

 gw_i2c_pld.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/gpio/gw_i2c_pld.c
+++ b/drivers/gpio/gw_i2c_pld.c
@@ -348,7 +348,6 @@ static int gw_i2c_pld_remove(struct i2c_
 static struct i2c_driver gw_i2c_pld_driver = {
 	.driver = {
 		.name	= "gw_i2c_pld",
-		.owner	= THIS_MODULE,
 	},
 	.probe	= gw_i2c_pld_probe,
 	.remove	= gw_i2c_pld_remove,

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2017-02-20 10:33 ` Patrick Vogelaar
@ 2017-02-20 12:05     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2017-02-20 12:05 UTC (permalink / raw)
  To: Patrick Vogelaar
  Cc: kbuild-all, dmitry.torokhov, linux-kernel, devicetree,
	linux-input, Patrick Vogelaar

drivers/input/misc/cy8cmbr3102.c:210:4-9: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Patrick Vogelaar <Patrick.Vogelaar@gigatronik.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 cy8cmbr3102.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/input/misc/cy8cmbr3102.c
+++ b/drivers/input/misc/cy8cmbr3102.c
@@ -207,7 +207,6 @@ MODULE_DEVICE_TABLE(of, of_cy8cmbr3102_m
 static struct i2c_driver cy8cmbr3102_driver = {
 		.driver			= {
 			.name		= "cy8cmbr3102",
-			.owner		= THIS_MODULE,
 			.of_match_table	= of_match_ptr(of_cy8cmbr3102_match),
 		},
 		.probe = cy8cmbr3102_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2017-02-20 12:05     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2017-02-20 12:05 UTC (permalink / raw)
  Cc: kbuild-all, dmitry.torokhov, linux-kernel, devicetree,
	linux-input, Patrick Vogelaar

drivers/input/misc/cy8cmbr3102.c:210:4-9: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Patrick Vogelaar <Patrick.Vogelaar@gigatronik.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 cy8cmbr3102.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/input/misc/cy8cmbr3102.c
+++ b/drivers/input/misc/cy8cmbr3102.c
@@ -207,7 +207,6 @@ MODULE_DEVICE_TABLE(of, of_cy8cmbr3102_m
 static struct i2c_driver cy8cmbr3102_driver = {
 		.driver			= {
 			.name		= "cy8cmbr3102",
-			.owner		= THIS_MODULE,
 			.of_match_table	= of_match_ptr(of_cy8cmbr3102_match),
 		},
 		.probe = cy8cmbr3102_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2016-11-23  4:57 ` Ryan Lee
@ 2016-11-23 18:13   ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-11-23 18:13 UTC (permalink / raw)
  To: Ryan Lee
  Cc: kbuild-all, lgirdwood, broonie, robh+dt, mark.rutland, perex,
	tiwai, arnd, michael, oder_chiou, yesanishhere, jacob,
	Damien.Horsley, bardliao, kuninori.morimoto.gx, petr, lars, nh6z,
	ryans.lee, alsa-devel, devicetree, linux-kernel

sound/soc/codecs/max98927.c:941:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Ryan Lee <RyanS.Lee@maximintegrated.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 max98927.c |    1 -
 1 file changed, 1 deletion(-)

--- a/sound/soc/codecs/max98927.c
+++ b/sound/soc/codecs/max98927.c
@@ -938,7 +938,6 @@ MODULE_DEVICE_TABLE(of, max98927_of_matc
 static struct i2c_driver max98927_i2c_driver = {
 	.driver = {
 		.name = "max98927",
-		.owner = THIS_MODULE,
 		.of_match_table = of_match_ptr(max98927_of_match),
 		.pm = NULL,
 	},

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2016-07-27 14:41 ` Julia Lawall
@ 2016-08-08  5:47   ` Vinod Koul
  -1 siblings, 0 replies; 44+ messages in thread
From: Vinod Koul @ 2016-08-08  5:47 UTC (permalink / raw)
  To: Julia Lawall
  Cc: Michal Simek, Dan Williams, Sören Brinkmann, Hyun Kwon,
	kbuild-all, linux-arm-kernel, dmaengine, linux-kernel

On Wed, Jul 27, 2016 at 04:41:16PM +0200, Julia Lawall wrote:
> No need to set .owner here. The core will do it.

And which tree was this generated against :-)

Upstream doesn't have  _dpdma.c

> 
> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
> 
> Signed-off-by: Julia Lawall <julia.lawall@lip6.fr>
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> ---
> 
>  xilinx_dpdma.c |    1 -
>  1 file changed, 1 deletion(-)
> 
> --- a/drivers/dma/xilinx/xilinx_dpdma.c
> +++ b/drivers/dma/xilinx/xilinx_dpdma.c
> @@ -1944,7 +1944,6 @@ static struct platform_driver xilinx_dpd
>  	.remove			= xilinx_dpdma_remove,
>  	.driver			= {
>  		.name		= "xilinx-dpdma",
> -		.owner		= THIS_MODULE,
>  		.of_match_table	= xilinx_dpdma_of_match,
>  	},
>  };

-- 
~Vinod

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-08-08  5:47   ` Vinod Koul
  0 siblings, 0 replies; 44+ messages in thread
From: Vinod Koul @ 2016-08-08  5:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 27, 2016 at 04:41:16PM +0200, Julia Lawall wrote:
> No need to set .owner here. The core will do it.

And which tree was this generated against :-)

Upstream doesn't have  _dpdma.c

> 
> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
> 
> Signed-off-by: Julia Lawall <julia.lawall@lip6.fr>
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> ---
> 
>  xilinx_dpdma.c |    1 -
>  1 file changed, 1 deletion(-)
> 
> --- a/drivers/dma/xilinx/xilinx_dpdma.c
> +++ b/drivers/dma/xilinx/xilinx_dpdma.c
> @@ -1944,7 +1944,6 @@ static struct platform_driver xilinx_dpd
>  	.remove			= xilinx_dpdma_remove,
>  	.driver			= {
>  		.name		= "xilinx-dpdma",
> -		.owner		= THIS_MODULE,
>  		.of_match_table	= xilinx_dpdma_of_match,
>  	},
>  };

-- 
~Vinod

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2016-08-06 15:03 ` Gerard H. Pille
@ 2016-08-06 22:00   ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-08-06 22:00 UTC (permalink / raw)
  To: Gerard H. Pille; +Cc: kbuild-all, linux-media, Gerard H. Pille

drivers/media/dvb-frontends/si2165.c:1192:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Gerard H. Pille <g.h.p@skynet.be>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 si2165.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/media/dvb-frontends/si2165.c
+++ b/drivers/media/dvb-frontends/si2165.c
@@ -1189,7 +1189,6 @@ MODULE_DEVICE_TABLE(i2c, si2165_id_table
 
 static struct i2c_driver si2165_driver = {
 	.driver = {
-		.owner	= THIS_MODULE,
 		.name	= "si2165",
 	},
 	.probe		= si2165_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-07-27 14:41 ` Julia Lawall
  0 siblings, 0 replies; 44+ messages in thread
From: Julia Lawall @ 2016-07-27 14:41 UTC (permalink / raw)
  To: Michal Simek, Dan Williams, Vinod Koul, Sören Brinkmann, Hyun Kwon
  Cc: kbuild-all, linux-arm-kernel, dmaengine, linux-kernel

No need to set .owner here. The core will do it.

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

Signed-off-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 xilinx_dpdma.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/dma/xilinx/xilinx_dpdma.c
+++ b/drivers/dma/xilinx/xilinx_dpdma.c
@@ -1944,7 +1944,6 @@ static struct platform_driver xilinx_dpd
 	.remove			= xilinx_dpdma_remove,
 	.driver			= {
 		.name		= "xilinx-dpdma",
-		.owner		= THIS_MODULE,
 		.of_match_table	= xilinx_dpdma_of_match,
 	},
 };

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-07-27 14:41 ` Julia Lawall
  0 siblings, 0 replies; 44+ messages in thread
From: Julia Lawall @ 2016-07-27 14:41 UTC (permalink / raw)
  To: linux-arm-kernel

No need to set .owner here. The core will do it.

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

Signed-off-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 xilinx_dpdma.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/dma/xilinx/xilinx_dpdma.c
+++ b/drivers/dma/xilinx/xilinx_dpdma.c
@@ -1944,7 +1944,6 @@ static struct platform_driver xilinx_dpd
 	.remove			= xilinx_dpdma_remove,
 	.driver			= {
 		.name		= "xilinx-dpdma",
-		.owner		= THIS_MODULE,
 		.of_match_table	= xilinx_dpdma_of_match,
 	},
 };

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2016-02-15  6:08 ` info
@ 2016-02-15  7:34   ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-02-15  7:34 UTC (permalink / raw)
  To: info
  Cc: kbuild-all, linux-media,
	Буди
	Романто,
	AreMa Inc, linux-kernel, crope, m.chehab, mchehab, hdegoede,
	laurent.pinchart, mkrufky, sylvester.nawrocki, g.liakhovetski,
	peter.senna

drivers/media/dvb-frontends/tc90522.c:271:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Буди Романто, AreMa Inc <knightrider@are.ma>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 tc90522.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/media/dvb-frontends/tc90522.c
+++ b/drivers/media/dvb-frontends/tc90522.c
@@ -268,7 +268,6 @@ MODULE_DEVICE_TABLE(i2c, tc90522_id);
 
 static struct i2c_driver tc90522_driver = {
 	.driver = {
-		.owner	= THIS_MODULE,
 		.name	= tc90522_id->name,
 	},
 	.probe		= tc90522_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-01-10 10:44     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:44 UTC (permalink / raw)
  Cc: kbuild-all-JC7UmRfGjtg, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, jdelvare-IBi9RG/b67k,
	linux-0h96xk9xTtrk1uMJSBkQmQ, wim-IQzOog9fTRqzQB+pC5nmwQ,
	jo.sunga-ELdSlb/RfAS1Z/+hSey0Gg, Richard Vidal-Dorsch

drivers/video/backlight/imanager-bl.c:187:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Fengguang Wu <fengguang.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---

 imanager-bl.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/video/backlight/imanager-bl.c
+++ b/drivers/video/backlight/imanager-bl.c
@@ -184,7 +184,6 @@ static int imanager_backlight_remove(str
 
 static struct platform_driver imanager_backlight_driver = {
 	.driver = {
-		.owner	= THIS_MODULE,
 		.name	= "imanager_backlight",
 	},
 	.probe	= imanager_backlight_probe,
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-01-10 10:44     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:44 UTC (permalink / raw)
  To: richard.dorsch
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/video/backlight/imanager-bl.c:187:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-bl.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/video/backlight/imanager-bl.c
+++ b/drivers/video/backlight/imanager-bl.c
@@ -184,7 +184,6 @@ static int imanager_backlight_remove(str
 
 static struct platform_driver imanager_backlight_driver = {
 	.driver = {
-		.owner	= THIS_MODULE,
 		.name	= "imanager_backlight",
 	},
 	.probe	= imanager_backlight_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2016-01-10  9:11 ` richard.dorsch
@ 2016-01-10 10:34     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:34 UTC (permalink / raw)
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/i2c/busses/imanager-i2c.c:228:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-i2c.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/i2c/busses/imanager-i2c.c
+++ b/drivers/i2c/busses/imanager-i2c.c
@@ -225,7 +225,6 @@ static int imanager_i2c_remove(struct pl
 
 static struct platform_driver imanager_i2c_driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name  = "imanager_i2c",
 	},
 	.probe	= imanager_i2c_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-01-10 10:34     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:34 UTC (permalink / raw)
  To: richard.dorsch
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/i2c/busses/imanager-i2c.c:228:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-i2c.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/i2c/busses/imanager-i2c.c
+++ b/drivers/i2c/busses/imanager-i2c.c
@@ -225,7 +225,6 @@ static int imanager_i2c_remove(struct pl
 
 static struct platform_driver imanager_i2c_driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name  = "imanager_i2c",
 	},
 	.probe	= imanager_i2c_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2016-01-10  9:11 ` richard.dorsch
@ 2016-01-10 10:25     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:25 UTC (permalink / raw)
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/hwmon/imanager-hwmon.c:1047:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-hwmon.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/hwmon/imanager-hwmon.c
+++ b/drivers/hwmon/imanager-hwmon.c
@@ -1044,7 +1044,6 @@ static int imanager_hwmon_probe(struct p
 
 static struct platform_driver imanager_hwmon_driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name  = "imanager_hwmon",
 	},
 	.probe	= imanager_hwmon_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-01-10 10:25     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-10 10:25 UTC (permalink / raw)
  To: richard.dorsch
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/hwmon/imanager-hwmon.c:1047:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-hwmon.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/hwmon/imanager-hwmon.c
+++ b/drivers/hwmon/imanager-hwmon.c
@@ -1044,7 +1044,6 @@ static int imanager_hwmon_probe(struct p
 
 static struct platform_driver imanager_hwmon_driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name  = "imanager_hwmon",
 	},
 	.probe	= imanager_hwmon_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-01-09  2:02     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-09  2:02 UTC (permalink / raw)
  Cc: kbuild-all-JC7UmRfGjtg, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, jdelvare-IBi9RG/b67k,
	linux-0h96xk9xTtrk1uMJSBkQmQ, wim-IQzOog9fTRqzQB+pC5nmwQ,
	jo.sunga-ELdSlb/RfAS1Z/+hSey0Gg, Richard Vidal-Dorsch

drivers/watchdog/imanager-wdt.c:322:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Fengguang Wu <fengguang.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---

 imanager-wdt.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/watchdog/imanager-wdt.c
+++ b/drivers/watchdog/imanager-wdt.c
@@ -319,7 +319,6 @@ static int imanager_wdt_remove(struct pl
 
 static struct platform_driver imanager_wdt_driver = {
 	.driver = {
-		.owner	= THIS_MODULE,
 		.name	= "imanager_wdt",
 	},
 	.probe	= imanager_wdt_probe,
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-01-09  2:02     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-09  2:02 UTC (permalink / raw)
  To: richard.dorsch
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/watchdog/imanager-wdt.c:322:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-wdt.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/watchdog/imanager-wdt.c
+++ b/drivers/watchdog/imanager-wdt.c
@@ -319,7 +319,6 @@ static int imanager_wdt_remove(struct pl
 
 static struct platform_driver imanager_wdt_driver = {
 	.driver = {
-		.owner	= THIS_MODULE,
 		.name	= "imanager_wdt",
 	},
 	.probe	= imanager_wdt_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2016-01-08 22:29 ` richard.dorsch
@ 2016-01-09  0:50     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-09  0:50 UTC (permalink / raw)
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/gpio/imanager-gpio.c:170:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-gpio.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/gpio/imanager-gpio.c
+++ b/drivers/gpio/imanager-gpio.c
@@ -167,7 +167,6 @@ static int imanager_remove(struct platfo
 
 static struct platform_driver imanager_gpio_driver = {
 	.driver = {
-		.owner	= THIS_MODULE,
 		.name	= "imanager_gpio",
 	},
 	.probe	= imanager_gpio_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2016-01-09  0:50     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2016-01-09  0:50 UTC (permalink / raw)
  To: richard.dorsch
  Cc: kbuild-all, linux-kernel, lm-sensors, linux-i2c, linux-watchdog,
	linux-gpio, lee.jones, jdelvare, linux, wim, jo.sunga,
	Richard Vidal-Dorsch

drivers/gpio/imanager-gpio.c:170:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Richard Vidal-Dorsch <richard.dorsch@gmail.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 imanager-gpio.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/gpio/imanager-gpio.c
+++ b/drivers/gpio/imanager-gpio.c
@@ -167,7 +167,6 @@ static int imanager_remove(struct platfo
 
 static struct platform_driver imanager_gpio_driver = {
 	.driver = {
-		.owner	= THIS_MODULE,
 		.name	= "imanager_gpio",
 	},
 	.probe	= imanager_gpio_probe,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-11-13 12:06 ` [PATCHv3] " Joao Pinto
@ 2015-11-13 11:36   ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2015-11-13 11:36 UTC (permalink / raw)
  To: Joao Pinto; +Cc: kbuild-all, bhelgaas, CARLOS.PALMINHA, linux-pci, Joao Pinto

drivers/pci/host/pcie-snpsdev.c:323:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Joao Pinto <Joao.Pinto@synopsys.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 pcie-snpsdev.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/pci/host/pcie-snpsdev.c
+++ b/drivers/pci/host/pcie-snpsdev.c
@@ -320,7 +320,6 @@ static struct platform_driver snpsdev_pc
 	.remove		= __exit_p(snpsdev_pcie_rc_remove),
 	.driver = {
 		.name	= "pcie-snpsdev",
-		.owner	= THIS_MODULE,
 		.of_match_table = snpsdev_pcie_rc_of_match,
 	},
 };

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-04-07 13:09     ` Linus Walleij
@ 2015-04-08  1:24       ` Fengguang Wu
  0 siblings, 0 replies; 44+ messages in thread
From: Fengguang Wu @ 2015-04-08  1:24 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Thierry Reding, Alexandre Courbot, kbuild-all, linux-gpio, linux-kernel

On Tue, Apr 07, 2015 at 03:09:46PM +0200, Linus Walleij wrote:
> On Mon, Mar 30, 2015 at 3:05 PM, Thierry Reding <treding@nvidia.com> wrote:
> > On Sun, Mar 29, 2015 at 03:49:20PM +0800, kbuild test robot wrote:
> >> drivers/pinctrl/pinctrl-max77620.c:472:3-8: No need to set .owner here. The core will do it.
> >>
> >>  Remove .owner field if calls are used which set it automatically
> >>
> >> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
> >>
> >> CC: Alexandre Courbot <acourbot@nvidia.com>
> >> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> >> ---
> >>
> >>  pinctrl-max77620.c |    1 -
> >>  1 file changed, 1 deletion(-)
> >
> > Hi Linus,
> >
> > please ignore this. It's from a staging tree and against a driver that
> > doesn't exist upstream yet. I have for now removed these branches from
> > my github tree completely until we can figure out a way to keep the 0-
> > day builder from generating these patches.
> 
> Bah no big deal, I think I managed to fire off a similar thing on
> a PWM driver down your path :P
> 
> Fengguang said he'd fixed it though IIRC.

Yes sorry for the noise! I've listed Thierry's tree as private report
tree (the black list way).  Perhaps would be better to make the logic
white list based -- then it will be completely noise free.

Thanks,
Fengguang

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-03-30 13:05     ` Thierry Reding
  (?)
@ 2015-04-07 13:09     ` Linus Walleij
  2015-04-08  1:24       ` Fengguang Wu
  -1 siblings, 1 reply; 44+ messages in thread
From: Linus Walleij @ 2015-04-07 13:09 UTC (permalink / raw)
  To: Thierry Reding
  Cc: kbuild test robot, Alexandre Courbot, kbuild-all, linux-gpio,
	linux-kernel

On Mon, Mar 30, 2015 at 3:05 PM, Thierry Reding <treding@nvidia.com> wrote:
> On Sun, Mar 29, 2015 at 03:49:20PM +0800, kbuild test robot wrote:
>> drivers/pinctrl/pinctrl-max77620.c:472:3-8: No need to set .owner here. The core will do it.
>>
>>  Remove .owner field if calls are used which set it automatically
>>
>> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
>>
>> CC: Alexandre Courbot <acourbot@nvidia.com>
>> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
>> ---
>>
>>  pinctrl-max77620.c |    1 -
>>  1 file changed, 1 deletion(-)
>
> Hi Linus,
>
> please ignore this. It's from a staging tree and against a driver that
> doesn't exist upstream yet. I have for now removed these branches from
> my github tree completely until we can figure out a way to keep the 0-
> day builder from generating these patches.

Bah no big deal, I think I managed to fire off a similar thing on
a PWM driver down your path :P

Fengguang said he'd fixed it though IIRC.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-03-29  7:49 ` kbuild test robot
@ 2015-03-30 13:05     ` Thierry Reding
  0 siblings, 0 replies; 44+ messages in thread
From: Thierry Reding @ 2015-03-30 13:05 UTC (permalink / raw)
  To: kbuild test robot
  Cc: Alexandre Courbot, kbuild-all, Linus Walleij, linux-gpio, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1160 bytes --]

On Sun, Mar 29, 2015 at 03:49:20PM +0800, kbuild test robot wrote:
> drivers/pinctrl/pinctrl-max77620.c:472:3-8: No need to set .owner here. The core will do it.
> 
>  Remove .owner field if calls are used which set it automatically
> 
> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
> 
> CC: Alexandre Courbot <acourbot@nvidia.com>
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> ---
> 
>  pinctrl-max77620.c |    1 -
>  1 file changed, 1 deletion(-)

Hi Linus,

please ignore this. It's from a staging tree and against a driver that
doesn't exist upstream yet. I have for now removed these branches from
my github tree completely until we can figure out a way to keep the 0-
day builder from generating these patches.

Thierry

> --- a/drivers/pinctrl/pinctrl-max77620.c
> +++ b/drivers/pinctrl/pinctrl-max77620.c
> @@ -469,7 +469,6 @@ static int max77620_pinctrl_remove(struc
>  static struct platform_driver max77620_pinctrl_driver = {
>  	.driver = {
>  		.name = "max77620-pinctrl",
> -		.owner = THIS_MODULE,
>  	},
>  	.probe = max77620_pinctrl_probe,
>  	.remove = max77620_pinctrl_remove,

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
@ 2015-03-30 13:05     ` Thierry Reding
  0 siblings, 0 replies; 44+ messages in thread
From: Thierry Reding @ 2015-03-30 13:05 UTC (permalink / raw)
  To: kbuild test robot
  Cc: Alexandre Courbot, kbuild-all, Linus Walleij, linux-gpio, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1160 bytes --]

On Sun, Mar 29, 2015 at 03:49:20PM +0800, kbuild test robot wrote:
> drivers/pinctrl/pinctrl-max77620.c:472:3-8: No need to set .owner here. The core will do it.
> 
>  Remove .owner field if calls are used which set it automatically
> 
> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
> 
> CC: Alexandre Courbot <acourbot@nvidia.com>
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> ---
> 
>  pinctrl-max77620.c |    1 -
>  1 file changed, 1 deletion(-)

Hi Linus,

please ignore this. It's from a staging tree and against a driver that
doesn't exist upstream yet. I have for now removed these branches from
my github tree completely until we can figure out a way to keep the 0-
day builder from generating these patches.

Thierry

> --- a/drivers/pinctrl/pinctrl-max77620.c
> +++ b/drivers/pinctrl/pinctrl-max77620.c
> @@ -469,7 +469,6 @@ static int max77620_pinctrl_remove(struc
>  static struct platform_driver max77620_pinctrl_driver = {
>  	.driver = {
>  		.name = "max77620-pinctrl",
> -		.owner = THIS_MODULE,
>  	},
>  	.probe = max77620_pinctrl_probe,
>  	.remove = max77620_pinctrl_remove,

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-03-29 16:24   ` Mark Brown
@ 2015-03-30 12:52     ` Thierry Reding
  0 siblings, 0 replies; 44+ messages in thread
From: Thierry Reding @ 2015-03-30 12:52 UTC (permalink / raw)
  To: Mark Brown
  Cc: kbuild test robot, Paul Walmsley, kbuild-all, Liam Girdwood,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 580 bytes --]

On Sun, Mar 29, 2015 at 09:24:13AM -0700, Mark Brown wrote:
> * PGP Signed by an unknown key
> 
> On Sun, Mar 29, 2015 at 03:33:33PM +0800, kbuild test robot wrote:
> > drivers/regulator/max77620-regulator.c:800:3-8: No need to set .owner here. The core will do it.
> 
> This doesn't apply against current code, this file is not present.

Hi Mark,

Sorry about this. The tree that this was generated against is heavily
work in progress and should certainly not have patches for mainline
generated against it.

I'm working with Fengguang to resolve this.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-03-29  7:42 ` kbuild test robot
@ 2015-03-29 16:27   ` Mark Brown
  0 siblings, 0 replies; 44+ messages in thread
From: Mark Brown @ 2015-03-29 16:27 UTC (permalink / raw)
  To: kbuild test robot
  Cc: Alexandre Courbot, kbuild-all, Thierry Reding, Liam Girdwood,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 310 bytes --]

On Sun, Mar 29, 2015 at 03:42:46PM +0800, kbuild test robot wrote:
> drivers/regulator/regulator-pwm.c:333:3-8: No need to set .owner here. The core will do it.
> 
>  Remove .owner field if calls are used which set it automatically

This doesn't apply against current code, the above file isn't present.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-03-29  7:33 ` kbuild test robot
@ 2015-03-29 16:24   ` Mark Brown
  2015-03-30 12:52     ` Thierry Reding
  0 siblings, 1 reply; 44+ messages in thread
From: Mark Brown @ 2015-03-29 16:24 UTC (permalink / raw)
  To: kbuild test robot
  Cc: Paul Walmsley, kbuild-all, Thierry Reding, Liam Girdwood, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 234 bytes --]

On Sun, Mar 29, 2015 at 03:33:33PM +0800, kbuild test robot wrote:
> drivers/regulator/max77620-regulator.c:800:3-8: No need to set .owner here. The core will do it.

This doesn't apply against current code, this file is not present.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
       [not found] <201503291519.K9Z6Qptb%fengguang.wu@intel.com>
@ 2015-03-29  7:49 ` kbuild test robot
  2015-03-30 13:05     ` Thierry Reding
  0 siblings, 1 reply; 44+ messages in thread
From: kbuild test robot @ 2015-03-29  7:49 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: kbuild-all, Thierry Reding, Linus Walleij, linux-gpio, linux-kernel

drivers/pinctrl/pinctrl-max77620.c:472:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 pinctrl-max77620.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/pinctrl/pinctrl-max77620.c
+++ b/drivers/pinctrl/pinctrl-max77620.c
@@ -469,7 +469,6 @@ static int max77620_pinctrl_remove(struc
 static struct platform_driver max77620_pinctrl_driver = {
 	.driver = {
 		.name = "max77620-pinctrl",
-		.owner = THIS_MODULE,
 	},
 	.probe = max77620_pinctrl_probe,
 	.remove = max77620_pinctrl_remove,

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
       [not found] <201503291545.My1tADgz%fengguang.wu@intel.com>
@ 2015-03-29  7:42 ` kbuild test robot
  2015-03-29 16:27   ` Mark Brown
  0 siblings, 1 reply; 44+ messages in thread
From: kbuild test robot @ 2015-03-29  7:42 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: kbuild-all, Thierry Reding, Liam Girdwood, Mark Brown, linux-kernel

drivers/regulator/regulator-pwm.c:333:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 regulator-pwm.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/regulator/regulator-pwm.c
+++ b/drivers/regulator/regulator-pwm.c
@@ -330,7 +330,6 @@ MODULE_DEVICE_TABLE(of, pwm_regulator_of
 static struct platform_driver pwm_regulator_driver = {
 	.driver = {
 		.name	= "regulator-pwm",
-		.owner  = THIS_MODULE,
 		.pm = &pwm_regulator_pm_ops,
 		.of_match_table = pwm_regulator_of_match,
 	},

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
       [not found] <201503291531.GP28FwKy%fengguang.wu@intel.com>
@ 2015-03-29  7:33 ` kbuild test robot
  2015-03-29 16:24   ` Mark Brown
  0 siblings, 1 reply; 44+ messages in thread
From: kbuild test robot @ 2015-03-29  7:33 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: kbuild-all, Thierry Reding, Liam Girdwood, Mark Brown, linux-kernel

drivers/regulator/max77620-regulator.c:800:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: Paul Walmsley <pwalmsley@nvidia.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 max77620-regulator.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/regulator/max77620-regulator.c
+++ b/drivers/regulator/max77620-regulator.c
@@ -797,7 +797,6 @@ static struct platform_driver max77620_r
 	.probe = max77620_regulator_probe,
 	.driver = {
 		.name = "max77620-pmic",
-		.owner = THIS_MODULE,
 	},
 };
 

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-03-24 10:43       ` Thierry Reding
@ 2015-03-25  1:56         ` Fengguang Wu
  0 siblings, 0 replies; 44+ messages in thread
From: Fengguang Wu @ 2015-03-25  1:56 UTC (permalink / raw)
  To: Thierry Reding; +Cc: Linus Walleij, kbuild-all, linux-pwm, linux-kernel

On Tue, Mar 24, 2015 at 11:43:41AM +0100, Thierry Reding wrote:
> On Wed, Mar 18, 2015 at 02:38:18AM +0100, Linus Walleij wrote:
> > On Wed, Mar 11, 2015 at 12:05 PM, Thierry Reding
> > <thierry.reding@gmail.com> wrote:
> > > On Fri, Jan 16, 2015 at 09:06:14AM +0800, kbuild test robot wrote:
> > >> drivers/pwm/pwm-stmpe.c:99:3-8: No need to set .owner here. The core will do it.
> > >>
> > >>  Remove .owner field if calls are used which set it automatically
> > >>
> > >> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
> > >>
> > >> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> > >> ---
> > >>
> > >>  pwm-stmpe.c |    1 -
> > >>  1 file changed, 1 deletion(-)
> > >
> > > Erm... this driver doesn't exist in my tree. What's going on?
> > 
> > What's going on is that the 0day build robot builds everything it
> > finds, including experimental branches.
> > 
> > I dunno why it's mailing you though, probably I already added your
> > CC on the patch... stupid me. A bit much to think of.
> 
> I guess the robot generates this patch and then runs get_maintainers.pl
> on it, so it's doing the right thing. Anyway, I'll know to ignore these
> in the future if drivers aren't in my tree yet.

Sorry I've added some heuristics to avoid adding CC from
get_maintainers.pl for the likely private branches. It should reduce
such confusions and noises considerably in future.

Thanks,
Fengguang

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-03-18  1:38     ` Linus Walleij
@ 2015-03-24 10:43       ` Thierry Reding
  2015-03-25  1:56         ` Fengguang Wu
  0 siblings, 1 reply; 44+ messages in thread
From: Thierry Reding @ 2015-03-24 10:43 UTC (permalink / raw)
  To: Linus Walleij; +Cc: kbuild test robot, kbuild-all, linux-pwm, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1140 bytes --]

On Wed, Mar 18, 2015 at 02:38:18AM +0100, Linus Walleij wrote:
> On Wed, Mar 11, 2015 at 12:05 PM, Thierry Reding
> <thierry.reding@gmail.com> wrote:
> > On Fri, Jan 16, 2015 at 09:06:14AM +0800, kbuild test robot wrote:
> >> drivers/pwm/pwm-stmpe.c:99:3-8: No need to set .owner here. The core will do it.
> >>
> >>  Remove .owner field if calls are used which set it automatically
> >>
> >> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
> >>
> >> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> >> ---
> >>
> >>  pwm-stmpe.c |    1 -
> >>  1 file changed, 1 deletion(-)
> >
> > Erm... this driver doesn't exist in my tree. What's going on?
> 
> What's going on is that the 0day build robot builds everything it
> finds, including experimental branches.
> 
> I dunno why it's mailing you though, probably I already added your
> CC on the patch... stupid me. A bit much to think of.

I guess the robot generates this patch and then runs get_maintainers.pl
on it, so it's doing the right thing. Anyway, I'll know to ignore these
in the future if drivers aren't in my tree yet.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-03-11 11:05   ` Thierry Reding
@ 2015-03-18  1:38     ` Linus Walleij
  2015-03-24 10:43       ` Thierry Reding
  0 siblings, 1 reply; 44+ messages in thread
From: Linus Walleij @ 2015-03-18  1:38 UTC (permalink / raw)
  To: Thierry Reding; +Cc: kbuild test robot, kbuild-all, linux-pwm, linux-kernel

On Wed, Mar 11, 2015 at 12:05 PM, Thierry Reding
<thierry.reding@gmail.com> wrote:
> On Fri, Jan 16, 2015 at 09:06:14AM +0800, kbuild test robot wrote:
>> drivers/pwm/pwm-stmpe.c:99:3-8: No need to set .owner here. The core will do it.
>>
>>  Remove .owner field if calls are used which set it automatically
>>
>> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
>>
>> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
>> ---
>>
>>  pwm-stmpe.c |    1 -
>>  1 file changed, 1 deletion(-)
>
> Erm... this driver doesn't exist in my tree. What's going on?

What's going on is that the 0day build robot builds everything it
finds, including experimental branches.

I dunno why it's mailing you though, probably I already added your
CC on the patch... stupid me. A bit much to think of.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH] fix platform_no_drv_owner.cocci warnings
  2015-01-16  1:06 ` kbuild test robot
@ 2015-03-11 11:05   ` Thierry Reding
  2015-03-18  1:38     ` Linus Walleij
  0 siblings, 1 reply; 44+ messages in thread
From: Thierry Reding @ 2015-03-11 11:05 UTC (permalink / raw)
  To: kbuild test robot; +Cc: Linus Walleij, kbuild-all, linux-pwm, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 503 bytes --]

On Fri, Jan 16, 2015 at 09:06:14AM +0800, kbuild test robot wrote:
> drivers/pwm/pwm-stmpe.c:99:3-8: No need to set .owner here. The core will do it.
> 
>  Remove .owner field if calls are used which set it automatically
> 
> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
> 
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> ---
> 
>  pwm-stmpe.c |    1 -
>  1 file changed, 1 deletion(-)

Erm... this driver doesn't exist in my tree. What's going on?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
       [not found] <201502131224.TGzEj1Ve%fengguang.wu@intel.com>
@ 2015-02-13  4:49 ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2015-02-13  4:49 UTC (permalink / raw)
  To: Rob Clark
  Cc: kbuild-all, Mike Turquette, Stephen Boyd, Srinivas Kandagatla,
	linux-kernel

drivers/clk/qcom/clk-rpm.c:262:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 clk-rpm.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/clk/qcom/clk-rpm.c
+++ b/drivers/clk/qcom/clk-rpm.c
@@ -259,7 +259,6 @@ static struct platform_driver rpm_clk_dr
 	.probe		= rpm_clk_probe,
 	.driver		= {
 		.name	= "qcom-rpm-clk",
-		.owner	= THIS_MODULE,
 		.of_match_table = of_match_ptr(clk_rpm_of_match),
 	},
 };

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] fix platform_no_drv_owner.cocci warnings
       [not found] <201501160912.S502Nlmz%fengguang.wu@intel.com>
@ 2015-01-16  1:06 ` kbuild test robot
  2015-03-11 11:05   ` Thierry Reding
  0 siblings, 1 reply; 44+ messages in thread
From: kbuild test robot @ 2015-01-16  1:06 UTC (permalink / raw)
  To: Linus Walleij; +Cc: kbuild-all, Thierry Reding, linux-pwm, linux-kernel

drivers/pwm/pwm-stmpe.c:99:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---

 pwm-stmpe.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/pwm/pwm-stmpe.c
+++ b/drivers/pwm/pwm-stmpe.c
@@ -96,7 +96,6 @@ static int stmpe_pwm_remove(struct platf
 static struct platform_driver stmpe_pwm_driver = {
 	.driver = {
 		.name = "stmpe-pwm",
-		.owner = THIS_MODULE,
 	},
 	.probe = stmpe_pwm_probe,
 	.remove = stmpe_pwm_remove,

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2019-06-23 18:50 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-10 10:11 [PATCH v2 1/6] Add Advantech iManager MFD core driver kbuild test robot
2016-01-10 10:11 ` kbuild test robot
2016-01-10  9:10 ` richard.dorsch-Re5JQEeQqe8AvxtiuMwx3w
2016-01-10  9:10   ` richard.dorsch
2016-01-10 10:11   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2016-01-10 10:11     ` kbuild test robot
     [not found] <201906240241.S3kwAGar%lkp@intel.com>
2019-06-23 18:50 ` kbuild test robot
  -- strict thread matches above, loose matches on Subject: below --
2018-12-30  5:10 [nomadik:ixp4 4/9] drivers/gpio/gw_i2c_pld.c:25:10: fatal error: linux/i2c/gw_i2c_pld.h: No such file or directory kbuild test robot
2018-12-30  5:10 ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2017-02-20 12:05 [PATCH 1/2] add driver for cypress cy8cmbr3102 kbuild test robot
2017-02-20 10:33 ` Patrick Vogelaar
2017-02-20 12:05   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2017-02-20 12:05     ` kbuild test robot
2016-11-23 18:13 [PATCH] ALSA SoC MAX98927 driver - Initial release kbuild test robot
2016-11-23  4:57 ` Ryan Lee
2016-11-23 18:13   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2016-08-06 22:00 [PATCH] This patch allows the Terratec Cinergy HTC Stick HD (0ccb:0101) to be used to watch DVB-T kbuild test robot
2016-08-06 15:03 ` Gerard H. Pille
2016-08-06 22:00   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2016-07-27 14:41 Julia Lawall
2016-07-27 14:41 ` Julia Lawall
2016-08-08  5:47 ` Vinod Koul
2016-08-08  5:47   ` Vinod Koul
2016-02-15  7:34 [media 7/7] PCI bridge driver for PT3 & PXQ3PE kbuild test robot
2016-02-15  6:08 ` info
2016-02-15  7:34   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2016-01-10 10:44 [PATCH v2 5/6] Add Advantech iManager Backlight driver kbuild test robot
     [not found] ` <1452417098-28667-1-git-send-email-richard.dorsch-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-01-10 10:44   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2016-01-10 10:44     ` kbuild test robot
2016-01-10 10:34 [PATCH v2 4/6] Add Advantech iManager I2C driver kbuild test robot
2016-01-10  9:11 ` richard.dorsch
2016-01-10 10:34   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2016-01-10 10:34     ` kbuild test robot
2016-01-10 10:25 [PATCH v2 3/6] Add Advantech iManager HWmon driver kbuild test robot
2016-01-10  9:11 ` richard.dorsch
2016-01-10 10:25   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2016-01-10 10:25     ` kbuild test robot
2016-01-09  2:02 [PATCH 6/6] Add Advantech iManager Watchdog driver kbuild test robot
     [not found] ` <1452292166-20118-7-git-send-email-richard.dorsch-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-01-09  2:02   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2016-01-09  2:02     ` kbuild test robot
2016-01-09  0:50 [PATCH 2/6] Add Advantech iManager GPIO driver kbuild test robot
2016-01-08 22:29 ` richard.dorsch
2016-01-09  0:50   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
2016-01-09  0:50     ` kbuild test robot
2015-11-13 11:36 [PATCH] add new platform driver for PCI RC kbuild test robot
2015-11-13 12:06 ` [PATCHv3] " Joao Pinto
2015-11-13 11:36   ` [PATCH] fix platform_no_drv_owner.cocci warnings kbuild test robot
     [not found] <201503291519.K9Z6Qptb%fengguang.wu@intel.com>
2015-03-29  7:49 ` kbuild test robot
2015-03-30 13:05   ` Thierry Reding
2015-03-30 13:05     ` Thierry Reding
2015-04-07 13:09     ` Linus Walleij
2015-04-08  1:24       ` Fengguang Wu
     [not found] <201503291545.My1tADgz%fengguang.wu@intel.com>
2015-03-29  7:42 ` kbuild test robot
2015-03-29 16:27   ` Mark Brown
     [not found] <201503291531.GP28FwKy%fengguang.wu@intel.com>
2015-03-29  7:33 ` kbuild test robot
2015-03-29 16:24   ` Mark Brown
2015-03-30 12:52     ` Thierry Reding
     [not found] <201502131224.TGzEj1Ve%fengguang.wu@intel.com>
2015-02-13  4:49 ` kbuild test robot
     [not found] <201501160912.S502Nlmz%fengguang.wu@intel.com>
2015-01-16  1:06 ` kbuild test robot
2015-03-11 11:05   ` Thierry Reding
2015-03-18  1:38     ` Linus Walleij
2015-03-24 10:43       ` Thierry Reding
2015-03-25  1:56         ` Fengguang Wu

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.