Skip to contentSkip to conversation

Introduce MEN 14F02100 BMC driver series

PATCH Superseded Andreas Werner 5 participants 16 messages May 27, 2014 – Jul 18, 2014

Subsystems (4)

v2 of 6 Superseded Latest is v6 →

lore
Share & tools
lore

Andreas Werner

author maintainer
#0 lore raw

v2 cover Introduce MEN 14F02100 BMC driver series

This patch set add support for the MEN 14F021P00 Board Management called BMC.

The BMC is a PIC Mikrocontroller which assembled on almost all of our 3U Compact PCI CPU board and a few Box PCs.
The main part of the BMC is to start and monitor the board, but there are a lot more features which can be accessed using an I2C Host interface

Features supported in this Patchset:
- Watchdog
- LEDs

The Patchset includes a MFD Core driver, Watchdog and LEDs driver.

Changes in v2:
- changed i2c_smbus_read wrapper function to return both, value and error.
- moved "leave production mode" from Watchdog driver to mfd core.
- fixed some return values in the watchdog driver to return the original error value instead of -EIO.

Andreas Werner (3):
drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver drivers/watchdog/menf21bmc_wd: introduce MEN 14F021P00 BMC Watchdog
driver
drivers/leds/leds-menf21bmc: introduce MEN 14F021P00 BMC LED driver

 drivers/leds/Kconfig            |   6 ++
 drivers/leds/Makefile           |   2 +-
 drivers/leds/leds-menf21bmc.c   | 136 +++++++++++++++++++++++++
 drivers/mfd/Kconfig             |  12 +++
 drivers/mfd/Makefile            |   1 +
 drivers/mfd/menf21bmc.c         | 220 ++++++++++++++++++++++++++++++++++++++++
 drivers/watchdog/Kconfig        |   7 ++
 drivers/watchdog/Makefile       |   1 +
 drivers/watchdog/menf21bmc_wd.c | 217 +++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/menf21bmc.h   |  31 ++++++
 10 files changed, 632 insertions(+), 1 deletion(-)
 create mode 100644 drivers/leds/leds-menf21bmc.c
 create mode 100644 drivers/mfd/menf21bmc.c
 create mode 100644 drivers/watchdog/menf21bmc_wd.c
 create mode 100644 include/linux/mfd/menf21bmc.h
Signature · 1 line
1.9.3
author maintainer
#1 lore raw

PATCH v2 1/3 drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

The MEN 14F021P00 Board Management Controller provides an
I2C interface to the host to access the feature implemented in the BMC. The BMC is a PIC Microntroller assembled on CPCI Card from MEN Mikroelektronik and on a few Box/Display Computer.

Added MFD Core driver, supporting the I2C communication to the device.

The MFD driver currently supports the following features:
- Watchdog
- LEDs

---
 drivers/mfd/Kconfig           |  12 +++
 drivers/mfd/Makefile          |   1 +
 drivers/mfd/menf21bmc.c       | 220 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/menf21bmc.h |  31 ++++++
 4 files changed, 264 insertions(+)
 create mode 100644 drivers/mfd/menf21bmc.c
 create mode 100644 include/linux/mfd/menf21bmc.h
drivers/mfd/Kconfig +12 -0
index ab5a43c..7c2e8d2 100644
@@ -427,6 +427,18 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 
+config MFD_MENF21BMC
+	tristate "MEN 14F021P00 Board Management Controller Support"
+	depends on I2C=y
+	select MFD_CORE
+	help
+	  Say yes here to add support for the MEN 14F021P00 BMC
+	  which is a Board Management Controller connected to the I2C bus.
+	  This driver provides common support for accessing the devices;
+	  additional drivers must be enabled in order to use the
+	  functionality of the BMC device.
+
+
 config EZX_PCAP
 	bool "Motorola EZXPCAP Support"
 	depends on SPI_MASTER
drivers/mfd/Makefile +1 -0
index 5913208..8f2be38 100644
@@ -167,3 +167,4 @@ obj-$(CONFIG_MFD_AS3711)	+= as3711.o
 obj-$(CONFIG_MFD_AS3722)	+= as3722.o
 obj-$(CONFIG_MFD_STW481X)	+= stw481x.o
 obj-$(CONFIG_MFD_IPAQ_MICRO)	+= ipaq-micro.o
+obj-$(CONFIG_MFD_MENF21BMC)	+= menf21bmc.o
drivers/mfd/menf21bmc.c new file +220 -0

220 lines not on this page · raw message

include/linux/mfd/menf21bmc.h new file +31 -0
new file mode 100644
index 0000000..1fc9b5c
@@ -0,0 +1,31 @@
+/*
+ *  MEN 14F021P00 Board Management Controller (BMC)
+ *
+ *  Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
+ *  Author: Andreas Werner <[email protected]>
+ *  All rights reserved.
+ *
+ *  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 MENF21BMC_H
+#define MENF21BMC_H
+
+struct menf21bmc {
+	struct i2c_client *client;
+	struct mutex lock;
+
+	int (*read_word_data)(struct i2c_client *client, u8 reg);
+	int (*read_byte_data)(struct i2c_client *client, u8 reg);
+	int (*write_word_data)(struct i2c_client *client, u8 reg, u16 val);
+	int (*write_byte_data)(struct i2c_client *client, u8 reg, u8 val);
+	int (*write_byte)(struct i2c_client *client, u8 val);
+};
+
+#endif /* MENF21BMC_H */
+
+
Signature · 1 line
1.9.3
#2 lore raw

Re: [PATCH v2 1/3] drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

Quoted 29 lines

The MEN 14F021P00 Board Management Controller provides an
I2C interface to the host to access the feature implemented in the BMC. The BMC is a PIC Microntroller assembled on CPCI Card from MEN Mikroelektronik and on a few Box/Display Computer.

Added MFD Core driver, supporting the I2C communication to the device.

The MFD driver currently supports the following features:
- Watchdog
- LEDs

---
 drivers/mfd/Kconfig           |  12 +++
 drivers/mfd/Makefile          |   1 +
 drivers/mfd/menf21bmc.c       | 220 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/menf21bmc.h |  31 ++++++
 4 files changed, 264 insertions(+)
 create mode 100644 drivers/mfd/menf21bmc.c
 create mode 100644 include/linux/mfd/menf21bmc.h
drivers/mfd/Kconfig +0 -0
index ab5a43c..7c2e8d2 100644
@@ -427,6 +427,18 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 

drivers/mfd/Kconfig config MFD_MAX8998 · line 439

Quoted 10 lines
drivers/mfd/Kconfig +10 -0
+config MFD_MENF21BMC
+	tristate "MEN 14F021P00 Board Management Controller Support"
+	depends on I2C=y
+	select MFD_CORE
+	help
+	  Say yes here to add support for the MEN 14F021P00 BMC
+	  which is a Board Management Controller connected to the I2C bus.
+	  This driver provides common support for accessing the devices;
+	  additional drivers must be enabled in order to use the
+	  functionality of the BMC device.

Would be good if you mention the WD and LED devices here too.

drivers/mfd/Kconfig config MFD_MAX8998 · line 441

Quoted 2 lines
drivers/mfd/Kconfig +2 -0
+
+

To many '\n's here.

Quoted 40 lines
drivers/mfd/Kconfig +0 -0
 config EZX_PCAP
 	bool "Motorola EZXPCAP Support"
 	depends on SPI_MASTER
drivers/mfd/Makefile +1 -0
index 5913208..8f2be38 100644
@@ -167,3 +167,4 @@ obj-$(CONFIG_MFD_AS3711)	+= as3711.o
 obj-$(CONFIG_MFD_AS3722)	+= as3722.o
 obj-$(CONFIG_MFD_STW481X)	+= stw481x.o
 obj-$(CONFIG_MFD_IPAQ_MICRO)	+= ipaq-micro.o
