openbmc.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] sysfs interface to miscellaneous BMC controls and fields
@ 2018-07-03  7:04 Andrew Jeffery
  2018-07-03  7:04 ` [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl Andrew Jeffery
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Andrew Jeffery @ 2018-07-03  7:04 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Jeffery, robh+dt, mark.rutland, joel, gregkh, Eugene.Cho,
	a.amelkin, stewart, benh, openbmc, devicetree, linux-arm-kernel

*Dons firefighting gear*

Hello,

This series introduces a bmc-misc-ctrl driver for exposing hardware interfaces
provided by the BMC (Baseboard Management Controller) for scratch register
communication between the host and the BMC, and other miscellaneous switches
controlling BMC hardware features that can be exposed to the host.

Previously Ben Herrenschmidt sent mail wanting to get some consensus on a good
way forward:

https://lkml.org/lkml/2018/4/10/222

To summarise Ben's points:

We have found that the controls we need to expose do not fit well into existing
driver models for several reasons:

1. Not exposing the fields to userspace would instead mean encoding policy
   affecting the host system into the BMC kernel (typically scratch registers)
2. Some controls are so unique as to defy integration into other drivers
3. Exposing specific, well-constrained fields feels less evil than falling back
   to devmem.

This series is one implementation of what we had in mind. My motivation is with
respect to ASPEED BMC hardware but Dell have also indicated they would also
make use of something similar for Nuvoton BMCs.

To those ends, the implementation of bmc-misc-ctrl introduced here:

1. Uses devicetree to describe the miscellaneous fields and switches
2. Exposes the fields in sysfs via value/mask/set/clear attributes
3. Adds a 'bmc' class for the fields to aid discovery in userspace

Now, the intent is bmc-misc-ctrl is used as a last resort. If features can
sanely be exposed in more appropriate drivers, then that should (obviously) be
done instead.

I'm sending this out as an RFC as I'm sure people will have feedback. I hope it
will be more constructive than 'NAK'.

Thanks,

Andrew

Andrew Jeffery (4):
  dts: misc: Add bindings documentation for bmc-misc-ctrl
  Documentation: ABI: Add sysfs-class-bmc documentation to testing
  misc: Add bmc-misc-ctrl
  dts: aspeed-g5: Add bmc-misc-ctrl nodes to devicetree

 Documentation/ABI/testing/sysfs-class-bmc     |  62 +++
 .../bindings/misc/bmc-misc-ctrl.txt           | 252 ++++++++++++
 MAINTAINERS                                   |   7 +
 arch/arm/boot/dts/aspeed-g5.dtsi              | 192 +++++++++
 drivers/misc/Kconfig                          |   8 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/bmc-misc-ctrl.c                  | 363 ++++++++++++++++++
 7 files changed, 885 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-bmc
 create mode 100644 Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt
 create mode 100644 drivers/misc/bmc-misc-ctrl.c

-- 
2.17.1

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

* [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl
  2018-07-03  7:04 [RFC PATCH 0/4] sysfs interface to miscellaneous BMC controls and fields Andrew Jeffery
@ 2018-07-03  7:04 ` Andrew Jeffery
  2018-07-03  7:50   ` Greg KH
  2018-07-03  7:04 ` [RFC PATCH 2/4] Documentation: ABI: Add sysfs-class-bmc documentation to testing Andrew Jeffery
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 16+ messages in thread
From: Andrew Jeffery @ 2018-07-03  7:04 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Jeffery, robh+dt, mark.rutland, joel, gregkh, Eugene.Cho,
	a.amelkin, stewart, benh, openbmc, devicetree, linux-arm-kernel

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 .../bindings/misc/bmc-misc-ctrl.txt           | 252 ++++++++++++++++++
 MAINTAINERS                                   |   6 +
 2 files changed, 258 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt

diff --git a/Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt b/Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt
new file mode 100644
index 000000000000..4661926030e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt
@@ -0,0 +1,252 @@
+BMC Miscellaneous Control Interfaces
+====================================
+
+Baseboard Management Controllers (BMCs) often have an array of hardware
+features that need to be described but are awkward to sensibly expose.
+
+This bindings document provides a generic mechanism for describing such
+features, covering read-only (RO), read-modify-write (RMW) and
+write-1-set/write-1-clear (W1SC) semantics.
+
+All uses of bmc-misc-ctrl must be documented under Valid Uses below.
+
+The bindings are similar in nature to register-bit-led.
+
+Required Properties
+-------------------
+
+compatible: 	Must be "bmc-misc-ctrl"
+offset:		A one or three cell property describing the registers
+		associated with the field.
+
+		If the optional property 'set-clear' is not present then the
+		node describes a register with read-modify-write semantics. The
+		offset property has one cell describing the register of
+		interest.
+
+		If the optional property 'set-clear' is present then the node
+		describes a register set that together implement read,
+		write-1-set and write-1-clear semantics. The offset property
+		must be three cells, the first is the address of the register
+		to read from, the second the write-1-set register and the third
+		write-1-clear.
+
+mask: 		A mask whose set bits represent the bits of the field.
+label:		The name of the field
+
+Optional Properties
+-------------------
+
+read-only:	Define a read-only field (RMW/W1SC irrelevant).
+set-clear:	Define whether the field exists in a RMW or W1SC register set
+default-value:	Single cell applicable to RMW. The field will be updated to the
+		cell's value.
+default-set:	For W1SC, set all bits in the field
+default-clear:	For W1SC, clear all bits in the field
+
+Valid Uses
+----------
+
+Description:	Control bit for switching the video display DAC mux between
+		host VGA and BMC CRT mode
+Machines:	aspeed,ast2500
+Parent:		compatible = "aspeed,ast2500-scu", "syscon", "simple-mfd";
+Node:
+		field@2c.16 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0x2c>;
+			mask = <0x00030000>;
+			label = "dac-mux";
+		};
+
+Description:	Host VGA scratch registers
+Machines:	aspeed,ast2500
+Parent:		compatible = "aspeed,ast2500-scu", "syscon", "simple-mfd";
+Node:
+		field@50.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0x50>;
+			mask = <0xffffffff>;
+			label = "vga0";
+			read-only;
+		};
+
+		field@54.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0x54>;
+			mask = <0xffffffff>;
+			label = "vga1";
+			read-only;
+		};
+
+		field@58.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0x58>;
+			mask = <0xffffffff>;
+			label = "vga2";
+			read-only;
+		};
+
+		field@5c.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0x5c>;
+			mask = <0xffffffff>;
+			label = "vga3";
+			read-only;
+		};
+
+		field@60.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0x60>;
+			mask = <0xffffffff>;
+			label = "vga4";
+			read-only;
+		};
+
+		field@64.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0x64>;
+			mask = <0xffffffff>;
+			label = "vga5";
+			read-only;
+		};
+
+		field@68.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0x68>;
+			mask = <0xffffffff>;
+			label = "vga6";
+			read-only;
+		};
+
+		field@6c.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0x6c>;
+			mask = <0xffffffff>;
+			label = "vga7";
+			read-only;
+		};
+
+Description:	Super I/O device scratch registers for host/BMC communication
+Machines:	aspeed,ast2500
+Parent:		compatible = "aspeed,ast2500-lpc-host", "simple-mfd", "syscon";
+		field@f0.24 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf0 24 8>;
+			mask = <0xff000000>;
+			label = "sio-2b";
+		};
+
+		field@f0.16 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf0>;
+			mask = <0x00ff0000>;
+			label = "sio-2a";
+		};
+
+		field@f0.8 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf0>;
+			mask = <0x0000ff00>;
+			bit-shift = <8>;
+			label = "sio-29";
+		};
+
+		field@f0.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf0>;
+			mask = <0x000000ff>;
+			label = "sio-28";
+		};
+
+		field@f4.24 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf4>;
+			mask = <0xff000000>;
+			label = "sio-2f";
+		};
+
+		field@f4.16 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf4>;
+			mask = <0x00ff0000>;
+			label = "sio-2e";
+		};
+
+		field@f4.8 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf4>;
+			mask = <0x0000ff00>;
+			label = "sio-2d";
+		};
+
+		field@f4.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf4>;
+			mask = <0x000000ff>;
+			label = "sio-2c";
+		};
+
+		field@f8.24 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf8>;
+			mask = <0xff000000>;
+			read-only;
+			label = "sio-23";
+		};
+
+		field@f8.16 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf8>;
+			mask = <0x00ff0000>;
+			read-only;
+			label = "sio-22";
+		};
+
+		field@f8.8 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf8>;
+			mask = <0x0000ff00>;
+			read-only;
+			label = "sio-21";
+		};
+
+		field@f8.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xf8>;
+			mask = <0x000000ff>;
+			read-only;
+			label = "sio-20";
+		};
+
+		field@fc.24 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xfc>;
+			mask = <0xff000000>;
+			read-only;
+			label = "sio-27";
+		};
+
+		field@fc.16 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xfc>;
+			mask = <0x00ff0000>;
+			read-only;
+			label = "sio-26";
+		};
+
+		field@fc.8 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xfc>;
+			mask = <0x0000ff00>;
+			read-only;
+			label = "sio-25";
+		};
+
+		field@fc.0 {
+			compatible = "bmc-misc-ctrl";
+			offset = <0xfc>;
+			mask = <0x000000ff>;
+			read-only;
+			label = "sio-24";
+		};
diff --git a/MAINTAINERS b/MAINTAINERS
index 07d1576fc766..9766d7832d8b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2736,6 +2736,12 @@ S:	Supported
 F:	drivers/net/bonding/
 F:	include/uapi/linux/if_bonding.h
 
