[PATCH v4 0/2] Use NVMEM as reboot-mode write interface

2019-05-15 Thread Han Nandor
Description
---
Extend the reboot mode driver to use a NVMEM cell as writing interface.

Testing
---
The testing is done by configuring DT from a custom board.
The NVMEM cell is configured in an RTC non-volatile memory.
Kernel: 4.14.60 (the patchset was rebased on kernel master)

DT configurations:
`
...
reboot-mode-nvmem@0 {
compatible = "simple-mfd";
reboot-mode {
compatible = "nvmem-reboot-mode";
nvmem-cells = <_mode>;
nvmem-cell-names = "reboot-mode";

mode-test   = <0x21969147>;
};
};
...
reboot_mode: nvmem_reboot_mode@0 {
reg = <0x00 0x4>;
};
...
`

1. Reboot the system using the command `reboot test`

2. Verify that kernel logs show that reboot was done in mode `test`:
PASS
`[  413.957172] reboot: Restarting system with command 'test' `

3. Stop in U-Boot and verify that mode `test` magic value is present
in RTCs non-volatile memory: PASS

Kernel: 5.1.0-rc3

1. Configure `arch/arm/configs/imx_v6_v7_defconfig` to contain 
`CONFIG_NVMEM_REBOOT_MODE=y`
2. Verify that Kernel compiles successful: PASS
`
make ARCH=arm CROSS_COMPILE=arm-linux-gnu- imx_v6_v7_defconfig zImage
...
CC  drivers/power/reset/nvmem-reboot-mode.o
...
Kernel: arch/arm/boot/zImage is ready
`
Changes since v1:
-
 - split the documentation on a separate patch
 - add a missing header

Changes since v2:

 - change the module license to GPL since GPL v2 is deprecated

Changes since v3:

 - documentation updated according to the comments

Nandor Han (2):
  power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write
interface
  dt-bindings: power: reset: add document for NVMEM based reboot-mode

 .../power/reset/nvmem-reboot-mode.txt | 26 +++
 drivers/power/reset/Kconfig   |  9 +++
 drivers/power/reset/Makefile  |  1 +
 drivers/power/reset/nvmem-reboot-mode.c   | 76 +++
 4 files changed, 112 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
 create mode 100644 drivers/power/reset/nvmem-reboot-mode.c

-- 
2.17.2



[PATCH v4 2/2] dt-bindings: power: reset: add document for NVMEM based reboot-mode

2019-05-15 Thread Han Nandor
Add the device tree bindings document for the NVMEM based reboot-mode
driver.

Signed-off-by: Nandor Han 
---
 .../power/reset/nvmem-reboot-mode.txt | 26 +++
 1 file changed, 26 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt

diff --git 
a/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt 
b/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
new file mode 100644
index ..752d6126d5da
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
@@ -0,0 +1,26 @@
+NVMEM reboot mode driver
+
+This driver gets reboot mode magic value from reboot-mode driver
+and stores it in a NVMEM cell named "reboot-mode". Then the bootloader
+can read it and take different action according to the magic
+value stored.
+
+Required properties:
+- compatible: should be "nvmem-reboot-mode".
+- nvmem-cells: A phandle to the reboot mode provided by a nvmem device.
+- nvmem-cell-names: Should be "reboot-mode".
+
+The rest of the properties should follow the generic reboot-mode description
+found in reboot-mode.txt
+
+Example:
+   reboot-mode {
+   compatible = "nvmem-reboot-mode";
+   nvmem-cells = <_mode>;
+   nvmem-cell-names = "reboot-mode";
+
+   mode-normal = <0x5501>;
+   mode-bootloader = <0x5500>;
+   mode-recovery   = <0x5502>;
+   mode-test   = <0x5503>;
+   };
-- 
2.17.2



[PATCH v4 1/2] power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write interface

2019-05-15 Thread Han Nandor
Add a new reboot mode write interface that is using an NVMEM cell
to store the reboot mode magic.

Signed-off-by: Nandor Han 
---
 drivers/power/reset/Kconfig |  9 +++
 drivers/power/reset/Makefile|  1 +
 drivers/power/reset/nvmem-reboot-mode.c | 76 +
 3 files changed, 86 insertions(+)
 create mode 100644 drivers/power/reset/nvmem-reboot-mode.c

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 6533aa560aa1..bb4a4e854f96 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -245,5 +245,14 @@ config POWER_RESET_SC27XX
  PMICs includes the SC2720, SC2721, SC2723, SC2730
  and SC2731 chips.
 
+config NVMEM_REBOOT_MODE
+   tristate "Generic NVMEM reboot mode driver"
+   select REBOOT_MODE
+   help
+ Say y here will enable reboot mode driver. This will
+ get reboot mode arguments and store it in a NVMEM cell,
+ then the bootloader can read it and take different
+ action according to the mode.
+
 endif
 
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 0aebee954ac1..85da3198e4e0 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
 obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
 obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
 obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
+obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o
diff --git a/drivers/power/reset/nvmem-reboot-mode.c 
b/drivers/power/reset/nvmem-reboot-mode.c
new file mode 100644
index ..e229308d43e2
--- /dev/null
+++ b/drivers/power/reset/nvmem-reboot-mode.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Vaisala Oyj. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct nvmem_reboot_mode {
+   struct reboot_mode_driver reboot;
+   struct nvmem_cell *cell;
+};
+
+static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
+   unsigned int magic)
+{
+   int ret;
+   struct nvmem_reboot_mode *nvmem_rbm;
+
+   nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot);
+
+   ret = nvmem_cell_write(nvmem_rbm->cell, , sizeof(magic));
+   if (ret < 0)
+   dev_err(reboot->dev, "update reboot mode bits failed\n");
+
+   return ret;
+}
+
+static int nvmem_reboot_mode_probe(struct platform_device *pdev)
+{
+   int ret;
+   struct nvmem_reboot_mode *nvmem_rbm;
+
+   nvmem_rbm = devm_kzalloc(>dev, sizeof(*nvmem_rbm), GFP_KERNEL);
+   if (!nvmem_rbm)
+   return -ENOMEM;
+
+   nvmem_rbm->reboot.dev = >dev;
+   nvmem_rbm->reboot.write = nvmem_reboot_mode_write;
+
+   nvmem_rbm->cell = devm_nvmem_cell_get(>dev, "reboot-mode");
+   if (IS_ERR(nvmem_rbm->cell)) {
+   dev_err(>dev, "failed to get the nvmem cell 
reboot-mode\n");
+   return PTR_ERR(nvmem_rbm->cell);
+   }
+
+   ret = devm_reboot_mode_register(>dev, _rbm->reboot);
+   if (ret)
+   dev_err(>dev, "can't register reboot mode\n");
+
+   return ret;
+}
+
+static const struct of_device_id nvmem_reboot_mode_of_match[] = {
+   { .compatible = "nvmem-reboot-mode" },
+   {}
+};
+MODULE_DEVICE_TABLE(of, nvmem_reboot_mode_of_match);
+
+static struct platform_driver nvmem_reboot_mode_driver = {
+   .probe = nvmem_reboot_mode_probe,
+   .driver = {
+   .name = "nvmem-reboot-mode",
+   .of_match_table = nvmem_reboot_mode_of_match,
+   },
+};
+module_platform_driver(nvmem_reboot_mode_driver);
+
+MODULE_AUTHOR("Nandor Han ");
+MODULE_DESCRIPTION("NVMEM reboot mode driver");
+MODULE_LICENSE("GPL");
-- 
2.17.2



[PATCH v3 2/2] dt-bindings: power: reset: add document for NVMEM based reboot-mode

2019-04-21 Thread Han Nandor
Add the device tree bindings document for the NVMEM based reboot-mode
driver.

Signed-off-by: Nandor Han 
---
 .../power/reset/nvmem-reboot-mode.txt | 32 +++
 1 file changed, 32 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt

diff --git 
a/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt 
b/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
new file mode 100644
index ..2e1b86c31cb3
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
@@ -0,0 +1,32 @@
+NVMEM reboot mode driver
+
+This driver gets reboot mode magic value from reboot-mode driver
+and stores it in a NVMEM cell named "reboot-mode". Then the bootloader
+can read it and take different action according to the magic
+value stored.
+
+This DT node should be represented as a sub-node of a "simple-mfd"
+node.
+
+Required properties:
+- compatible: should be "nvmem-reboot-mode".
+- nvmem-cells: A phandle to the reboot mode provided by a nvmem device.
+- nvmem-cell-names: Should be "reboot-mode".
+
+The rest of the properties should follow the generic reboot-mode description
+found in reboot-mode.txt
+
+Example:
+   reboot-mode-nvmem@0 {
+   compatible = "simple-mfd";
+   reboot-mode {
+   compatible = "nvmem-reboot-mode";
+   nvmem-cells = <_mode>;
+   nvmem-cell-names = "reboot-mode";
+
+   mode-normal = <0x5501>;
+   mode-bootloader = <0x5500>;
+   mode-recovery   = <0x5502>;
+   mode-test   = <0x5503>;
+   };
+   };
-- 
2.17.2



[PATCH v3 0/2] Use NVMEM as reboot-mode write interface

2019-04-21 Thread Han Nandor
Description
---
Extend the reboot mode driver to use a NVMEM cell as writing interface.

Testing
---
The testing is done by configuring DT from a custom board.
The NVMEM cell is configured in an RTC non-volatile memory.
Kernel: 4.14.60 (the patchset was rebased on kernel master)

DT configurations:
`
...
reboot-mode-nvmem@0 {
compatible = "simple-mfd";
reboot-mode {
compatible = "nvmem-reboot-mode";
nvmem-cells = <_mode>;
nvmem-cell-names = "reboot-mode";

mode-test   = <0x21969147>;
};
};
...
reboot_mode: nvmem_reboot_mode@0 {
reg = <0x00 0x4>;
};
...
`

1. Reboot the system using the command `reboot test`

2. Verify that kernel logs show that reboot was done in mode `test`:
PASS
`[  413.957172] reboot: Restarting system with command 'test' `

3. Stop in U-Boot and verify that mode `test` magic value is present
in RTCs non-volatile memory: PASS

Kernel: 5.1.0-rc3

1. Configure `arch/arm/configs/imx_v6_v7_defconfig` to contain 
`CONFIG_NVMEM_REBOOT_MODE=y`
2. Verify that Kernel compiles successful: PASS
`
make ARCH=arm CROSS_COMPILE=arm-linux-gnu- imx_v6_v7_defconfig zImage
...
CC  drivers/power/reset/nvmem-reboot-mode.o
...
Kernel: arch/arm/boot/zImage is ready
`
Changes since v1:
-
 - split the documentation on a separate patch
 - add a missing header

Changes since v2:

 - change the module license to GPL since GPL v2 is deprecated

Nandor Han (2):
  power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write
interface
  dt-bindings: power: reset: add document for NVMEM based reboot-mode

 .../power/reset/nvmem-reboot-mode.txt | 32 
 drivers/power/reset/Kconfig   |  9 +++
 drivers/power/reset/Makefile  |  1 +
 drivers/power/reset/nvmem-reboot-mode.c   | 76 +++
 4 files changed, 118 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
 create mode 100644 drivers/power/reset/nvmem-reboot-mode.c

-- 
2.17.2



[PATCH v3 1/2] power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write interface

2019-04-21 Thread Han Nandor
Add a new reboot mode write interface that is using an NVMEM cell
to store the reboot mode magic.

Signed-off-by: Nandor Han 
---
 drivers/power/reset/Kconfig |  9 +++
 drivers/power/reset/Makefile|  1 +
 drivers/power/reset/nvmem-reboot-mode.c | 76 +
 3 files changed, 86 insertions(+)
 create mode 100644 drivers/power/reset/nvmem-reboot-mode.c

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 6533aa560aa1..bb4a4e854f96 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -245,5 +245,14 @@ config POWER_RESET_SC27XX
  PMICs includes the SC2720, SC2721, SC2723, SC2730
  and SC2731 chips.
 
+config NVMEM_REBOOT_MODE
+   tristate "Generic NVMEM reboot mode driver"
+   select REBOOT_MODE
+   help
+ Say y here will enable reboot mode driver. This will
+ get reboot mode arguments and store it in a NVMEM cell,
+ then the bootloader can read it and take different
+ action according to the mode.
+
 endif
 
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 0aebee954ac1..85da3198e4e0 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
 obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
 obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
 obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
+obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o
diff --git a/drivers/power/reset/nvmem-reboot-mode.c 
b/drivers/power/reset/nvmem-reboot-mode.c
new file mode 100644
index ..e229308d43e2
--- /dev/null
+++ b/drivers/power/reset/nvmem-reboot-mode.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Vaisala Oyj. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct nvmem_reboot_mode {
+   struct reboot_mode_driver reboot;
+   struct nvmem_cell *cell;
+};
+
+static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
+   unsigned int magic)
+{
+   int ret;
+   struct nvmem_reboot_mode *nvmem_rbm;
+
+   nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot);
+
+   ret = nvmem_cell_write(nvmem_rbm->cell, , sizeof(magic));
+   if (ret < 0)
+   dev_err(reboot->dev, "update reboot mode bits failed\n");
+
+   return ret;
+}
+
+static int nvmem_reboot_mode_probe(struct platform_device *pdev)
+{
+   int ret;
+   struct nvmem_reboot_mode *nvmem_rbm;
+
+   nvmem_rbm = devm_kzalloc(>dev, sizeof(*nvmem_rbm), GFP_KERNEL);
+   if (!nvmem_rbm)
+   return -ENOMEM;
+
+   nvmem_rbm->reboot.dev = >dev;
+   nvmem_rbm->reboot.write = nvmem_reboot_mode_write;
+
+   nvmem_rbm->cell = devm_nvmem_cell_get(>dev, "reboot-mode");
+   if (IS_ERR(nvmem_rbm->cell)) {
+   dev_err(>dev, "failed to get the nvmem cell 
reboot-mode\n");
+   return PTR_ERR(nvmem_rbm->cell);
+   }
+
+   ret = devm_reboot_mode_register(>dev, _rbm->reboot);
+   if (ret)
+   dev_err(>dev, "can't register reboot mode\n");
+
+   return ret;
+}
+
+static const struct of_device_id nvmem_reboot_mode_of_match[] = {
+   { .compatible = "nvmem-reboot-mode" },
+   {}
+};
+MODULE_DEVICE_TABLE(of, nvmem_reboot_mode_of_match);
+
+static struct platform_driver nvmem_reboot_mode_driver = {
+   .probe = nvmem_reboot_mode_probe,
+   .driver = {
+   .name = "nvmem-reboot-mode",
+   .of_match_table = nvmem_reboot_mode_of_match,
+   },
+};
+module_platform_driver(nvmem_reboot_mode_driver);
+
+MODULE_AUTHOR("Nandor Han ");
+MODULE_DESCRIPTION("NVMEM reboot mode driver");
+MODULE_LICENSE("GPL");
-- 
2.17.2



[PATCH v3 1/1] rtc: ds3232: get SRAM access using NVMEM Framework

2019-04-16 Thread Han Nandor
DS3232 RTC has 236 bytes of persistent memory.

Add RTC SRAM read and write access using
the NVMEM Framework.

Signed-off-by: Nandor Han 
---

Description
---
Provides DS3232 RTC SRAM access using NVMEM framework.

Testing
---
The test was done on a custom board which contains a
DS3232 RTC device.
Kernel Version: 4.14.60 (Just for clarity, the patch is against master)

1. Verify that SRAM is accessible using NVMEM interface: PASS
`
# hexdump /sys/bus/nvmem/devices/ds3232_sram0/nvmem
000        
*
0e0
`
2. Modify the content.
`
# echo testing > /sys/bus/nvmem/devices/ds3232_sram0/nvmem
#
`
3. Power cycle the board and verify that contents are preserved: PASS
`
# hexdump -n 10 -C /sys/bus/nvmem/devices/ds3232_sram0/nvmem
  74 65 73 74 69 6e 67 0a  00 00|testing...|
000a
`

Testing on Kernel v5.1.0-rc3

1. Update `arch/arm/configs/imx_v6_v7_defconfig` to contain
`CONFIG_RTC_DRV_DS3232=y`
2. Verify that building the kernel is successful: PASS
`
make ARCH=arm CROSS_COMPILE=arm-linux-gnu- imx_v6_v7_defconfig zImage
...
CC  drivers/rtc/rtc-ds3232.o
...
Kernel: arch/arm/boot/zImage is ready
`

Changes since v1

 - remove the unnecessary header "rtc-core.h"
 - use nvmem_config from the stack
 - configure the nvmem type
 - remove the `of_node` configuration

Changes since v2

 - init unused struct nvmem_cfg members to 0
 - use regmap as private data to nvmem struct

 drivers/rtc/rtc-ds3232.c | 40 ++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 7184e5145f12..1e9312f96021 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -48,6 +48,10 @@
 #   define DS3232_REG_SR_A1F 0x01
 
 #define DS3232_REG_TEMPERATURE 0x11
+#define DS3232_REG_SRAM_START   0x14
+#define DS3232_REG_SRAM_END 0xFF
+
+#define DS3232_REG_SRAM_SIZE236
 
 struct ds3232 {
struct device *dev;
@@ -461,11 +465,39 @@ static const struct rtc_class_ops ds3232_rtc_ops = {
.alarm_irq_enable = ds3232_alarm_irq_enable,
 };
 
+static int ds3232_nvmem_read(void *priv, unsigned int offset, void *val,
+size_t bytes)
+{
+   struct regmap *ds3232_regmap = (struct regmap *)priv;
+
+   return regmap_bulk_read(ds3232_regmap, DS3232_REG_SRAM_START + offset,
+   val, bytes);
+}
+
+static int ds3232_nvmem_write(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+   struct regmap *ds3232_regmap = (struct regmap *)priv;
+
+   return regmap_bulk_write(ds3232_regmap, DS3232_REG_SRAM_START + offset,
+val, bytes);
+}
+
 static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name)
 {
struct ds3232 *ds3232;
int ret;
+   struct nvmem_config nvmem_cfg = {
+   .name = "ds3232_sram",
+   .stride = 1,
+   .size = DS3232_REG_SRAM_SIZE,
+   .word_size = 1,
+   .reg_read = ds3232_nvmem_read,
+   .reg_write = ds3232_nvmem_write,
+   .priv = regmap,
+   .type = NVMEM_TYPE_BATTERY_BACKED
+   };
 
ds3232 = devm_kzalloc(dev, sizeof(*ds3232), GFP_KERNEL);
if (!ds3232)
@@ -490,6 +522,10 @@ static int ds3232_probe(struct device *dev, struct regmap 
*regmap, int irq,
if (IS_ERR(ds3232->rtc))
return PTR_ERR(ds3232->rtc);
 
+   ret = rtc_nvmem_register(ds3232->rtc, _cfg);
+   if(ret)
+   return ret;
+
if (ds3232->irq > 0) {
ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
ds3232_irq,
@@ -542,7 +578,7 @@ static int ds3232_i2c_probe(struct i2c_client *client,
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
-   .max_register = 0x13,
+   .max_register = DS3232_REG_SRAM_END,
};
 
regmap = devm_regmap_init_i2c(client, );
@@ -609,7 +645,7 @@ static int ds3234_probe(struct spi_device *spi)
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
-   .max_register = 0x13,
+   .max_register = DS3232_REG_SRAM_END,
.write_flag_mask = 0x80,
};
struct regmap *regmap;
-- 
2.17.2



[PATCH v2 2/2] dt-bindings: power: reset: add document for NVMEM based reboot-mode

2019-04-10 Thread Han Nandor
Add the device tree bindings document for the NVMEM based reboot-mode
driver.

Signed-off-by: Nandor Han 
---
 .../power/reset/nvmem-reboot-mode.txt | 32 +++
 1 file changed, 32 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt

diff --git 
a/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt 
b/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
new file mode 100644
index ..2e1b86c31cb3
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
@@ -0,0 +1,32 @@
+NVMEM reboot mode driver
+
+This driver gets reboot mode magic value from reboot-mode driver
+and stores it in a NVMEM cell named "reboot-mode". Then the bootloader
+can read it and take different action according to the magic
+value stored.
+
+This DT node should be represented as a sub-node of a "simple-mfd"
+node.
+
+Required properties:
+- compatible: should be "nvmem-reboot-mode".
+- nvmem-cells: A phandle to the reboot mode provided by a nvmem device.
+- nvmem-cell-names: Should be "reboot-mode".
+
+The rest of the properties should follow the generic reboot-mode description
+found in reboot-mode.txt
+
+Example:
+   reboot-mode-nvmem@0 {
+   compatible = "simple-mfd";
+   reboot-mode {
+   compatible = "nvmem-reboot-mode";
+   nvmem-cells = <_mode>;
+   nvmem-cell-names = "reboot-mode";
+
+   mode-normal = <0x5501>;
+   mode-bootloader = <0x5500>;
+   mode-recovery   = <0x5502>;
+   mode-test   = <0x5503>;
+   };
+   };
-- 
2.17.2



[PATCH v2 1/2] power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write interface

2019-04-10 Thread Han Nandor
Add a new reboot mode write interface that is using an NVMEM cell
to store the reboot mode magic.

Signed-off-by: Nandor Han 
---
 drivers/power/reset/Kconfig |  9 +++
 drivers/power/reset/Makefile|  1 +
 drivers/power/reset/nvmem-reboot-mode.c | 76 +
 3 files changed, 86 insertions(+)
 create mode 100644 drivers/power/reset/nvmem-reboot-mode.c

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 6533aa560aa1..bb4a4e854f96 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -245,5 +245,14 @@ config POWER_RESET_SC27XX
  PMICs includes the SC2720, SC2721, SC2723, SC2730
  and SC2731 chips.
 
+config NVMEM_REBOOT_MODE
+   tristate "Generic NVMEM reboot mode driver"
+   select REBOOT_MODE
+   help
+ Say y here will enable reboot mode driver. This will
+ get reboot mode arguments and store it in a NVMEM cell,
+ then the bootloader can read it and take different
+ action according to the mode.
+
 endif
 
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 0aebee954ac1..85da3198e4e0 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
 obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
 obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
 obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
+obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o
diff --git a/drivers/power/reset/nvmem-reboot-mode.c 
b/drivers/power/reset/nvmem-reboot-mode.c
new file mode 100644
index ..816cfdab16a7
--- /dev/null
+++ b/drivers/power/reset/nvmem-reboot-mode.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Vaisala Oyj. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct nvmem_reboot_mode {
+   struct reboot_mode_driver reboot;
+   struct nvmem_cell *cell;
+};
+
+static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
+   unsigned int magic)
+{
+   int ret;
+   struct nvmem_reboot_mode *nvmem_rbm;
+
+   nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot);
+
+   ret = nvmem_cell_write(nvmem_rbm->cell, , sizeof(magic));
+   if (ret < 0)
+   dev_err(reboot->dev, "update reboot mode bits failed\n");
+
+   return ret;
+}
+
+static int nvmem_reboot_mode_probe(struct platform_device *pdev)
+{
+   int ret;
+   struct nvmem_reboot_mode *nvmem_rbm;
+
+   nvmem_rbm = devm_kzalloc(>dev, sizeof(*nvmem_rbm), GFP_KERNEL);
+   if (!nvmem_rbm)
+   return -ENOMEM;
+
+   nvmem_rbm->reboot.dev = >dev;
+   nvmem_rbm->reboot.write = nvmem_reboot_mode_write;
+
+   nvmem_rbm->cell = devm_nvmem_cell_get(>dev, "reboot-mode");
+   if (IS_ERR(nvmem_rbm->cell)) {
+   dev_err(>dev, "failed to get the nvmem cell 
reboot-mode\n");
+   return PTR_ERR(nvmem_rbm->cell);
+   }
+
+   ret = devm_reboot_mode_register(>dev, _rbm->reboot);
+   if (ret)
+   dev_err(>dev, "can't register reboot mode\n");
+
+   return ret;
+}
+
+static const struct of_device_id nvmem_reboot_mode_of_match[] = {
+   { .compatible = "nvmem-reboot-mode" },
+   {}
+};
+MODULE_DEVICE_TABLE(of, nvmem_reboot_mode_of_match);
+
+static struct platform_driver nvmem_reboot_mode_driver = {
+   .probe = nvmem_reboot_mode_probe,
+   .driver = {
+   .name = "nvmem-reboot-mode",
+   .of_match_table = nvmem_reboot_mode_of_match,
+   },
+};
+module_platform_driver(nvmem_reboot_mode_driver);
+
+MODULE_AUTHOR("Nandor Han ");
+MODULE_DESCRIPTION("NVMEM reboot mode driver");
+MODULE_LICENSE("GPL v2");
-- 
2.17.2



[PATCH v2 0/2] Use NVMEM as reboot-mode write interface

2019-04-10 Thread Han Nandor
Description
---
Extend the reboot mode driver to use a NVMEM cell as writing interface.

Testing
---
The testing is done by configuring DT from a custom board.
The NVMEM cell is configured in an RTC non-volatile memory.
Kernel: 4.14.60 (the patchset was rebased on kernel master)

DT configurations:
`
...
reboot-mode-nvmem@0 {
compatible = "simple-mfd";
reboot-mode {
compatible = "nvmem-reboot-mode";
nvmem-cells = <_mode>;
nvmem-cell-names = "reboot-mode";

mode-test   = <0x21969147>;
};
};
...
reboot_mode: nvmem_reboot_mode@0 {
reg = <0x00 0x4>;
};
...
`

1. Reboot the system using the command `reboot test`

2. Verify that kernel logs show that reboot was done in mode `test`:
PASS
`[  413.957172] reboot: Restarting system with command 'test' `

3. Stop in U-Boot and verify that mode `test` magic value is present
in RTCs non-volatile memory: PASS

Kernel: 5.1.0-rc3

1. Configure `arch/arm/configs/imx_v6_v7_defconfig` to contain 
`CONFIG_NVMEM_REBOOT_MODE=y`
2. Verify that Kernel compiles successful: PASS
`
make ARCH=arm CROSS_COMPILE=arm-linux-gnu- imx_v6_v7_defconfig zImage
...
CC  drivers/power/reset/nvmem-reboot-mode.o
...
Kernel: arch/arm/boot/zImage is ready
`
Changes since v1:
-
 - split the documentation on a separate patch
 - add a missing header

Nandor Han (2):
  power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write
interface
  dt-bindings: power: reset: add document for NVMEM based reboot-mode

 .../power/reset/nvmem-reboot-mode.txt | 32 
 drivers/power/reset/Kconfig   |  9 +++
 drivers/power/reset/Makefile  |  1 +
 drivers/power/reset/nvmem-reboot-mode.c   | 76 +++
 4 files changed, 118 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
 create mode 100644 drivers/power/reset/nvmem-reboot-mode.c

-- 
2.17.2



[PATCH v2 1/1] rtc: ds3232: get SRAM access using NVMEM Framework

2019-04-08 Thread Han Nandor
DS3232 RTC has 236 bytes of persistent memory.

Add RTC SRAM read and write access using
the NVMEM Framework.

Signed-off-by: Nandor Han 
---

Description
---
Provides DS3232 RTC SRAM access using NVMEM framework.

Testing
---
The test was done on a custom board which contains a
DS3232 RTC device.
Kernel Version: 4.14.60 (Just for clarity, the patch is against master)

1. Verify that SRAM is accessible using NVMEM interface: PASS
`
# hexdump /sys/bus/nvmem/devices/ds3232_sram0/nvmem
000        
*
0e0
`
2. Modify the content.
`
# echo testing > /sys/bus/nvmem/devices/ds3232_sram0/nvmem
#
`
3. Power cycle the board and verify that contents are preserved: PASS
`
# hexdump -n 10 -C /sys/bus/nvmem/devices/ds3232_sram0/nvmem
  74 65 73 74 69 6e 67 0a  00 00|testing...|
000a
`

Testing on Kernel v5.1.0-rc3

1. Update `arch/arm/configs/imx_v6_v7_defconfig` to contain
`CONFIG_RTC_DRV_DS3232=y`
2. Verify that building the kernel is successful: PASS
`
make ARCH=arm CROSS_COMPILE=arm-linux-gnu- imx_v6_v7_defconfig zImage
...
CC  drivers/rtc/rtc-ds3232.o
...
Kernel: arch/arm/boot/zImage is ready
`

Changes since v1

 - remove the unnecessary header "rtc-core.h"
 - use nvmem_config from the stack
 - configure the nvmem type
 - remove the `of_node` configuration


 drivers/rtc/rtc-ds3232.c | 40 ++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 7184e5145f12..77908c9e5e09 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -48,6 +48,10 @@
 #   define DS3232_REG_SR_A1F 0x01
 
 #define DS3232_REG_TEMPERATURE 0x11
+#define DS3232_REG_SRAM_START   0x14
+#define DS3232_REG_SRAM_END 0xFF
+
+#define DS3232_REG_SRAM_SIZE236
 
 struct ds3232 {
struct device *dev;
@@ -461,11 +465,30 @@ static const struct rtc_class_ops ds3232_rtc_ops = {
.alarm_irq_enable = ds3232_alarm_irq_enable,
 };
 
+static int ds3232_nvmem_read(void *priv, unsigned int offset, void *val,
+size_t bytes)
+{
+   struct ds3232 *ds3232 = (struct ds3232 *)priv;
+
+   return regmap_bulk_read(ds3232->regmap, DS3232_REG_SRAM_START + offset,
+   val, bytes);
+}
+
+static int ds3232_nvmem_write(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+   struct ds3232 *ds3232 = (struct ds3232 *)priv;
+
+   return regmap_bulk_write(ds3232->regmap, DS3232_REG_SRAM_START + offset,
+val, bytes);
+}
+
 static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name)
 {
struct ds3232 *ds3232;
int ret;
+   struct nvmem_config nvmem_cfg;
 
ds3232 = devm_kzalloc(dev, sizeof(*ds3232), GFP_KERNEL);
if (!ds3232)
@@ -476,6 +499,15 @@ static int ds3232_probe(struct device *dev, struct regmap 
*regmap, int irq,
ds3232->dev = dev;
dev_set_drvdata(dev, ds3232);
 
+   nvmem_cfg.name = "ds3232_sram";
+   nvmem_cfg.stride = 1;
+   nvmem_cfg.size = DS3232_REG_SRAM_SIZE;
+   nvmem_cfg.word_size = 1;
+   nvmem_cfg.reg_read = ds3232_nvmem_read;
+   nvmem_cfg.reg_write = ds3232_nvmem_write;
+   nvmem_cfg.priv = ds3232;
+   nvmem_cfg.type = NVMEM_TYPE_BATTERY_BACKED;
+
ret = ds3232_check_rtc_status(dev);
if (ret)
return ret;
@@ -490,6 +522,10 @@ static int ds3232_probe(struct device *dev, struct regmap 
*regmap, int irq,
if (IS_ERR(ds3232->rtc))
return PTR_ERR(ds3232->rtc);
 
+   ret = rtc_nvmem_register(ds3232->rtc, _cfg);
+   if(ret)
+   return ret;
+
if (ds3232->irq > 0) {
ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
ds3232_irq,
@@ -542,7 +578,7 @@ static int ds3232_i2c_probe(struct i2c_client *client,
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
-   .max_register = 0x13,
+   .max_register = DS3232_REG_SRAM_END,
};
 
regmap = devm_regmap_init_i2c(client, );
@@ -609,7 +645,7 @@ static int ds3234_probe(struct spi_device *spi)
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
-   .max_register = 0x13,
+   .max_register = DS3232_REG_SRAM_END,
.write_flag_mask = 0x80,
};
struct regmap *regmap;
-- 
2.17.2



[PATCH 1/1] rtc: ds3232: get SRAM access using NVMEM Framework

2019-04-05 Thread Han Nandor
DS3232 RTC has 236 bytes of persistent memory.

Add RTC SRAM read and write access using
the NVMEM Framework.

Signed-off-by: Nandor Han 
---

Description
---
Provides DS3232 RTC SRAM access using NVMEM framework.

Testing
---
The test was done on a custom board which contains a
DS3232 RTC device.
Kernel Version: 4.14.60 (Just for clarity, the patch is against master)

1. Verify that SRAM is accessible using NVMEM interface: PASS
`
# hexdump /sys/bus/nvmem/devices/ds3232_sram0/nvmem
000        
*
0e0
`
2. Modify the content.
`
# echo testing > /sys/bus/nvmem/devices/ds3232_sram0/nvmem
#
`
3. Power cycle the board and verify that contents are preserved: PASS
`
# hexdump -n 10 -C /sys/bus/nvmem/devices/ds3232_sram0/nvmem
  74 65 73 74 69 6e 67 0a  00 00|testing...|
000a
`

 drivers/rtc/rtc-ds3232.c | 41 ++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 7184e5145f12..fe615aedaa9a 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -24,6 +24,8 @@
 #include 
 #include 
 
+#include "rtc-core.h"
+
 #define DS3232_REG_SECONDS  0x00
 #define DS3232_REG_MINUTES  0x01
 #define DS3232_REG_HOURS0x02
@@ -48,12 +50,17 @@
 #   define DS3232_REG_SR_A1F 0x01
 
 #define DS3232_REG_TEMPERATURE 0x11
+#define DS3232_REG_SRAM_START   0x14
+#define DS3232_REG_SRAM_END 0xFF
+
+#define DS3232_REG_SRAM_SIZE236
 
 struct ds3232 {
struct device *dev;
struct regmap *regmap;
int irq;
struct rtc_device *rtc;
+   struct nvmem_config nvmem_cfg;
 
bool suspended;
 };
@@ -461,6 +468,24 @@ static const struct rtc_class_ops ds3232_rtc_ops = {
.alarm_irq_enable = ds3232_alarm_irq_enable,
 };
 
+static int ds3232_nvmem_read(void *priv, unsigned int offset, void *val,
+size_t bytes)
+{
+   struct ds3232 *ds3232 = (struct ds3232 *)priv;
+
+   return regmap_bulk_read(ds3232->regmap, DS3232_REG_SRAM_START + offset,
+   val, bytes);
+}
+
+static int ds3232_nvmem_write(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+   struct ds3232 *ds3232 = (struct ds3232 *)priv;
+
+   return regmap_bulk_write(ds3232->regmap, DS3232_REG_SRAM_START + offset,
+val, bytes);
+}
+
 static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name)
 {
@@ -476,6 +501,14 @@ static int ds3232_probe(struct device *dev, struct regmap 
*regmap, int irq,
ds3232->dev = dev;
dev_set_drvdata(dev, ds3232);
 
+   ds3232->nvmem_cfg.name = "ds3232_sram";
+   ds3232->nvmem_cfg.stride = 1;
+   ds3232->nvmem_cfg.size = DS3232_REG_SRAM_SIZE;
+   ds3232->nvmem_cfg.word_size = 1;
+   ds3232->nvmem_cfg.reg_read = ds3232_nvmem_read;
+   ds3232->nvmem_cfg.reg_write = ds3232_nvmem_write;
+   ds3232->nvmem_cfg.priv = ds3232;
+
ret = ds3232_check_rtc_status(dev);
if (ret)
return ret;
@@ -490,6 +523,10 @@ static int ds3232_probe(struct device *dev, struct regmap 
*regmap, int irq,
if (IS_ERR(ds3232->rtc))
return PTR_ERR(ds3232->rtc);
 
+   ds3232->rtc->dev.of_node = dev->of_node;
+   ds3232->rtc->nvmem_config = >nvmem_cfg;
+   rtc_nvmem_register(ds3232->rtc);
+
if (ds3232->irq > 0) {
ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
ds3232_irq,
@@ -542,7 +579,7 @@ static int ds3232_i2c_probe(struct i2c_client *client,
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
-   .max_register = 0x13,
+   .max_register = DS3232_REG_SRAM_END,
};
 
regmap = devm_regmap_init_i2c(client, );
@@ -609,7 +646,7 @@ static int ds3234_probe(struct spi_device *spi)
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
-   .max_register = 0x13,
+   .max_register = DS3232_REG_SRAM_END,
.write_flag_mask = 0x80,
};
struct regmap *regmap;
-- 
2.17.2



[PATCH 1/1] power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write interface

2019-04-05 Thread Han Nandor
Add a new reboot mode write interface that is using a NVMEM cell,
called "reboot-mode", to store the reboot mode magic.

Signed-off-by: Nandor Han 
---

Description
---
Extend the reboot mode driver to use a NVMEM cell as writing interface.

Testing
---
The testing is done by configuring DT from a custom board.
The NVMEM cell is configured in an RTC non-volatile memory.

DT configurations:
`
...
reboot-mode-nvmem@0 {
compatible = "simple-mfd";
reboot-mode {
compatible = "nvmem-reboot-mode";
nvmem-cells = <_mode>;
nvmem-cell-names = "reboot-mode";

mode-test   = <0x21969147>;
 };
};
...
reboot_mode: nvmem_reboot_mode@0 {
reg = <0x00 0x4>;
};
...
`

1. Reboot the system using the command `reboot test`

2. Verify that kernel logs show that reboot was done in mode `test`:
PASS
`[  413.957172] reboot: Restarting system with command 'test' `

3. Stop in U-Boot and verify that mode `test` magic value is present
in RTCs non-volatile memory: PASS

 .../power/reset/nvmem-reboot-mode.txt | 32 
 drivers/power/reset/Kconfig   |  9 +++
 drivers/power/reset/Makefile  |  1 +
 drivers/power/reset/nvmem-reboot-mode.c   | 75 +++
 4 files changed, 117 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
 create mode 100644 drivers/power/reset/nvmem-reboot-mode.c

diff --git 
a/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt 
b/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
new file mode 100644
index ..2e1b86c31cb3
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/nvmem-reboot-mode.txt
@@ -0,0 +1,32 @@
+NVMEM reboot mode driver
+
+This driver gets reboot mode magic value from reboot-mode driver
+and stores it in a NVMEM cell named "reboot-mode". Then the bootloader
+can read it and take different action according to the magic
+value stored.
+
+This DT node should be represented as a sub-node of a "simple-mfd"
+node.
+
+Required properties:
+- compatible: should be "nvmem-reboot-mode".
+- nvmem-cells: A phandle to the reboot mode provided by a nvmem device.
+- nvmem-cell-names: Should be "reboot-mode".
+
+The rest of the properties should follow the generic reboot-mode description
+found in reboot-mode.txt
+
+Example:
+   reboot-mode-nvmem@0 {
+   compatible = "simple-mfd";
+   reboot-mode {
+   compatible = "nvmem-reboot-mode";
+   nvmem-cells = <_mode>;
+   nvmem-cell-names = "reboot-mode";
+
+   mode-normal = <0x5501>;
+   mode-bootloader = <0x5500>;
+   mode-recovery   = <0x5502>;
+   mode-test   = <0x5503>;
+   };
+   };
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 6533aa560aa1..bb4a4e854f96 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -245,5 +245,14 @@ config POWER_RESET_SC27XX
  PMICs includes the SC2720, SC2721, SC2723, SC2730
  and SC2731 chips.
 
+config NVMEM_REBOOT_MODE
+   tristate "Generic NVMEM reboot mode driver"
+   select REBOOT_MODE
+   help
+ Say y here will enable reboot mode driver. This will
+ get reboot mode arguments and store it in a NVMEM cell,
+ then the bootloader can read it and take different
+ action according to the mode.
+
 endif
 
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 0aebee954ac1..85da3198e4e0 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
 obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
 obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
 obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o
+obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o
diff --git a/drivers/power/reset/nvmem-reboot-mode.c 
b/drivers/power/reset/nvmem-reboot-mode.c
new file mode 100644
index ..31b73c7a0dad
--- /dev/null
+++ b/drivers/power/reset/nvmem-reboot-mode.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Vaisala Oyj. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct nvmem_reboot_mode {
+   struct reboot_mode_driver reboot;
+   struct nvmem_cell *cell;
+};
+
+static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
+   unsigned int magic)
+{
+   int ret;
+   struct nvmem_reboot_mode *nvmem_rbm;
+
+   nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot);
+
+   ret = nvmem_cell_write(nvmem_rbm->cell, , sizeof(magic));
+   if (ret < 0)
+   dev_err(reboot->dev, "update reboot mode bits failed\n");
+
+   return 

[RFC PATCH 1/1] regmap: verify if register is writeable before writing operations

2019-04-02 Thread Han Nandor
regmap provides a couple of ways to validate the register range used.
a) maxim allowed register, b) writable/readable register tables,
c) callback function that can be provided by the driver to validate
a register. regmap framework should verify if registers
are writeable before every write operation. However this doesn't
seems to happen in every situation.

The method `_regmap_raw_write_impl` is only using the `writeable_reg`
callback to verify if register is writeable, ignoring the other two.
This can lead to undefined behaviour since this allows to write to
registers that could be declared un-writeable by using any other
option.

Change `_regmap_raw_write_impl` to use the `regmap_writeable` method
to verify if registers are writable before the write operation.

Signed-off-by: Nandor Han 
---
 drivers/base/regmap/regmap.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 4f822e087def..42d8404bc8cc 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1493,11 +1493,10 @@ static int _regmap_raw_write_impl(struct regmap *map, 
unsigned int reg,
WARN_ON(!map->bus);
 
/* Check for unwritable registers before we start */
-   if (map->writeable_reg)
-   for (i = 0; i < val_len / map->format.val_bytes; i++)
-   if (!map->writeable_reg(map->dev,
-  reg + regmap_get_offset(map, i)))
-   return -EINVAL;
+   for (i = 0; i < val_len / map->format.val_bytes; i++)
+   if (!regmap_writeable(map,
+reg + regmap_get_offset(map, i)))
+   return -EINVAL;
 
if (!map->cache_bypass && map->format.parse_val) {
unsigned int ival;
-- 
2.17.2



[RFC PATCH 0/1] Verify if register is writeable before a write operation

2019-04-02 Thread Han Nandor
Description
---
This is an RFC because I don't know if this is a bug or a normal use
case. It seems that the function `_regmap_raw_write_impl` from the regmap
framework verifies that a register is writable only using
the callback function, ignoring the other two (max allowed register,
register ranges)

Note: As a left right look I did check also `_regmap_raw_read` function,
and it seems that is missing this checks completely.
Is this a problem as well?

Device/Subsystems Impacted
-
This will impact drivers that end up using raw writes (firmware
download, ...)


Testing
---
Test configuration:
- Kernel Version: 4.14.60 (just for clarification, the patch is rebased on 
master)
- The testing was done using a driver that has NVMEM support and is
  using `regmap_bulk_write` method to write data to registers.
- The valid register range is 0x00->0xFF.

1. Configure a nvcell (4 bytes long) in DT which is outside the valid register 
range.
2. Write data to NVMEM using the nvcell
3. Verify the result:
3.1 Without the patch the data write in registers is successful with
no error displayed.
3.2 With the patch the data write is denied and an error is displayed.

Nandor Han (1):
  regmap: verify if register is writeable before writing operations

 drivers/base/regmap/regmap.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

-- 
2.17.2



RE: [PATCH] gpio: xra1403: select REGMAP_SPI

2017-05-30 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Arnd Bergmann [mailto:a...@arndb.de]
> Sent: 30 May 2017 14:13
> To: Linus Walleij <linus.wall...@linaro.org>
> Cc: Han, Nandor (GE Healthcare) <nandor@ge.com>; Arnd Bergmann 
> <a...@arndb.de>; linux-g...@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: EXT: [PATCH] gpio: xra1403: select REGMAP_SPI
> 
> Without the regmap code, we get a link error:
> 
> drivers/gpio/built-in.o: In function `xra1403_probe':
> (.text+0x132e0): undefined reference to `__devm_regmap_init_spi'
> 
> Fixes: 5704520d7880 ("gpio: xra1403: Add EXAR XRA1403 SPI GPIO expander 
> driver")
> Signed-off-by: Arnd Bergmann <a...@arndb.de>

Reviewed-by:  Nandor Han <nandor@ge.com>

> ---
>  drivers/gpio/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 66d1f353ca73..238fc231081a 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1241,6 +1241,7 @@ config GPIO_PISOSR
> 
>  config GPIO_XRA1403
>   tristate "EXAR XRA1403 16-bit GPIO expander"
> + select REGMAP_SPI
>   help
> GPIO driver for EXAR XRA1403 16-bit SPI-based GPIO expander.
> 
> --
> 2.9.0



RE: [PATCH] gpio: xra1403: select REGMAP_SPI

2017-05-30 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Arnd Bergmann [mailto:a...@arndb.de]
> Sent: 30 May 2017 14:13
> To: Linus Walleij 
> Cc: Han, Nandor (GE Healthcare) ; Arnd Bergmann 
> ; linux-g...@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: EXT: [PATCH] gpio: xra1403: select REGMAP_SPI
> 
> Without the regmap code, we get a link error:
> 
> drivers/gpio/built-in.o: In function `xra1403_probe':
> (.text+0x132e0): undefined reference to `__devm_regmap_init_spi'
> 
> Fixes: 5704520d7880 ("gpio: xra1403: Add EXAR XRA1403 SPI GPIO expander 
> driver")
> Signed-off-by: Arnd Bergmann 

Reviewed-by:  Nandor Han 

> ---
>  drivers/gpio/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 66d1f353ca73..238fc231081a 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1241,6 +1241,7 @@ config GPIO_PISOSR
> 
>  config GPIO_XRA1403
>   tristate "EXAR XRA1403 16-bit GPIO expander"
> + select REGMAP_SPI
>   help
> GPIO driver for EXAR XRA1403 16-bit SPI-based GPIO expander.
> 
> --
> 2.9.0



[PATCH v2 2/4] gpio - Add EXAR XRA1403 SPI GPIO expander driver

2017-04-24 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Linus Walleij [mailto:linus.wall...@linaro.org]
> Sent: 24 April 2017 16:47
> To: Han, Nandor (GE Healthcare) <nandor@ge.com>
> Cc: Greg KH <gre...@linuxfoundation.org>; David S. Miller 
> <da...@davemloft.net>; Geert Uytterhoeven <geert@linux-
> m68k.org>; Mauro Carvalho Chehab <mche...@kernel.org>; Daniel Vetter 
> <daniel.vet...@ffwll.ch>; Alexandre Courbot
> <gnu...@gmail.com>; Rob Herring <robh...@kernel.org>; Mark Rutland 
> <mark.rutl...@arm.com>; linux-
> g...@vger.kernel.org; devicet...@vger.kernel.org; 
> linux-kernel@vger.kernel.org; Malinen, Semi (GE Healthcare)
> <semi.mali...@ge.com>
> Subject: EXT: Re: [PATCH v2 2/4] gpio - Add EXAR XRA1403 SPI GPIO expander 
> driver
> 
> On Thu, Apr 13, 2017 at 12:27 PM, Nandor Han <nandor@ge.com> wrote:
> 
> > This is a simple driver that provides a /sys/class/gpio
> > interface for controlling and configuring the GPIO lines.
> > It does not provide support for chip select or interrupts.
> >
> > Signed-off-by: Nandor Han <nandor@ge.com>
> > Signed-off-by: Semi Malinen <semi.mali...@ge.com>
> 
> I almost want to make the driver depend on !GPIO_SYSFS because
> of this commit message.
> 
> DO NOT USE OR ENCOURAGE THE USE OF THE GPIO SYSFS
> INTERFACE.
> 

Ahh.. I forgot to change this commit message. Sorry I will change it ASAP.

> Use the character device.
> 
> Use the example in tools/gpio/* as a guideline and testbed.
> 
> Use libgpiod as a rich userspace.
> 
> And the commit message should state that this is a driver
> for such and such Exar hardware instead.
> 
> Thanks.
> 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> 
> You are missing
> #include 
> 
> and that is why the build robot is complaining.
> 

I've noticed that. I will change it in the next rev.

> Yours,
> Linus Walleij

Thanks,
   Nandy


[PATCH v2 2/4] gpio - Add EXAR XRA1403 SPI GPIO expander driver

2017-04-24 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Linus Walleij [mailto:linus.wall...@linaro.org]
> Sent: 24 April 2017 16:47
> To: Han, Nandor (GE Healthcare) 
> Cc: Greg KH ; David S. Miller 
> ; Geert Uytterhoeven  m68k.org>; Mauro Carvalho Chehab ; Daniel Vetter 
> ; Alexandre Courbot
> ; Rob Herring ; Mark Rutland 
> ; linux-
> g...@vger.kernel.org; devicet...@vger.kernel.org; 
> linux-kernel@vger.kernel.org; Malinen, Semi (GE Healthcare)
> 
> Subject: EXT: Re: [PATCH v2 2/4] gpio - Add EXAR XRA1403 SPI GPIO expander 
> driver
> 
> On Thu, Apr 13, 2017 at 12:27 PM, Nandor Han  wrote:
> 
> > This is a simple driver that provides a /sys/class/gpio
> > interface for controlling and configuring the GPIO lines.
> > It does not provide support for chip select or interrupts.
> >
> > Signed-off-by: Nandor Han 
> > Signed-off-by: Semi Malinen 
> 
> I almost want to make the driver depend on !GPIO_SYSFS because
> of this commit message.
> 
> DO NOT USE OR ENCOURAGE THE USE OF THE GPIO SYSFS
> INTERFACE.
> 

Ahh.. I forgot to change this commit message. Sorry I will change it ASAP.

> Use the character device.
> 
> Use the example in tools/gpio/* as a guideline and testbed.
> 
> Use libgpiod as a rich userspace.
> 
> And the commit message should state that this is a driver
> for such and such Exar hardware instead.
> 
> Thanks.
> 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> 
> You are missing
> #include 
> 
> and that is why the build robot is complaining.
> 

I've noticed that. I will change it in the next rev.

> Yours,
> Linus Walleij

Thanks,
   Nandy


[PATCH 1/3] gpio - Add EXAR XRA1403 SPI GPIO expander driver

2017-04-08 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Linus Walleij [mailto:linus.wall...@linaro.org]
> Sent: 07 April 2017 13:07
> To: Han, Nandor (GE Healthcare) <nandor@ge.com>
> Cc: Alexandre Courbot <gnu...@gmail.com>; Rob Herring <robh...@kernel.org>; 
> Mark Rutland
> <mark.rutl...@arm.com>; linux-g...@vger.kernel.org; 
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> Malinen, Semi (GE Healthcare) <semi.mali...@ge.com>
> Subject: EXT: Re: [PATCH 1/3] gpio - Add EXAR XRA1403 SPI GPIO expander driver
> 
> On Wed, Apr 5, 2017 at 3:24 PM, Han, Nandor (GE Healthcare)
> <nandor@ge.com> wrote:
> > [Me]
> >> > +   /* bring the chip out of reset */
> >> > +   reset_gpio = gpiod_get_optional(>dev, "reset", 
> >> > GPIOD_OUT_LOW);
> >> > +   if (IS_ERR(reset_gpio))
> >> > +   dev_warn(>dev, "could not get reset-gpios\n");
> >> > +   else if (reset_gpio)
> >> > +   gpiod_put(reset_gpio);
> >>
> >> I don't think you should put it, other than in the remove()
> >> function and in that case you need to have it in the
> >> state container.
> >
> > Can you please be more explicit here.
> >
> > Currently I'm trying to bring the device out from reset in case reset GPIO 
> > is provided.
> > I don't see how this could be done in remove()  :)
> 
> If you issue gpiod_put() you release the GPIO hande so something else
> can go in and grab the GPIO and assert the reset.
> 
> This is not what you want to make possible: you want to hold this gpiod handle
> as long as the driver is running. devm_gpiod_get_optional() will do the
> trick if you don't want to put the handle under explicit control.
> 

That was my first intention to release the reset line in case somebody else 
wants to control it. I did it
like that because usually reset line controls multiple devices and probably 
some upper layer wants to
control that. 

After your comment I did some analysing and I will follow your advice and 
change the reset line handling. 
Once the GPIO is provided to the driver the driver will own it and bring out 
the device from reset. In case not
provided the reset line is somebody else responsibility. 

This way we are able to cover multiple use-cases. 

Thanks Linus,
Nandy

> Yours,
> Linus Walleij


[PATCH 1/3] gpio - Add EXAR XRA1403 SPI GPIO expander driver

2017-04-08 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Linus Walleij [mailto:linus.wall...@linaro.org]
> Sent: 07 April 2017 13:07
> To: Han, Nandor (GE Healthcare) 
> Cc: Alexandre Courbot ; Rob Herring ; 
> Mark Rutland
> ; linux-g...@vger.kernel.org; 
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> Malinen, Semi (GE Healthcare) 
> Subject: EXT: Re: [PATCH 1/3] gpio - Add EXAR XRA1403 SPI GPIO expander driver
> 
> On Wed, Apr 5, 2017 at 3:24 PM, Han, Nandor (GE Healthcare)
>  wrote:
> > [Me]
> >> > +   /* bring the chip out of reset */
> >> > +   reset_gpio = gpiod_get_optional(>dev, "reset", 
> >> > GPIOD_OUT_LOW);
> >> > +   if (IS_ERR(reset_gpio))
> >> > +   dev_warn(>dev, "could not get reset-gpios\n");
> >> > +   else if (reset_gpio)
> >> > +   gpiod_put(reset_gpio);
> >>
> >> I don't think you should put it, other than in the remove()
> >> function and in that case you need to have it in the
> >> state container.
> >
> > Can you please be more explicit here.
> >
> > Currently I'm trying to bring the device out from reset in case reset GPIO 
> > is provided.
> > I don't see how this could be done in remove()  :)
> 
> If you issue gpiod_put() you release the GPIO hande so something else
> can go in and grab the GPIO and assert the reset.
> 
> This is not what you want to make possible: you want to hold this gpiod handle
> as long as the driver is running. devm_gpiod_get_optional() will do the
> trick if you don't want to put the handle under explicit control.
> 

That was my first intention to release the reset line in case somebody else 
wants to control it. I did it
like that because usually reset line controls multiple devices and probably 
some upper layer wants to
control that. 

After your comment I did some analysing and I will follow your advice and 
change the reset line handling. 
Once the GPIO is provided to the driver the driver will own it and bring out 
the device from reset. In case not
provided the reset line is somebody else responsibility. 

This way we are able to cover multiple use-cases. 

Thanks Linus,
Nandy

> Yours,
> Linus Walleij


[PATCH 1/3] gpio - Add EXAR XRA1403 SPI GPIO expander driver

2017-04-05 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Linus Walleij [mailto:linus.wall...@linaro.org]
> Sent: 29 March 2017 05:07
> To: Han, Nandor (GE Healthcare) <nandor@ge.com>
> Cc: Alexandre Courbot <gnu...@gmail.com>; Rob Herring <robh...@kernel.org>; 
> Mark Rutland
> <mark.rutl...@arm.com>; linux-g...@vger.kernel.org; 
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> Malinen, Semi (GE Healthcare) <semi.mali...@ge.com>
> Subject: EXT: Re: [PATCH 1/3] gpio - Add EXAR XRA1403 SPI GPIO expander driver
> 
> On Mon, Mar 27, 2017 at 8:23 AM, Nandor Han <nandor@ge.com> wrote:
> 
> > This is a simple driver that provides a /sys/class/gpio
> > interface for controlling and configuring the GPIO lines.
> 
> Use the gpio tools in tools/gpio, use the characcter device.
> Do not use sysfs. Change this to reference the tools.
> 
> > It does not provide support for chip select or interrupts.
> >
> > Signed-off-by: Nandor Han <nandor@ge.com>
> > Signed-off-by: Semi Malinen <semi.mali...@ge.com>
> (...)
> > +exar   Exar Corporation
> 
> Send this as a separate patch to the DT bindings maintainer
> (Rob Herring.)
> 

OK. I will create a separate patch with this one. 
I guess is not an issue to send all the patches to Rob as well.



> > +
> > +   ret = xra1403_get_byte(xra, addr + (bit > 7));
> > +   if (ret < 0)
> > +   return ret;
> > +
> > +   return !!(ret & BIT(bit % 8));
> > +}
> 
> This looks like it can use regmap-spi right off, do you agree?
> 

Yes. Using regmap-spi will definitely improve the code readability and reduce 
boilerplate.
Done.

> git grep devm_regmap_init_spi
> should give you some examples of how to use it.
> 
> If it's not off-the shelf regmap drivers like
> drivers/iio/pressure/mpl115_spi.c
> give examples of how to make more elaborate custom
> SPI transfers with regmap.
> 

Thanks, I did check other drivers as examples. 
Not that I needed for this driver, but ...mpl115_spi.c doesn't seem to
use regmap (checked on next-20170327)



> > +
> > +   if (value != ret) {
> > +   tx[0] = addr << 1;
> > +   tx[1] = value;
> > +   ret = spi_write(xra->spi, tx, sizeof(tx));
> > +   } else {
> > +   ret = 0;
> > +   }
> > +
> > +out_unlock:
> > +   mutex_unlock(>lock);
> > +
> > +   return ret;
> > +}
> 
> Classical mask-and-set implementation right?
> With regmap this becomes simply regmap_update_bits(map, addr, mask, set)
> 

True. :)



> > +   /* bring the chip out of reset */
> > +   reset_gpio = gpiod_get_optional(>dev, "reset", GPIOD_OUT_LOW);
> > +   if (IS_ERR(reset_gpio))
> > +   dev_warn(>dev, "could not get reset-gpios\n");
> > +   else if (reset_gpio)
> > +   gpiod_put(reset_gpio);
> 
> I don't think you should put it, other than in the remove()
> function and in that case you need to have it in the
> state container.

Can you please be more explicit here.

Currently I'm trying to bring the device out from reset in case reset GPIO is 
provided.
I don't see how this could be done in remove()  :)

> 
> > +   mutex_init(>lock);
> > +
> > +   xra->chip.direction_input = xra1403_direction_input;
> > +   xra->chip.direction_output = xra1403_direction_output;
> 
> Please implement .get_direction(). This is very nice to have.
> 

Done

> > +static int xra1403_remove(struct spi_device *spi)
> > +{
> > +   struct xra1403 *xra = spi_get_drvdata(spi);
> > +
> > +   gpiochip_remove(>chip);
> 
> Use devm_gpiochip_add_data() and this remove is not
> needed at all.
> 

True. Done



> > +subsys_initcall(xra1403_init);
> > +
> > +static void __exit xra1403_exit(void)
> > +{
> > +   spi_unregister_driver(_driver);
> > +}
> > +module_exit(xra1403_exit);
> 
> This seems like tricksy. Just module_spi_driver()
> should be fine don't you think?

Yeah. TBH I don't have a strong reason why module_spi_driver init level 
shouldn't be enough. 
Done.

Regards,
Nandor


[PATCH 1/3] gpio - Add EXAR XRA1403 SPI GPIO expander driver

2017-04-05 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Linus Walleij [mailto:linus.wall...@linaro.org]
> Sent: 29 March 2017 05:07
> To: Han, Nandor (GE Healthcare) 
> Cc: Alexandre Courbot ; Rob Herring ; 
> Mark Rutland
> ; linux-g...@vger.kernel.org; 
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> Malinen, Semi (GE Healthcare) 
> Subject: EXT: Re: [PATCH 1/3] gpio - Add EXAR XRA1403 SPI GPIO expander driver
> 
> On Mon, Mar 27, 2017 at 8:23 AM, Nandor Han  wrote:
> 
> > This is a simple driver that provides a /sys/class/gpio
> > interface for controlling and configuring the GPIO lines.
> 
> Use the gpio tools in tools/gpio, use the characcter device.
> Do not use sysfs. Change this to reference the tools.
> 
> > It does not provide support for chip select or interrupts.
> >
> > Signed-off-by: Nandor Han 
> > Signed-off-by: Semi Malinen 
> (...)
> > +exar   Exar Corporation
> 
> Send this as a separate patch to the DT bindings maintainer
> (Rob Herring.)
> 

OK. I will create a separate patch with this one. 
I guess is not an issue to send all the patches to Rob as well.



> > +
> > +   ret = xra1403_get_byte(xra, addr + (bit > 7));
> > +   if (ret < 0)
> > +   return ret;
> > +
> > +   return !!(ret & BIT(bit % 8));
> > +}
> 
> This looks like it can use regmap-spi right off, do you agree?
> 

Yes. Using regmap-spi will definitely improve the code readability and reduce 
boilerplate.
Done.

> git grep devm_regmap_init_spi
> should give you some examples of how to use it.
> 
> If it's not off-the shelf regmap drivers like
> drivers/iio/pressure/mpl115_spi.c
> give examples of how to make more elaborate custom
> SPI transfers with regmap.
> 

Thanks, I did check other drivers as examples. 
Not that I needed for this driver, but ...mpl115_spi.c doesn't seem to
use regmap (checked on next-20170327)



> > +
> > +   if (value != ret) {
> > +   tx[0] = addr << 1;
> > +   tx[1] = value;
> > +   ret = spi_write(xra->spi, tx, sizeof(tx));
> > +   } else {
> > +   ret = 0;
> > +   }
> > +
> > +out_unlock:
> > +   mutex_unlock(>lock);
> > +
> > +   return ret;
> > +}
> 
> Classical mask-and-set implementation right?
> With regmap this becomes simply regmap_update_bits(map, addr, mask, set)
> 

True. :)



> > +   /* bring the chip out of reset */
> > +   reset_gpio = gpiod_get_optional(>dev, "reset", GPIOD_OUT_LOW);
> > +   if (IS_ERR(reset_gpio))
> > +   dev_warn(>dev, "could not get reset-gpios\n");
> > +   else if (reset_gpio)
> > +   gpiod_put(reset_gpio);
> 
> I don't think you should put it, other than in the remove()
> function and in that case you need to have it in the
> state container.

Can you please be more explicit here.

Currently I'm trying to bring the device out from reset in case reset GPIO is 
provided.
I don't see how this could be done in remove()  :)

> 
> > +   mutex_init(>lock);
> > +
> > +   xra->chip.direction_input = xra1403_direction_input;
> > +   xra->chip.direction_output = xra1403_direction_output;
> 
> Please implement .get_direction(). This is very nice to have.
> 

Done

> > +static int xra1403_remove(struct spi_device *spi)
> > +{
> > +   struct xra1403 *xra = spi_get_drvdata(spi);
> > +
> > +   gpiochip_remove(>chip);
> 
> Use devm_gpiochip_add_data() and this remove is not
> needed at all.
> 

True. Done



> > +subsys_initcall(xra1403_init);
> > +
> > +static void __exit xra1403_exit(void)
> > +{
> > +   spi_unregister_driver(_driver);
> > +}
> > +module_exit(xra1403_exit);
> 
> This seems like tricksy. Just module_spi_driver()
> should be fine don't you think?

Yeah. TBH I don't have a strong reason why module_spi_driver init level 
shouldn't be enough. 
Done.

Regards,
Nandor


[PATCH 0/3] XRA1403,gpio - add XRA1403 gpio expander driver

2017-04-05 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Linus Walleij [mailto:linus.wall...@linaro.org]
> Sent: 29 March 2017 04:51
> To: Han, Nandor (GE Healthcare) <nandor@ge.com>
> Cc: Alexandre Courbot <gnu...@gmail.com>; Rob Herring <robh...@kernel.org>; 
> Mark Rutland
> <mark.rutl...@arm.com>; linux-g...@vger.kernel.org; 
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: EXT: Re: [PATCH 0/3] XRA1403,gpio - add XRA1403 gpio expander driver
> 



> Do *NOT* use the sysfs for testing GPIO.
> This is being phased out.
> 
> Use the tools in tools/gpio/* so that you exercise the
> character device instead of the old deprecated ABI.
> 

Thanks Linus, really good and  helpful comments.
I agree that make more sense to test with tools/gpio/*.

> Yours,
> Linus Walleij


[PATCH 0/3] XRA1403,gpio - add XRA1403 gpio expander driver

2017-04-05 Thread Han, Nandor (GE Healthcare)


> -Original Message-
> From: Linus Walleij [mailto:linus.wall...@linaro.org]
> Sent: 29 March 2017 04:51
> To: Han, Nandor (GE Healthcare) 
> Cc: Alexandre Courbot ; Rob Herring ; 
> Mark Rutland
> ; linux-g...@vger.kernel.org; 
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: EXT: Re: [PATCH 0/3] XRA1403,gpio - add XRA1403 gpio expander driver
> 



> Do *NOT* use the sysfs for testing GPIO.
> This is being phased out.
> 
> Use the tools in tools/gpio/* so that you exercise the
> character device instead of the old deprecated ABI.
> 

Thanks Linus, really good and  helpful comments.
I agree that make more sense to test with tools/gpio/*.

> Yours,
> Linus Walleij


Re: EXT: pre 4.9-rc dma regression, imx6 sound etc

2016-10-13 Thread Han, Nandor (GE Healthcare)



On 12/10/2016 16:25, Mika Penttilä wrote:

Hi!

Bisected that commit 5881826 - "dmaengine: imx-sdma - update the residue 
calculation for cyclic channels" is first bad commit to cause audio regression on 
imx6q, sgtl5000 codec. It causes audible disturbing background noise when playing wavs.

Unfortunately, reverting only 5881826 causes uarts to fail, so another fix is 
needed.

Thanks,

Mika







Hi Mika,
   Thanks for info. I have already posted a patch that will fix this issue.

https://lkml.org/lkml/2016/10/11/319

It was already tested on imx6 and imx53. Let me know how it works.

--
Regards,
Nandor


Re: EXT: pre 4.9-rc dma regression, imx6 sound etc

2016-10-13 Thread Han, Nandor (GE Healthcare)



On 12/10/2016 16:25, Mika Penttilä wrote:

Hi!

Bisected that commit 5881826 - "dmaengine: imx-sdma - update the residue 
calculation for cyclic channels" is first bad commit to cause audio regression on 
imx6q, sgtl5000 codec. It causes audible disturbing background noise when playing wavs.

Unfortunately, reverting only 5881826 causes uarts to fail, so another fix is 
needed.

Thanks,

Mika







Hi Mika,
   Thanks for info. I have already posted a patch that will fix this issue.

https://lkml.org/lkml/2016/10/11/319

It was already tested on imx6 and imx53. Let me know how it works.

--
Regards,
Nandor