+obj-$(CONFIG_MFD_MENF21BMC)	+= menf21bmc.o
drivers/mfd/menf21bmc.c new file +22 -0
new file mode 100644
index 0000000..8de92b5
@@ -0,0 +1,220 @@
+/*
+ *  MEN 14F021P00 Board Management Controller (BMC) MFD Core Driver.
+ *
+ *  Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
+ *  Author: Andreas Werner <[email protected]>
+ *  All rights reserved.
+ *
+ *  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/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/menf21bmc.h>
+
+#define BMC_CMD_REV_MAJOR	0x80

drivers/mfd/menf21bmc.c line 32

Quoted 10 lines
drivers/mfd/menf21bmc.c new file +10 -0
+#define BMC_CMD_REV_MINOR	0x81
+#define BMC_CMD_REV_MAIN	0x82
+#define BMC_CMD_REV_BUILD	0x83
+#define BMC_CMD_REV_VERI	0x84
+#define BMC_CMD_WD_ARM_SET	0x18
+#define BMC_CMD_WD_ARM_GET	0x19
+
+static struct mfd_cell menf21bmc_cell[] = {
+	{
+		.name = "menf21bmc_wd",

I prefer wdog to wd, as it's a little move obvious what we're dealing with.

drivers/mfd/menf21bmc.c line 37

Quoted 5 lines
drivers/mfd/menf21bmc.c new file +5 -0
+	},
+	{
+		.name = "menf21bmc_led",
+	},
+};

If these are the only struct attributes, please place them on a single line (each).

Quoted 51 lines
drivers/mfd/menf21bmc.c new file +51 -0
+static int
+menf21bmc_read_byte_data(struct i2c_client *client, u8 reg)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_read_byte_data(client, reg);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int
+menf21bmc_read_word_data(struct i2c_client *client, u8 reg)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_read_word_data(client, reg);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int menf21bmc_write_byte_data(struct i2c_client *client, u8 reg, u8 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte_data(client, reg, val);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int menf21bmc_write_word_data(struct i2c_client *client, u8 reg, u16 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_word_data(client, reg, val);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int menf21bmc_write_byte(struct i2c_client *client, u8 val)

drivers/mfd/menf21bmc.c line 99

Quoted 10 lines
drivers/mfd/menf21bmc.c new file +10 -0
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte(client, val);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}

Didn't we ask you to remove these? Just make the i2c_smbus_* calls from within the driver. The I2C subsystem conducts its own locking. I'm really starting to frown on aggregation for the sake of aggregation. It's just overhead.

drivers/mfd/menf21bmc.c line 105

Quoted 5 lines
drivers/mfd/menf21bmc.c new file +5 -0
+static int menf21bmc_wd_leave_prod_mode(struct i2c_client *client)
+{
+	int val, ret;
+
+	val = menf21bmc_read_byte_data(client, BMC_CMD_WD_ARM_GET);

ARM like the processor, or 'arm' as in "arm the missile", or something else?

drivers/mfd/menf21bmc.c line 113

Quoted 8 lines
drivers/mfd/menf21bmc.c new file +8 -0
+	if (val < 0)
+		return val;
+
+	/*
+	 * Production mode should be not active after delivery of the Board.
+	 * To be sure we check it, inform the user and leave the mode
+	 * if active.
+	 */

I prefer the term 'exit', as 'leave' is ambiguous. It could read "leave it in production mode", or "leave (exit) production mode".

Quoted 13 lines
drivers/mfd/menf21bmc.c new file +13 -0
+	if (val == 0x00) {
+		dev_info(&client->dev,
+			"BMC in production mode. Leave production mode\n");
+
+		ret = menf21bmc_write_byte(client, BMC_CMD_WD_ARM_SET);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int

drivers/mfd/menf21bmc.c line 136

Quoted 10 lines
drivers/mfd/menf21bmc.c new file +10 -0
+menf21bmc_probe(struct i2c_client *client, const struct i2c_device_id *ids)
+{
+	int ret;
+	struct menf21bmc *data;
+	int rev_major, rev_minor, rev_main;
+
+	if (!i2c_check_functionality(client->adapter,
+						I2C_FUNC_SMBUS_BYTE_DATA |
+						I2C_FUNC_SMBUS_WORD_DATA |
+						I2C_FUNC_SMBUS_BYTE))

Tabbing is off. Try to line up with the '('.

drivers/mfd/menf21bmc.c line 137

Quoted 1 line
drivers/mfd/menf21bmc.c new file +1 -0
+		return -EIO;

-ENODEV is more common.

drivers/mfd/menf21bmc.c line 139

Quoted 1 line
drivers/mfd/menf21bmc.c new file +1 -0
+	data = devm_kzalloc(&client->dev, sizeof(struct menf21bmc), GFP_KERNEL);

s/sizeof(struct menf21bmc)/sizeof(*data)/

data doesn't tend to be a good name for a variable.

drivers/mfd/menf21bmc.c line 140

Quoted 1 line
drivers/mfd/menf21bmc.c new file +1 -0
+	if (data == NULL)

if (!data)

drivers/mfd/menf21bmc.c line 151

Quoted 11 lines
drivers/mfd/menf21bmc.c new file +11 -0
+		return -ENOMEM;
+
+	mutex_init(&data->lock);
+
+	i2c_set_clientdata(client, data);
+	data->client = client;
+	data->read_word_data = menf21bmc_read_word_data;
+	data->read_byte_data = menf21bmc_read_byte_data;
+	data->write_word_data = menf21bmc_write_word_data;
+	data->write_byte_data = menf21bmc_write_byte_data;
+	data->write_byte = menf21bmc_write_byte;

Yuck, please remove these.

Quoted 20 lines
drivers/mfd/menf21bmc.c new file +20 -0
+	rev_major = menf21bmc_read_word_data(client, BMC_CMD_REV_MAJOR);
+	if (rev_major < 0) {
+		dev_err(&client->dev, "failed to get BMC major revision\n");
+		return rev_major;
+	}
+
+	rev_minor = menf21bmc_read_word_data(client, BMC_CMD_REV_MINOR);
+	if (rev_minor < 0) {
+		dev_err(&client->dev, "failed to get BMC minor revision\n");
+		return rev_minor;
+	}
+
+	rev_main = menf21bmc_read_word_data(client, BMC_CMD_REV_MAIN);
+	if (rev_main < 0) {
+		dev_err(&client->dev, "failed to get BMC main revision\n");
+		return rev_main;
+	}
+
+	dev_info(&client->dev, "FW Revision: %02d.%02d.%02d\n",
+					rev_major, rev_minor, rev_main);

drivers/mfd/menf21bmc.c line 182

Quoted 10 lines
drivers/mfd/menf21bmc.c new file +10 -0
+
+	/*
+	 * We have to leave the Production Mode of the BMC to activate the
+	 * Watchdog functionality and the BIOS life sign monitoring.
+	 */
+	ret = menf21bmc_wd_leave_prod_mode(client);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to leave production mode\n");
+		return ret;
+	}

Is it possible that someone might want to use production mode?

drivers/mfd/menf21bmc.c line 187

Quoted 4 lines
drivers/mfd/menf21bmc.c new file +4 -0
+	ret = mfd_add_devices(&client->dev, 0, menf21bmc_cell,
+				ARRAY_SIZE(menf21bmc_cell), NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(&client->dev, "mfd_add_devices failed\n");

This error message should be more useful to the user.

E.g. "Failed to add sub-devices"

Quoted 4 lines
drivers/mfd/menf21bmc.c new file +4 -0
+		return ret;
+	}
+
+	return 0;

drivers/mfd/menf21bmc.c line 201

Quoted 10 lines
drivers/mfd/menf21bmc.c new file +10 -0
+}
+
+static int menf21bmc_remove(struct i2c_client *client)
+{
+	mfd_remove_devices(&client->dev);
+	return 0;
+}
+
+static const struct i2c_device_id menf21bmc_id_table[] = {
+	{"menf21bmc", 0},

Please add a ' ' after '{' and before '}'.

Quoted 8 lines
drivers/mfd/menf21bmc.c new file +8 -0
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, menf21bmc_id_table);
+
+static struct i2c_driver menf21bmc_driver = {
+	.driver		= {
+		.name	= "menf21bmc",
+		.owner	= THIS_MODULE,

drivers/mfd/menf21bmc.c line 219

Quoted 10 lines
drivers/mfd/menf21bmc.c new file +10 -0
+	},
+	.id_table	= menf21bmc_id_table,
+	.probe		= menf21bmc_probe,
+	.remove		= menf21bmc_remove,
+};
+
+module_i2c_driver(menf21bmc_driver);
+
+MODULE_DESCRIPTION("MEN 14F021P00 BMC mfd core driver");
+MODULE_AUTHOR("Andreas Werner <[email protected]");

Missing '>'.

Quoted 28 lines
drivers/mfd/menf21bmc.c new file +1 -0
+MODULE_LICENSE("GPL");
include/linux/mfd/menf21bmc.h new file +21 -0
new file mode 100644
index 0000000..1fc9b5c
@@ -0,0 +1,31 @@
+/*
+ *  MEN 14F021P00 Board Management Controller (BMC)
+ *
+ *  Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
+ *  Author: Andreas Werner <[email protected]>
+ *  All rights reserved.
+ *
+ *  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 MENF21BMC_H
+#define MENF21BMC_H
+
+struct menf21bmc {
+	struct i2c_client *client;
+	struct mutex lock;
+

include/linux/mfd/menf21bmc.h line 31

Quoted 10 lines
include/linux/mfd/menf21bmc.h new file +10 -0
+	int (*read_word_data)(struct i2c_client *client, u8 reg);
+	int (*read_byte_data)(struct i2c_client *client, u8 reg);
+	int (*write_word_data)(struct i2c_client *client, u8 reg, u16 val);
+	int (*write_byte_data)(struct i2c_client *client, u8 reg, u8 val);
+	int (*write_byte)(struct i2c_client *client, u8 val);
+};
+
+#endif /* MENF21BMC_H */
+
+