+BMC MISCELLANEOUS CONTROL
+R:	Andrew Jeffery <andrew@aj.id.au>
+L:	openbmc@lists.ozlabs.org (moderated for non-subscribers)
+S:	Supported
+F:	Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt
+
 BPF (Safe dynamic programs and tools)
 M:	Alexei Starovoitov <ast@kernel.org>
 M:	Daniel Borkmann <daniel@iogearbox.net>
-- 
2.17.1

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

* [RFC PATCH 2/4] Documentation: ABI: Add sysfs-class-bmc documentation to testing
  2018-07-03  7:04 [RFC PATCH 0/4] sysfs interface to miscellaneous BMC controls and fields Andrew Jeffery
  2018-07-03  7:04 ` [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl Andrew Jeffery
@ 2018-07-03  7:04 ` Andrew Jeffery
  2018-07-03  7:50   ` Greg KH
  2018-07-03  7:04 ` [RFC PATCH 3/4] misc: Add bmc-misc-ctrl Andrew Jeffery
  2018-07-03  7:04 ` [RFC PATCH 4/4] dts: aspeed-g5: Add bmc-misc-ctrl nodes to devicetree Andrew Jeffery
  3 siblings, 1 reply; 16+ messages in thread
From: Andrew Jeffery @ 2018-07-03  7:04 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Jeffery, robh+dt, mark.rutland, joel, gregkh, Eugene.Cho,
	a.amelkin, stewart, benh, openbmc, devicetree, linux-arm-kernel

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 Documentation/ABI/testing/sysfs-class-bmc | 62 +++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-bmc

diff --git a/Documentation/ABI/testing/sysfs-class-bmc b/Documentation/ABI/testing/sysfs-class-bmc
new file mode 100644
index 000000000000..9d42106b89f9
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-bmc
@@ -0,0 +1,62 @@
+This document defines the sysfs attributes common to the bmc device class. See
+Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt for exhaustive list of
+field definitions.
+
+What:		/sys/class/bmc/<field>/label
+Date:		July, 2018
+KernelVersion:	v4.19
+Contact:	openbmc@lists.ozlabs.org
+Description:
+		The name of the field of interest. Corresponds to the value of
+		<field> in the path
+Users:		openbmc@lists.ozlabs.org
+
+What:		/sys/class/bmc/<field>/value
+Date:		July, 2018
+KernelVersion:	v4.19
+Contact:	openbmc@lists.ozlabs.org
+Description:
+		The value of the field of interest.
+
+		If the field is exposed from a read-modify-write register this
+		attribute will be RW, where writes will set the field to the
+		value written. Writing values that exceed the width of the
+		field will return an error.
+
+		If the field is exposed from a write-1-set/write-1-clear
+		register this attribute will be RO, and the attributes 'set'
+		and 'clear' will be present as write-only.
+Users:		openbmc@lists.ozlabs.org
+
+What:		/sys/class/bmc/<field>/mask
+Date:		July, 2018
+KernelVersion:	v4.19
+Contact:	openbmc@lists.ozlabs.org
+Description:
+		The mask applied to the value read/written from the 'value'
+		attribute.
+Users:		openbmc@lists.ozlabs.org
+
+What:		/sys/class/bmc/<field>/set
+Users:		openbmc@lists.ozlabs.org
+Date:		July, 2018
+KernelVersion:	v4.19
+Contact:	openbmc@lists.ozlabs.org
+Description:
+		For fields backed by write-1-set/write-1-clear registers,
+		set bits in the value written will be set in hardware. Zero
+		values are ignored. Writing values that exceed the width of the
+		mask value will return an error.
+Users:		openbmc@lists.ozlabs.org
+
+What:		/sys/class/bmc/<field>/clear
+Users:		openbmc@lists.ozlabs.org
+Date:		July, 2018
+KernelVersion:	v4.19
+Contact:	openbmc@lists.ozlabs.org
+Description:
+		For fields backed by write-1-set/write-1-clear registers,
+		set bits in the value written will be cleared in hardware. Zero
+		values are ignored. Writing values that exceed the width of the
+		mask value will return an error.
+Users:		openbmc@lists.ozlabs.org
-- 
2.17.1

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

* [RFC PATCH 3/4] misc: Add bmc-misc-ctrl
  2018-07-03  7:04 [RFC PATCH 0/4] sysfs interface to miscellaneous BMC controls and fields Andrew Jeffery
  2018-07-03  7:04 ` [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl Andrew Jeffery
  2018-07-03  7:04 ` [RFC PATCH 2/4] Documentation: ABI: Add sysfs-class-bmc documentation to testing Andrew Jeffery
@ 2018-07-03  7:04 ` Andrew Jeffery
  2018-07-03  7:54   ` Greg KH
  2018-07-03  7:04 ` [RFC PATCH 4/4] dts: aspeed-g5: Add bmc-misc-ctrl nodes to devicetree Andrew Jeffery
  3 siblings, 1 reply; 16+ messages in thread
From: Andrew Jeffery @ 2018-07-03  7:04 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Jeffery, robh+dt, mark.rutland, joel, gregkh, Eugene.Cho,
	a.amelkin, stewart, benh, openbmc, devicetree, linux-arm-kernel

bmc-misc-ctrl is used to expose miscellaneous Baseboard
Management Controller (BMC) hardware features described in the devicetree
to userspace.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 MAINTAINERS                  |   1 +
 drivers/misc/Kconfig         |   8 +
 drivers/misc/Makefile        |   1 +
 drivers/misc/bmc-misc-ctrl.c | 363 +++++++++++++++++++++++++++++++++++
 4 files changed, 373 insertions(+)
 create mode 100644 drivers/misc/bmc-misc-ctrl.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9766d7832d8b..30d39440b6f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2741,6 +2741,7 @@ R:	Andrew Jeffery <andrew@aj.id.au>
 L:	openbmc@lists.ozlabs.org (moderated for non-subscribers)
 S:	Supported
 F:	Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt
+F:	drivers/misc/bmc-misc-ctrl.c
 
 BPF (Safe dynamic programs and tools)
 M:	Alexei Starovoitov <ast@kernel.org>
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 3726eacdf65d..f46bc8208b50 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -513,6 +513,14 @@ config MISC_RTSX
 	tristate
 	default MISC_RTSX_PCI || MISC_RTSX_USB
 
+config BMC_MISC_CTRL
+	tristate "Miscellaneous BMC Control Interfaces"
+	depends on REGMAP && MFD_SYSCON
+	help
+	  Say yes to expose scratch registers used to communicate between the
+	  host and BMC along with other miscellaneous control interfaces
+	  provided by BMC SoCs
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index af22bbc3d00c..4fb2fac7a486 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
 obj-$(CONFIG_PCI_ENDPOINT_TEST)	+= pci_endpoint_test.o
 obj-$(CONFIG_OCXL)		+= ocxl/
 obj-$(CONFIG_MISC_RTSX)		+= cardreader/
+obj-$(CONFIG_BMC_MISC_CTRL)     += bmc-misc-ctrl.o
diff --git a/drivers/misc/bmc-misc-ctrl.c b/drivers/misc/bmc-misc-ctrl.c
new file mode 100644
index 000000000000..ff907029163f
--- /dev/null
+++ b/drivers/misc/bmc-misc-ctrl.c
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2018 IBM Corp.
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/kobject.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct bmc_ctrl {
+	struct device *dev;
+	struct regmap *map;
+	bool ro;
+	u32 shift;
+	u32 mask;
+	struct kobj_attribute mask_attr;
+	const char *label;
+	struct kobj_attribute label_attr;
+	union {
+		struct {
+			u32 value;
+			struct kobj_attribute value_attr;
+		};
+		struct {
+			u32 read;
+			u32 set;
+			u32 clear;
+			struct kobj_attribute read_attr;
+			struct kobj_attribute set_attr;
+			struct kobj_attribute clear_attr;
+		};
+	};
+};
+
+static ssize_t bmc_misc_rmw_show(struct kobject *kobj,
+					struct kobj_attribute *attr, char *buf)
+{
+	struct bmc_ctrl *ctrl;
+	unsigned int val;
+	int rc;
+
+	ctrl = container_of(attr, struct bmc_ctrl, value_attr);
+	rc = regmap_read(ctrl->map, ctrl->value, &val);
+	if (rc)
+		return rc;
+
+	val = (val & ctrl->mask) >> ctrl->shift;
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t bmc_misc_rmw_store(struct kobject *kobj,
+					 struct kobj_attribute *attr,
+					 const char *buf, size_t count)
+{
+	struct bmc_ctrl *ctrl;
+	long val;
+	int rc;
+
+	rc = kstrtol(buf, 0, &val);
+	if (rc)
+		return rc;
+
+	ctrl = container_of(attr, struct bmc_ctrl, value_attr);
+	val <<= ctrl->shift;
+	if (val & ~ctrl->mask)
+		return -EINVAL;
+	rc = regmap_update_bits(ctrl->map, ctrl->value, ctrl->mask, val);
+
+	return rc < 0 ? rc : count;
+}
+
+static void bmc_misc_add_rmw_attrs(struct bmc_ctrl *ctrl,
+				   struct attribute *attrs[6])
+{
+	sysfs_attr_init(&ctrl->attr.attr);
+	ctrl->value_attr.attr.name = "value";
+	ctrl->value_attr.attr.mode = 0664;
+	ctrl->value_attr.show = bmc_misc_rmw_show;
+	ctrl->value_attr.store = bmc_misc_rmw_store;
+	attrs[2] = &ctrl->value_attr.attr;
+	attrs[3] = NULL;
+}
+
+static int bmc_misc_init_rmw(struct bmc_ctrl *ctrl, struct device_node *node,
+			     struct attribute *attrs[6])
+{
+	u32 val;
+	int rc;
+
+	rc = of_property_read_u32(node, "offset", &ctrl->value);
+	if (rc < 0)
+		return rc;
+
+	if (!of_property_read_u32(node, "default-value", &val)) {
+		val <<= ctrl->shift;
+		if (val & ~ctrl->mask)
+			return -EINVAL;
+		val &= ctrl->mask;
+		regmap_update_bits(ctrl->map, ctrl->value, ctrl->mask, val);
+	}
+
+	bmc_misc_add_rmw_attrs(ctrl, attrs);
+
+	return 0;
+}
+
+static ssize_t bmc_misc_sc_read_show(struct kobject *kobj,
+					struct kobj_attribute *attr, char *buf)
+{
+	struct bmc_ctrl *ctrl;
+	unsigned int val;
+	int rc;
+
+	ctrl = container_of(attr, struct bmc_ctrl, read_attr);
+	rc = regmap_read(ctrl->map, ctrl->read, &val);
+	if (rc)
+		return rc;
+
+	val = (val & ctrl->mask) >> ctrl->shift;
+
+	return sprintf(buf, "%u\n", val);
+
+}
+
+static ssize_t bmc_misc_sc_set_store(struct kobject *kobj,
+					    struct kobj_attribute *attr,
+					    const char *buf, size_t count)
+{
+	struct bmc_ctrl *ctrl;
+	long val;
+	int rc;
+
+	rc = kstrtol(buf, 0, &val);
+	if (rc)
+		return rc;
+
+	ctrl = container_of(attr, struct bmc_ctrl, set_attr);
+	val <<= ctrl->shift;
+	if (val & ~ctrl->mask)
+		return -EINVAL;
+	val &= ctrl->mask;
+	rc = regmap_write(ctrl->map, ctrl->set, val);
+
+	return rc < 0 ? rc : count;
+}
+
+static ssize_t bmc_misc_sc_clear_store(struct kobject *kobj,
+					      struct kobj_attribute *attr,
+					      const char *buf, size_t count)
+{
+	struct bmc_ctrl *ctrl;
+	long val;
+	int rc;
+
+	rc = kstrtol(buf, 0, &val);
+	if (rc)
+		return rc;
+
+	ctrl = container_of(attr, struct bmc_ctrl, clear_attr);
+	val <<= ctrl->shift;
+	if (val & ~ctrl->mask)
+		return -EINVAL;
+	val &= ctrl->mask;
+	rc = regmap_write(ctrl->map, ctrl->clear, val);
+
+	return rc < 0 ? rc : count;
+}
+
+static void bmc_misc_add_sc_attrs(struct bmc_ctrl *ctrl,
+				  struct attribute *attrs[6])
+{
+	sysfs_attr_init(&ctrl->read_attr.attr);
+	ctrl->read_attr.attr.name = "value";
+	ctrl->read_attr.attr.mode = 0444;
+	ctrl->read_attr.show = bmc_misc_sc_read_show;
+	attrs[2] = &ctrl->read_attr.attr;
+
+	sysfs_attr_init(&ctrl->set_attr.attr);
+	ctrl->set_attr.attr.name = "set";
+	ctrl->set_attr.attr.mode = 0200;
+	ctrl->set_attr.store = bmc_misc_sc_set_store;
+	attrs[3] = &ctrl->set_attr.attr;
+
+	sysfs_attr_init(&ctrl->clear_attr.attr);
+	ctrl->clear_attr.attr.name = "clear";
+	ctrl->clear_attr.attr.mode = 0200;
+	ctrl->clear_attr.store = bmc_misc_sc_clear_store;
+	attrs[4] = &ctrl->clear_attr.attr;
+
+	attrs[5] = NULL;
+}
+
+static int bmc_misc_init_sc(struct bmc_ctrl *ctrl, struct device_node *node,
+			    struct attribute *attrs[6])
+{
+	int rc;
+
+	rc = of_property_read_u32_array(node, "offset", &ctrl->read, 3);
+	if (rc < 0)
+		return rc;
+
+	if (of_property_read_bool(node, "default-set"))
+		regmap_write(ctrl->map, ctrl->set, ctrl->mask);
+	else if (of_property_read_bool(node, "default-clear"))
+		regmap_write(ctrl->map, ctrl->clear, ctrl->mask);
+
+	bmc_misc_add_sc_attrs(ctrl, attrs);
+
+	return 0;
+}
+
+static ssize_t bmc_misc_label_show(struct kobject *kobj,
+				   struct kobj_attribute *attr, char *buf)
+{
+	struct bmc_ctrl *ctrl = container_of(attr, struct bmc_ctrl, label_attr);
+
+	return sprintf(buf, "%s\n", ctrl->label);
+}
+
+static ssize_t bmc_misc_mask_show(struct kobject *kobj,
+				   struct kobj_attribute *attr, char *buf)
+{
+	struct bmc_ctrl *ctrl = container_of(attr, struct bmc_ctrl, mask_attr);
+
+	return sprintf(buf, "0x%x\n", ctrl->mask >> ctrl->shift);
+}
+
+static int bmc_misc_init_dt(struct bmc_ctrl *ctrl, struct device_node *node,
+			    struct attribute *attrs[6])
+{
+	int rc;
+
+	/* Example children:
+	 *
+	 * field@80.6 {
+	 *      compatible = "bmc-misc-control";
+	 *      reg = <0x80>;
+	 *      bit-mask = <0x1>;
+	 *      bit-shift = <6>;
+	 *      label = "ilpc2ahb-disable";
+	 * };
+	 *
+	 * field@70.6 {
+	 *      compatible = "bmc-misc-control";
+	 *      // Write-1-set/Write-1-clear semantics
+	 *      set-clear;
+	 *      default-set;
+	 *      reg = <0x70 0x70 0x7c>
+	 *      bit-mask = <0x1>;
+	 *      bit-shift = <6>;
+	 *      label = "lpc-sio-decode-disable";
+	 * };
+	 *
+	 * field@50.0 {
+	 *	compatible = "bmc-misc-control";
+	 *	read-only;
+	 *	reg = <0x50>;
+	 *	bit-mask = <0xffffffff>;
+	 *	bit-shift = <0>;
+	 *	label = "vga-scratch-1";
+	 * };
+	 */
+	rc = of_property_read_u32(node, "mask", &ctrl->mask);
+	if (rc < 0)
+		return rc;
+
+	ctrl->shift = __ffs(ctrl->mask);
+	ctrl->ro = of_property_read_bool(node, "read-only");
+
+	rc = of_property_read_string(node, "label", &ctrl->label);
+	if (rc < 0)
+		return rc;
+
+	ctrl->label_attr.attr.name = "label";
+	ctrl->label_attr.attr.mode = 0444;
+	ctrl->label_attr.show = bmc_misc_label_show;
+	attrs[0] = &ctrl->label_attr.attr;
+
+	ctrl->mask_attr.attr.name = "mask";
+	ctrl->mask_attr.attr.mode = 0444;
+	ctrl->mask_attr.show = bmc_misc_mask_show;
+	attrs[1] = &ctrl->mask_attr.attr;
+
+	if (of_property_read_bool(node, "set-clear"))
+		return bmc_misc_init_sc(ctrl, node, attrs);
+
+	return bmc_misc_init_rmw(ctrl, node, attrs);
+}
+
+static struct class bmc_class = {
+	.name =		"bmc",
+};
+
+static int bmc_misc_probe(struct platform_device *pdev)
+{
+	struct attribute *attrs[6];
+	struct attribute **attr;
+	struct bmc_ctrl *ctrl;
+	int rc;
+
+	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
+	if (!ctrl)
+		return -ENOMEM;
+
+	ctrl->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
+
+	rc = bmc_misc_init_dt(ctrl, pdev->dev.of_node, attrs);
+	if (rc < 0)
+		return rc;
+
+	ctrl->dev = device_create(&bmc_class, &pdev->dev, 0, ctrl, "%s",
+			     ctrl->label);
+	if (IS_ERR(ctrl->dev))
+		return PTR_ERR(ctrl->dev);
+
+	for (attr = &attrs[0]; *attr; attr++) {
+		rc = sysfs_create_file(&ctrl->dev->kobj, *attr);
+		if (rc < 0)
+			/* FIXME: Cleanup */
+			return rc;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id bmc_misc_match[] = {
+	{ .compatible = "bmc-misc-ctrl" },
+	{ },
+};
+
+static struct platform_driver bmc_misc = {
+	.driver = {
+		.name		=  "bmc-misc-ctrl",
+		.of_match_table = bmc_misc_match,
+	},
+	.probe = bmc_misc_probe,
+};
+
+static int bmc_misc_ctrl_init(void)
+{
+	int rc;
+
+	rc = class_register(&bmc_class);
+	if (rc < 0)
+		return rc;
+
+	return platform_driver_register(&bmc_misc);
+}
+module_init(bmc_misc_ctrl_init);
+
+static void bmc_misc_ctrl_exit(void)
+{
+	platform_driver_unregister(&bmc_misc);
+	class_unregister(&bmc_class);
+}
+module_exit(bmc_misc_ctrl_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>");
-- 
2.17.1

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

* [RFC PATCH 4/4] dts: aspeed-g5: Add bmc-misc-ctrl nodes to devicetree
  2018-07-03  7:04 [RFC PATCH 0/4] sysfs interface to miscellaneous BMC controls and fields Andrew Jeffery
                   ` (2 preceding siblings ...)
  2018-07-03  7:04 ` [RFC PATCH 3/4] misc: Add bmc-misc-ctrl Andrew Jeffery
@ 2018-07-03  7:04 ` Andrew Jeffery
  2018-07-03  7:54   ` Greg KH
  3 siblings, 1 reply; 16+ messages in thread
From: Andrew Jeffery @ 2018-07-03  7:04 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Jeffery, robh+dt, mark.rutland, joel, gregkh, Eugene.Cho,
	a.amelkin, stewart, benh, openbmc, devicetree, linux-arm-kernel

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 arch/arm/boot/dts/aspeed-g5.dtsi | 192 +++++++++++++++++++++++++++++++
 1 file changed, 192 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 17f2714d18a7..57d477e17c0c 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -187,6 +187,77 @@
 					aspeed,external-nodes = <&gfx &lhc>;
 
 				};
+
+				field@2c.16 {
+					compatible = "bmc-misc-ctrl";
+					offset = <0x2c>;
+					mask = <0x00030000>;
+					label = "dac-mux";
+				};
+
+				field@50.0 {
+					compatible = "bmc-misc-ctrl";
+					offset = <0x50>;
+					mask = <0xffffffff>;
+					label = "vga0";
+					read-only;
+				};
+
+				field@54.0 {
+					compatible = "bmc-misc-ctrl";
+					offset = <0x54>;
+					mask = <0xffffffff>;
+					label = "vga1";
+					read-only;
+				};
+
+				field@58.0 {
+					compatible = "bmc-misc-ctrl";
+					offset = <0x58>;
+					mask = <0xffffffff>;
+					label = "vga2";
+					read-only;
+				};
+
+				field@5c.0 {
+					compatible = "bmc-misc-ctrl";
+					offset = <0x5c>;
+					mask = <0xffffffff>;
+					label = "vga3";
+					read-only;
+				};
+
+				field@60.0 {
+					compatible = "bmc-misc-ctrl";
+					offset = <0x60>;
+					mask = <0xffffffff>;
+					label = "vga4";
+					read-only;
+				};
+
+				field@64.0 {
+					compatible = "bmc-misc-ctrl";
+					offset = <0x64>;
+					mask = <0xffffffff>;
+					label = "vga5";
+					read-only;
+				};
+
+				field@68.0 {
+					compatible = "bmc-misc-ctrl";
+					offset = <0x68>;
+					mask = <0xffffffff>;
+					label = "vga6";
+					read-only;
+				};
+
+				field@6c.0 {
+					compatible = "bmc-misc-ctrl";
+					offset = <0x6c>;
+					mask = <0xffffffff>;
+					label = "vga7";
+					read-only;
+				};
 			};
 
 			rng: hwrng@1e6e2078 {
@@ -343,6 +414,127 @@
 						#reset-cells = <1>;
 					};
 
+					field@f0.24 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf0 24 8>;
+						mask = <0xff000000>;
+						label = "sio-2b";
+					};
+
+					field@f0.16 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf0>;
+						mask = <0x00ff0000>;
+						label = "sio-2a";
+					};
+
+					field@f0.8 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf0>;
+						mask = <0x0000ff00>;
+						bit-shift = <8>;
+						label = "sio-29";
+					};
+
+					field@f0.0 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf0>;
+						mask = <0x000000ff>;
+						label = "sio-28";
+					};
+
+					field@f4.24 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf4>;
+						mask = <0xff000000>;
+						label = "sio-2f";
+					};
+
+					field@f4.16 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf4>;
+						mask = <0x00ff0000>;
+						label = "sio-2e";
+					};
+
+					field@f4.8 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf4>;
+						mask = <0x0000ff00>;
+						label = "sio-2d";
+					};
+
+					field@f4.0 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf4>;
+						mask = <0x000000ff>;
+						label = "sio-2c";
+					};
+
+					field@f8.24 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf8>;
+						mask = <0xff000000>;
+						read-only;
+						label = "sio-23";
+					};
+
+					field@f8.16 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf8>;
+						mask = <0x00ff0000>;
+						read-only;
+						label = "sio-22";
+					};
+
+					field@f8.8 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf8>;
+						mask = <0x0000ff00>;
+						read-only;
+						label = "sio-21";
+					};
+
+					field@f8.0 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xf8>;
+						mask = <0x000000ff>;
+						read-only;
+						label = "sio-20";
+					};
+
+					field@fc.24 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xfc>;
+						mask = <0xff000000>;
+						read-only;
+						label = "sio-27";
+					};
+
+					field@fc.16 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xfc>;
+						mask = <0x00ff0000>;
+						read-only;
+						label = "sio-26";
+					};
+
+					field@fc.8 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xfc>;
+						mask = <0x0000ff00>;
+						read-only;
+						label = "sio-25";
+					};
+
+					field@fc.0 {
+						compatible = "bmc-misc-ctrl";
+						offset = <0xfc>;
+						mask = <0x000000ff>;
+						read-only;
+						label = "sio-24";
+					};
+
 					ibt: ibt@c0 {
 						compatible = "aspeed,ast2500-ibt-bmc";
 						reg = <0xc0 0x18>;
-- 
2.17.1

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

* Re: [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl
  2018-07-03  7:04 ` [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl Andrew Jeffery
@ 2018-07-03  7:50   ` Greg KH
  2018-07-03 14:16     ` Benjamin Herrenschmidt
  2018-07-04  6:28     ` Andrew Jeffery
  0 siblings, 2 replies; 16+ messages in thread
From: Greg KH @ 2018-07-03  7:50 UTC (permalink / raw)
  To: Andrew Jeffery
  Cc: linux-kernel, robh+dt, mark.rutland, joel, Eugene.Cho, a.amelkin,
	stewart, benh, openbmc, devicetree, linux-arm-kernel

On Tue, Jul 03, 2018 at 05:04:10PM +1000, Andrew Jeffery wrote:
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> ---

I can't take patches without any changelog text at all :(

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

* Re: [RFC PATCH 2/4] Documentation: ABI: Add sysfs-class-bmc documentation to testing
  2018-07-03  7:04 ` [RFC PATCH 2/4] Documentation: ABI: Add sysfs-class-bmc documentation to testing Andrew Jeffery
@ 2018-07-03  7:50   ` Greg KH
  2018-07-04  6:29     ` Andrew Jeffery
  0 siblings, 1 reply; 16+ messages in thread
From: Greg KH @ 2018-07-03  7:50 UTC (permalink / raw)
  To: Andrew Jeffery
  Cc: linux-kernel, robh+dt, mark.rutland, joel, Eugene.Cho, a.amelkin,
	stewart, benh, openbmc, devicetree, linux-arm-kernel

On Tue, Jul 03, 2018 at 05:04:11PM +1000, Andrew Jeffery wrote:
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

Same problem here :(

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

* Re: [RFC PATCH 3/4] misc: Add bmc-misc-ctrl
  2018-07-03  7:04 ` [RFC PATCH 3/4] misc: Add bmc-misc-ctrl Andrew Jeffery
@ 2018-07-03  7:54   ` Greg KH
  2018-07-04  7:18     ` Andrew Jeffery
  0 siblings, 1 reply; 16+ messages in thread
From: Greg KH @ 2018-07-03  7:54 UTC (permalink / raw)
  To: Andrew Jeffery
  Cc: linux-kernel, robh+dt, mark.rutland, joel, Eugene.Cho, a.amelkin,
	stewart, benh, openbmc, devicetree, linux-arm-kernel

On Tue, Jul 03, 2018 at 05:04:12PM +1000, Andrew Jeffery wrote:
> bmc-misc-ctrl is used to expose miscellaneous Baseboard
> Management Controller (BMC) hardware features described in the devicetree
> to userspace.
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> ---
>  MAINTAINERS                  |   1 +
>  drivers/misc/Kconfig         |   8 +
>  drivers/misc/Makefile        |   1 +
>  drivers/misc/bmc-misc-ctrl.c | 363 +++++++++++++++++++++++++++++++++++
>  4 files changed, 373 insertions(+)
>  create mode 100644 drivers/misc/bmc-misc-ctrl.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9766d7832d8b..30d39440b6f2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2741,6 +2741,7 @@ R:	Andrew Jeffery <andrew@aj.id.au>
>  L:	openbmc@lists.ozlabs.org (moderated for non-subscribers)
>  S:	Supported
>  F:	Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt
> +F:	drivers/misc/bmc-misc-ctrl.c
>  
>  BPF (Safe dynamic programs and tools)
>  M:	Alexei Starovoitov <ast@kernel.org>
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 3726eacdf65d..f46bc8208b50 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -513,6 +513,14 @@ config MISC_RTSX
>  	tristate
>  	default MISC_RTSX_PCI || MISC_RTSX_USB
>  
> +config BMC_MISC_CTRL
> +	tristate "Miscellaneous BMC Control Interfaces"
> +	depends on REGMAP && MFD_SYSCON
> +	help
> +	  Say yes to expose scratch registers used to communicate between the
> +	  host and BMC along with other miscellaneous control interfaces
> +	  provided by BMC SoCs
> +
>  source "drivers/misc/c2port/Kconfig"
>  source "drivers/misc/eeprom/Kconfig"
>  source "drivers/misc/cb710/Kconfig"
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index af22bbc3d00c..4fb2fac7a486 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
>  obj-$(CONFIG_PCI_ENDPOINT_TEST)	+= pci_endpoint_test.o
>  obj-$(CONFIG_OCXL)		+= ocxl/
>  obj-$(CONFIG_MISC_RTSX)		+= cardreader/
> +obj-$(CONFIG_BMC_MISC_CTRL)     += bmc-misc-ctrl.o
> diff --git a/drivers/misc/bmc-misc-ctrl.c b/drivers/misc/bmc-misc-ctrl.c
> new file mode 100644
> index 000000000000..ff907029163f
> --- /dev/null
> +++ b/drivers/misc/bmc-misc-ctrl.c
> @@ -0,0 +1,363 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +// Copyright 2018 IBM Corp.
> +
> +#include <linux/bitops.h>
> +#include <linux/device.h>
> +#include <linux/kobject.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +struct bmc_ctrl {
> +	struct device *dev;
> +	struct regmap *map;
> +	bool ro;
> +	u32 shift;
> +	u32 mask;
> +	struct kobj_attribute mask_attr;
> +	const char *label;
> +	struct kobj_attribute label_attr;
> +	union {
> +		struct {
> +			u32 value;
> +			struct kobj_attribute value_attr;
> +		};
> +		struct {
> +			u32 read;
> +			u32 set;
> +			u32 clear;
> +			struct kobj_attribute read_attr;
> +			struct kobj_attribute set_attr;
> +			struct kobj_attribute clear_attr;
> +		};

What is this crazy union for?  Why are you messing around with "raw"
kobject attributes?  This is a device, you should never have to mess
with sysfs calls or kobject calls or structures directly.  If you do,
that's a huge hint something is wrong here.


> +	};
> +};
> +
> +static ssize_t bmc_misc_rmw_show(struct kobject *kobj,
> +					struct kobj_attribute *attr, char *buf)
> +{
> +	struct bmc_ctrl *ctrl;
> +	unsigned int val;
> +	int rc;
> +
> +	ctrl = container_of(attr, struct bmc_ctrl, value_attr);
> +	rc = regmap_read(ctrl->map, ctrl->value, &val);
> +	if (rc)
> +		return rc;
> +
> +	val = (val & ctrl->mask) >> ctrl->shift;
> +
> +	return sprintf(buf, "%u\n", val);
> +}
> +
> +static ssize_t bmc_misc_rmw_store(struct kobject *kobj,
> +					 struct kobj_attribute *attr,
> +					 const char *buf, size_t count)
> +{
> +	struct bmc_ctrl *ctrl;
> +	long val;
> +	int rc;
> +
> +	rc = kstrtol(buf, 0, &val);
> +	if (rc)
> +		return rc;
> +
> +	ctrl = container_of(attr, struct bmc_ctrl, value_attr);
> +	val <<= ctrl->shift;
> +	if (val & ~ctrl->mask)
> +		return -EINVAL;
> +	rc = regmap_update_bits(ctrl->map, ctrl->value, ctrl->mask, val);
> +
> +	return rc < 0 ? rc : count;
> +}
> +
> +static void bmc_misc_add_rmw_attrs(struct bmc_ctrl *ctrl,
> +				   struct attribute *attrs[6])
> +{
> +	sysfs_attr_init(&ctrl->attr.attr);
> +	ctrl->value_attr.attr.name = "value";
> +	ctrl->value_attr.attr.mode = 0664;
> +	ctrl->value_attr.show = bmc_misc_rmw_show;
> +	ctrl->value_attr.store = bmc_misc_rmw_store;
> +	attrs[2] = &ctrl->value_attr.attr;
> +	attrs[3] = NULL;

You aren't "adding" any attributes here, you are only setting them up
(in an odd way, see below...)

> +}
> +
> +static int bmc_misc_init_rmw(struct bmc_ctrl *ctrl, struct device_node *node,
> +			     struct attribute *attrs[6])

That's an oddly-hard-coded array size for no good reason :(


> +{
> +	u32 val;
> +	int rc;
> +
> +	rc = of_property_read_u32(node, "offset", &ctrl->value);
> +	if (rc < 0)
> +		return rc;
> +
> +	if (!of_property_read_u32(node, "default-value", &val)) {
> +		val <<= ctrl->shift;
> +		if (val & ~ctrl->mask)
> +			return -EINVAL;
> +		val &= ctrl->mask;
> +		regmap_update_bits(ctrl->map, ctrl->value, ctrl->mask, val);
> +	}
> +
> +	bmc_misc_add_rmw_attrs(ctrl, attrs);
> +
> +	return 0;
> +}
> +
> +static ssize_t bmc_misc_sc_read_show(struct kobject *kobj,
> +					struct kobj_attribute *attr, char *buf)
> +{
> +	struct bmc_ctrl *ctrl;
> +	unsigned int val;
> +	int rc;
> +
> +	ctrl = container_of(attr, struct bmc_ctrl, read_attr);
> +	rc = regmap_read(ctrl->map, ctrl->read, &val);
> +	if (rc)
> +		return rc;
> +
> +	val = (val & ctrl->mask) >> ctrl->shift;
> +
> +	return sprintf(buf, "%u\n", val);
> +
> +}
> +
> +static ssize_t bmc_misc_sc_set_store(struct kobject *kobj,
> +					    struct kobj_attribute *attr,
> +					    const char *buf, size_t count)
> +{
> +	struct bmc_ctrl *ctrl;
> +	long val;
> +	int rc;
> +
> +	rc = kstrtol(buf, 0, &val);
> +	if (rc)
> +		return rc;
> +
> +	ctrl = container_of(attr, struct bmc_ctrl, set_attr);
> +	val <<= ctrl->shift;
> +	if (val & ~ctrl->mask)
> +		return -EINVAL;
> +	val &= ctrl->mask;
> +	rc = regmap_write(ctrl->map, ctrl->set, val);
> +
> +	return rc < 0 ? rc : count;
> +}
> +
> +static ssize_t bmc_misc_sc_clear_store(struct kobject *kobj,
> +					      struct kobj_attribute *attr,
> +					      const char *buf, size_t count)
> +{
> +	struct bmc_ctrl *ctrl;
> +	long val;
> +	int rc;
> +
> +	rc = kstrtol(buf, 0, &val);
> +	if (rc)
> +		return rc;
> +
> +	ctrl = container_of(attr, struct bmc_ctrl, clear_attr);
> +	val <<= ctrl->shift;
> +	if (val & ~ctrl->mask)
> +		return -EINVAL;
> +	val &= ctrl->mask;
> +	rc = regmap_write(ctrl->map, ctrl->clear, val);
> +
> +	return rc < 0 ? rc : count;
> +}
> +
> +static void bmc_misc_add_sc_attrs(struct bmc_ctrl *ctrl,
> +				  struct attribute *attrs[6])
> +{
> +	sysfs_attr_init(&ctrl->read_attr.attr);
> +	ctrl->read_attr.attr.name = "value";
> +	ctrl->read_attr.attr.mode = 0444;
> +	ctrl->read_attr.show = bmc_misc_sc_read_show;
> +	attrs[2] = &ctrl->read_attr.attr;
> +
> +	sysfs_attr_init(&ctrl->set_attr.attr);
> +	ctrl->set_attr.attr.name = "set";
> +	ctrl->set_attr.attr.mode = 0200;
> +	ctrl->set_attr.store = bmc_misc_sc_set_store;
> +	attrs[3] = &ctrl->set_attr.attr;
> +
> +	sysfs_attr_init(&ctrl->clear_attr.attr);
> +	ctrl->clear_attr.attr.name = "clear";
> +	ctrl->clear_attr.attr.mode = 0200;
> +	ctrl->clear_attr.store = bmc_misc_sc_clear_store;
> +	attrs[4] = &ctrl->clear_attr.attr;
> +
> +	attrs[5] = NULL;
> +}
> +
> +static int bmc_misc_init_sc(struct bmc_ctrl *ctrl, struct device_node *node,
> +			    struct attribute *attrs[6])
> +{
> +	int rc;
> +
> +	rc = of_property_read_u32_array(node, "offset", &ctrl->read, 3);
> +	if (rc < 0)
> +		return rc;
> +
> +	if (of_property_read_bool(node, "default-set"))
> +		regmap_write(ctrl->map, ctrl->set, ctrl->mask);
> +	else if (of_property_read_bool(node, "default-clear"))
> +		regmap_write(ctrl->map, ctrl->clear, ctrl->mask);
> +
> +	bmc_misc_add_sc_attrs(ctrl, attrs);
> +
> +	return 0;
> +}
> +
> +static ssize_t bmc_misc_label_show(struct kobject *kobj,
> +				   struct kobj_attribute *attr, char *buf)
> +{
> +	struct bmc_ctrl *ctrl = container_of(attr, struct bmc_ctrl, label_attr);
> +
> +	return sprintf(buf, "%s\n", ctrl->label);
> +}
> +
> +static ssize_t bmc_misc_mask_show(struct kobject *kobj,
> +				   struct kobj_attribute *attr, char *buf)
> +{
> +	struct bmc_ctrl *ctrl = container_of(attr, struct bmc_ctrl, mask_attr);
> +
> +	return sprintf(buf, "0x%x\n", ctrl->mask >> ctrl->shift);
> +}
> +
> +static int bmc_misc_init_dt(struct bmc_ctrl *ctrl, struct device_node *node,
> +			    struct attribute *attrs[6])
> +{
> +	int rc;
> +
> +	/* Example children:
> +	 *
> +	 * field@80.6 {
> +	 *      compatible = "bmc-misc-control";
> +	 *      reg = <0x80>;
> +	 *      bit-mask = <0x1>;
> +	 *      bit-shift = <6>;
> +	 *      label = "ilpc2ahb-disable";
> +	 * };
> +	 *
> +	 * field@70.6 {
> +	 *      compatible = "bmc-misc-control";
> +	 *      // Write-1-set/Write-1-clear semantics
> +	 *      set-clear;
> +	 *      default-set;
> +	 *      reg = <0x70 0x70 0x7c>
> +	 *      bit-mask = <0x1>;
> +	 *      bit-shift = <6>;
> +	 *      label = "lpc-sio-decode-disable";
> +	 * };
> +	 *
> +	 * field@50.0 {
> +	 *	compatible = "bmc-misc-control";
> +	 *	read-only;
> +	 *	reg = <0x50>;
> +	 *	bit-mask = <0xffffffff>;
> +	 *	bit-shift = <0>;
> +	 *	label = "vga-scratch-1";
> +	 * };
> +	 */
> +	rc = of_property_read_u32(node, "mask", &ctrl->mask);
> +	if (rc < 0)
> +		return rc;
> +
> +	ctrl->shift = __ffs(ctrl->mask);
> +	ctrl->ro = of_property_read_bool(node, "read-only");
> +
> +	rc = of_property_read_string(node, "label", &ctrl->label);
> +	if (rc < 0)
> +		return rc;
> +
> +	ctrl->label_attr.attr.name = "label";
> +	ctrl->label_attr.attr.mode = 0444;
> +	ctrl->label_attr.show = bmc_misc_label_show;
> +	attrs[0] = &ctrl->label_attr.attr;

This works?  You normally have to manually initialize a dynamic
attribute.  Why are you doing it this way and not using an attribute
group?

> +	ctrl->mask_attr.attr.name = "mask";
> +	ctrl->mask_attr.attr.mode = 0444;
> +	ctrl->mask_attr.show = bmc_misc_mask_show;
> +	attrs[1] = &ctrl->mask_attr.attr;
> +
> +	if (of_property_read_bool(node, "set-clear"))
> +		return bmc_misc_init_sc(ctrl, node, attrs);
> +
> +	return bmc_misc_init_rmw(ctrl, node, attrs);
> +}
> +
> +static struct class bmc_class = {
> +	.name =		"bmc",
> +};

Why are you using a custom device class for a single device?

you need to document the heck out of this in the changelog to help
explain all of these odd design decisions.

thanks,

greg k-h

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

* Re: [RFC PATCH 4/4] dts: aspeed-g5: Add bmc-misc-ctrl nodes to devicetree
  2018-07-03  7:04 ` [RFC PATCH 4/4] dts: aspeed-g5: Add bmc-misc-ctrl nodes to devicetree Andrew Jeffery
@ 2018-07-03  7:54   ` Greg KH
  2018-07-04  6:29     ` Andrew Jeffery
  0 siblings, 1 reply; 16+ messages in thread
From: Greg KH @ 2018-07-03  7:54 UTC (permalink / raw)
  To: Andrew Jeffery
  Cc: linux-kernel, robh+dt, mark.rutland, joel, Eugene.Cho, a.amelkin,
	stewart, benh, openbmc, devicetree, linux-arm-kernel

On Tue, Jul 03, 2018 at 05:04:13PM +1000, Andrew Jeffery wrote:
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> ---
>  arch/arm/boot/dts/aspeed-g5.dtsi | 192 +++++++++++++++++++++++++++++++
>  1 file changed, 192 insertions(+)

No changelog :(

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

* Re: [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl
  2018-07-03  7:50   ` Greg KH
@ 2018-07-03 14:16     ` Benjamin Herrenschmidt
  2018-07-03 14:31       ` Greg KH
  2018-07-04  6:28     ` Andrew Jeffery
  1 sibling, 1 reply; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-07-03 14:16 UTC (permalink / raw)
  To: Greg KH, Andrew Jeffery
  Cc: linux-kernel, robh+dt, mark.rutland, joel, Eugene.Cho, a.amelkin,
	stewart, openbmc, devicetree, linux-arm-kernel

On Tue, 2018-07-03 at 09:50 +0200, Greg KH wrote:
> On Tue, Jul 03, 2018 at 05:04:10PM +1000, Andrew Jeffery wrote:
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > ---
> 
> I can't take patches without any changelog text at all :(

Greg (and replying to your other comments as well)...

This is an RFC series, it's not meant for you to take at this point,
it's about discussing the overall approach to exposing BMC random
"tunables" as explained in patch 0 of the series.

Yes the individual patches aren't yet at the level of polish for a
formal submission, we (naively ?) thought that's what the whole RFC tag
is about :-)

Cheers,
Ben.

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

* Re: [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl
  2018-07-03 14:16     ` Benjamin Herrenschmidt
@ 2018-07-03 14:31       ` Greg KH
  2018-07-03 15:39         ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 16+ messages in thread
From: Greg KH @ 2018-07-03 14:31 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Andrew Jeffery, linux-kernel, robh+dt, mark.rutland, joel,
	Eugene.Cho, a.amelkin, stewart, openbmc, devicetree,
	linux-arm-kernel

On Wed, Jul 04, 2018 at 12:16:49AM +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2018-07-03 at 09:50 +0200, Greg KH wrote:
> > On Tue, Jul 03, 2018 at 05:04:10PM +1000, Andrew Jeffery wrote:
> > > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > > ---
> > 
> > I can't take patches without any changelog text at all :(
> 
> Greg (and replying to your other comments as well)...
> 
> This is an RFC series, it's not meant for you to take at this point,
> it's about discussing the overall approach to exposing BMC random
> "tunables" as explained in patch 0 of the series.
> 
> Yes the individual patches aren't yet at the level of polish for a
> formal submission, we (naively ?) thought that's what the whole RFC tag
> is about :-)

Oh come on, putting a basic "here is what this patch does" comment
should be part of every patch, otherwise what is there to comment on if
we don't know what is going on in the patch itself?

Anyway, I provided a bunch of feedback to the "real" patch in this
series...


greg k-h

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

* Re: [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl
  2018-07-03 14:31       ` Greg KH
@ 2018-07-03 15:39         ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-07-03 15:39 UTC (permalink / raw)
  To: Greg KH
  Cc: Andrew Jeffery, linux-kernel, robh+dt, mark.rutland, joel,
	Eugene.Cho, a.amelkin, stewart, openbmc, devicetree,
	linux-arm-kernel

On Tue, 2018-07-03 at 16:31 +0200, Greg KH wrote:
> On Wed, Jul 04, 2018 at 12:16:49AM +1000, Benjamin Herrenschmidt wrote:
> > On Tue, 2018-07-03 at 09:50 +0200, Greg KH wrote:
> > > On Tue, Jul 03, 2018 at 05:04:10PM +1000, Andrew Jeffery wrote:
> > > > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > > > ---
> > > 
> > > I can't take patches without any changelog text at all :(
> > 
> > Greg (and replying to your other comments as well)...
> > 
> > This is an RFC series, it's not meant for you to take at this point,
> > it's about discussing the overall approach to exposing BMC random
> > "tunables" as explained in patch 0 of the series.
> > 
> > Yes the individual patches aren't yet at the level of polish for a
> > formal submission, we (naively ?) thought that's what the whole RFC tag
> > is about :-)
> 
> Oh come on, putting a basic "here is what this patch does" comment
> should be part of every patch, otherwise what is there to comment on if
> we don't know what is going on in the patch itself?