Too many '\n's here.

Signature · 4 lines
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
#3 lore raw

Re: [PATCH v2 1/3] drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

Quoted 168 lines · Lee Jones
Quoted 29 lines

The MEN 14F021P00 Board Management Controller provides an
I2C interface to the host to access the feature implemented in the BMC. The BMC is a PIC Microntroller assembled on CPCI Card from MEN Mikroelektronik and on a few Box/Display Computer.

Added MFD Core driver, supporting the I2C communication to the device.

The MFD driver currently supports the following features:
- Watchdog
- LEDs

---
 drivers/mfd/Kconfig           |  12 +++
 drivers/mfd/Makefile          |   1 +
 drivers/mfd/menf21bmc.c       | 220 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/menf21bmc.h |  31 ++++++
 4 files changed, 264 insertions(+)
 create mode 100644 drivers/mfd/menf21bmc.c
 create mode 100644 include/linux/mfd/menf21bmc.h
drivers/mfd/Kconfig +0 -0
index ab5a43c..7c2e8d2 100644
@@ -427,6 +427,18 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 

drivers/mfd/Kconfig config MFD_MAX8998 · line 439

Quoted 10 lines
drivers/mfd/Kconfig +10 -0
+config MFD_MENF21BMC
+	tristate "MEN 14F021P00 Board Management Controller Support"
+	depends on I2C=y
+	select MFD_CORE
+	help
+	  Say yes here to add support for the MEN 14F021P00 BMC
+	  which is a Board Management Controller connected to the I2C bus.
+	  This driver provides common support for accessing the devices;
+	  additional drivers must be enabled in order to use the
+	  functionality of the BMC device.

Would be good if you mention the WD and LED devices here too.

drivers/mfd/Kconfig config MFD_MAX8998 · line 441

Quoted 2 lines
drivers/mfd/Kconfig +2 -0
+
+

To many '\n's here.

Quoted 40 lines
drivers/mfd/Kconfig +0 -0
 config EZX_PCAP
 	bool "Motorola EZXPCAP Support"
 	depends on SPI_MASTER
drivers/mfd/Makefile +1 -0
index 5913208..8f2be38 100644
@@ -167,3 +167,4 @@ obj-$(CONFIG_MFD_AS3711)	+= as3711.o
 obj-$(CONFIG_MFD_AS3722)	+= as3722.o
 obj-$(CONFIG_MFD_STW481X)	+= stw481x.o
 obj-$(CONFIG_MFD_IPAQ_MICRO)	+= ipaq-micro.o
+obj-$(CONFIG_MFD_MENF21BMC)	+= menf21bmc.o
drivers/mfd/menf21bmc.c new file +22 -0
new file mode 100644
index 0000000..8de92b5
@@ -0,0 +1,220 @@
+/*
+ *  MEN 14F021P00 Board Management Controller (BMC) MFD Core Driver.
+ *
+ *  Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
+ *  Author: Andreas Werner <[email protected]>
+ *  All rights reserved.
+ *
+ *  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/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/menf21bmc.h>
+
+#define BMC_CMD_REV_MAJOR	0x80

drivers/mfd/menf21bmc.c line 32

Quoted 10 lines
drivers/mfd/menf21bmc.c new file +10 -0
+#define BMC_CMD_REV_MINOR	0x81
+#define BMC_CMD_REV_MAIN	0x82
+#define BMC_CMD_REV_BUILD	0x83
+#define BMC_CMD_REV_VERI	0x84
+#define BMC_CMD_WD_ARM_SET	0x18
+#define BMC_CMD_WD_ARM_GET	0x19
+
+static struct mfd_cell menf21bmc_cell[] = {
+	{
+		.name = "menf21bmc_wd",

I prefer wdog to wd, as it's a little move obvious what we're dealing with.

drivers/mfd/menf21bmc.c line 37

Quoted 5 lines
drivers/mfd/menf21bmc.c new file +5 -0
+	},
+	{
+		.name = "menf21bmc_led",
+	},
+};

If these are the only struct attributes, please place them on a single line (each).

Quoted 58 lines
drivers/mfd/menf21bmc.c new file +58 -0
+static int
+menf21bmc_read_byte_data(struct i2c_client *client, u8 reg)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_read_byte_data(client, reg);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int
+menf21bmc_read_word_data(struct i2c_client *client, u8 reg)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_read_word_data(client, reg);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int menf21bmc_write_byte_data(struct i2c_client *client, u8 reg, u8 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte_data(client, reg, val);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int menf21bmc_write_word_data(struct i2c_client *client, u8 reg, u16 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_word_data(client, reg, val);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int menf21bmc_write_byte(struct i2c_client *client, u8 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte(client, val);
+	mutex_unlock(&data->lock);
Quoted 9 lines

drivers/mfd/menf21bmc.c line 50

Quoted 3 lines
drivers/mfd/menf21bmc.c new file +3 -0
+
+	return ret;
+}

Didn't we ask you to remove these? Just make the i2c_smbus_* calls from within the driver. The I2C subsystem conducts its own locking. I'm really starting to frown on aggregation for the sake of aggregation. It's just overhead.

Correct me if I'm wrong but as far as I remember Guenther asked to retain the original API, not the remove the "abstraction layer". Once we build a board with one of these BMCs attached via e.g. SPI we would have to reintroduce it anyways, in order to re-use these drivers.

Just my 2 cents.

Johannes

#4 lore raw

Re: [PATCH v2 1/3] drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

Quoted 20 lines
Quoted 20 lines
Quoted 20 lines

The MEN 14F021P00 Board Management Controller provides an
I2C interface to the host to access the feature implemented in the BMC. The BMC is a PIC Microntroller assembled on CPCI Card from MEN Mikroelektronik and on a few Box/Display Computer.

Added MFD Core driver, supporting the I2C communication to the device.

The MFD driver currently supports the following features:
- Watchdog
- LEDs

---
 drivers/mfd/Kconfig           |  12 +++
 drivers/mfd/Makefile          |   1 +
 drivers/mfd/menf21bmc.c       | 220 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/menf21bmc.h |  31 ++++++
 4 files changed, 264 insertions(+)
 create mode 100644 drivers/mfd/menf21bmc.c
 create mode 100644 include/linux/mfd/menf21bmc.h

[...]

Quoted 18 lines
Quoted 8 lines
Quoted 8 lines
drivers/mfd/menf21bmc.c new file +8 -0
+static int menf21bmc_write_byte(struct i2c_client *client, u8 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte(client, val);
+	mutex_unlock(&data->lock);
Quoted 9 lines

drivers/mfd/menf21bmc.c line 50

Quoted 3 lines
drivers/mfd/menf21bmc.c new file +3 -0
+
+	return ret;
+}

Didn't we ask you to remove these? Just make the i2c_smbus_* calls from within the driver. The I2C subsystem conducts its own locking. I'm really starting to frown on aggregation for the sake of aggregation. It's just overhead.

Quoted 4 lines

Correct me if I'm wrong but as far as I remember Guenther asked to retain the original API, not the remove the "abstraction layer". Once we build a board with one of these BMCs attached via e.g. SPI we would have to reintroduce it anyways, in order to re-use these drivers.

If there are two or more possible interfaces then I agree, these aggregations would be the best approach. However, as it stands, that's not currently the case.

Genuine question; are Men on the verge of building such a board, or are we talking about 'ifs' and 'maybes'?

Signature · 4 lines
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
author maintainer
#5 lore raw

Re: [PATCH v2 1/3] drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

Quoted 46 lines · Lee Jones
Quoted 20 lines
Quoted 20 lines
Quoted 20 lines

The MEN 14F021P00 Board Management Controller provides an
I2C interface to the host to access the feature implemented in the BMC. The BMC is a PIC Microntroller assembled on CPCI Card from MEN Mikroelektronik and on a few Box/Display Computer.

Added MFD Core driver, supporting the I2C communication to the device.

The MFD driver currently supports the following features:
- Watchdog
- LEDs

---
 drivers/mfd/Kconfig           |  12 +++
 drivers/mfd/Makefile          |   1 +
 drivers/mfd/menf21bmc.c       | 220 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/menf21bmc.h |  31 ++++++
 4 files changed, 264 insertions(+)
 create mode 100644 drivers/mfd/menf21bmc.c
 create mode 100644 include/linux/mfd/menf21bmc.h

[...]

Quoted 18 lines
Quoted 8 lines
Quoted 8 lines
drivers/mfd/menf21bmc.c new file +8 -0
+static int menf21bmc_write_byte(struct i2c_client *client, u8 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte(client, val);
+	mutex_unlock(&data->lock);
Quoted 9 lines

drivers/mfd/menf21bmc.c line 50

Quoted 3 lines
drivers/mfd/menf21bmc.c new file +3 -0
+
+	return ret;
+}

Didn't we ask you to remove these? Just make the i2c_smbus_* calls from within the driver. The I2C subsystem conducts its own locking. I'm really starting to frown on aggregation for the sake of aggregation. It's just overhead.

Quoted 4 lines

Correct me if I'm wrong but as far as I remember Guenther asked to retain the original API, not the remove the "abstraction layer". Once we build a board with one of these BMCs attached via e.g. SPI we would have to reintroduce it anyways, in order to re-use these drivers.

Quoted 7 lines

If there are two or more possible interfaces then I agree, these aggregations would be the best approach. However, as it stands, that's not currently the case.

Genuine question; are Men on the verge of building such a board, or are we talking about 'ifs' and 'maybes'?

I think it was a missunderstanding. I also thought that i just have to adapt the wrapper to the original API, that is what I did in the patch, and not to delete the functions completly.

Anayway, we currently have another project which use a STM32 MCR connected to USB. A nice feature of this STM is to update the firmware using the USB interface. This is easy to implement and fast.

We want to use such a functionality in all of our MCRs to easily update the firmware at the customer if we found a bug.

We also plan to have a BMC connected to USB. Then we have i2c and USB.

Regards
Andy

Quoted 5 lines
Signature · 4 lines
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
maintainer
#6 lore raw

Re: [PATCH v2 1/3] drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

Quoted 59 lines · Andreas Werner
Quoted 46 lines · Lee Jones
Quoted 20 lines
Quoted 20 lines
Quoted 20 lines

The MEN 14F021P00 Board Management Controller provides an
I2C interface to the host to access the feature implemented in the BMC. The BMC is a PIC Microntroller assembled on CPCI Card from MEN Mikroelektronik and on a few Box/Display Computer.

Added MFD Core driver, supporting the I2C communication to the device.

The MFD driver currently supports the following features:
- Watchdog
- LEDs

---
  drivers/mfd/Kconfig           |  12 +++
  drivers/mfd/Makefile          |   1 +
  drivers/mfd/menf21bmc.c       | 220 ++++++++++++++++++++++++++++++++++++++++++
  include/linux/mfd/menf21bmc.h |  31 ++++++
  4 files changed, 264 insertions(+)

create mode 100644 drivers/mfd/menf21bmc.c create mode 100644 include/linux/mfd/menf21bmc.h

[...]

Quoted 18 lines
Quoted 8 lines
Quoted 8 lines
drivers/mfd/menf21bmc.c new file +8 -0
+static int menf21bmc_write_byte(struct i2c_client *client, u8 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte(client, val);
+	mutex_unlock(&data->lock);
Quoted 9 lines

drivers/mfd/menf21bmc.c line 50

Quoted 3 lines
drivers/mfd/menf21bmc.c new file +3 -0
+
+	return ret;
+}

Didn't we ask you to remove these? Just make the i2c_smbus_* calls from within the driver. The I2C subsystem conducts its own locking. I'm really starting to frown on aggregation for the sake of aggregation. It's just overhead.

Quoted 4 lines

Correct me if I'm wrong but as far as I remember Guenther asked to retain the original API, not the remove the "abstraction layer". Once we build a board with one of these BMCs attached via e.g. SPI we would have to reintroduce it anyways, in order to re-use these drivers.

Quoted 7 lines

If there are two or more possible interfaces then I agree, these aggregations would be the best approach. However, as it stands, that's not currently the case.

Genuine question; are Men on the verge of building such a board, or are we talking about 'ifs' and 'maybes'?

I think it was a missunderstanding. I also thought that i just have to adapt the wrapper to the original API, that is what I did in the patch, and not to delete the functions completly.

Quoted 9 lines

Anayway, we currently have another project which use a STM32 MCR connected to USB. A nice feature of this STM is to update the firmware using the USB interface. This is easy to implement and fast.

We want to use such a functionality in all of our MCRs to easily update the firmware at the customer if we found a bug.

We also plan to have a BMC connected to USB. Then we have i2c and USB.

Even more likely that you would have to change the API in that case to be less I2C centric.

Guenter

maintainer
#7 lore raw

Re: [PATCH v2 1/3] drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

Quoted 64 lines · Guenter Roeck
Quoted 63 lines · Andreas Werner
Quoted 46 lines · Lee Jones
Quoted 20 lines
Quoted 20 lines
Quoted 20 lines

The MEN 14F021P00 Board Management Controller provides an
I2C interface to the host to access the feature implemented in the BMC. The BMC is a PIC Microntroller assembled on CPCI Card from MEN Mikroelektronik and on a few Box/Display Computer.

Added MFD Core driver, supporting the I2C communication to the device.

The MFD driver currently supports the following features:
- Watchdog
- LEDs

---
  drivers/mfd/Kconfig           |  12 +++
  drivers/mfd/Makefile          |   1 +
  drivers/mfd/menf21bmc.c       | 220 ++++++++++++++++++++++++++++++++++++++++++
  include/linux/mfd/menf21bmc.h |  31 ++++++
  4 files changed, 264 insertions(+)

create mode 100644 drivers/mfd/menf21bmc.c create mode 100644 include/linux/mfd/menf21bmc.h

[...]

Quoted 18 lines
Quoted 8 lines
Quoted 8 lines
drivers/mfd/menf21bmc.c new file +8 -0
+static int menf21bmc_write_byte(struct i2c_client *client, u8 val)
+{
+    int ret;
+    struct menf21bmc *data = i2c_get_clientdata(client);
+
+    mutex_lock(&data->lock);
+    ret = i2c_smbus_write_byte(client, val);
+    mutex_unlock(&data->lock);
Quoted 9 lines

drivers/mfd/menf21bmc.c line 50

Quoted 3 lines
drivers/mfd/menf21bmc.c new file +3 -0
+
+    return ret;
+}

Didn't we ask you to remove these? Just make the i2c_smbus_* calls from within the driver. The I2C subsystem conducts its own locking. I'm really starting to frown on aggregation for the sake of aggregation. It's just overhead.

Quoted 4 lines

Correct me if I'm wrong but as far as I remember Guenther asked to retain the original API, not the remove the "abstraction layer". Once we build a board with one of these BMCs attached via e.g. SPI we would have to reintroduce it anyways, in order to re-use these drivers.

Quoted 7 lines

If there are two or more possible interfaces then I agree, these aggregations would be the best approach. However, as it stands, that's not currently the case.

Genuine question; are Men on the verge of building such a board, or are we talking about 'ifs' and 'maybes'?

I think it was a missunderstanding. I also thought that i just have to adapt the wrapper to the original API, that is what I did in the patch, and not to delete the functions completly.

Anayway, we currently have another project which use a STM32 MCR connected to USB. A nice feature of this STM is to update the firmware using the USB interface. This is easy to implement and fast.

Quoted 9 lines
Quoted 5 lines

We want to use such a functionality in all of our MCRs to easily update the firmware at the customer if we found a bug.

We also plan to have a BMC connected to USB. Then we have i2c and USB.

Even more likely that you would have to change the API in that case to be less I2C centric.

... especially since you have "struct i2c_client *client" in your API function.

Guenter

author maintainer
#8 lore raw

Re: [PATCH v2 1/3] drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

Quoted 71 lines · Guenter Roeck
Quoted 70 lines · Guenter Roeck
Quoted 68 lines · Andreas Werner
Quoted 46 lines · Lee Jones
Quoted 20 lines
Quoted 20 lines
Quoted 20 lines

The MEN 14F021P00 Board Management Controller provides an
I2C interface to the host to access the feature implemented in the BMC. The BMC is a PIC Microntroller assembled on CPCI Card from MEN Mikroelektronik and on a few Box/Display Computer.

Added MFD Core driver, supporting the I2C communication to the device.

The MFD driver currently supports the following features:
- Watchdog
- LEDs

---
 drivers/mfd/Kconfig           |  12 +++
 drivers/mfd/Makefile          |   1 +
 drivers/mfd/menf21bmc.c       | 220 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/menf21bmc.h |  31 ++++++
 4 files changed, 264 insertions(+)
 create mode 100644 drivers/mfd/menf21bmc.c
 create mode 100644 include/linux/mfd/menf21bmc.h

[...]

Quoted 18 lines
Quoted 8 lines
Quoted 8 lines
(quoted diff) +8 -0
+static int menf21bmc_write_byte(struct i2c_client *client, u8 val)
+{
+    int ret;
+    struct menf21bmc *data = i2c_get_clientdata(client);
+
+    mutex_lock(&data->lock);
+    ret = i2c_smbus_write_byte(client, val);
+    mutex_unlock(&data->lock);
Quoted 9 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+
+    return ret;
+}

Didn't we ask you to remove these? Just make the i2c_smbus_* calls from within the driver. The I2C subsystem conducts its own locking. I'm really starting to frown on aggregation for the sake of aggregation. It's just overhead.

Quoted 4 lines

Correct me if I'm wrong but as far as I remember Guenther asked to retain the original API, not the remove the "abstraction layer". Once we build a board with one of these BMCs attached via e.g. SPI we would have to reintroduce it anyways, in order to re-use these drivers.

Quoted 7 lines

If there are two or more possible interfaces then I agree, these aggregations would be the best approach. However, as it stands, that's not currently the case.

Genuine question; are Men on the verge of building such a board, or are we talking about 'ifs' and 'maybes'?

I think it was a missunderstanding. I also thought that i just have to adapt the wrapper to the original API, that is what I did in the patch, and not to delete the functions completly.

Anayway, we currently have another project which use a STM32 MCR connected to USB. A nice feature of this STM is to update the firmware using the USB interface. This is easy to implement and fast.

We want to use such a functionality in all of our MCRs to easily update the firmware at the customer if we found a bug.

We also plan to have a BMC connected to USB. Then we have i2c and USB.

Quoted 9 lines
Quoted 3 lines

Even more likely that you would have to change the API in that case to be less I2C centric.

... especially since you have "struct i2c_client *client" in your API function.

Guenter

Ok I agree. I will change that and delete the wrapper functions completley. I will prepare and send a v3.

Thanks for the discussion.

Regards
Andy

maintainer
#9 lore raw

Re: [PATCH v2 1/3] drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

In reply to Johannes Thumshirn

On 05/28/2014 12:02 AM, Johannes Thumshirn wrote:
[ ... ]

Quoted 19 lines
Quoted 9 lines
Quoted 9 lines
drivers/mfd/menf21bmc.c new file +9 -0
+
+static int menf21bmc_write_byte(struct i2c_client *client, u8 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte(client, val);
+	mutex_unlock(&data->lock);
Quoted 9 lines

drivers/mfd/menf21bmc.c line 50

Quoted 3 lines
drivers/mfd/menf21bmc.c new file +3 -0
+
+	return ret;
+}

Didn't we ask you to remove these? Just make the i2c_smbus_* calls from within the driver. The I2C subsystem conducts its own locking. I'm really starting to frown on aggregation for the sake of aggregation. It's just overhead.

Quoted 5 lines

Correct me if I'm wrong but as far as I remember Guenther asked to retain the original API, not the remove the "abstraction layer". Once we build a board with one of these BMCs attached via e.g. SPI we would have to reintroduce it anyways, in order to re-use these drivers.

If you introduce boards with SPI support, you'll likely have to change those APIs, since some of the functions don't make sense in the SPI world. So I tend to agree with Lee. If you need those APIs later on you can introduce them at that time, and introduce them such that they truly work for all hardware variants.

Guenter

author maintainer
#10 lore raw

Re: [PATCH v2 1/3] drivers/mfd/menf21bmc: introduce MEN 14F021P00 BMC MFD Core driver

In reply to Lee Jones
Quoted 42 lines · Lee Jones
Quoted 29 lines

The MEN 14F021P00 Board Management Controller provides an
I2C interface to the host to access the feature implemented in the BMC. The BMC is a PIC Microntroller assembled on CPCI Card from MEN Mikroelektronik and on a few Box/Display Computer.

Added MFD Core driver, supporting the I2C communication to the device.

The MFD driver currently supports the following features:
- Watchdog
- LEDs

---
 drivers/mfd/Kconfig           |  12 +++
 drivers/mfd/Makefile          |   1 +
 drivers/mfd/menf21bmc.c       | 220 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/menf21bmc.h |  31 ++++++
 4 files changed, 264 insertions(+)
 create mode 100644 drivers/mfd/menf21bmc.c
 create mode 100644 include/linux/mfd/menf21bmc.h
drivers/mfd/Kconfig +0 -0
index ab5a43c..7c2e8d2 100644
@@ -427,6 +427,18 @@ config MFD_MAX8998
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 

drivers/mfd/Kconfig config MFD_MAX8998 · line 439

Quoted 10 lines
drivers/mfd/Kconfig +10 -0
+config MFD_MENF21BMC
+	tristate "MEN 14F021P00 Board Management Controller Support"
+	depends on I2C=y
+	select MFD_CORE
+	help
+	  Say yes here to add support for the MEN 14F021P00 BMC
+	  which is a Board Management Controller connected to the I2C bus.
+	  This driver provides common support for accessing the devices;
+	  additional drivers must be enabled in order to use the
+	  functionality of the BMC device.

Would be good if you mention the WD and LED devices here too.

Quoted 4 lines

drivers/mfd/Kconfig config MFD_MAX8998 · line 441

Quoted 2 lines
drivers/mfd/Kconfig +2 -0
+
+

To many '\n's here.

I will ad WD and LED and fix the \n.

Quoted 46 lines
Quoted 46 lines
drivers/mfd/Kconfig +0 -0
 config EZX_PCAP
 	bool "Motorola EZXPCAP Support"
 	depends on SPI_MASTER
drivers/mfd/Makefile +1 -0
index 5913208..8f2be38 100644
@@ -167,3 +167,4 @@ obj-$(CONFIG_MFD_AS3711)	+= as3711.o
 obj-$(CONFIG_MFD_AS3722)	+= as3722.o
 obj-$(CONFIG_MFD_STW481X)	+= stw481x.o
 obj-$(CONFIG_MFD_IPAQ_MICRO)	+= ipaq-micro.o
+obj-$(CONFIG_MFD_MENF21BMC)	+= menf21bmc.o
drivers/mfd/menf21bmc.c new file +27 -0
new file mode 100644
index 0000000..8de92b5
@@ -0,0 +1,220 @@
+/*
+ *  MEN 14F021P00 Board Management Controller (BMC) MFD Core Driver.
+ *
+ *  Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
+ *  Author: Andreas Werner <[email protected]>
+ *  All rights reserved.
+ *
+ *  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/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/menf21bmc.h>
+
+#define BMC_CMD_REV_MAJOR	0x80
+#define BMC_CMD_REV_MINOR	0x81
+#define BMC_CMD_REV_MAIN	0x82
+#define BMC_CMD_REV_BUILD	0x83
+#define BMC_CMD_REV_VERI	0x84
+#define BMC_CMD_WD_ARM_SET	0x18
Quoted 8 lines

drivers/mfd/menf21bmc.c line 32

Quoted 5 lines
drivers/mfd/menf21bmc.c new file +5 -0
+#define BMC_CMD_WD_ARM_GET	0x19
+
+static struct mfd_cell menf21bmc_cell[] = {
+	{
+		.name = "menf21bmc_wd",

I prefer wdog to wd, as it's a little move obvious what we're dealing with.

I agree.

Quoted 10 lines

drivers/mfd/menf21bmc.c line 37

Quoted 6 lines
drivers/mfd/menf21bmc.c new file +5 -0
+	},
+	{
+		.name = "menf21bmc_led",
+	},
+};

If these are the only struct attributes, please place them on a single line (each).

Ok i'll change that.

Quoted 58 lines
Quoted 58 lines
drivers/mfd/menf21bmc.c new file +58 -0
+static int
+menf21bmc_read_byte_data(struct i2c_client *client, u8 reg)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_read_byte_data(client, reg);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int
+menf21bmc_read_word_data(struct i2c_client *client, u8 reg)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_read_word_data(client, reg);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int menf21bmc_write_byte_data(struct i2c_client *client, u8 reg, u8 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte_data(client, reg, val);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int menf21bmc_write_word_data(struct i2c_client *client, u8 reg, u16 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_word_data(client, reg, val);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int menf21bmc_write_byte(struct i2c_client *client, u8 val)
+{
+	int ret;
+	struct menf21bmc *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->lock);
+	ret = i2c_smbus_write_byte(client, val);
+	mutex_unlock(&data->lock);
Quoted 9 lines

drivers/mfd/menf21bmc.c line 50

Quoted 3 lines
drivers/mfd/menf21bmc.c new file +3 -0
+
+	return ret;
+}

Didn't we ask you to remove these? Just make the i2c_smbus_* calls from within the driver. The I2C subsystem conducts its own locking. I'm really starting to frown on aggregation for the sake of aggregation. It's just overhead.

I'll remove that.

Quoted 9 lines

drivers/mfd/menf21bmc.c line 105

Quoted 5 lines
drivers/mfd/menf21bmc.c new file +5 -0
+static int menf21bmc_wd_leave_prod_mode(struct i2c_client *client)
+{
+	int val, ret;
+
+	val = menf21bmc_read_byte_data(client, BMC_CMD_WD_ARM_GET);

ARM like the processor, or 'arm' as in "arm the missile", or something else?

I will change that name.

Quoted 12 lines

drivers/mfd/menf21bmc.c line 113

Quoted 8 lines
drivers/mfd/menf21bmc.c new file +8 -0
+	if (val < 0)
+		return val;
+
+	/*
+	 * Production mode should be not active after delivery of the Board.
+	 * To be sure we check it, inform the user and leave the mode
+	 * if active.
+	 */