Well, it adds documentation :-) You can just read the patch which is
... the documentation :)
> 
> Anyway, I provided a bunch of feedback to the "real" patch in this
> series...

Yes, you did that's fine. Thanks.

Cheers,
Ben.

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

* Re: [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl
  2018-07-03  7:50   ` Greg KH
  2018-07-03 14:16     ` Benjamin Herrenschmidt
@ 2018-07-04  6:28     ` Andrew Jeffery
  1 sibling, 0 replies; 16+ messages in thread
From: Andrew Jeffery @ 2018-07-04  6:28 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-kernel, robh+dt, mark.rutland, joel, Eugene.Cho, a.amelkin,
	stewart, benh, openbmc, devicetree, linux-arm-kernel

Hi Greg,

On Tue, 3 Jul 2018, at 17:20, Greg KH wrote:
> On Tue, Jul 03, 2018 at 05:04:10PM +1000, Andrew Jeffery wrote:
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > ---
> 
> I can't take patches without any changelog text at all :(
> 

I wasn't expecting you to put them into your tree - the general concept/implementation is still too immature for that, let alone the commit messages :) However, I'll address this before sending another spin of the patches.

Sorry for the noise and thanks for the quick response.

Andrew

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

* Re: [RFC PATCH 2/4] Documentation: ABI: Add sysfs-class-bmc documentation to testing
  2018-07-03  7:50   ` Greg KH
@ 2018-07-04  6:29     ` Andrew Jeffery
  0 siblings, 0 replies; 16+ messages in thread
From: Andrew Jeffery @ 2018-07-04  6:29 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-kernel, robh+dt, mark.rutland, joel, Eugene.Cho, a.amelkin,
	stewart, benh, openbmc, devicetree, linux-arm-kernel

On Tue, 3 Jul 2018, at 17:20, Greg KH wrote:
> On Tue, Jul 03, 2018 at 05:04:11PM +1000, Andrew Jeffery wrote:
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> 
> Same problem here :(

Will fix.

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

* Re: [RFC PATCH 4/4] dts: aspeed-g5: Add bmc-misc-ctrl nodes to devicetree
  2018-07-03  7:54   ` Greg KH
@ 2018-07-04  6:29     ` Andrew Jeffery
  0 siblings, 0 replies; 16+ messages in thread
From: Andrew Jeffery @ 2018-07-04  6:29 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-kernel, robh+dt, mark.rutland, joel, Eugene.Cho, a.amelkin,
	stewart, benh, openbmc, devicetree, linux-arm-kernel

On Tue, 3 Jul 2018, at 17:24, Greg KH wrote:
> On Tue, Jul 03, 2018 at 05:04:13PM +1000, Andrew Jeffery wrote:
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > ---
> >  arch/arm/boot/dts/aspeed-g5.dtsi | 192 +++++++++++++++++++++++++++++++
> >  1 file changed, 192 insertions(+)
> 
> No changelog :(

Will fix.

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

* Re: [RFC PATCH 3/4] misc: Add bmc-misc-ctrl
  2018-07-03  7:54   ` Greg KH
@ 2018-07-04  7:18     ` Andrew Jeffery
  0 siblings, 0 replies; 16+ messages in thread
From: Andrew Jeffery @ 2018-07-04  7:18 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-kernel, robh+dt, mark.rutland, joel, Eugene.Cho, a.amelkin,
	stewart, benh, openbmc, devicetree, linux-arm-kernel

On Tue, 3 Jul 2018, at 17:24, Greg KH wrote:
> On Tue, Jul 03, 2018 at 05:04:12PM +1000, Andrew Jeffery wrote:
> > bmc-misc-ctrl is used to expose miscellaneous Baseboard
> > Management Controller (BMC) hardware features described in the devicetree
> > to userspace.
> > 
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > ---
> >  MAINTAINERS                  |   1 +
> >  drivers/misc/Kconfig         |   8 +
> >  drivers/misc/Makefile        |   1 +
> >  drivers/misc/bmc-misc-ctrl.c | 363 +++++++++++++++++++++++++++++++++++
> >  4 files changed, 373 insertions(+)
> >  create mode 100644 drivers/misc/bmc-misc-ctrl.c
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 9766d7832d8b..30d39440b6f2 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2741,6 +2741,7 @@ R:	Andrew Jeffery <andrew@aj.id.au>
> >  L:	openbmc@lists.ozlabs.org (moderated for non-subscribers)
> >  S:	Supported
> >  F:	Documentation/devicetree/bindings/misc/bmc-misc-ctrl.txt
> > +F:	drivers/misc/bmc-misc-ctrl.c
> >  
> >  BPF (Safe dynamic programs and tools)
> >  M:	Alexei Starovoitov <ast@kernel.org>
> > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> > index 3726eacdf65d..f46bc8208b50 100644
> > --- a/drivers/misc/Kconfig
> > +++ b/drivers/misc/Kconfig
> > @@ -513,6 +513,14 @@ config MISC_RTSX
> >  	tristate
> >  	default MISC_RTSX_PCI || MISC_RTSX_USB
> >  
> > +config BMC_MISC_CTRL
> > +	tristate "Miscellaneous BMC Control Interfaces"
> > +	depends on REGMAP && MFD_SYSCON
> > +	help
> > +	  Say yes to expose scratch registers used to communicate between the
> > +	  host and BMC along with other miscellaneous control interfaces
> > +	  provided by BMC SoCs
> > +
> >  source "drivers/misc/c2port/Kconfig"
> >  source "drivers/misc/eeprom/Kconfig"
> >  source "drivers/misc/cb710/Kconfig"
> > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> > index af22bbc3d00c..4fb2fac7a486 100644
> > --- a/drivers/misc/Makefile
> > +++ b/drivers/misc/Makefile
> > @@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
> >  obj-$(CONFIG_PCI_ENDPOINT_TEST)	+= pci_endpoint_test.o
> >  obj-$(CONFIG_OCXL)		+= ocxl/
> >  obj-$(CONFIG_MISC_RTSX)		+= cardreader/
> > +obj-$(CONFIG_BMC_MISC_CTRL)     += bmc-misc-ctrl.o
> > diff --git a/drivers/misc/bmc-misc-ctrl.c b/drivers/misc/bmc-misc-ctrl.c
> > new file mode 100644
> > index 000000000000..ff907029163f
> > --- /dev/null
> > +++ b/drivers/misc/bmc-misc-ctrl.c
> > @@ -0,0 +1,363 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +// Copyright 2018 IBM Corp.
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/device.h>
> > +#include <linux/kobject.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +
> > +struct bmc_ctrl {
> > +	struct device *dev;
> > +	struct regmap *map;
> > +	bool ro;
> > +	u32 shift;
> > +	u32 mask;
> > +	struct kobj_attribute mask_attr;
> > +	const char *label;
> > +	struct kobj_attribute label_attr;
> > +	union {
> > +		struct {
> > +			u32 value;
> > +			struct kobj_attribute value_attr;
> > +		};
> > +		struct {
> > +			u32 read;
> > +			u32 set;
> > +			u32 clear;
> > +			struct kobj_attribute read_attr;
> > +			struct kobj_attribute set_attr;
> > +			struct kobj_attribute clear_attr;
> > +		};
> 
> What is this crazy union for?  Why are you messing around with "raw"
> kobject attributes?  This is a device, you should never have to mess
> with sysfs calls or kobject calls or structures directly.  If you do,
> that's a huge hint something is wrong here.
> 
> 
> > +	};
> > +};
> > +
> > +static ssize_t bmc_misc_rmw_show(struct kobject *kobj,
> > +					struct kobj_attribute *attr, char *buf)
> > +{
> > +	struct bmc_ctrl *ctrl;
> > +	unsigned int val;
> > +	int rc;
> > +
> > +	ctrl = container_of(attr, struct bmc_ctrl, value_attr);
> > +	rc = regmap_read(ctrl->map, ctrl->value, &val);
> > +	if (rc)
> > +		return rc;
> > +
> > +	val = (val & ctrl->mask) >> ctrl->shift;
> > +
> > +	return sprintf(buf, "%u\n", val);
> > +}
> > +
> > +static ssize_t bmc_misc_rmw_store(struct kobject *kobj,
> > +					 struct kobj_attribute *attr,
> > +					 const char *buf, size_t count)
> > +{
> > +	struct bmc_ctrl *ctrl;
> > +	long val;
> > +	int rc;
> > +
> > +	rc = kstrtol(buf, 0, &val);
> > +	if (rc)
> > +		return rc;
> > +
> > +	ctrl = container_of(attr, struct bmc_ctrl, value_attr);
> > +	val <<= ctrl->shift;
> > +	if (val & ~ctrl->mask)
> > +		return -EINVAL;
> > +	rc = regmap_update_bits(ctrl->map, ctrl->value, ctrl->mask, val);
> > +
> > +	return rc < 0 ? rc : count;
> > +}
> > +
> > +static void bmc_misc_add_rmw_attrs(struct bmc_ctrl *ctrl,
> > +				   struct attribute *attrs[6])
> > +{
> > +	sysfs_attr_init(&ctrl->attr.attr);
> > +	ctrl->value_attr.attr.name = "value";
> > +	ctrl->value_attr.attr.mode = 0664;
> > +	ctrl->value_attr.show = bmc_misc_rmw_show;
> > +	ctrl->value_attr.store = bmc_misc_rmw_store;
> > +	attrs[2] = &ctrl->value_attr.attr;
> > +	attrs[3] = NULL;
> 
> You aren't "adding" any attributes here, you are only setting them up
> (in an odd way, see below...)
> 
> > +}
> > +
> > +static int bmc_misc_init_rmw(struct bmc_ctrl *ctrl, struct device_node *node,
> > +			     struct attribute *attrs[6])
> 
> That's an oddly-hard-coded array size for no good reason :(
> 
> 
> > +{
> > +	u32 val;
> > +	int rc;
> > +
> > +	rc = of_property_read_u32(node, "offset", &ctrl->value);
> > +	if (rc < 0)
> > +		return rc;
> > +
> > +	if (!of_property_read_u32(node, "default-value", &val)) {
> > +		val <<= ctrl->shift;
> > +		if (val & ~ctrl->mask)
> > +			return -EINVAL;
> > +		val &= ctrl->mask;
> > +		regmap_update_bits(ctrl->map, ctrl->value, ctrl->mask, val);
> > +	}
> > +
> > +	bmc_misc_add_rmw_attrs(ctrl, attrs);
> > +
> > +	return 0;
> > +}
> > +
> > +static ssize_t bmc_misc_sc_read_show(struct kobject *kobj,
> > +					struct kobj_attribute *attr, char *buf)
> > +{
> > +	struct bmc_ctrl *ctrl;
> > +	unsigned int val;
> > +	int rc;
> > +
> > +	ctrl = container_of(attr, struct bmc_ctrl, read_attr);
> > +	rc = regmap_read(ctrl->map, ctrl->read, &val);
> > +	if (rc)
> > +		return rc;
> > +
> > +	val = (val & ctrl->mask) >> ctrl->shift;
> > +
> > +	return sprintf(buf, "%u\n", val);
> > +
> > +}
> > +
> > +static ssize_t bmc_misc_sc_set_store(struct kobject *kobj,
> > +					    struct kobj_attribute *attr,
> > +					    const char *buf, size_t count)
> > +{
> > +	struct bmc_ctrl *ctrl;
> > +	long val;
> > +	int rc;
> > +
> > +	rc = kstrtol(buf, 0, &val);
> > +	if (rc)
> > +		return rc;
> > +
> > +	ctrl = container_of(attr, struct bmc_ctrl, set_attr);
> > +	val <<= ctrl->shift;
> > +	if (val & ~ctrl->mask)
> > +		return -EINVAL;
> > +	val &= ctrl->mask;
> > +	rc = regmap_write(ctrl->map, ctrl->set, val);
> > +
> > +	return rc < 0 ? rc : count;
> > +}
> > +
> > +static ssize_t bmc_misc_sc_clear_store(struct kobject *kobj,
> > +					      struct kobj_attribute *attr,
> > +					      const char *buf, size_t count)
> > +{
> > +	struct bmc_ctrl *ctrl;
> > +	long val;
> > +	int rc;
> > +
> > +	rc = kstrtol(buf, 0, &val);
> > +	if (rc)
> > +		return rc;
> > +
> > +	ctrl = container_of(attr, struct bmc_ctrl, clear_attr);
> > +	val <<= ctrl->shift;
> > +	if (val & ~ctrl->mask)
> > +		return -EINVAL;
> > +	val &= ctrl->mask;
> > +	rc = regmap_write(ctrl->map, ctrl->clear, val);
> > +
> > +	return rc < 0 ? rc : count;
> > +}
> > +
> > +static void bmc_misc_add_sc_attrs(struct bmc_ctrl *ctrl,
> > +				  struct attribute *attrs[6])
> > +{
> > +	sysfs_attr_init(&ctrl->read_attr.attr);
> > +	ctrl->read_attr.attr.name = "value";
> > +	ctrl->read_attr.attr.mode = 0444;
> > +	ctrl->read_attr.show = bmc_misc_sc_read_show;
> > +	attrs[2] = &ctrl->read_attr.attr;
> > +
> > +	sysfs_attr_init(&ctrl->set_attr.attr);
> > +	ctrl->set_attr.attr.name = "set";
> > +	ctrl->set_attr.attr.mode = 0200;
> > +	ctrl->set_attr.store = bmc_misc_sc_set_store;
> > +	attrs[3] = &ctrl->set_attr.attr;
> > +
> > +	sysfs_attr_init(&ctrl->clear_attr.attr);
> > +	ctrl->clear_attr.attr.name = "clear";
> > +	ctrl->clear_attr.attr.mode = 0200;
> > +	ctrl->clear_attr.store = bmc_misc_sc_clear_store;
> > +	attrs[4] = &ctrl->clear_attr.attr;
> > +
> > +	attrs[5] = NULL;
> > +}
> > +
> > +static int bmc_misc_init_sc(struct bmc_ctrl *ctrl, struct device_node *node,
> > +			    struct attribute *attrs[6])
> > +{
> > +	int rc;
> > +
> > +	rc = of_property_read_u32_array(node, "offset", &ctrl->read, 3);
> > +	if (rc < 0)
> > +		return rc;
> > +
> > +	if (of_property_read_bool(node, "default-set"))
> > +		regmap_write(ctrl->map, ctrl->set, ctrl->mask);
> > +	else if (of_property_read_bool(node, "default-clear"))
> > +		regmap_write(ctrl->map, ctrl->clear, ctrl->mask);
> > +
> > +	bmc_misc_add_sc_attrs(ctrl, attrs);
> > +
> > +	return 0;
> > +}
> > +
> > +static ssize_t bmc_misc_label_show(struct kobject *kobj,
> > +				   struct kobj_attribute *attr, char *buf)
> > +{
> > +	struct bmc_ctrl *ctrl = container_of(attr, struct bmc_ctrl, label_attr);
> > +
> > +	return sprintf(buf, "%s\n", ctrl->label);
> > +}
> > +
> > +static ssize_t bmc_misc_mask_show(struct kobject *kobj,
> > +				   struct kobj_attribute *attr, char *buf)
> > +{
> > +	struct bmc_ctrl *ctrl = container_of(attr, struct bmc_ctrl, mask_attr);
> > +
> > +	return sprintf(buf, "0x%x\n", ctrl->mask >> ctrl->shift);
> > +}
> > +
> > +static int bmc_misc_init_dt(struct bmc_ctrl *ctrl, struct device_node *node,
> > +			    struct attribute *attrs[6])
> > +{
> > +	int rc;
> > +
> > +	/* Example children:
> > +	 *
> > +	 * field@80.6 {
> > +	 *      compatible = "bmc-misc-control";
> > +	 *      reg = <0x80>;
> > +	 *      bit-mask = <0x1>;
> > +	 *      bit-shift = <6>;
> > +	 *      label = "ilpc2ahb-disable";
> > +	 * };
> > +	 *
> > +	 * field@70.6 {
> > +	 *      compatible = "bmc-misc-control";
> > +	 *      // Write-1-set/Write-1-clear semantics
> > +	 *      set-clear;
> > +	 *      default-set;
> > +	 *      reg = <0x70 0x70 0x7c>
> > +	 *      bit-mask = <0x1>;
> > +	 *      bit-shift = <6>;
> > +	 *      label = "lpc-sio-decode-disable";
> > +	 * };
> > +	 *
> > +	 * field@50.0 {
> > +	 *	compatible = "bmc-misc-control";
> > +	 *	read-only;
> > +	 *	reg = <0x50>;
> > +	 *	bit-mask = <0xffffffff>;
> > +	 *	bit-shift = <0>;
> > +	 *	label = "vga-scratch-1";
> > +	 * };
> > +	 */
> > +	rc = of_property_read_u32(node, "mask", &ctrl->mask);
> > +	if (rc < 0)
> > +		return rc;
> > +
> > +	ctrl->shift = __ffs(ctrl->mask);
> > +	ctrl->ro = of_property_read_bool(node, "read-only");
> > +
> > +	rc = of_property_read_string(node, "label", &ctrl->label);
> > +	if (rc < 0)
> > +		return rc;
> > +
> > +	ctrl->label_attr.attr.name = "label";
> > +	ctrl->label_attr.attr.mode = 0444;
> > +	ctrl->label_attr.show = bmc_misc_label_show;
> > +	attrs[0] = &ctrl->label_attr.attr;
> 
> This works?  You normally have to manually initialize a dynamic
> attribute.  Why are you doing it this way and not using an attribute
> group?
> 
> > +	ctrl->mask_attr.attr.name = "mask";
> > +	ctrl->mask_attr.attr.mode = 0444;
> > +	ctrl->mask_attr.show = bmc_misc_mask_show;
> > +	attrs[1] = &ctrl->mask_attr.attr;
> > +
> > +	if (of_property_read_bool(node, "set-clear"))
> > +		return bmc_misc_init_sc(ctrl, node, attrs);
> > +
> > +	return bmc_misc_init_rmw(ctrl, node, attrs);
> > +}
> > +
> > +static struct class bmc_class = {
> > +	.name =		"bmc",
> > +};
> 
> Why are you using a custom device class for a single device?
> 
> you need to document the heck out of this in the changelog to help
> explain all of these odd design decisions.

It got a bit perverse from attempting to separate the devicetree handling from everything else. I'll fix the issues you've pointed out and rework the sysfs/kobj stuff.

However, the patch (and the series) was intended as a straw man. I should have put more effort in to avoid some of the distraction (sorry), but I was also hoping to get feedback on the general approach (so devicetree design and how to expose the bits to userspace in a useful manner).

Regarding the class, yeah, it's probably not the right choice and I'm not going to double down on it, but it collates the fields in an easy to discover location. Not doing something like this means a lot of grubbing around in /sys/device. Is there a better approach?

Thanks for the feedback so far.

Andrew

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

end of thread, other threads:[~2018-07-04  7:19 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-03  7:04 [RFC PATCH 0/4] sysfs interface to miscellaneous BMC controls and fields Andrew Jeffery
2018-07-03  7:04 ` [RFC PATCH 1/4] dts: misc: Add bindings documentation for bmc-misc-ctrl Andrew Jeffery
2018-07-03  7:50   ` Greg KH
2018-07-03 14:16     ` Benjamin Herrenschmidt
2018-07-03 14:31       ` Greg KH
2018-07-03 15:39         ` Benjamin Herrenschmidt
2018-07-04  6:28     ` Andrew Jeffery
2018-07-03  7:04 ` [RFC PATCH 2/4] Documentation: ABI: Add sysfs-class-bmc documentation to testing Andrew Jeffery
2018-07-03  7:50   ` Greg KH
2018-07-04  6:29     ` Andrew Jeffery
2018-07-03  7:04 ` [RFC PATCH 3/4] misc: Add bmc-misc-ctrl Andrew Jeffery
2018-07-03  7:54   ` Greg KH
2018-07-04  7:18     ` Andrew Jeffery
2018-07-03  7:04 ` [RFC PATCH 4/4] dts: aspeed-g5: Add bmc-misc-ctrl nodes to devicetree Andrew Jeffery
2018-07-03  7:54   ` Greg KH
2018-07-04  6:29     ` Andrew Jeffery

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).