I prefer the term 'exit', as 'leave' is ambiguous. It could read "leave it in production mode", or "leave (exit) production mode".

I agree.

Quoted 17 lines
Quoted 17 lines
drivers/mfd/menf21bmc.c new file +17 -0
+	if (val == 0x00) {
+		dev_info(&client->dev,
+			"BMC in production mode. Leave production mode\n");
+
+		ret = menf21bmc_write_byte(client, BMC_CMD_WD_ARM_SET);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int
+menf21bmc_probe(struct i2c_client *client, const struct i2c_device_id *ids)
+{
+	int ret;
+	struct menf21bmc *data;
Quoted 9 lines

drivers/mfd/menf21bmc.c line 136

Quoted 6 lines
drivers/mfd/menf21bmc.c new file +6 -0
+	int rev_major, rev_minor, rev_main;
+
+	if (!i2c_check_functionality(client->adapter,
+						I2C_FUNC_SMBUS_BYTE_DATA |
+						I2C_FUNC_SMBUS_WORD_DATA |
+						I2C_FUNC_SMBUS_BYTE))

Tabbing is off. Try to line up with the '('.

I agree.

Quoted 3 lines

drivers/mfd/menf21bmc.c line 137

Quoted 1 line
drivers/mfd/menf21bmc.c new file +1 -0
+		return -EIO;

-ENODEV is more common.

I agree.

Quoted 11 lines

drivers/mfd/menf21bmc.c line 139

Quoted 2 lines
drivers/mfd/menf21bmc.c new file +1 -0
+	data = devm_kzalloc(&client->dev, sizeof(struct menf21bmc), GFP_KERNEL);

s/sizeof(struct menf21bmc)/sizeof(*data)/

data doesn't tend to be a good name for a variable.

drivers/mfd/menf21bmc.c line 140

Quoted 1 line
drivers/mfd/menf21bmc.c new file +1 -0
+	if (data == NULL)

if (!data)

Quoted 14 lines

drivers/mfd/menf21bmc.c line 151

Quoted 11 lines
drivers/mfd/menf21bmc.c new file +11 -0
+		return -ENOMEM;
+
+	mutex_init(&data->lock);
+
+	i2c_set_clientdata(client, data);
+	data->client = client;
+	data->read_word_data = menf21bmc_read_word_data;
+	data->read_byte_data = menf21bmc_read_byte_data;
+	data->write_word_data = menf21bmc_write_word_data;
+	data->write_byte_data = menf21bmc_write_byte_data;
+	data->write_byte = menf21bmc_write_byte;

Yuck, please remove these.

Yes will be removed.

Quoted 24 lines
Quoted 24 lines
drivers/mfd/menf21bmc.c new file +24 -0
+	rev_major = menf21bmc_read_word_data(client, BMC_CMD_REV_MAJOR);
+	if (rev_major < 0) {
+		dev_err(&client->dev, "failed to get BMC major revision\n");
+		return rev_major;
+	}
+
+	rev_minor = menf21bmc_read_word_data(client, BMC_CMD_REV_MINOR);
+	if (rev_minor < 0) {
+		dev_err(&client->dev, "failed to get BMC minor revision\n");
+		return rev_minor;
+	}
+
+	rev_main = menf21bmc_read_word_data(client, BMC_CMD_REV_MAIN);
+	if (rev_main < 0) {
+		dev_err(&client->dev, "failed to get BMC main revision\n");
+		return rev_main;
+	}
+
+	dev_info(&client->dev, "FW Revision: %02d.%02d.%02d\n",
+					rev_major, rev_minor, rev_main);
+
+	/*
+	 * We have to leave the Production Mode of the BMC to activate the
+	 * Watchdog functionality and the BIOS life sign monitoring.
Quoted 9 lines

drivers/mfd/menf21bmc.c line 182

Quoted 6 lines
drivers/mfd/menf21bmc.c new file +6 -0
+	 */
+	ret = menf21bmc_wd_leave_prod_mode(client);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to leave production mode\n");
+		return ret;
+	}

Is it possible that someone might want to use production mode?

No it is just for the board bring up. Because if the BIOS does not implement the Life sign the BMC will not start the Board. Production mode is active after programming the PIC.

Quoted 9 lines

drivers/mfd/menf21bmc.c line 187

Quoted 4 lines
drivers/mfd/menf21bmc.c new file +4 -0
+	ret = mfd_add_devices(&client->dev, 0, menf21bmc_cell,
+				ARRAY_SIZE(menf21bmc_cell), NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(&client->dev, "mfd_add_devices failed\n");

This error message should be more useful to the user.

E.g. "Failed to add sub-devices"

I'll change that.

Quoted 8 lines
Quoted 8 lines
drivers/mfd/menf21bmc.c new file +8 -0
+		return ret;
+	}
+
+	return 0;
+}
+
+static int menf21bmc_remove(struct i2c_client *client)
+{
Quoted 9 lines

drivers/mfd/menf21bmc.c line 201

Quoted 6 lines
drivers/mfd/menf21bmc.c new file +6 -0
+	mfd_remove_devices(&client->dev);
+	return 0;
+}
+
+static const struct i2c_device_id menf21bmc_id_table[] = {
+	{"menf21bmc", 0},

Please add a ' ' after '{' and before '}'.

I agree.

Quoted 12 lines
Quoted 12 lines
drivers/mfd/menf21bmc.c new file +12 -0
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, menf21bmc_id_table);
+
+static struct i2c_driver menf21bmc_driver = {
+	.driver		= {
+		.name	= "menf21bmc",
+		.owner	= THIS_MODULE,
+	},
+	.id_table	= menf21bmc_id_table,
+	.probe		= menf21bmc_probe,
+	.remove		= menf21bmc_remove,
Quoted 8 lines

drivers/mfd/menf21bmc.c line 219

Quoted 6 lines
drivers/mfd/menf21bmc.c new file +6 -0
+};
+
+module_i2c_driver(menf21bmc_driver);
+
+MODULE_DESCRIPTION("MEN 14F021P00 BMC mfd core driver");
+MODULE_AUTHOR("Andreas Werner <[email protected]");

Missing '>'.

I'll change that.

Quoted 33 lines
Quoted 33 lines
drivers/mfd/menf21bmc.c new file +1 -0
+MODULE_LICENSE("GPL");
include/linux/mfd/menf21bmc.h new file +25 -0
new file mode 100644
index 0000000..1fc9b5c
@@ -0,0 +1,31 @@
+/*
+ *  MEN 14F021P00 Board Management Controller (BMC)
+ *
+ *  Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
+ *  Author: Andreas Werner <[email protected]>
+ *  All rights reserved.
+ *
+ *  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 MENF21BMC_H
+#define MENF21BMC_H
+
+struct menf21bmc {
+	struct i2c_client *client;
+	struct mutex lock;
+
+	int (*read_word_data)(struct i2c_client *client, u8 reg);
+	int (*read_byte_data)(struct i2c_client *client, u8 reg);
+	int (*write_word_data)(struct i2c_client *client, u8 reg, u16 val);
+	int (*write_byte_data)(struct i2c_client *client, u8 reg, u8 val);
Quoted 9 lines

include/linux/mfd/menf21bmc.h line 31

Quoted 6 lines
include/linux/mfd/menf21bmc.h new file +6 -0
+	int (*write_byte)(struct i2c_client *client, u8 val);
+};
+
+#endif /* MENF21BMC_H */
+
+

Too many '\n's here.

I'll change that.

Quoted 5 lines
Signature · 4 lines
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

Thanks.
Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author maintainer
#11 lore raw

PATCH v2 2/3 drivers/watchdog/menf21bmc_wd: introduce MEN 14F021P00 BMC Watchdog driver

In reply to Andreas Werner

Added driver to support the 14F021P00 BMC Watchdog.
The BMC is a Board Management Controller including watchdog functionality.

This driver use the I2C interface to the BMC using the menf21bmc MFD Core driver.

---
 drivers/watchdog/Kconfig        |   7 ++
 drivers/watchdog/Makefile       |   1 +
 drivers/watchdog/menf21bmc_wd.c | 217 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 225 insertions(+)
 create mode 100644 drivers/watchdog/menf21bmc_wd.c
drivers/watchdog/Kconfig +7 -0
index 2b4c1fc..ede3201 100644
@@ -95,6 +95,13 @@ config GPIO_WATCHDOG
 	  If you say yes here you get support for watchdog device
 	  controlled through GPIO-line.
 
+config MENF21BMC_WATCHDOG
+	tristate "MEN 14F021P00 BMC Watchdog"
+	depends on MFD_MENF21BMC
+	select WATCHDOG_CORE
+	help
+	  Say Y here to include support for the MEN 14F021P00 BMC Watchdog.
+
 config WM831X_WATCHDOG
 	tristate "WM831x watchdog"
 	depends on MFD_WM831X
drivers/watchdog/Makefile +1 -0
index 1b5f3d5..0a5465d 100644
@@ -178,3 +178,4 @@ obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
 obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
 obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
 obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
+obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wd.o
drivers/watchdog/menf21bmc_wd.c new file +217 -0

217 lines not on this page · raw message

Signature · 1 line
1.9.3
author maintainer
#12 lore raw

PATCH v2 3/3 drivers/leds/leds-menf21bmc: introduce MEN 14F021P00 BMC LED driver

In reply to Andreas Werner

Added driver to support the 14F021P00 BMC LEDs.
The BMC is a Board Management Controll include four LEDs which can be switched on and off.

This driver use the I2C interface to the BMC using the menf21bmc MFD Core driver.

---
 drivers/leds/Kconfig          |   6 ++
 drivers/leds/Makefile         |   2 +-
 drivers/leds/leds-menf21bmc.c | 136 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100644 drivers/leds/leds-menf21bmc.c
drivers/leds/Kconfig +6 -0
index 1e81d7a..8f98e0f 100644
@@ -466,6 +466,12 @@ config LEDS_OT200
 	  This option enables support for the LEDs on the Bachmann OT200.
 	  Say Y to enable LEDs on the Bachmann OT200.
 
+config LEDS_MENF21BMC
+	tristate "LED support for the MEN 14F021P00 BMC"
+	depends on LEDS_CLASS && MFD_MENF21BMC
+	help
+	  Say Y here to include support for the MEN 14F021P00 BMC LEDs.
+
 comment "LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)"
 
 config LEDS_BLINKM
drivers/leds/Makefile +1 -1
index 79c5155..1c465fe 100644
@@ -54,7 +54,7 @@ obj-$(CONFIG_LEDS_MAX8997)		+= leds-max8997.o
 obj-$(CONFIG_LEDS_LM355x)		+= leds-lm355x.o
 obj-$(CONFIG_LEDS_BLINKM)		+= leds-blinkm.o
 obj-$(CONFIG_LEDS_VERSATILE)		+= leds-versatile.o
-
+obj-$(CONFIG_LEDS_MENF21BMC)		+= leds-menf21bmc.o
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
 
drivers/leds/leds-menf21bmc.c new file +136 -0

136 lines not on this page · raw message

Signature · 1 line
1.9.3
#13 lore raw

Re: [PATCH v2 3/3] drivers/leds/leds-menf21bmc: introduce MEN 14F021P00 BMC LED driver

Quoted 6 lines · Andreas Werner

Added driver to support the 14F021P00 BMC LEDs.
The BMC is a Board Management Controll include four LEDs which can be switched on and off.

This driver use the I2C interface to the BMC using the menf21bmc MFD Core driver.

Will you submit v2 patch based on Lee and others' review? I prefer to review the new one.

Thanks,
-Bryan

Quoted 183 lines
---
 drivers/leds/Kconfig          |   6 ++
 drivers/leds/Makefile         |   2 +-
 drivers/leds/leds-menf21bmc.c | 136 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100644 drivers/leds/leds-menf21bmc.c
drivers/leds/Kconfig +6 -0
index 1e81d7a..8f98e0f 100644
@@ -466,6 +466,12 @@ config LEDS_OT200
          This option enables support for the LEDs on the Bachmann OT200.
          Say Y to enable LEDs on the Bachmann OT200.
 
+config LEDS_MENF21BMC
+       tristate "LED support for the MEN 14F021P00 BMC"
+       depends on LEDS_CLASS && MFD_MENF21BMC
+       help
+         Say Y here to include support for the MEN 14F021P00 BMC LEDs.
+
 comment "LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)"
 
 config LEDS_BLINKM
drivers/leds/Makefile +1 -1
index 79c5155..1c465fe 100644
@@ -54,7 +54,7 @@ obj-$(CONFIG_LEDS_MAX8997)            += leds-max8997.o
 obj-$(CONFIG_LEDS_LM355x)              += leds-lm355x.o
 obj-$(CONFIG_LEDS_BLINKM)              += leds-blinkm.o
 obj-$(CONFIG_LEDS_VERSATILE)           += leds-versatile.o
-
+obj-$(CONFIG_LEDS_MENF21BMC)           += leds-menf21bmc.o
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)          += leds-dac124s085.o
 
drivers/leds/leds-menf21bmc.c new file +136 -1
new file mode 100644
index 0000000..6099524
@@ -0,0 +1,136 @@
+/*
+ *  MEN 14F021P00 Board Management Controller (BMC) LEDs Driver.
+ *
+ *  This is the core LED driver of the MEN 14F021P00 BMC.
+ *  There are four LEDs available which can be switched on and off.
+ *  STATUS LED, HOT SWAP LED, USER LED 1, USER LED 2
+ *
+ *  Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
+ *  Author: Andreas Werner <[email protected]>
+ *  All rights reserved.
+ *
+ *  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/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/mfd/menf21bmc.h>
+
+#define BMC_CMD_LED_GET_SET    0xA0
+#define BMC_BIT_LED_STATUS     BIT(0)
+#define BMC_BIT_LED_HOTSWAP    BIT(1)
+#define BMC_BIT_LED_USER1      BIT(2)
+#define BMC_BIT_LED_USER2      BIT(3)
+
+struct menf21bmc_led_data {
+       struct led_classdev cdev;
+       struct menf21bmc *menf21bmc;
+       u8 led_bit;
+       const char *name;
+};
+
+static struct menf21bmc_led_data leds[] = {
+       {
+               .name = "menf21bmc:led_status",
+               .led_bit = BMC_BIT_LED_STATUS,
+       },
+       {
+               .name = "menf21bmc:led_hotswap",
+               .led_bit = BMC_BIT_LED_HOTSWAP,
+       },
+       {
+               .name = "menf21bmc:led_user1",
+               .led_bit = BMC_BIT_LED_USER1,
+       },
+       {
+               .name = "menf21bmc:led_user2",
+               .led_bit = BMC_BIT_LED_USER2,
+       }
+};
+
+static DEFINE_MUTEX(led_lock);
+
+static void
+menf21bmc_led_set(struct led_classdev *led_cdev, enum led_brightness value)
+{
+       int led_val;
+       struct menf21bmc_led_data *led = container_of(led_cdev,
+                                       struct menf21bmc_led_data, cdev);
+       struct menf21bmc *menf21bmc = led->menf21bmc;
+
+       mutex_lock(&led_lock);
+       led_val = menf21bmc->read_byte_data(menf21bmc->client,
+                                               BMC_CMD_LED_GET_SET);
+       if (led_val < 0)
+               goto err_out;
+
+       if (value == LED_OFF)
+               led_val &= ~led->led_bit;
+       else
+               led_val |= led->led_bit;
+
+       menf21bmc->write_byte_data(menf21bmc->client,
+                                       BMC_CMD_LED_GET_SET, led_val);
+err_out:
+       mutex_unlock(&led_lock);
+}
+
+static int menf21bmc_led_probe(struct platform_device *pdev)
+{
+       int i;
+       int ret;
+       struct menf21bmc *menf21bmc = dev_get_drvdata(pdev->dev.parent);
+
+       for (i = 0; i < ARRAY_SIZE(leds); i++) {
+               leds[i].cdev.name = leds[i].name;
+               leds[i].cdev.brightness_set = menf21bmc_led_set;
+               leds[i].menf21bmc = menf21bmc;
+
+               ret = led_classdev_register(&pdev->dev, &leds[i].cdev);
+               if (ret < 0)
+                       goto err_free_leds;
+       }
+       dev_info(&pdev->dev, "MEN 140F21P00 BMC LED device enabled\n");
+
+       return 0;
+
+err_free_leds:
+       dev_err(&pdev->dev, "failed to register LED devicei\n");
+
+       for (i = i - 1; i >= 0; i--)
+               led_classdev_unregister(&leds[i].cdev);
+
+       return ret;
+}
+
+static int menf21bmc_led_remove(struct platform_device *pdev)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(leds); i++)
+               led_classdev_unregister(&leds[i].cdev);
+
+       return 0;
+}
+
+static struct platform_driver menf21bmc_led = {
+       .probe          = menf21bmc_led_probe,
+       .remove         = menf21bmc_led_remove,
+       .driver         = {
+               .name           = "menf21bmc_led",
+               .owner          = THIS_MODULE,
+       },
+};
+
+module_platform_driver(menf21bmc_led);
+
+MODULE_AUTHOR("Andreas Werner <[email protected]>");
+MODULE_DESCRIPTION("MEN 14F021P00 BMC led driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:menf21bmc_led");
--

1.9.3

#14 lore raw

AW: [PATCH v2 3/3] drivers/leds/leds-menf21bmc: introduce MEN 14F021P00 BMC LED driver

Quoted 16 lines

Von: Bryan Wu [mailto:[email protected]]
Gesendet: Donnerstag, 26. Juni 2014 01:11
An: Werner, Andreas
Cc: lkml; Samuel Ortiz; Lee Jones; [email protected]; linux- [email protected]; [email protected]; Linux LED Subsystem; Thumshirn, Johannes Tobias
Betreff: Re: [PATCH v2 3/3] drivers/leds/leds-menf21bmc: introduce MEN 14F021P00 BMC LED driver

Quoted 5 lines · Andreas Werner

Added driver to support the 14F021P00 BMC LEDs.
The BMC is a Board Management Controll include four LEDs which can be switched on and off.

This driver use the I2C interface to the BMC using the menf21bmc MFD Core

Quoted 8 lines

driver.

Quoted 1 line

Will you submit v2 patch based on Lee and others' review? I prefer to review the new one.

Thanks,
-Bryan

Hi,
Andreas is currently on vacation, but he'll send a v3 as soon as he's back.

Johannes
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay� ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m���� ������?�I�

author maintainer
#15 lore raw

Re: [PATCH v2 3/3] drivers/leds/leds-menf21bmc: introduce MEN 14F021P00 BMC LED driver

In reply to Bryan Wu
Quoted 11 lines · Bryan Wu
Quoted 6 lines · Andreas Werner

Added driver to support the 14F021P00 BMC LEDs.
The BMC is a Board Management Controll include four LEDs which can be switched on and off.

This driver use the I2C interface to the BMC using the menf21bmc MFD Core driver.

Will you submit v2 patch based on Lee and others' review? I prefer to review the new one.

Patch v3 is submitted so you can start review it :-)

Thanks
Andy

Quoted 186 lines

Thanks,
-Bryan

Quoted 183 lines
---
 drivers/leds/Kconfig          |   6 ++
 drivers/leds/Makefile         |   2 +-
 drivers/leds/leds-menf21bmc.c | 136 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100644 drivers/leds/leds-menf21bmc.c
drivers/leds/Kconfig +6 -0
index 1e81d7a..8f98e0f 100644
@@ -466,6 +466,12 @@ config LEDS_OT200
          This option enables support for the LEDs on the Bachmann OT200.
          Say Y to enable LEDs on the Bachmann OT200.
 
+config LEDS_MENF21BMC
+       tristate "LED support for the MEN 14F021P00 BMC"
+       depends on LEDS_CLASS && MFD_MENF21BMC
+       help
+         Say Y here to include support for the MEN 14F021P00 BMC LEDs.
+
 comment "LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)"
 
 config LEDS_BLINKM
drivers/leds/Makefile +1 -1
index 79c5155..1c465fe 100644
@@ -54,7 +54,7 @@ obj-$(CONFIG_LEDS_MAX8997)            += leds-max8997.o
 obj-$(CONFIG_LEDS_LM355x)              += leds-lm355x.o
 obj-$(CONFIG_LEDS_BLINKM)              += leds-blinkm.o
 obj-$(CONFIG_LEDS_VERSATILE)           += leds-versatile.o
-
+obj-$(CONFIG_LEDS_MENF21BMC)           += leds-menf21bmc.o
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)          += leds-dac124s085.o
 
drivers/leds/leds-menf21bmc.c new file +136 -1
new file mode 100644
index 0000000..6099524
@@ -0,0 +1,136 @@
+/*
+ *  MEN 14F021P00 Board Management Controller (BMC) LEDs Driver.
+ *
+ *  This is the core LED driver of the MEN 14F021P00 BMC.
+ *  There are four LEDs available which can be switched on and off.
+ *  STATUS LED, HOT SWAP LED, USER LED 1, USER LED 2
+ *
+ *  Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
+ *  Author: Andreas Werner <[email protected]>
+ *  All rights reserved.
+ *
+ *  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/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/mfd/menf21bmc.h>
+
+#define BMC_CMD_LED_GET_SET    0xA0
+#define BMC_BIT_LED_STATUS     BIT(0)
+#define BMC_BIT_LED_HOTSWAP    BIT(1)
+#define BMC_BIT_LED_USER1      BIT(2)
+#define BMC_BIT_LED_USER2      BIT(3)
+
+struct menf21bmc_led_data {
+       struct led_classdev cdev;
+       struct menf21bmc *menf21bmc;
+       u8 led_bit;
+       const char *name;
+};
+
+static struct menf21bmc_led_data leds[] = {
+       {
+               .name = "menf21bmc:led_status",
+               .led_bit = BMC_BIT_LED_STATUS,
+       },
+       {
+               .name = "menf21bmc:led_hotswap",
+               .led_bit = BMC_BIT_LED_HOTSWAP,
+       },
+       {
+               .name = "menf21bmc:led_user1",
+               .led_bit = BMC_BIT_LED_USER1,
+       },
+       {
+               .name = "menf21bmc:led_user2",
+               .led_bit = BMC_BIT_LED_USER2,
+       }
+};
+
+static DEFINE_MUTEX(led_lock);
+
+static void
+menf21bmc_led_set(struct led_classdev *led_cdev, enum led_brightness value)
+{
+       int led_val;
+       struct menf21bmc_led_data *led = container_of(led_cdev,
+                                       struct menf21bmc_led_data, cdev);
+       struct menf21bmc *menf21bmc = led->menf21bmc;
+
+       mutex_lock(&led_lock);
+       led_val = menf21bmc->read_byte_data(menf21bmc->client,
+                                               BMC_CMD_LED_GET_SET);
+       if (led_val < 0)
+               goto err_out;
+
+       if (value == LED_OFF)
+               led_val &= ~led->led_bit;
+       else
+               led_val |= led->led_bit;
+
+       menf21bmc->write_byte_data(menf21bmc->client,
+                                       BMC_CMD_LED_GET_SET, led_val);
+err_out:
+       mutex_unlock(&led_lock);
+}
+
+static int menf21bmc_led_probe(struct platform_device *pdev)
+{
+       int i;
+       int ret;
+       struct menf21bmc *menf21bmc = dev_get_drvdata(pdev->dev.parent);
+
+       for (i = 0; i < ARRAY_SIZE(leds); i++) {
+               leds[i].cdev.name = leds[i].name;
+               leds[i].cdev.brightness_set = menf21bmc_led_set;
+               leds[i].menf21bmc = menf21bmc;
+
+               ret = led_classdev_register(&pdev->dev, &leds[i].cdev);
+               if (ret < 0)
+                       goto err_free_leds;
+       }
+       dev_info(&pdev->dev, "MEN 140F21P00 BMC LED device enabled\n");
+
+       return 0;
+
+err_free_leds:
+       dev_err(&pdev->dev, "failed to register LED devicei\n");
+
+       for (i = i - 1; i >= 0; i--)
+               led_classdev_unregister(&leds[i].cdev);
+
+       return ret;
+}
+
+static int menf21bmc_led_remove(struct platform_device *pdev)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(leds); i++)
+               led_classdev_unregister(&leds[i].cdev);
+
+       return 0;
+}
+
+static struct platform_driver menf21bmc_led = {
+       .probe          = menf21bmc_led_probe,
+       .remove         = menf21bmc_led_remove,
+       .driver         = {
+               .name           = "menf21bmc_led",
+               .owner          = THIS_MODULE,
+       },
+};
+
+module_platform_driver(menf21bmc_led);
+
+MODULE_AUTHOR("Andreas Werner <[email protected]>");
+MODULE_DESCRIPTION("MEN 14F021P00 BMC led driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:menf21bmc_led");
--

1.9.3