[PATCH v2] cpufreq: nforce2: Remove meaningless return

2018-12-05 Thread Yangtao Li
Delete a line of meaningless return and some useless blank lines. In a function
whose return type is void, returning on the last line is not required.

Signed-off-by: Yangtao Li 
---
Changes in v2:
-revert modify of MODULE_
-delete some blank lines
---
 drivers/cpufreq/cpufreq-nforce2.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/cpufreq/cpufreq-nforce2.c 
b/drivers/cpufreq/cpufreq-nforce2.c
index dbf82f36d270..33c309a08c64 100644
--- a/drivers/cpufreq/cpufreq-nforce2.c
+++ b/drivers/cpufreq/cpufreq-nforce2.c
@@ -123,8 +123,6 @@ static void nforce2_write_pll(int pll)
/* Now write the value in all 64 registers */
for (temp = 0; temp <= 0x3f; temp++)
pci_write_config_dword(nforce2_dev, NFORCE2_PLLREG, pll);
-
-   return;
 }
 
 /**
@@ -438,4 +436,3 @@ static void __exit nforce2_exit(void)
 
 module_init(nforce2_init);
 module_exit(nforce2_exit);
-
-- 
2.17.0



[PATCH 4/4] dmaengine: qcom_hidma: convert to DEFINE_SHOW_ATTRIBUTE

2018-12-05 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
Acked-by: Sinan Kaya 
---
 drivers/dma/qcom/hidma_dbg.c | 33 ++---
 1 file changed, 6 insertions(+), 27 deletions(-)

diff --git a/drivers/dma/qcom/hidma_dbg.c b/drivers/dma/qcom/hidma_dbg.c
index 3bdcb8056a36..9523faf7acdc 100644
--- a/drivers/dma/qcom/hidma_dbg.c
+++ b/drivers/dma/qcom/hidma_dbg.c
@@ -85,11 +85,11 @@ static void hidma_ll_devstats(struct seq_file *s, void 
*llhndl)
 }
 
 /*
- * hidma_chan_stats: display HIDMA channel statistics
+ * hidma_chan_show: display HIDMA channel statistics
  *
  * Display the statistics for the current HIDMA virtual channel device.
  */
-static int hidma_chan_stats(struct seq_file *s, void *unused)
+static int hidma_chan_show(struct seq_file *s, void *unused)
 {
struct hidma_chan *mchan = s->private;
struct hidma_desc *mdesc;
@@ -117,11 +117,11 @@ static int hidma_chan_stats(struct seq_file *s, void 
*unused)
 }
 
 /*
- * hidma_dma_info: display HIDMA device info
+ * hidma_dma_show: display HIDMA device info
  *
  * Display the info for the current HIDMA device.
  */
-static int hidma_dma_info(struct seq_file *s, void *unused)
+static int hidma_dma_show(struct seq_file *s, void *unused)
 {
struct hidma_dev *dmadev = s->private;
resource_size_t sz;
@@ -138,29 +138,8 @@ static int hidma_dma_info(struct seq_file *s, void *unused)
return 0;
 }
 
-static int hidma_chan_stats_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, hidma_chan_stats, inode->i_private);
-}
-
-static int hidma_dma_info_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, hidma_dma_info, inode->i_private);
-}
-
-static const struct file_operations hidma_chan_fops = {
-   .open = hidma_chan_stats_open,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = single_release,
-};
-
-static const struct file_operations hidma_dma_fops = {
-   .open = hidma_dma_info_open,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(hidma_chan);
+DEFINE_SHOW_ATTRIBUTE(hidma_dma);
 
 void hidma_debug_uninit(struct hidma_dev *dmadev)
 {
-- 
2.17.0



[PATCH 3/4] dmaengine: pxa: remove DBGFS_FUNC_DECL()

2018-12-05 Thread Yangtao Li
We already have the DEFINE_SHOW_ATTRIBUTE, There is no need to define
such a macro, so remove DBGFS_FUNC_DECL.

Signed-off-by: Yangtao Li 
Acked-by: Robert Jarzmik 
---
 drivers/dma/pxa_dma.c | 36 
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index 825725057e00..e78fe98b5cf1 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -189,7 +189,7 @@ bool pxad_filter_fn(struct dma_chan *chan, void *param);
 #include 
 #include 
 
-static int dbg_show_requester_chan(struct seq_file *s, void *p)
+static int requester_chan_show(struct seq_file *s, void *p)
 {
struct pxad_phy *phy = s->private;
int i;
@@ -220,7 +220,7 @@ static int is_phys_valid(unsigned long addr)
 #define PXA_DCSR_STR(flag) (dcsr & PXA_DCSR_##flag ? #flag" " : "")
 #define PXA_DCMD_STR(flag) (dcmd & PXA_DCMD_##flag ? #flag" " : "")
 
-static int dbg_show_descriptors(struct seq_file *s, void *p)
+static int descriptors_show(struct seq_file *s, void *p)
 {
struct pxad_phy *phy = s->private;
int i, max_show = 20, burst, width;
@@ -263,7 +263,7 @@ static int dbg_show_descriptors(struct seq_file *s, void *p)
return 0;
 }
 
-static int dbg_show_chan_state(struct seq_file *s, void *p)
+static int chan_state_show(struct seq_file *s, void *p)
 {
struct pxad_phy *phy = s->private;
u32 dcsr, dcmd;
@@ -306,7 +306,7 @@ static int dbg_show_chan_state(struct seq_file *s, void *p)
return 0;
 }
 
-static int dbg_show_state(struct seq_file *s, void *p)
+static int state_show(struct seq_file *s, void *p)
 {
struct pxad_device *pdev = s->private;
 
@@ -317,22 +317,10 @@ static int dbg_show_state(struct seq_file *s, void *p)
return 0;
 }
 
-#define DBGFS_FUNC_DECL(name) \
-static int dbg_open_##name(struct inode *inode, struct file *file) \
-{ \
-   return single_open(file, dbg_show_##name, inode->i_private); \
-} \
-static const struct file_operations dbg_fops_##name = { \
-   .open   = dbg_open_##name, \
-   .llseek = seq_lseek, \
-   .read   = seq_read, \
-   .release= single_release, \
-}
-
-DBGFS_FUNC_DECL(state);
-DBGFS_FUNC_DECL(chan_state);
-DBGFS_FUNC_DECL(descriptors);
-DBGFS_FUNC_DECL(requester_chan);
+DEFINE_SHOW_ATTRIBUTE(state);
+DEFINE_SHOW_ATTRIBUTE(chan_state);
+DEFINE_SHOW_ATTRIBUTE(descriptors);
+DEFINE_SHOW_ATTRIBUTE(requester_chan);
 
 static struct dentry *pxad_dbg_alloc_chan(struct pxad_device *pdev,
 int ch, struct dentry *chandir)
@@ -348,13 +336,13 @@ static struct dentry *pxad_dbg_alloc_chan(struct 
pxad_device *pdev,
 
if (chan)
chan_state = debugfs_create_file("state", 0400, chan, dt,
-_fops_chan_state);
+_state_fops);
if (chan_state)
chan_descr = debugfs_create_file("descriptors", 0400, chan, dt,
-_fops_descriptors);
+_fops);
if (chan_descr)
chan_reqs = debugfs_create_file("requesters", 0400, chan, dt,
-   _fops_requester_chan);
+   _chan_fops);
if (!chan_reqs)
goto err_state;
 
@@ -375,7 +363,7 @@ static void pxad_init_debugfs(struct pxad_device *pdev)
goto err_root;
 
pdev->dbgfs_state = debugfs_create_file("state", 0400, pdev->dbgfs_root,
-   pdev, _fops_state);
+   pdev, _fops);
if (!pdev->dbgfs_state)
goto err_state;
 
-- 
2.17.0



[PATCH 1/4] dmaengine: amba-pl08x: convert to DEFINE_SHOW_ATTRIBUTE

2018-12-05 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
---
 drivers/dma/amba-pl08x.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 97483df1f82e..fc8c2bab563c 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -2505,24 +2505,14 @@ static int pl08x_debugfs_show(struct seq_file *s, void 
*data)
return 0;
 }
 
-static int pl08x_debugfs_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, pl08x_debugfs_show, inode->i_private);
-}
-
-static const struct file_operations pl08x_debugfs_operations = {
-   .open   = pl08x_debugfs_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pl08x_debugfs);
 
 static void init_pl08x_debugfs(struct pl08x_driver_data *pl08x)
 {
/* Expose a simple debugfs interface to view all clocks */
(void) debugfs_create_file(dev_name(>adev->dev),
S_IFREG | S_IRUGO, NULL, pl08x,
-   _debugfs_operations);
+   _debugfs_fops);
 }
 
 #else
-- 
2.17.0



[PATCH 2/4] dmaengine: mic_x100_dma: convert to DEFINE_SHOW_ATTRIBUTE

2018-12-05 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
---
 drivers/dma/mic_x100_dma.c | 22 +++---
 1 file changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/dma/mic_x100_dma.c b/drivers/dma/mic_x100_dma.c
index adfd316db1a8..6a91e28d537d 100644
--- a/drivers/dma/mic_x100_dma.c
+++ b/drivers/dma/mic_x100_dma.c
@@ -676,7 +676,7 @@ static void mic_dma_dev_unreg(struct mic_dma_device 
*mic_dma_dev)
 }
 
 /* DEBUGFS CODE */
-static int mic_dma_reg_seq_show(struct seq_file *s, void *pos)
+static int mic_dma_reg_show(struct seq_file *s, void *pos)
 {
struct mic_dma_device *mic_dma_dev = s->private;
int i, chan_num, first_chan = mic_dma_dev->start_ch;
@@ -707,23 +707,7 @@ static int mic_dma_reg_seq_show(struct seq_file *s, void 
*pos)
return 0;
 }
 
-static int mic_dma_reg_debug_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, mic_dma_reg_seq_show, inode->i_private);
-}
-
-static int mic_dma_reg_debug_release(struct inode *inode, struct file *file)
-{
-   return single_release(inode, file);
-}
-
-static const struct file_operations mic_dma_reg_ops = {
-   .owner   = THIS_MODULE,
-   .open= mic_dma_reg_debug_open,
-   .read= seq_read,
-   .llseek  = seq_lseek,
-   .release = mic_dma_reg_debug_release
-};
+DEFINE_SHOW_ATTRIBUTE(mic_dma_reg);
 
 /* Debugfs parent dir */
 static struct dentry *mic_dma_dbg;
@@ -747,7 +731,7 @@ static int mic_dma_driver_probe(struct mbus_device *mbdev)
if (mic_dma_dev->dbg_dir)
debugfs_create_file("mic_dma_reg", 0444,
mic_dma_dev->dbg_dir, mic_dma_dev,
-   _dma_reg_ops);
+   _dma_reg_fops);
}
return 0;
 }
-- 
2.17.0



[PATCH] usb: host: isp1362-hcd: convert to DEFINE_SHOW_ATTRIBUTE

2018-12-05 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
---
 drivers/usb/host/isp1362-hcd.c | 16 +++-
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index b21c386e6a46..28bf8bfb091e 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2159,25 +2159,15 @@ static int isp1362_show(struct seq_file *s, void 
*unused)
 
return 0;
 }
-
-static int isp1362_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, isp1362_show, inode);
-}
-
-static const struct file_operations debug_ops = {
-   .open = isp1362_open,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(isp1362);
 
 /* expect just one isp1362_hcd per system */
 static void create_debug_file(struct isp1362_hcd *isp1362_hcd)
 {
isp1362_hcd->debug_file = debugfs_create_file("isp1362", S_IRUGO,
  usb_debug_root,
- isp1362_hcd, _ops);
+ isp1362_hcd,
+ _fops);
 }
 
 static void remove_debug_file(struct isp1362_hcd *isp1362_hcd)
-- 
2.17.0



[PATCH] softirq: modify comments about PF_MEMALLOC in __do_softirq

2018-10-18 Thread Yangtao Li
---
 kernel/softirq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/softirq.c b/kernel/softirq.c
index 6f584861d329..6193e1d1b30d 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -257,7 +257,7 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
int softirq_bit;
 
/*
-* Mask out PF_MEMALLOC s current task context is borrowed for the
+* Mask out PF_MEMALLOC as current task context is borrowed for the
 * softirq. A softirq handled such as network RX might set PF_MEMALLOC
 * again if the socket is related to swap
 */
-- 
2.17.0



[PATCH v4 0/2] cpufreq: Add sunxi nvmem based CPU scaling driver

2019-04-16 Thread Yangtao Li
Add sunxi nvmem based CPU scaling driver, refers to qcom-cpufreq-kryo.

Yangtao Li (2):
  cpufreq: Add sunxi nvmem based CPU scaling driver
  dt-bindings: cpufreq: Document allwinner,sun50i-h6-operating-points

 .../bindings/opp/sun50i-nvmem-cpufreq.txt | 167 +
 MAINTAINERS   |   7 +
 drivers/cpufreq/Kconfig.arm   |  12 +
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c  |   2 +
 drivers/cpufreq/sun50i-cpufreq-nvmem.c| 226 ++
 6 files changed, 415 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt
 create mode 100644 drivers/cpufreq/sun50i-cpufreq-nvmem.c

---
v4:
-I removed this sunxi_cpufreq_soc_data structure for now.
-Convert to less generic name.
-Update soc_bin xlate.
v3:
-update changelog and title
-convert compatibles to allwinner,cpu-operating-points-v2
-document the valid names for opp-microvolt-
v2:
-update changelog
-convert to dev_pm_opp_set_prop_name instead of
 dev_pm_opp_set_supported_hw
-some change in OPP Node  
---
2.17.0



[PATCH v4 1/2] cpufreq: Add sunxi nvmem based CPU scaling driver

2019-04-16 Thread Yangtao Li
For some SoCs, the CPU frequency subset and voltage value of each OPP
varies based on the silicon variant in use. The sun50i-cpufreq-nvmem
driver reads the efuse value from the SoC to provide the OPP framework
with required information.

Signed-off-by: Yangtao Li 
---
 MAINTAINERS|   7 +
 drivers/cpufreq/Kconfig.arm|  12 ++
 drivers/cpufreq/Makefile   |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c   |   2 +
 drivers/cpufreq/sun50i-cpufreq-nvmem.c | 226 +
 5 files changed, 248 insertions(+)
 create mode 100644 drivers/cpufreq/sun50i-cpufreq-nvmem.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3671fdea5010..4ad6dd051149 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -667,6 +667,13 @@ S: Maintained
 F: Documentation/i2c/busses/i2c-ali1563
 F: drivers/i2c/busses/i2c-ali1563.c
 
+ALLWINNER CPUFREQ DRIVER
+M: Yangtao Li 
+L: linux...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt
+F: drivers/cpufreq/sun50i-cpufreq-nvmem.c
+
 ALLWINNER SECURITY SYSTEM
 M: Corentin Labbe 
 L: linux-cry...@vger.kernel.org
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 179a1d302f48..71377e01a370 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -18,6 +18,18 @@ config ACPI_CPPC_CPUFREQ
 
  If in doubt, say N.
 
+config ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM
+   tristate "Allwinner nvmem based SUN50I CPUFreq driver"
+   depends on ARCH_SUNXI
+   depends on NVMEM_SUNXI_SID
+   select PM_OPP
+   help
+ This adds the nvmem based CPUFreq driver for Allwinner
+ h6 SoC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sun50i-cpufreq-nvmem.
+
 config ARM_ARMADA_37XX_CPUFREQ
tristate "Armada 37xx CPUFreq support"
depends on ARCH_MVEBU && CPUFREQ_DT
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 689b26c6f949..a78b8da80383 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_ARM_SCMI_CPUFREQ)+= 
scmi-cpufreq.o
 obj-$(CONFIG_ARM_SCPI_CPUFREQ) += scpi-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)+= spear-cpufreq.o
 obj-$(CONFIG_ARM_STI_CPUFREQ)  += sti-cpufreq.o
+obj-$(CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM) += sun50i-cpufreq-nvmem.o
 obj-$(CONFIG_ARM_TANGO_CPUFREQ)+= tango-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)  += tegra20-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c 
b/drivers/cpufreq/cpufreq-dt-platdev.c
index 47729a22c159..50e7810f3a28 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -105,6 +105,8 @@ static const struct of_device_id whitelist[] __initconst = {
  * platforms using "operating-points-v2" property.
  */
 static const struct of_device_id blacklist[] __initconst = {
+   { .compatible = "allwinner,sun50i-h6", },
+
{ .compatible = "calxeda,highbank", },
{ .compatible = "calxeda,ecx-2000", },
 
diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c 
b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
new file mode 100644
index ..eca32e443716
--- /dev/null
+++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner CPUFreq nvmem based driver
+ *
+ * The sun50i-cpufreq-nvmem driver reads the efuse value from the SoC to
+ * provide the OPP framework with required information.
+ *
+ * Copyright (C) 2019 Yangtao Li 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MAX_NAME_LEN   7
+
+#define NVMEM_MASK 0x7
+#define NVMEM_SHIFT5
+
+static struct platform_device *cpufreq_dt_pdev, *sun50i_cpufreq_pdev;
+
+/**
+ * sun50i_cpufreq_get_efuse() - Parse and return efuse value present on SoC
+ * @versions: Set to the value parsed from efuse
+ *
+ * Returns 0 if success.
+ */
+static int sun50i_cpufreq_get_efuse(u32 *versions)
+{
+   struct nvmem_cell *speedbin_nvmem;
+   struct device_node *np;
+   struct device *cpu_dev;
+   u32 *speedbin, efuse_value;
+   size_t len;
+   int ret;
+
+   cpu_dev = get_cpu_device(0);
+   if (!cpu_dev)
+   return -ENODEV;
+
+   np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+   if (!np)
+   return -ENOENT;
+
+   ret = of_device_is_compatible(np,
+ "allwinner,sun50i-h6-operating-points");
+   if (!ret) {
+   of_node_put(np);
+   return -ENOENT;
+   }
+
+   speedbin_nvmem = of_nvmem_cell_get(np, NULL);
+   of_node_put(np);
+   if

[PATCH v4 2/2] dt-bindings: cpufreq: Document allwinner,sun50i-h6-operating-points

2019-04-16 Thread Yangtao Li
Allwinner Process Voltage Scaling Tables defines the voltage and
frequency value based on the speedbin blown in the efuse combination.
The sunxi-cpufreq-nvmem driver reads the efuse value from the SoC to
provide the OPP framework with required information.
This is used to determine the voltage and frequency value for each
OPP of operating-points-v2 table when it is parsed by the OPP framework.

The "allwinner,sun50i-h6-operating-points" DT extends the
"operating-points-v2"
with following parameters:
- nvmem-cells (NVMEM area containig the speedbin information)
- opp-microvolt-: voltage in micro Volts.
  At runtime, the platform can pick a  and matching
  opp-microvolt- property.
HW: :
sun50iw-h6  speed0 speed1 speed2

Signed-off-by: Yangtao Li 
---
 .../bindings/opp/sun50i-nvmem-cpufreq.txt | 167 ++
 1 file changed, 167 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt

diff --git a/Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt 
b/Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt
new file mode 100644
index ..3cb39c6caec3
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt
@@ -0,0 +1,167 @@
+Allwinner Technologies, Inc. NVMEM CPUFreq and OPP bindings
+===
+
+For some SoCs, the CPU frequency subset and voltage value of each OPP
+varies based on the silicon variant in use. Allwinner Process Voltage
+Scaling Tables defines the voltage and frequency value based on the
+speedbin blown in the efuse combination. The sun50i-cpufreq-nvmem driver
+reads the efuse value from the SoC to provide the OPP framework with
+required information.
+
+Required properties:
+
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be
+   - 'allwinner,sun50i-h6-operating-points'.
+- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
+   efuse registers that has information about the speedbin
+   that is used to select the right frequency/voltage value
+   pair. Please refer the for nvmem-cells bindings
+   Documentation/devicetree/bindings/nvmem/nvmem.txt and
+   also examples below.
+
+In every OPP node:
+- opp-microvolt-: Voltage in micro Volts.
+   At runtime, the platform can pick a  and
+   matching opp-microvolt- property.
+   [See: opp.txt]
+   HW: :
+   sun50iw-h6  speed0 speed1 speed2
+
+Example 1:
+-
+
+   cpus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   cpu0: cpu@0 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <0>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu1: cpu@1 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <1>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu2: cpu@2 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <2>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu3: cpu@3 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <3>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+};
+
+

[PATCH] PM / Domains: remove unnecessary unlikely()

2019-04-16 Thread Yangtao Li
WARN_ON() already contains an unlikely(), so it's not necessary to use
unlikely.

Signed-off-by: Yangtao Li 
---
 drivers/base/power/domain.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 96a6dc9d305c..598a4e02aee1 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -391,11 +391,9 @@ int dev_pm_genpd_set_performance_state(struct device *dev, 
unsigned int state)
if (unlikely(!genpd->set_performance_state))
return -EINVAL;
 
-   if (unlikely(!dev->power.subsys_data ||
-!dev->power.subsys_data->domain_data)) {
-   WARN_ON(1);
+   if (WARN_ON(!dev->power.subsys_data ||
+!dev->power.subsys_data->domain_data))
return -EINVAL;
-   }
 
genpd_lock(genpd);
 
-- 
2.17.0



[RESEND] dt-bindings: cpufreq: Document allwinner,sun50i-h6-operating-points

2019-04-18 Thread Yangtao Li
Allwinner Process Voltage Scaling Tables defines the voltage and
frequency value based on the speedbin blown in the efuse combination.
The sunxi-cpufreq-nvmem driver reads the efuse value from the SoC to
provide the OPP framework with required information.
This is used to determine the voltage and frequency value for each
OPP of operating-points-v2 table when it is parsed by the OPP framework.

The "allwinner,sun50i-h6-operating-points" DT extends the
"operating-points-v2"
with following parameters:
- nvmem-cells (NVMEM area containig the speedbin information)
- opp-microvolt-: voltage in micro Volts.
  At runtime, the platform can pick a  and matching
  opp-microvolt- property.
HW: :
sun50i-h6  speed0 speed1 speed2

Signed-off-by: Yangtao Li 
Acked-by: Maxime Ripard 
---
just fix a typo:
sun50iw-h6 -> sun50i-h6

This patch is [2/2].
for [1/2]:
https://patchwork.kernel.org/patch/10903381/
---
 .../bindings/opp/sun50i-nvmem-cpufreq.txt | 167 ++
 1 file changed, 167 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt

diff --git a/Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt 
b/Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt
new file mode 100644
index ..7deae57a587b
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt
@@ -0,0 +1,167 @@
+Allwinner Technologies, Inc. NVMEM CPUFreq and OPP bindings
+===
+
+For some SoCs, the CPU frequency subset and voltage value of each OPP
+varies based on the silicon variant in use. Allwinner Process Voltage
+Scaling Tables defines the voltage and frequency value based on the
+speedbin blown in the efuse combination. The sun50i-cpufreq-nvmem driver
+reads the efuse value from the SoC to provide the OPP framework with
+required information.
+
+Required properties:
+
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be
+   - 'allwinner,sun50i-h6-operating-points'.
+- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
+   efuse registers that has information about the speedbin
+   that is used to select the right frequency/voltage value
+   pair. Please refer the for nvmem-cells bindings
+   Documentation/devicetree/bindings/nvmem/nvmem.txt and
+   also examples below.
+
+In every OPP node:
+- opp-microvolt-: Voltage in micro Volts.
+   At runtime, the platform can pick a  and
+   matching opp-microvolt- property.
+   [See: opp.txt]
+   HW: :
+   sun50i-h6   speed0 speed1 speed2
+
+Example 1:
+-
+
+   cpus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   cpu0: cpu@0 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <0>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu1: cpu@1 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <1>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu2: cpu@2 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <2>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu3: cpu@3 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <3>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   

[PATCH 2/3] thermal: sun50i: add thermal driver for h6

2019-05-12 Thread Yangtao Li
This patch adds the support for allwinner thermal sensor, within
allwinner SoC. It will register sensors for thermal framework
and use device tree to bind cooling device.

Based on driver code found here:
https://megous.com/git/linux and 
https://github.com/Allwinner-Homlet/H6-BSP4.9-linux

Signed-off-by: Yangtao Li 
---
 MAINTAINERS  |   7 +
 drivers/thermal/Kconfig  |  14 ++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/sun50i_thermal.c | 357 +++
 4 files changed, 379 insertions(+)
 create mode 100644 drivers/thermal/sun50i_thermal.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3c65228e93c5..8da56582e72a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -674,6 +674,13 @@ L: linux-cry...@vger.kernel.org
 S: Maintained
 F: drivers/crypto/sunxi-ss/
 
+ALLWINNER THERMAL DRIVER
+M: Yangtao Li 
+L: linux...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/thermal/sun50i-thermal.txt
+F: drivers/thermal/sun50i_thermal.c
+
 ALLWINNER VPU DRIVER
 M: Maxime Ripard 
 M: Paul Kocialkowski 
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 653aa27a25a4..2a8d1c98c6ca 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -252,6 +252,20 @@ config SPEAR_THERMAL
  Enable this to plug the SPEAr thermal sensor driver into the Linux
  thermal framework.
 
+config SUN50I_THERMAL
+   tristate "Allwinner sun50i thermal driver"
+   depends on ARCH_SUNXI || COMPILE_TEST
+   depends on HAS_IOMEM
+   depends on NVMEM
+   depends on OF
+   depends on RESET_CONTROLLER
+   help
+ Support for the sun50i thermal sensor driver into the Linux thermal
+ framework.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sun50i-thermal.
+
 config ROCKCHIP_THERMAL
tristate "Rockchip thermal driver"
depends on ARCH_ROCKCHIP || COMPILE_TEST
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 486d682be047..a09b30b90003 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -30,6 +30,7 @@ thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
 # platform thermal drivers
 obj-y  += broadcom/
 obj-$(CONFIG_SPEAR_THERMAL)+= spear_thermal.o
+obj-$(CONFIG_SUN50I_THERMAL)   += sun50i_thermal.o
 obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o
 obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o
 obj-$(CONFIG_RCAR_GEN3_THERMAL)+= rcar_gen3_thermal.o
diff --git a/drivers/thermal/sun50i_thermal.c b/drivers/thermal/sun50i_thermal.c
new file mode 100644
index ..3bdb3677b3d4
--- /dev/null
+++ b/drivers/thermal/sun50i_thermal.c
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Thermal sensor driver for Allwinner SOC
+ * Copyright (C) 2019 Yangtao Li
+ *
+ * Based on the work of Icenowy Zheng 
+ * Based on the work of Ondrej Jirman 
+ * Based on the work of Josef Gajdusek 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MAX_SENSOR_NUM 4
+
+#define FT_TEMP_MASK   GENMASK(11, 0)
+#define TEMP_CALIB_MASKGENMASK(11, 0)
+#define TEMP_TO_REG672
+#define CALIBRATE_DEFAULT  0x800
+
+#define SUN50I_THS_CTRL0   0x00
+#define SUN50I_H6_THS_ENABLE   0x04
+#define SUN50I_H6_THS_PC   0x08
+#define SUN50I_H6_THS_MFC  0x30
+#define SUN50I_H6_TEMP_CALIB   0xa0
+#define SUN50I_H6_TEMP_DATA0xc0
+
+#define SUN50I_THS_CTRL0_T_ACQ(x)  ((GENMASK(15, 0) & (x)) << 16)
+#define SUN50I_THS_FILTER_EN   BIT(2)
+#define SUN50I_THS_FILTER_TYPE(x)  (GENMASK(1, 0) & (x))
+#define SUN50I_H6_THS_PC_TEMP_PERIOD(x)((GENMASK(19, 0) & (x)) 
<< 12)
+
+/* millidegree celsius */
+#define SUN50I_H6_FT_DEVIATION 7000
+
+struct tsens_device;
+
+struct tsensor {
+   struct tsens_device *tmdev;
+   struct thermal_zone_device  *tzd;
+   int id;
+};
+
+struct sun50i_thermal_chip {
+   int sensor_num;
+   int offset;
+   int scale;
+   int ft_deviation;
+   int temp_calib_base;
+   int temp_data_base;
+   int (*enable)(struct tsens_device *tmdev);
+   int (*disable)(struct tsens_device *tmdev);
+};
+
+
+struct tsens_device {
+   const struct sun50i_thermal_chip*chip;
+   struct device   *dev;
+   struct regmap   *regmap;
+   struct reset_control*reset;
+   struct clk  *bus_clk;
+   st

[PATCH 3/3] dt-bindings: thermal: add binding document for h6 thermal controller

2019-05-12 Thread Yangtao Li
This patch adds binding document for allwinner h6 thermal controller.

Signed-off-by: Yangtao Li 
---
 .../bindings/thermal/sun50i-thermal.txt   | 32 +++
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/sun50i-thermal.txt

diff --git a/Documentation/devicetree/bindings/thermal/sun50i-thermal.txt 
b/Documentation/devicetree/bindings/thermal/sun50i-thermal.txt
new file mode 100644
index ..67eda7794262
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/sun50i-thermal.txt
@@ -0,0 +1,32 @@
+Binding for Thermal Sensor of Allwinner SOC.
+
+This describes the device tree binding for the Allwinner thermal controller
+which measures the on-SoC temperatures.
+
+Required properties:
+- compatible:
+  - "allwinner,sun50i-h6-ths" : For H6
+- reg: Address range of the thermal controller
+- clocks, clock-names: Clocks needed for the thermal controller.
+  The required clocks for h6 are: "bus".
+- resets, reset-names: Reference to the reset controller controlling
+  the thermal controller.
+- nvmem-cells: A phandle to the calibration data provided by a nvmem device. If
+  unspecified default values shall be used.
+- nvmem-cell-names: Should be "calib"
+- #thermal-sensor-cells : For H6 Should be 1.
+ See ./thermal.txt for a description.
+
+Example:
+
+   ths: ths@1c25000 {
+   compatible = "allwinner,sun50i-h6-ths";
+   reg = <0x05070400 0x100>;
+   clocks = < CLK_BUS_THS>;
+   clock-names = "bus";
+   resets = < RST_BUS_THS>;
+   reset-names = "bus";
+   nvmem-cells = <_calib>;
+   nvmem-cell-names = "calib";
+   #thermal-sensor-cells = <1>;
+   };
-- 
2.17.0



[PATCH 1/3] arm64: defconfig: add allwinner sid support

2019-05-12 Thread Yangtao Li
Sid contains speedbin information and temperature sensor
calibration information and more, which are important for SOC.

This patch enables CONFIG_NVMEM_SUNXI_SID by default.

Signed-off-by: Yangtao Li 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 2d9c39033c1a..8c23dd60f906 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -736,6 +736,7 @@ CONFIG_PHY_TEGRA_XUSB=y
 CONFIG_HISI_PMU=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
+CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_QCOM_QFPROM=y
 CONFIG_ROCKCHIP_EFUSE=y
 CONFIG_UNIPHIER_EFUSE=y
-- 
2.17.0



[PATCH 0/3] add thermal driver for h6

2019-05-12 Thread Yangtao Li
This patchset support thermal driver of allwinner H6.

Yangtao Li (3):
  arm64: defconfig: add allwinner sid support
  thermal: sun50i: add thermal driver for h6
  dt-bindings: thermal: add binding document for h6 thermal controller

 .../bindings/thermal/sun50i-thermal.txt   |  32 ++
 MAINTAINERS   |   7 +
 arch/arm64/configs/defconfig  |   1 +
 drivers/thermal/Kconfig   |  14 +
 drivers/thermal/Makefile  |   1 +
 drivers/thermal/sun50i_thermal.c  | 357 ++
 6 files changed, 412 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/sun50i-thermal.txt
 create mode 100644 drivers/thermal/sun50i_thermal.c

-- 
2.17.0



[PATCH] iio: adc: sun4i-gpadc-iio convert to SPDX license tags

2019-05-12 Thread Yangtao Li
Updates license to use SPDX-License-Identifier.

Signed-off-by: Yangtao Li 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 04d7147e0110..f13c6248a662 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
  *
  * Copyright (c) 2016 Quentin Schulz 
  *
- * This program is free software; you can redistribute it and/or modify it 
under
- * the terms of the GNU General Public License version 2 as published by the
- * Free Software Foundation.
- *
  * The Allwinner SoCs all have an ADC that can also act as a touchscreen
  * controller and a thermal sensor.
  * The thermal sensor works only when the ADC acts as a touchscreen controller
-- 
2.17.0



[PATCH] arm64: dts: allwinner: h6: Enable HDMI output on orangepi 3

2019-04-20 Thread Yangtao Li
Orangepi 3 has HDMI type A connector.

Signed-off-by: Yangtao Li 
---
rebase:
sunxi/dt64-for-5.2 arm64: dts: allwinner: a64-amarula-relic: Add OV5640
camera node
---
 .../dts/allwinner/sun50i-h6-orangepi-3.dts| 25 +++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
index 17d496990108..6ed3a1ee297d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
@@ -21,6 +21,17 @@
stdout-path = "serial0:115200n8";
};
 
+   connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
leds {
compatible = "gpio-leds";
 
@@ -50,6 +61,10 @@
cpu-supply = <_dcdca>;
 };
 
+ {
+   status = "okay";
+};
+
  {
status = "okay";
 };
@@ -58,6 +73,16 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
vmmc-supply = <_cldo1>;
cd-gpios = < 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
-- 
2.17.0



[PATCH 7/7] iio: adc: sun4i-gpadc-iio convert to SPDX license tags

2019-05-03 Thread Yangtao Li
Updates license to use SPDX-License-Identifier.

Signed-off-by: Yangtao Li 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 9b6fc592f54c..cf2bf3ab3342 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
  *
  * Copyright (c) 2016 Quentin Schulz 
  *
- * This program is free software; you can redistribute it and/or modify it 
under
- * the terms of the GNU General Public License version 2 as published by the
- * Free Software Foundation.
- *
  * The Allwinner SoCs all have an ADC that can also act as a touchscreen
  * controller and a thermal sensor.
  * The thermal sensor works only when the ADC acts as a touchscreen controller
-- 
2.17.1



[PATCH 2/7] iio: adc: sun4i-gpadc: introduce temp_data in gpadc_data

2019-05-03 Thread Yangtao Li
For some SOCs, the temperature data register start address may be
different, so introduce temp_data in gpadc_data.

Also modify read temperature to support multiple sensor.

Signed-off-by: Yangtao Li 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 844fd52bd22f..b41ec0d5964d 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -57,6 +57,7 @@ struct gpadc_data {
unsigned int(*adc_chan_select)(unsigned int chan);
unsigned intadc_chan_mask;
unsigned intsensor_count;
+   unsigned inttemp_data_base;
 };
 
 static const struct gpadc_data sun4i_gpadc_data = {
@@ -67,6 +68,7 @@ static const struct gpadc_data sun4i_gpadc_data = {
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
.sensor_count = 1,
+   .temp_data_base = SUN4I_GPADC_TEMP_DATA,
 };
 
 static const struct gpadc_data sun5i_gpadc_data = {
@@ -77,6 +79,7 @@ static const struct gpadc_data sun5i_gpadc_data = {
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
.sensor_count = 1,
+   .temp_data_base = SUN4I_GPADC_TEMP_DATA,
 };
 
 static const struct gpadc_data sun6i_gpadc_data = {
@@ -87,6 +90,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
.sensor_count = 1,
+   .temp_data_base = SUN4I_GPADC_TEMP_DATA,
 };
 
 static const struct gpadc_data sun8i_a33_gpadc_data = {
@@ -94,6 +98,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_scale = 162,
.tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
.sensor_count = 1,
+   .temp_data_base = SUN4I_GPADC_TEMP_DATA,
 };
 
 struct sun4i_sensor_tzd {
@@ -291,7 +296,8 @@ static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, 
int *val,
if (info->no_irq) {
pm_runtime_get_sync(indio_dev->dev.parent);
 
-   regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val);
+   regmap_read(info->regmap, info->data->temp_data_base +
+   0x4 * sensor, val);
 
pm_runtime_mark_last_busy(indio_dev->dev.parent);
pm_runtime_put_autosuspend(indio_dev->dev.parent);
-- 
2.17.1



[PATCH 1/7] iio: adc: sun4i-gpadc: rework for support multiple thermal sensor

2019-05-03 Thread Yangtao Li
For some SOCs, there are more than one thermal sensor, and there are
currently four sensors on the A80. So we need to do some work in order
to support multiple thermal sensors:

  1) add sensor_count in gpadc_data.
  2) introduce sun4i_sensor_tzd in sun4i_gpadc_iio, to support multiple
 thermal_zone_device and distinguish between different sensors.
  3) modify read temperature and initialization function.

Signed-off-by: Yangtao Li 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 61 +++
 1 file changed, 45 insertions(+), 16 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 04d7147e0110..844fd52bd22f 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -56,6 +56,7 @@ struct gpadc_data {
unsigned inttp_adc_select;
unsigned int(*adc_chan_select)(unsigned int chan);
unsigned intadc_chan_mask;
+   unsigned intsensor_count;
 };
 
 static const struct gpadc_data sun4i_gpadc_data = {
@@ -65,6 +66,7 @@ static const struct gpadc_data sun4i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .sensor_count = 1,
 };
 
 static const struct gpadc_data sun5i_gpadc_data = {
@@ -74,6 +76,7 @@ static const struct gpadc_data sun5i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .sensor_count = 1,
 };
 
 static const struct gpadc_data sun6i_gpadc_data = {
@@ -83,14 +86,24 @@ static const struct gpadc_data sun6i_gpadc_data = {
.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .sensor_count = 1,
 };
 
 static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_offset = -1662,
.temp_scale = 162,
.tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
+   .sensor_count = 1,
 };
 
+struct sun4i_sensor_tzd {
+   struct sun4i_gpadc_iio  *info;
+   struct thermal_zone_device  *tzd;
+   unsigned intsensor_id;
+};
+
+#define MAX_SENSOR_COUNT   4
+
 struct sun4i_gpadc_iio {
struct iio_dev  *indio_dev;
struct completion   completion;
@@ -105,7 +118,7 @@ struct sun4i_gpadc_iio {
boolno_irq;
/* prevents concurrent reads of temperature and ADC */
struct mutexmutex;
-   struct thermal_zone_device  *tzd;
+   struct sun4i_sensor_tzd tzds[MAX_SENSOR_COUNT];
struct device   *sensor_device;
 };
 
@@ -270,7 +283,8 @@ static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, 
int channel,
return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
 }
 
-static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
+static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val,
+unsigned int sensor)
 {
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 
@@ -324,7 +338,7 @@ static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev,
ret = sun4i_gpadc_adc_read(indio_dev, chan->channel,
   val);
else
-   ret = sun4i_gpadc_temp_read(indio_dev, val);
+   ret = sun4i_gpadc_temp_read(indio_dev, val, 0);
 
if (ret)
return ret;
@@ -417,10 +431,11 @@ static int sun4i_gpadc_runtime_resume(struct device *dev)
 
 static int sun4i_gpadc_get_temp(void *data, int *temp)
 {
-   struct sun4i_gpadc_iio *info = data;
+   struct sun4i_sensor_tzd *tzd = data;
+   struct sun4i_gpadc_iio *info = tzd->info;
int val, scale, offset;
 
-   if (sun4i_gpadc_temp_read(info->indio_dev, ))
+   if (sun4i_gpadc_temp_read(info->indio_dev, , tzd->sensor_id))
return -ETIMEDOUT;
 
sun4i_gpadc_temp_scale(info->indio_dev, );
@@ -609,6 +624,28 @@ static int sun4i_gpadc_probe_mfd(struct platform_device 
*pdev,
return 0;
 }
 
+static int sun4i_sensor_init(struct sun4i_gpadc_iio *info)
+{
+   int i = 0;
+
+   for (; i < info->data->sensor_count; i++) {
+   info->tzds[i].info = info;
+   info->tzds[i].sensor_id = i;
+   info->tzds[i].tzd = devm_thermal_zone_of_sensor_register(
+   info->sensor_device, i, >tzds[i],
+   _ts_tz_ops);
+
+   if (IS_ERR(info->tzds[i].tzd)) {
+   dev_err(info->sensor_device,
+ 

[PATCH 3/7] iio: adc: sun4i-gpadc: introduce gpadc_enable and gpadc_disable in gpadc_data

2019-05-03 Thread Yangtao Li
Different sensors may have different enable and disable functions, so
introduce enable and disable in gpadc_data to support soc specific
function.

Signed-off-by: Yangtao Li 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 37 ++-
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index b41ec0d5964d..de6b8556a549 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -49,6 +49,8 @@ static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
 }
 
+struct sun4i_gpadc_iio;
+
 struct gpadc_data {
int temp_offset;
int temp_scale;
@@ -56,10 +58,15 @@ struct gpadc_data {
unsigned inttp_adc_select;
unsigned int(*adc_chan_select)(unsigned int chan);
unsigned intadc_chan_mask;
+   int (*gpadc_enable)(struct sun4i_gpadc_iio *info);
+   int (*gpadc_disable)(struct sun4i_gpadc_iio *info);
unsigned intsensor_count;
unsigned inttemp_data_base;
 };
 
+static int sun4i_gpadc_disable(struct sun4i_gpadc_iio *info);
+static int sun4i_gpadc_enable(struct sun4i_gpadc_iio *info);
+
 static const struct gpadc_data sun4i_gpadc_data = {
.temp_offset = -1932,
.temp_scale = 133,
@@ -67,6 +74,8 @@ static const struct gpadc_data sun4i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .gpadc_enable = sun4i_gpadc_enable,
+   .gpadc_disable = sun4i_gpadc_disable,
.sensor_count = 1,
.temp_data_base = SUN4I_GPADC_TEMP_DATA,
 };
@@ -78,6 +87,8 @@ static const struct gpadc_data sun5i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .gpadc_enable = sun4i_gpadc_enable,
+   .gpadc_disable = sun4i_gpadc_disable,
.sensor_count = 1,
.temp_data_base = SUN4I_GPADC_TEMP_DATA,
 };
@@ -89,6 +100,8 @@ static const struct gpadc_data sun6i_gpadc_data = {
.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .gpadc_enable = sun4i_gpadc_enable,
+   .gpadc_disable = sun4i_gpadc_disable,
.sensor_count = 1,
.temp_data_base = SUN4I_GPADC_TEMP_DATA,
 };
@@ -97,6 +110,8 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_offset = -1662,
.temp_scale = 162,
.tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
+   .gpadc_enable = sun4i_gpadc_enable,
+   .gpadc_disable = sun4i_gpadc_disable,
.sensor_count = 1,
.temp_data_base = SUN4I_GPADC_TEMP_DATA,
 };
@@ -402,10 +417,8 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int 
irq, void *dev_id)
return IRQ_HANDLED;
 }
 
-static int sun4i_gpadc_runtime_suspend(struct device *dev)
+static int sun4i_gpadc_disable(struct sun4i_gpadc_iio *info)
 {
-   struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
-
/* Disable the ADC on IP */
regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0);
/* Disable temperature sensor on IP */
@@ -414,10 +427,8 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
return 0;
 }
 
-static int sun4i_gpadc_runtime_resume(struct device *dev)
+static int sun4i_gpadc_enable(struct sun4i_gpadc_iio *info)
 {
-   struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
-
/* clkin = 6MHz */
regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
 SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) |
@@ -435,6 +446,20 @@ static int sun4i_gpadc_runtime_resume(struct device *dev)
return 0;
 }
 
+static int sun4i_gpadc_runtime_suspend(struct device *dev)
+{
+   struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
+
+   return info->data->gpadc_disable(info);
+}
+
+static int sun4i_gpadc_runtime_resume(struct device *dev)
+{
+   struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
+
+   return info->data->gpadc_enable(info);
+}
+
 static int sun4i_gpadc_get_temp(void *data, int *temp)
 {
struct sun4i_sensor_tzd *tzd = data;
-- 
2.17.1



[PATCH 5/7] dt-bindings: mfd: Add H6 GPADC binding

2019-05-03 Thread Yangtao Li
This patch adds documentation for the H6 GPADC binding.

Signed-off-by: Yangtao Li 
---
 .../devicetree/bindings/mfd/sun4i-gpadc.txt   | 27 +--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt 
b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
index 86dd8191b04c..eeaf27eb8abd 100644
--- a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
+++ b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
@@ -5,11 +5,22 @@ and sometimes as a touchscreen controller.
 
 Required properties:
   - compatible: "allwinner,sun8i-a33-ths",
+   "allwinner,sun50i-h6-ths",
   - reg: mmio address range of the chip,
-  - #thermal-sensor-cells: shall be 0,
+  - #thermal-sensor-cells: shall be 0 for sun8i-a33-ths,
+  shall be 1 for sun50i-h6-ths,
   - #io-channel-cells: shall be 0,
 
-Example:
+Optional properties:
+  - clocks: Must contain an entry for each entry in clock-names.
+   See common clock-bindings.txt for details.
+  - clock-names: A list of clock names. For sun50i-h6-ths, it must contain
+"bus".
+  - resets: Must contain an entry for each entry in reset-names.
+   See ../reset/reset.txt for details.
+  - reset-names: For sun50i-h6-ths, it must contain "bus".
+
+Example1:
ths: ths@1c25000 {
compatible = "allwinner,sun8i-a33-ths";
reg = <0x01c25000 0x100>;
@@ -17,6 +28,18 @@ Example:
#io-channel-cells = <0>;
};
 
+Example2:
+   ths: ths@1c25000 {
+   compatible = "allwinner,sun50i-h6-ths";
+   reg = <0x05070400 0x100>;
+   clocks = < CLK_BUS_THS>;
+   clock-names = "bus";
+   resets = < RST_BUS_THS>;
+   reset-names = "bus";
+   #thermal-sensor-cells = <1>;
+   #io-channel-cells = <0>;
+   };
+
 sun4i, sun5i and sun6i SoCs are also supported via the older binding:
 
 sun4i resistive touchscreen controller
-- 
2.17.1



[PATCH 6/7] iio: adc: sun4i-gpadc-iio: add support for H6 thermal sensor

2019-05-03 Thread Yangtao Li
This patch adds support for the H6 ths sensor.

TODO: calibrate thermal sensor by using information from sid.

Signed-off-by: Yangtao Li 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 65 +++
 include/linux/mfd/sun4i-gpadc.h   |  9 +
 2 files changed, 74 insertions(+)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index f24eb76d65c0..9b6fc592f54c 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -120,6 +120,20 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_data_base = SUN4I_GPADC_TEMP_DATA,
 };
 
+static int sun50i_gpadc_disable(struct sun4i_gpadc_iio *info);
+static int sun50i_gpadc_enable(struct sun4i_gpadc_iio *info);
+
+static const struct gpadc_data sun50i_h6_gpadc_data = {
+   .temp_offset = -2809,
+   .temp_scale = -67,
+   .has_bus_clk = true,
+   .has_bus_rst = true,
+   .gpadc_enable = sun50i_gpadc_enable,
+   .gpadc_disable = sun50i_gpadc_disable,
+   .sensor_count = 2,
+   .temp_data_base = SUN50I_H6_GPADC_TEMP_DATA,
+};
+
 struct sun4i_sensor_tzd {
struct sun4i_gpadc_iio  *info;
struct thermal_zone_device  *tzd;
@@ -452,6 +466,53 @@ static int sun4i_gpadc_enable(struct sun4i_gpadc_iio *info)
return 0;
 }
 
+static int sun50i_gpadc_enable(struct sun4i_gpadc_iio *info)
+{
+   int ret, val;
+
+   ret = reset_control_deassert(info->reset);
+   if (ret)
+   return ret;
+
+   ret = clk_prepare_enable(info->bus_clk);
+   if (ret)
+   goto assert_reset;
+
+   /*
+* clkin = 24MHz
+* T acquire = clkin / (SUN50I_GPADC_CTRL0_T_ACQ + 1)
+*   = 20us
+*/
+   regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
+SUN50I_GPADC_CTRL0_T_ACQ(479));
+   /* average over 4 samples */
+   regmap_write(info->regmap, SUN50I_H6_GPADC_CTRL3,
+SUN4I_GPADC_CTRL3_FILTER_EN |
+SUN4I_GPADC_CTRL3_FILTER_TYPE(1));
+   /* period = (SUN50I_GPADC_TPR_TEMP_PERIOD + 1) * 4096 / clkin; ~10ms */
+   regmap_write(info->regmap, SUN50I_GPADC_TPR,
+SUN50I_GPADC_TPR_TEMP_PERIOD(58));
+   /* TODO: calibrate ths */
+   /* enable sensor */
+   val = GENMASK(info->data->sensor_count - 1, 0);
+   regmap_write(info->regmap, SUN4I_GPADC_CTRL1, val);
+
+   return 0;
+
+assert_reset:
+   reset_control_assert(info->reset);
+
+   return ret;
+}
+
+static int sun50i_gpadc_disable(struct sun4i_gpadc_iio *info)
+{
+   clk_disable_unprepare(info->bus_clk);
+   reset_control_assert(info->reset);
+
+   return 0;
+}
+
 static int sun4i_gpadc_runtime_suspend(struct device *dev)
 {
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
@@ -546,6 +607,10 @@ static const struct of_device_id sun4i_gpadc_of_id[] = {
.compatible = "allwinner,sun8i-a33-ths",
.data = _a33_gpadc_data,
},
+   {
+   .compatible = "allwinner,sun50i-h6-ths",
+   .data = _h6_gpadc_data,
+   },
{ /* sentinel */ }
 };
 
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
index 139872c2e0fe..f505013e9c0d 100644
--- a/include/linux/mfd/sun4i-gpadc.h
+++ b/include/linux/mfd/sun4i-gpadc.h
@@ -19,6 +19,9 @@
 #define SUN4I_GPADC_CTRL0_FS_DIV(x)((GENMASK(3, 0) & (x)) 
<< 16)
 #define SUN4I_GPADC_CTRL0_T_ACQ(x) (GENMASK(15, 0) & (x))
 
+/* TP_CTRL0 bits for sun50i SOCs */
+#define SUN50I_GPADC_CTRL0_T_ACQ(x)((GENMASK(15, 0) & (x)) 
<< 16)
+
 #define SUN4I_GPADC_CTRL1  0x04
 
 #define SUN4I_GPADC_CTRL1_STYLUS_UP_DEBOUNCE(x)((GENMASK(7, 0) 
& (x)) << 12)
@@ -49,6 +52,9 @@
 #define SUN4I_GPADC_CTRL2_PRE_MEA_EN   BIT(24)
 #define SUN4I_GPADC_CTRL2_PRE_MEA_THRE_CNT(x)  (GENMASK(23, 0) & (x))
 
+#define SUN50I_GPADC_TPR   0x08
+#define SUN50I_GPADC_TPR_TEMP_PERIOD(x)((GENMASK(19, 
0) & (x)) << 12)
+
 #define SUN4I_GPADC_CTRL3  0x0c
 
 #define SUN4I_GPADC_CTRL3_FILTER_ENBIT(2)
@@ -84,6 +90,9 @@
 #define SUN4I_GPADC_TEMP_DATA  0x20
 #define SUN4I_GPADC_DATA   0x24
 
+#define SUN50I_H6_GPADC_CTRL3  0x30
+#define SUN50I_H6_GPADC_TEMP_DATA  0xc0
+
 #define SUN4I_GPADC_IRQ_FIFO_DATA  0
 #define SUN4I_GPADC_IRQ_TEMP_DATA  1
 
-- 
2.17.1



[PATCH 4/7] iio: adc: sun4i-gpadc-iio: support clocks and reset

2019-05-03 Thread Yangtao Li
H6 has bus clock and a reset, so introduce something in
gpadc_data/sun4i_gpadc_iio and adds the process of the
clocks and resets.

This is pre-work for supprt it.

Signed-off-by: Yangtao Li 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 32 +--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index de6b8556a549..f24eb76d65c0 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -22,6 +22,7 @@
  * shutdown for not being used.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -31,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -52,6 +54,8 @@ static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
 struct sun4i_gpadc_iio;
 
 struct gpadc_data {
+   boolhas_bus_clk;
+   boolhas_bus_rst;
int temp_offset;
int temp_scale;
unsigned inttp_mode_en;
@@ -140,6 +144,8 @@ struct sun4i_gpadc_iio {
struct mutexmutex;
struct sun4i_sensor_tzd tzds[MAX_SENSOR_COUNT];
struct device   *sensor_device;
+   struct clk  *bus_clk;
+   struct reset_control*reset;
 };
 
 #define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) { \
@@ -564,14 +570,36 @@ static int sun4i_gpadc_probe_dt(struct platform_device 
*pdev,
if (IS_ERR(base))
return PTR_ERR(base);
 
-   info->regmap = devm_regmap_init_mmio(>dev, base,
-_gpadc_regmap_config);
+   if (info->data->has_bus_clk)
+   info->regmap = devm_regmap_init_mmio_clk(>dev, "bus",
+base,
+   _gpadc_regmap_config);
+   else
+   info->regmap = devm_regmap_init_mmio(>dev, base,
+   _gpadc_regmap_config);
+
if (IS_ERR(info->regmap)) {
ret = PTR_ERR(info->regmap);
dev_err(>dev, "failed to init regmap: %d\n", ret);
return ret;
}
 
+   if (info->data->has_bus_rst) {
+   info->reset = devm_reset_control_get(>dev, "bus");
+   if (IS_ERR(info->reset)) {
+   ret = PTR_ERR(info->reset);
+   return ret;
+   }
+   }
+
+   if (info->data->has_bus_clk) {
+   info->bus_clk = devm_clk_get(>dev, "bus");
+   if (IS_ERR(info->bus_clk)) {
+   ret = PTR_ERR(info->bus_clk);
+   return ret;
+   }
+   }
+
if (IS_ENABLED(CONFIG_THERMAL_OF))
info->sensor_device = >dev;
 
-- 
2.17.1



[PATCH 0/7] Add support for H6 thermal sensor

2019-05-03 Thread Yangtao Li
This patchset adds support for the H6 ths sensor.

Based on IIO-based thermal sensor driver for Allwinner H3 and A83T SoC,
thx to Philipp Rossak's work.

TODO: calibrate thermal sensor by using information from sid.

Yangtao Li (7):
  iio: adc: sun4i-gpadc: rework for support multiple thermal sensor
  iio: adc: sun4i-gpadc: introduce temp_data in gpadc_data
  iio: adc: sun4i-gpadc: introduce gpadc_enable and gpadc_disable in
gpadc_data
  iio: adc: sun4i-gpadc-iio: support clocks and reset
  dt-bindings: mfd: Add H6 GPADC binding
  iio: adc: sun4i-gpadc-iio: add support for H6 thermal sensor
  iio: adc: sun4i-gpadc-iio convert to SPDX license tags

 .../devicetree/bindings/mfd/sun4i-gpadc.txt   |  27 ++-
 drivers/iio/adc/sun4i-gpadc-iio.c | 208 +++---
 include/linux/mfd/sun4i-gpadc.h   |   9 +
 3 files changed, 213 insertions(+), 31 deletions(-)

-- 
2.17.1



[PATCH v2 0/2] add thermal driver for h6

2019-05-16 Thread Yangtao Li
This patchset supprt H6 thermal controller.

Yangtao Li (2):
  thermal: sun8i: add thermal driver for h6
  dt-bindings: thermal: add binding document for h6 thermal controller

 .../bindings/thermal/sun8i-thermal.txt|  34 ++
 MAINTAINERS   |   7 +
 drivers/thermal/Kconfig   |  14 +
 drivers/thermal/Makefile  |   1 +
 drivers/thermal/sun8i_thermal.c   | 422 ++
 5 files changed, 478 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/sun8i-thermal.txt
 create mode 100644 drivers/thermal/sun8i_thermal.c

---
v2:
-Additions and deletions of some comments
-Change some function prefix to "ths_"
-Support interrupt
---
2.17.0



[PATCH v2 1/2] thermal: sun8i: add thermal driver for h6

2019-05-16 Thread Yangtao Li
This patch adds the support for allwinner thermal sensor, within
allwinner SoC. It will register sensors for thermal framework
and use device tree to bind cooling device.

Signed-off-by: Yangtao Li 
---
 MAINTAINERS |   7 +
 drivers/thermal/Kconfig |  14 ++
 drivers/thermal/Makefile|   1 +
 drivers/thermal/sun8i_thermal.c | 422 
 4 files changed, 444 insertions(+)
 create mode 100644 drivers/thermal/sun8i_thermal.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 005902ea1450..4e753ed20cd0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -674,6 +674,13 @@ L: linux-cry...@vger.kernel.org
 S: Maintained
 F: drivers/crypto/sunxi-ss/
 
+ALLWINNER THERMAL DRIVER
+M: Yangtao Li 
+L: linux...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/thermal/sun8i-thermal.txt
+F: drivers/thermal/sun8i_thermal.c
+
 ALLWINNER VPU DRIVER
 M: Maxime Ripard 
 M: Paul Kocialkowski 
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 66a709d5d6b9..f03d941c5686 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -263,6 +263,20 @@ config SPEAR_THERMAL
  Enable this to plug the SPEAr thermal sensor driver into the Linux
  thermal framework.
 
+config SUN8I_THERMAL
+   tristate "Allwinner sun8i thermal driver"
+   depends on ARCH_SUNXI || COMPILE_TEST
+   depends on HAS_IOMEM
+   depends on NVMEM_SUNXI_SID
+   depends on OF
+   depends on RESET_CONTROLLER
+   help
+ Support for the sun8i thermal sensor driver into the Linux thermal
+ framework.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sun8i-thermal.
+
 config ROCKCHIP_THERMAL
tristate "Rockchip thermal driver"
depends on ARCH_ROCKCHIP || COMPILE_TEST
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 74a37c7f847a..fa6f8b206281 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -31,6 +31,7 @@ thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
 obj-y  += broadcom/
 obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o
 obj-$(CONFIG_SPEAR_THERMAL)+= spear_thermal.o
+obj-$(CONFIG_SUN8I_THERMAL) += sun8i_thermal.o
 obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o
 obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o
 obj-$(CONFIG_RCAR_GEN3_THERMAL)+= rcar_gen3_thermal.o
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
new file mode 100644
index ..c9920f58fc80
--- /dev/null
+++ b/drivers/thermal/sun8i_thermal.c
@@ -0,0 +1,422 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Thermal sensor driver for Allwinner SOC
+ * Copyright (C) 2019 Yangtao Li
+ *
+ * Based on the work of Icenowy Zheng 
+ * Based on the work of Ondrej Jirman 
+ * Based on the work of Josef Gajdusek 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MAX_SENSOR_NUM 4
+
+#define FT_TEMP_MASK   GENMASK(11, 0)
+#define TEMP_CALIB_MASKGENMASK(11, 0)
+#define TEMP_TO_REG672
+#define CALIBRATE_DEFAULT  0x800
+
+#define SUN50I_THS_CTRL0   0x00
+#define SUN50I_H6_THS_ENABLE   0x04
+#define SUN50I_H6_THS_PC   0x08
+#define SUN50I_H6_THS_DIC  0x10
+#define SUN50I_H6_THS_DIS  0x20
+#define SUN50I_H6_THS_MFC  0x30
+#define SUN50I_H6_THS_TEMP_CALIB   0xa0
+#define SUN50I_H6_THS_TEMP_DATA0xc0
+
+#define SUN50I_THS_CTRL0_T_ACQ(x)  ((GENMASK(15, 0) & (x)) << 16)
+#define SUN50I_THS_FILTER_EN   BIT(2)
+#define SUN50I_THS_FILTER_TYPE(x)  (GENMASK(1, 0) & (x))
+#define SUN50I_H6_THS_PC_TEMP_PERIOD(x)((GENMASK(19, 0) & (x)) 
<< 12)
+#define SUN50I_H6_THS_DATA_IRQ_STS(x)  BIT(x)
+
+/* millidegree celsius */
+#define SUN50I_H6_FT_DEVIATION 7000
+
+struct ths_device;
+
+struct tsensor {
+   struct ths_device   *tmdev;
+   struct thermal_zone_device  *tzd;
+   int id;
+};
+
+struct ths_thermal_chip {
+   int sensor_num;
+   int offset;
+   int scale;
+   int ft_deviation;
+   int temp_calib_base;
+   int temp_data_base;
+   int (*enable)(struct ths_device *tmdev);
+   int (*disable)(struct ths_device *tmdev);
+   irqreturn_t (*irq_thread)(int irq, void *data);
+};
+
+struct ths_device {
+   const struct ths_thermal_chip   *chip;
+   struct device  

[PATCH v2 2/2] dt-bindings: thermal: add binding document for h6 thermal controller

2019-05-16 Thread Yangtao Li
This patch adds binding document for allwinner h6 thermal controller.

Signed-off-by: Yangtao Li 
---
 .../bindings/thermal/sun8i-thermal.txt| 34 +++
 1 file changed, 34 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/sun8i-thermal.txt

diff --git a/Documentation/devicetree/bindings/thermal/sun8i-thermal.txt 
b/Documentation/devicetree/bindings/thermal/sun8i-thermal.txt
new file mode 100644
index ..bd417260501f
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/sun8i-thermal.txt
@@ -0,0 +1,34 @@
+* Allwinner Thermal
+
+This describes the device tree binding for the Allwinner thermal controller
+which measures the on-SoC temperatures.
+
+Required properties:
+- compatible:
+  - "allwinner,sun50i-h6-ths" : For H6
+- reg: Address range of the thermal controller
+- clocks, clock-names: Clocks needed for the thermal controller.
+  The required clocks for h6 are: "bus".
+- resets: Reference to the reset controller controlling the thermal controller.
+- interrupts: IRQ for the thermal controller
+- #thermal-sensor-cells : For H6 Should be 1.
+ See ./thermal.txt for a description.
+
+Optional properties:
+- nvmem-cells: A phandle to the calibration data provided by a nvmem device. If
+  unspecified default values shall be used.
+- nvmem-cell-names: Should be "calib".
+
+Example:
+
+   ths: ths@1c25000 {
+   compatible = "allwinner,sun50i-h6-ths";
+   reg = <0x05070400 0x100>;
+   clocks = < CLK_BUS_THS>;
+   clock-names = "bus";
+   resets = < RST_BUS_THS>;
+   interrupts = ;
+   nvmem-cells = <_calib>;
+   nvmem-cell-names = "calib";
+   #thermal-sensor-cells = <1>;
+   };
-- 
2.17.0



[PATCH] PM / core: fix kerneldoc comment for dpm_watchdog_handler()

2019-03-15 Thread Yangtao Li
This brings the kernel doc in line with the function signature.

Signed-off-by: Yangtao Li 
---
 drivers/base/power/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index f80d298de3fa..0cff68bd7b4b 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -478,7 +478,7 @@ struct dpm_watchdog {
 
 /**
  * dpm_watchdog_handler - Driver suspend / resume watchdog handler.
- * @data: Watchdog object address.
+ * @t: The timer that pm watchdog depends on.
  *
  * Called when a driver has timed out suspending or resuming.
  * There's not much we can do here to recover so panic() to
-- 
2.17.0



[PATCH] PM / core: fix kerneldoc comment for device_pm_wait_for_dev

2019-03-15 Thread Yangtao Li
Rearrange comment to make the comment style consistent, the previous
function parameters are described first.

Signed-off-by: Yangtao Li 
---
 drivers/base/power/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 0cff68bd7b4b..eddb54057ed6 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -2069,8 +2069,8 @@ EXPORT_SYMBOL_GPL(__suspend_report_result);
 
 /**
  * device_pm_wait_for_dev - Wait for suspend/resume of a device to complete.
- * @dev: Device to wait for.
  * @subordinate: Device that needs to wait for @dev.
+ * @dev: Device to wait for.
  */
 int device_pm_wait_for_dev(struct device *subordinate, struct device *dev)
 {
-- 
2.17.0



[PATCH 2/4] PM / core: Introduce DEVICE_SUSPEND_FUNC() helper macro

2019-03-15 Thread Yangtao Li
The devices_suspend_noirq, device_suspend_late, device_suspen functions
are basically the same. As we have seen:

static int device_xxx(struct device *dev)
{
   if (dpm_async_fn(dev, async_xxx))
   return 0;

   return __device_xxx(dev, pm_transition, false);
}

The DEVICE_SUSPEND_FUNC() helper macro can decrease
code duplication.

Signed-off-by: Yangtao Li 
---
 drivers/base/power/main.c | 33 -
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index cb44bb6b2b66..6026bda5e787 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -719,6 +719,15 @@ static bool dpm_async_fn(struct device *dev, async_func_t 
func)
return false;
 }
 
+#define DEVICE_SUSPEND_FUNC(__func, __name)\
+static int __func(struct device *dev)  \
+{  \
+   if (dpm_async_fn(dev, async_ ## __name))\
+   return 0;   \
+   \
+   return __device_ ## __name(dev, pm_transition, false);  \
+}
+
 static void async_resume_noirq(void *data, async_cookie_t cookie)
 {
struct device *dev = (struct device *)data;
@@ -1369,13 +1378,7 @@ static void async_suspend_noirq(void *data, 
async_cookie_t cookie)
put_device(dev);
 }
 
-static int device_suspend_noirq(struct device *dev)
-{
-   if (dpm_async_fn(dev, async_suspend_noirq))
-   return 0;
-
-   return __device_suspend_noirq(dev, pm_transition, false);
-}
+DEVICE_SUSPEND_FUNC(device_suspend_noirq, suspend_noirq);
 
 void dpm_noirq_begin(void)
 {
@@ -1568,13 +1571,7 @@ static void async_suspend_late(void *data, 
async_cookie_t cookie)
put_device(dev);
 }
 
-static int device_suspend_late(struct device *dev)
-{
-   if (dpm_async_fn(dev, async_suspend_late))
-   return 0;
-
-   return __device_suspend_late(dev, pm_transition, false);
-}
+DEVICE_SUSPEND_FUNC(device_suspend_late, suspend_late);
 
 /**
  * dpm_suspend_late - Execute "late suspend" callbacks for all devices.
@@ -1829,13 +1826,7 @@ static void async_suspend(void *data, async_cookie_t 
cookie)
put_device(dev);
 }
 
-static int device_suspend(struct device *dev)
-{
-   if (dpm_async_fn(dev, async_suspend))
-   return 0;
-
-   return __device_suspend(dev, pm_transition, false);
-}
+DEVICE_SUSPEND_FUNC(device_suspend, suspend);
 
 /**
  * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
-- 
2.17.0



[PATCH 0/4] PM / core: Introduce some helper for better Code reuse

2019-03-15 Thread Yangtao Li
This patch set introduces some functions and macros that help reduce
code duplication.

Yangtao Li (4):
  PM / core: Introduce dpm_async_fn() helper
  PM / core: Introduce DEVICE_SUSPEND_FUNC() helper macro
  PM / core: Introduce ASYNC_RESUME_FUNC() helper macro
  PM / core: Introduce ASYNC_SUSPEND_FUNC() helper macro

 drivers/base/power/main.c | 182 --
 1 file changed, 59 insertions(+), 123 deletions(-)

-- 
2.17.0



[PATCH 1/4] PM / core: Introduce dpm_async_fn() helper

2019-03-15 Thread Yangtao Li
When we want to execute device pm functions asynchronously, we'll
do the following for the device:

  1) reinit_completion(>power.completion);
  2) Check if the device enables asynchronous suspend.
  3) If necessary, execute the corresponding function asynchronously.

There are a lot of such repeated operations here, in fact we can avoid
this. So introduce dpm_async_fn() to have better code readability and
reuse.

And use this function to do some cleanup.

Signed-off-by: Yangtao Li 
---
 drivers/base/power/main.c | 62 +++
 1 file changed, 23 insertions(+), 39 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index eddb54057ed6..cb44bb6b2b66 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -706,6 +706,19 @@ static bool is_async(struct device *dev)
&& !pm_trace_is_enabled();
 }
 
+static bool dpm_async_fn(struct device *dev, async_func_t func)
+{
+   reinit_completion(>power.completion);
+
+   if (is_async(dev)) {
+   get_device(dev);
+   async_schedule(func, dev);
+   return true;
+   }
+
+   return false;
+}
+
 static void async_resume_noirq(void *data, async_cookie_t cookie)
 {
struct device *dev = (struct device *)data;
@@ -732,13 +745,8 @@ void dpm_noirq_resume_devices(pm_message_t state)
 * in case the starting of async threads is
 * delayed by non-async resuming devices.
 */
-   list_for_each_entry(dev, _noirq_list, power.entry) {
-   reinit_completion(>power.completion);
-   if (is_async(dev)) {
-   get_device(dev);
-   async_schedule_dev(async_resume_noirq, dev);
-   }
-   }
+   list_for_each_entry(dev, _noirq_list, power.entry)
+   dpm_async_fn(dev, async_resume_noirq);
 
while (!list_empty(_noirq_list)) {
dev = to_device(dpm_noirq_list.next);
@@ -889,13 +897,8 @@ void dpm_resume_early(pm_message_t state)
 * in case the starting of async threads is
 * delayed by non-async resuming devices.
 */
-   list_for_each_entry(dev, _late_early_list, power.entry) {
-   reinit_completion(>power.completion);
-   if (is_async(dev)) {
-   get_device(dev);
-   async_schedule_dev(async_resume_early, dev);
-   }
-   }
+   list_for_each_entry(dev, _late_early_list, power.entry)
+   dpm_async_fn(dev, async_resume_early);
 
while (!list_empty(_late_early_list)) {
dev = to_device(dpm_late_early_list.next);
@@ -1053,13 +1056,8 @@ void dpm_resume(pm_message_t state)
pm_transition = state;
async_error = 0;
 
-   list_for_each_entry(dev, _suspended_list, power.entry) {
-   reinit_completion(>power.completion);
-   if (is_async(dev)) {
-   get_device(dev);
-   async_schedule_dev(async_resume, dev);
-   }
-   }
+   list_for_each_entry(dev, _suspended_list, power.entry)
+   dpm_async_fn(dev, async_resume);
 
while (!list_empty(_suspended_list)) {
dev = to_device(dpm_suspended_list.next);
@@ -1373,13 +1371,9 @@ static void async_suspend_noirq(void *data, 
async_cookie_t cookie)
 
 static int device_suspend_noirq(struct device *dev)
 {
-   reinit_completion(>power.completion);
-
-   if (is_async(dev)) {
-   get_device(dev);
-   async_schedule_dev(async_suspend_noirq, dev);
+   if (dpm_async_fn(dev, async_suspend_noirq))
return 0;
-   }
+
return __device_suspend_noirq(dev, pm_transition, false);
 }
 
@@ -1576,13 +1570,8 @@ static void async_suspend_late(void *data, 
async_cookie_t cookie)
 
 static int device_suspend_late(struct device *dev)
 {
-   reinit_completion(>power.completion);
-
-   if (is_async(dev)) {
-   get_device(dev);
-   async_schedule_dev(async_suspend_late, dev);
+   if (dpm_async_fn(dev, async_suspend_late))
return 0;
-   }
 
return __device_suspend_late(dev, pm_transition, false);
 }
@@ -1842,13 +1831,8 @@ static void async_suspend(void *data, async_cookie_t 
cookie)
 
 static int device_suspend(struct device *dev)
 {
-   reinit_completion(>power.completion);
-
-   if (is_async(dev)) {
-   get_device(dev);
-   async_schedule_dev(async_suspend, dev);
+   if (dpm_async_fn(dev, async_suspend))
return 0;
-   }
 
return __device_suspend(dev, pm_transition, false);
 }
-- 
2.17.0



[PATCH 3/4] PM / core: Introduce ASYNC_RESUME_FUNC() helper macro

2019-03-15 Thread Yangtao Li
The async_resume_noirq, async_resume_early, async_resume functions
are basically the same. As we have seen:

static void async_xxx(void *data, async_cookie_t cookie)
{
struct device *dev = (struct device *)data;
int error;

error = device_xxx(dev, pm_transition, true);
if (error)
pm_dev_err(dev, pm_transition, " async", error);
put_device(dev);
}

The ASYNC_RESUME_FUNC() helper macro can decrease code duplication.

Signed-off-by: Yangtao Li 
---
 drivers/base/power/main.c | 46 +--
 1 file changed, 15 insertions(+), 31 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 6026bda5e787..d512bee9d9ca 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -728,18 +728,21 @@ static int __func(struct device *dev) 
\
return __device_ ## __name(dev, pm_transition, false);  \
 }
 
-static void async_resume_noirq(void *data, async_cookie_t cookie)
-{
-   struct device *dev = (struct device *)data;
-   int error;
-
-   error = device_resume_noirq(dev, pm_transition, true);
-   if (error)
-   pm_dev_err(dev, pm_transition, " async", error);
-
-   put_device(dev);
+#define ASYNC_RESUME_FUNC(__func, __name)  \
+static void __func(void *data, async_cookie_t cookie)  \
+{  \
+   struct device *dev = (struct device *)data; \
+   int error;  \
+   \
+   error = device_ ## __name(dev, pm_transition, true);\
+   if (error)  \
+   pm_dev_err(dev, pm_transition, " async", error);\
+   \
+   put_device(dev);\
 }
 
+ASYNC_RESUME_FUNC(async_resume_noirq, resume_noirq);
+
 void dpm_noirq_resume_devices(pm_message_t state)
 {
struct device *dev;
@@ -876,17 +879,7 @@ static int device_resume_early(struct device *dev, 
pm_message_t state, bool asyn
return error;
 }
 
-static void async_resume_early(void *data, async_cookie_t cookie)
-{
-   struct device *dev = (struct device *)data;
-   int error;
-
-   error = device_resume_early(dev, pm_transition, true);
-   if (error)
-   pm_dev_err(dev, pm_transition, " async", error);
-
-   put_device(dev);
-}
+ASYNC_RESUME_FUNC(async_resume_early, resume_early);
 
 /**
  * dpm_resume_early - Execute "early resume" callbacks for all devices.
@@ -1035,16 +1028,7 @@ static int device_resume(struct device *dev, 
pm_message_t state, bool async)
return error;
 }
 
-static void async_resume(void *data, async_cookie_t cookie)
-{
-   struct device *dev = (struct device *)data;
-   int error;
-
-   error = device_resume(dev, pm_transition, true);
-   if (error)
-   pm_dev_err(dev, pm_transition, " async", error);
-   put_device(dev);
-}
+ASYNC_RESUME_FUNC(async_resume, resume);
 
 /**
  * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
-- 
2.17.0



[PATCH 4/4] PM / core: Introduce ASYNC_SUSPEND_FUNC() helper macro

2019-03-15 Thread Yangtao Li
The async_suspend_noirq, async_suspend_late, async_suspend functions
are basically the same. As we have seen:

static void async_xxx(void *data, async_cookie_t cookie)
{
struct device *dev = (struct device *)data;
int error;

error = __device_xxx(dev, pm_transition, true);
if (error) {
dpm_save_failed_dev(dev_name(dev));
pm_dev_err(dev, pm_transition, " async", error);
}

put_device(dev);
}

The ASYNC_SUSPEND_FUNC() helper macro can decrease code duplication.

Signed-off-by: Yangtao Li 
---
 drivers/base/power/main.c | 55 ---
 1 file changed, 16 insertions(+), 39 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index d512bee9d9ca..3882dc5fee9f 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1348,20 +1348,22 @@ static int __device_suspend_noirq(struct device *dev, 
pm_message_t state, bool a
return error;
 }
 
-static void async_suspend_noirq(void *data, async_cookie_t cookie)
-{
-   struct device *dev = (struct device *)data;
-   int error;
-
-   error = __device_suspend_noirq(dev, pm_transition, true);
-   if (error) {
-   dpm_save_failed_dev(dev_name(dev));
-   pm_dev_err(dev, pm_transition, " async", error);
-   }
-
-   put_device(dev);
+#define ASYNC_SUSPEND_FUNC(__func, __name) \
+static void __func(void *data, async_cookie_t cookie)  \
+{  \
+   struct device *dev = (struct device *)data; \
+   int error;  \
+   \
+   error = __device_ ## __name(dev, pm_transition, true);  \
+   if (error) {\
+   dpm_save_failed_dev(dev_name(dev)); \
+   pm_dev_err(dev, pm_transition, " async", error);\
+   }   \
+   \
+   put_device(dev);\
 }
 
+ASYNC_SUSPEND_FUNC(async_suspend_noirq, suspend_noirq);
 DEVICE_SUSPEND_FUNC(device_suspend_noirq, suspend_noirq);
 
 void dpm_noirq_begin(void)
@@ -1542,19 +1544,7 @@ static int __device_suspend_late(struct device *dev, 
pm_message_t state, bool as
return error;
 }
 
-static void async_suspend_late(void *data, async_cookie_t cookie)
-{
-   struct device *dev = (struct device *)data;
-   int error;
-
-   error = __device_suspend_late(dev, pm_transition, true);
-   if (error) {
-   dpm_save_failed_dev(dev_name(dev));
-   pm_dev_err(dev, pm_transition, " async", error);
-   }
-   put_device(dev);
-}
-
+ASYNC_SUSPEND_FUNC(async_suspend_late, suspend_late);
 DEVICE_SUSPEND_FUNC(device_suspend_late, suspend_late);
 
 /**
@@ -1796,20 +1786,7 @@ static int __device_suspend(struct device *dev, 
pm_message_t state, bool async)
return error;
 }
 
-static void async_suspend(void *data, async_cookie_t cookie)
-{
-   struct device *dev = (struct device *)data;
-   int error;
-
-   error = __device_suspend(dev, pm_transition, true);
-   if (error) {
-   dpm_save_failed_dev(dev_name(dev));
-   pm_dev_err(dev, pm_transition, " async", error);
-   }
-
-   put_device(dev);
-}
-
+ASYNC_SUSPEND_FUNC(async_suspend, suspend);
 DEVICE_SUSPEND_FUNC(device_suspend, suspend);
 
 /**
-- 
2.17.0



[PATCH] interconnect: convert to DEFINE_SHOW_ATTRIBUTE

2019-03-27 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
---
 drivers/interconnect/core.c | 13 +
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
index 6005a1c189f6..871eb4bc4efc 100644
--- a/drivers/interconnect/core.c
+++ b/drivers/interconnect/core.c
@@ -90,18 +90,7 @@ static int icc_summary_show(struct seq_file *s, void *data)
 
return 0;
 }
-
-static int icc_summary_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, icc_summary_show, inode->i_private);
-}
-
-static const struct file_operations icc_summary_fops = {
-   .open   = icc_summary_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(icc_summary);
 
 static struct icc_node *node_find(const int id)
 {
-- 
2.17.0



[PATCH v2 0/5] nvmem: sunxi-sid: add SID controller support for H6

2019-04-02 Thread Yangtao Li
Add SID support for H6, and do some cleanup.
For endianness issue, add a new ref_read func.

Yangtao Li (5):
  nvmem: sunxi-sid: fix wrong description in kernel doc
  nvmem: sunxi-sid: add binding for H6's SID controller
  nvmem: sunxi-sid: convert to SPDX license tags
  nvmem: sunxi-sid: add new reg_read func
  nvmem: sunxi-sid: add support for H6's SID controller
---
v2:
-add a new ref_read func
-only support H6 now
---
 .../bindings/nvmem/allwinner,sunxi-sid.txt|  3 +-
 drivers/nvmem/sunxi_sid.c | 47 +++
 2 files changed, 39 insertions(+), 11 deletions(-)

-- 
2.17.0



[PATCH v2 2/5] nvmem: sunxi-sid: add binding for H6's SID controller

2019-04-02 Thread Yangtao Li
Add a binding for H6's SID controller.

Acked-by: Maxime Ripard 
Reviewed-by: Rob Herring 
Signed-off-by: Yangtao Li 
---
 Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt 
b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
index d37017e343b1..cfb18b4ef8f7 100644
--- a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
+++ b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
@@ -8,6 +8,7 @@ Required properties:
   "allwinner,sun8i-h3-sid"
   "allwinner,sun50i-a64-sid"
   "allwinner,sun50i-h5-sid"
+  "allwinner,sun50i-h6-sid"
 
 - reg: Should contain registers location and length
 
-- 
2.17.0



[PATCH v2 3/5] nvmem: sunxi-sid: convert to SPDX license tags

2019-04-02 Thread Yangtao Li
Updates license to use SPDX-License-Identifier.

Acked-by: Maxime Ripard 
Signed-off-by: Yangtao Li 
---
 drivers/nvmem/sunxi_sid.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 570a2e354f30..54620d72ddb9 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Allwinner sunXi SoCs Security ID support.
  *
  * Copyright (c) 2013 Oliver Schinagl 
  * Copyright (C) 2014 Maxime Ripard 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include 
-- 
2.17.0



[PATCH v2 4/5] nvmem: sunxi-sid: add new reg_read func

2019-04-02 Thread Yangtao Li
Because there was an endianness issue. It seems that reg_read
function which the nvmem the driver currently exposes is wrong.
So add the new read function, the new function is used when the
native_endian flag is set.

Signed-off-by: Yangtao Li 
---
 drivers/nvmem/sunxi_sid.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 54620d72ddb9..5b8a42f686cd 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -37,6 +37,7 @@ struct sunxi_sid_cfg {
u32 value_offset;
u32 size;
boolneed_register_readout;
+   boolnative_endian;
 };
 
 struct sunxi_sid {
@@ -75,6 +76,31 @@ static int sunxi_sid_read(void *context, unsigned int offset,
return 0;
 }
 
+static u8 sunxi_sid_read_byte_native(const struct sunxi_sid *sid,
+ const unsigned int offset)
+{
+   u32 sid_key;
+
+   sid_key = ioread32(sid->base + round_down(offset, 4));
+   sid_key >>= (offset % 4) * 8;
+
+   return sid_key;
+}
+
+static int sunxi_sid_read_native(void *context, unsigned int offset,
+ void *val, size_t bytes)
+{
+   struct sunxi_sid *sid = context;
+   u8 *buf = val;
+
+   offset += sid->value_offset;
+
+   while (bytes--)
+   *buf++ = sunxi_sid_read_byte_native(sid, offset++);
+
+   return 0;
+}
+
 static int sun8i_sid_register_readout(const struct sunxi_sid *sid,
  const unsigned int offset,
  u32 *out)
@@ -169,9 +195,12 @@ static int sunxi_sid_probe(struct platform_device *pdev)
econfig.dev = dev;
if (cfg->need_register_readout)
econfig.reg_read = sun8i_sid_read_by_reg;
+   else if (cfg->native_endian)
+   econfig.reg_read = sunxi_sid_read_native;
else
econfig.reg_read = sunxi_sid_read;
econfig.priv = sid;
+
nvmem = devm_nvmem_register(dev, );
if (IS_ERR(nvmem))
return PTR_ERR(nvmem);
-- 
2.17.0



[PATCH v2 5/5] nvmem: sunxi-sid: add support for H6's SID controller

2019-04-02 Thread Yangtao Li
Add support for H6's SID controller. It supports 4K-bit
EFUSE, bigger than before. And convert to use sunxi_sid_read_native
func.

Signed-off-by: Yangtao Li 
---
 drivers/nvmem/sunxi_sid.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 5b8a42f686cd..3c2b06140490 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -239,11 +239,18 @@ static const struct sunxi_sid_cfg sun50i_a64_cfg = {
.size = 0x100,
 };
 
+static const struct sunxi_sid_cfg sun50i_h6_cfg = {
+   .value_offset = 0x200,
+   .size = 0x200,
+   .native_endian = true,
+};
+
 static const struct of_device_id sunxi_sid_of_match[] = {
{ .compatible = "allwinner,sun4i-a10-sid", .data = _a10_cfg },
{ .compatible = "allwinner,sun7i-a20-sid", .data = _a20_cfg },
{ .compatible = "allwinner,sun8i-h3-sid", .data = _h3_cfg },
{ .compatible = "allwinner,sun50i-a64-sid", .data = _a64_cfg },
+   { .compatible = "allwinner,sun50i-h6-sid", .data = _h6_cfg },
{/* sentinel */},
 };
 MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
-- 
2.17.0



[PATCH v2 1/5] nvmem: sunxi-sid: fix wrong description in kernel doc

2019-04-02 Thread Yangtao Li
qfprom->sunxi-sid

Acked-by: Maxime Ripard 
Reviewed-by: Rob Herring 
Signed-off-by: Yangtao Li 
---
 Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt 
b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
index 99c4ba6a3f61..d37017e343b1 100644
--- a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
+++ b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
@@ -12,7 +12,7 @@ Required properties:
 - reg: Should contain registers location and length
 
 = Data cells =
-Are child nodes of qfprom, bindings of which as described in
+Are child nodes of sunxi-sid, bindings of which as described in
 bindings/nvmem/nvmem.txt
 
 Example for sun4i:
-- 
2.17.0



[PATCH v2 1/2] cpufreq: Add sunxi nvmem based CPU scaling driver

2019-04-09 Thread Yangtao Li
For some SoCs, the CPU frequency subset and voltage value of each OPP
varies based on the silicon variant in use. The sunxi-cpufreq-nvmem
driver reads the efuse value from the SoC to provide the OPP framework
with required information.

Signed-off-by: Yangtao Li 
---
 MAINTAINERS   |   7 +
 drivers/cpufreq/Kconfig.arm   |  10 ++
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c  |   2 +
 drivers/cpufreq/sunxi-cpufreq-nvmem.c | 234 ++
 5 files changed, 254 insertions(+)
 create mode 100644 drivers/cpufreq/sunxi-cpufreq-nvmem.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 391405091c6b..bfd18ba6aa1a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -667,6 +667,13 @@ S: Maintained
 F: Documentation/i2c/busses/i2c-ali1563
 F: drivers/i2c/busses/i2c-ali1563.c
 
+ALLWINNER CPUFREQ DRIVER
+M: Yangtao Li 
+L: linux...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
+F: drivers/cpufreq/sunxi-cpufreq-nvmem.c
+
 ALLWINNER SECURITY SYSTEM
 M: Corentin Labbe 
 L: linux-cry...@vger.kernel.org
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 179a1d302f48..25933c4321a7 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -18,6 +18,16 @@ config ACPI_CPPC_CPUFREQ
 
  If in doubt, say N.
 
+config ARM_ALLWINNER_CPUFREQ_NVMEM
+   tristate "Allwinner nvmem based CPUFreq"
+   depends on ARCH_SUNXI
+   depends on NVMEM_SUNXI_SID
+   select PM_OPP
+   help
+ This adds the CPUFreq driver for Allwinner nvmem based SoC.
+
+ If in doubt, say N.
+
 config ARM_ARMADA_37XX_CPUFREQ
tristate "Armada 37xx CPUFreq support"
depends on ARCH_MVEBU && CPUFREQ_DT
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 689b26c6f949..da28de67613c 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_ARM_SCMI_CPUFREQ)+= 
scmi-cpufreq.o
 obj-$(CONFIG_ARM_SCPI_CPUFREQ) += scpi-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)+= spear-cpufreq.o
 obj-$(CONFIG_ARM_STI_CPUFREQ)  += sti-cpufreq.o
+obj-$(CONFIG_ARM_ALLWINNER_CPUFREQ_NVMEM) += sunxi-cpufreq-nvmem.o
 obj-$(CONFIG_ARM_TANGO_CPUFREQ)+= tango-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)  += tegra20-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c 
b/drivers/cpufreq/cpufreq-dt-platdev.c
index 47729a22c159..50e7810f3a28 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -105,6 +105,8 @@ static const struct of_device_id whitelist[] __initconst = {
  * platforms using "operating-points-v2" property.
  */
 static const struct of_device_id blacklist[] __initconst = {
+   { .compatible = "allwinner,sun50i-h6", },
+
{ .compatible = "calxeda,highbank", },
{ .compatible = "calxeda,ecx-2000", },
 
diff --git a/drivers/cpufreq/sunxi-cpufreq-nvmem.c 
b/drivers/cpufreq/sunxi-cpufreq-nvmem.c
new file mode 100644
index ..a72caac572c4
--- /dev/null
+++ b/drivers/cpufreq/sunxi-cpufreq-nvmem.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner CPUFreq nvmem based driver
+ *
+ * The sunxi-cpufreq-nvmem driver reads the efuse value from the SoC to
+ * provide the OPP framework with required information.
+ *
+ * Copyright (C) 2019 Yangtao Li 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MAX_NAME_LEN  7
+
+struct sunxi_cpufreq_soc_data {
+   u32 (*efuse_xlate)(const struct sunxi_cpufreq_soc_data *soc_data,
+  u32 efuse);
+   u32 nvmem_mask;
+   u32 nvmem_shift;
+};
+
+static struct platform_device *cpufreq_dt_pdev, *sunxi_cpufreq_pdev;
+
+static u32 sun50i_efuse_xlate(const struct sunxi_cpufreq_soc_data *soc_data,
+ u32 efuse)
+{
+   return (efuse >> soc_data->nvmem_shift) & soc_data->nvmem_mask;
+}
+
+/**
+ * sunxi_cpufreq_get_efuse() - Parse and return efuse value present on SoC
+ * @soc_data: Pointer to sunxi_cpufreq_soc_data context
+ * @versions: Set to the value parsed from efuse
+ *
+ * Returns 0 if success.
+ */
+static int sunxi_cpufreq_get_efuse(const struct sunxi_cpufreq_soc_data 
*soc_data,
+  u32 *versions)
+{
+   struct nvmem_cell *speedbin_nvmem;
+   struct device_node *np;
+   struct device *cpu_dev;
+   u32 *speedbin;
+   size_t len;
+   int ret;
+
+   cpu_dev = get_cpu_device(0);
+   if (!cpu_dev)
+   return -ENODEV;
+
+   np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+   if (!np)
+   

[PATCH v2 0/2] cpufreq: Add sunxi nvmem based CPU scaling driver

2019-04-09 Thread Yangtao Li
Add sunxi nvmem based CPU scaling driver, refers to qcom-cpufreq-kryo.

Yangtao Li (2):
  cpufreq: Add sunxi nvmem based CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-sunxi-cpu

 .../bindings/opp/sunxi-nvmem-cpufreq.txt  | 166 +
 MAINTAINERS   |   7 +
 drivers/cpufreq/Kconfig.arm   |  10 +
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c  |   2 +
 drivers/cpufreq/sunxi-cpufreq-nvmem.c | 234 ++
 6 files changed, 420 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
 create mode 100644 drivers/cpufreq/sunxi-cpufreq-nvmem.c

---
v2:
-update changelog
-convert to dev_pm_opp_set_prop_name use instead of dev_pm_opp_set_supported_hw
-some change in OPP Node 
---
2.17.0



[PATCH v2 2/2] dt-bindings: cpufreq: Document operating-points-v2-sunxi-cpu

2019-04-09 Thread Yangtao Li
Allwinner Process Voltage Scaling Tables defines the voltage and
frequency value  based on the speedbin blown in the efuse combination.
The sunxi-cpufreq-nvmem driver reads the efuse value from the SoC to
provide the OPP framework with required information.
This is used to determine the voltage and frequency value for each
OPP of operating-points-v2 table when it is parsed by the OPP framework.

The "operating-points-v2-sunxi-cpu" DT extends the "operating-points-v2"
with following parameters:
- nvmem-cells (NVMEM area containig the speedbin information)
- opp-microvolt-: voltage in micro Volts.
  At runtime, the platform can pick a  and matching
  opp-microvolt- property

Signed-off-by: Yangtao Li 
---
 .../bindings/opp/sunxi-nvmem-cpufreq.txt  | 166 ++
 1 file changed, 166 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt

diff --git a/Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt 
b/Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
new file mode 100644
index ..c81a2075b974
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
@@ -0,0 +1,166 @@
+Allwinner Technologies, Inc. NVMEM CPUFreq and OPP bindings
+===
+
+For some SoCs, the CPU frequency subset and voltage value of each OPP
+varies based on the silicon variant in use. Allwinner Process Voltage
+Scaling Tables defines the voltage and frequency value  based on the
+speedbin blown in the efuse combination. The sunxi-cpufreq-nvmem driver
+reads the efuse value from the SoC to provide the OPP framework with
+required information.
+
+Required properties:
+
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be
+   - 'operating-points-v2-sunxi-cpu'.
+- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
+   efuse registers that has information about the
+   speedbin that is used to select the right frequency/voltage
+   value pair.
+   Please refer the for nvmem-cells
+   bindings Documentation/devicetree/bindings/nvmem/nvmem.txt
+   and also examples below.
+
+In every OPP node:
+- opp-microvolt-: Voltage in micro Volts.
+   At runtime, the platform can pick a  and
+   matching opp-microvolt- property.
+   [See: opp.txt]
+
+Example 1:
+-
+
+   cpus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   cpu0: cpu@0 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <0>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu1: cpu@1 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <1>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu2: cpu@2 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <2>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu3: cpu@3 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <3>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+};
+
+cpu_opp_table: opp_table {
+compatible = "operating-points-v2-sunxi-cpu";
+nvmem-cells = <_efuse>;
+opp-shared;
+
+opp@4

[PATCH v3 0/2] cpufreq: Add sunxi nvmem based CPU scaling driver

2019-04-10 Thread Yangtao Li
Add sunxi nvmem based CPU scaling driver, refers to qcom-cpufreq-kryo.

Yangtao Li (2):
  cpufreq: Add sunxi nvmem based CPU scaling driver
  dt-bindings: cpufreq: Document allwinner,cpu-operating-points-v2

 .../bindings/opp/sunxi-nvmem-cpufreq.txt  | 168 +
 MAINTAINERS   |   7 +
 drivers/cpufreq/Kconfig.arm   |  10 +
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c  |   2 +
 drivers/cpufreq/sunxi-cpufreq-nvmem.c | 232 ++
 6 files changed, 420 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
 create mode 100644 drivers/cpufreq/sunxi-cpufreq-nvmem.c

---
v3:
-update changelog and title
-convert compatibles to allwinner,cpu-operating-points-v2
-document the valid names for opp-microvolt-
v2:
-update changelog
-convert to dev_pm_opp_set_prop_name instead of
 dev_pm_opp_set_supported_hw
-some change in OPP Node 
---
2.17.0



[PATCH v3 1/2] cpufreq: Add sunxi nvmem based CPU scaling driver

2019-04-10 Thread Yangtao Li
For some SoCs, the CPU frequency subset and voltage value of each OPP
varies based on the silicon variant in use. The sunxi-cpufreq-nvmem
driver reads the efuse value from the SoC to provide the OPP framework
with required information.

Signed-off-by: Yangtao Li 
---
 MAINTAINERS   |   7 +
 drivers/cpufreq/Kconfig.arm   |  10 ++
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c  |   2 +
 drivers/cpufreq/sunxi-cpufreq-nvmem.c | 232 ++
 5 files changed, 252 insertions(+)
 create mode 100644 drivers/cpufreq/sunxi-cpufreq-nvmem.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 391405091c6b..bfd18ba6aa1a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -667,6 +667,13 @@ S: Maintained
 F: Documentation/i2c/busses/i2c-ali1563
 F: drivers/i2c/busses/i2c-ali1563.c
 
+ALLWINNER CPUFREQ DRIVER
+M: Yangtao Li 
+L: linux...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
+F: drivers/cpufreq/sunxi-cpufreq-nvmem.c
+
 ALLWINNER SECURITY SYSTEM
 M: Corentin Labbe 
 L: linux-cry...@vger.kernel.org
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 179a1d302f48..25933c4321a7 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -18,6 +18,16 @@ config ACPI_CPPC_CPUFREQ
 
  If in doubt, say N.
 
+config ARM_ALLWINNER_CPUFREQ_NVMEM
+   tristate "Allwinner nvmem based CPUFreq"
+   depends on ARCH_SUNXI
+   depends on NVMEM_SUNXI_SID
+   select PM_OPP
+   help
+ This adds the CPUFreq driver for Allwinner nvmem based SoC.
+
+ If in doubt, say N.
+
 config ARM_ARMADA_37XX_CPUFREQ
tristate "Armada 37xx CPUFreq support"
depends on ARCH_MVEBU && CPUFREQ_DT
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 689b26c6f949..da28de67613c 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_ARM_SCMI_CPUFREQ)+= 
scmi-cpufreq.o
 obj-$(CONFIG_ARM_SCPI_CPUFREQ) += scpi-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)+= spear-cpufreq.o
 obj-$(CONFIG_ARM_STI_CPUFREQ)  += sti-cpufreq.o
+obj-$(CONFIG_ARM_ALLWINNER_CPUFREQ_NVMEM) += sunxi-cpufreq-nvmem.o
 obj-$(CONFIG_ARM_TANGO_CPUFREQ)+= tango-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)  += tegra20-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c 
b/drivers/cpufreq/cpufreq-dt-platdev.c
index 47729a22c159..50e7810f3a28 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -105,6 +105,8 @@ static const struct of_device_id whitelist[] __initconst = {
  * platforms using "operating-points-v2" property.
  */
 static const struct of_device_id blacklist[] __initconst = {
+   { .compatible = "allwinner,sun50i-h6", },
+
{ .compatible = "calxeda,highbank", },
{ .compatible = "calxeda,ecx-2000", },
 
diff --git a/drivers/cpufreq/sunxi-cpufreq-nvmem.c 
b/drivers/cpufreq/sunxi-cpufreq-nvmem.c
new file mode 100644
index ..6bf4755d00d9
--- /dev/null
+++ b/drivers/cpufreq/sunxi-cpufreq-nvmem.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner CPUFreq nvmem based driver
+ *
+ * The sunxi-cpufreq-nvmem driver reads the efuse value from the SoC to
+ * provide the OPP framework with required information.
+ *
+ * Copyright (C) 2019 Yangtao Li 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MAX_NAME_LEN  7
+
+struct sunxi_cpufreq_soc_data {
+   u32 (*efuse_xlate)(const struct sunxi_cpufreq_soc_data *soc_data,
+  u32 efuse);
+   u32 nvmem_mask;
+   u32 nvmem_shift;
+};
+
+static struct platform_device *cpufreq_dt_pdev, *sunxi_cpufreq_pdev;
+
+static u32 sun50i_efuse_xlate(const struct sunxi_cpufreq_soc_data *soc_data,
+ u32 efuse)
+{
+   return (efuse >> soc_data->nvmem_shift) & soc_data->nvmem_mask;
+}
+
+/**
+ * sunxi_cpufreq_get_efuse() - Parse and return efuse value present on SoC
+ * @soc_data: Pointer to sunxi_cpufreq_soc_data context
+ * @versions: Set to the value parsed from efuse
+ *
+ * Returns 0 if success.
+ */
+static int sunxi_cpufreq_get_efuse(const struct sunxi_cpufreq_soc_data 
*soc_data,
+  u32 *versions)
+{
+   struct nvmem_cell *speedbin_nvmem;
+   struct device_node *np;
+   struct device *cpu_dev;
+   u32 *speedbin;
+   size_t len;
+   int ret;
+
+   cpu_dev = get_cpu_device(0);
+   if (!cpu_dev)
+   return -ENODEV;
+
+   np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+   if (!np)
+   

[PATCH v3 2/2] dt-bindings: cpufreq: Document allwinner,cpu-operating-points-v2

2019-04-10 Thread Yangtao Li
Allwinner Process Voltage Scaling Tables defines the voltage and
frequency value based on the speedbin blown in the efuse combination.
The sunxi-cpufreq-nvmem driver reads the efuse value from the SoC to
provide the OPP framework with required information.
This is used to determine the voltage and frequency value for each
OPP of operating-points-v2 table when it is parsed by the OPP framework.

The "allwinner,cpu-operating-points-v2" DT extends the "operating-points-v2"
with following parameters:
- nvmem-cells (NVMEM area containig the speedbin information)
- opp-microvolt-: voltage in micro Volts.
  At runtime, the platform can pick a  and matching
  opp-microvolt- property.
HW: :
sun50iw-h6  speed0 speed1 speed2

Signed-off-by: Yangtao Li 
---
 .../bindings/opp/sunxi-nvmem-cpufreq.txt  | 168 ++
 1 file changed, 168 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt

diff --git a/Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt 
b/Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
new file mode 100644
index ..9a1826724b47
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
@@ -0,0 +1,168 @@
+Allwinner Technologies, Inc. NVMEM CPUFreq and OPP bindings
+===
+
+For some SoCs, the CPU frequency subset and voltage value of each OPP
+varies based on the silicon variant in use. Allwinner Process Voltage
+Scaling Tables defines the voltage and frequency value based on the
+speedbin blown in the efuse combination. The sunxi-cpufreq-nvmem driver
+reads the efuse value from the SoC to provide the OPP framework with
+required information.
+
+Required properties:
+
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be
+   - 'allwinner,cpu-operating-points-v2'.
+- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
+   efuse registers that has information about the
+   speedbin that is used to select the right frequency/voltage
+   value pair.
+   Please refer the for nvmem-cells
+   bindings Documentation/devicetree/bindings/nvmem/nvmem.txt
+   and also examples below.
+
+In every OPP node:
+- opp-microvolt-: Voltage in micro Volts.
+   At runtime, the platform can pick a  and
+   matching opp-microvolt- property.
+   [See: opp.txt]
+   HW: :
+   sun50iw-h6  speed0 speed1 speed2
+
+Example 1:
+-
+
+   cpus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   cpu0: cpu@0 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <0>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu1: cpu@1 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <1>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu2: cpu@2 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <2>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu3: cpu@3 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <3>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+   

[RESEND 1/2] nvmem: sunxi_sid: Support SID on H6

2019-04-04 Thread Yangtao Li
Add support for H6's SID controller. It supports 4K-bit
EFUSE, bigger than before.

Signed-off-by: Yangtao Li 
---
 drivers/nvmem/sunxi_sid.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 7013f9cc43c7..a079a80ddf2c 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -188,6 +188,11 @@ static const struct sunxi_sid_cfg sun50i_a64_cfg = {
.size = 0x100,
 };
 
+static const struct sunxi_sid_cfg sun50i_h6_cfg = {
+   .value_offset = 0x200,
+   .size = 0x200,
+};
+
 static const struct of_device_id sunxi_sid_of_match[] = {
{ .compatible = "allwinner,sun4i-a10-sid", .data = _a10_cfg },
{ .compatible = "allwinner,sun7i-a20-sid", .data = _a20_cfg },
@@ -195,6 +200,7 @@ static const struct of_device_id sunxi_sid_of_match[] = {
{ .compatible = "allwinner,sun8i-h3-sid", .data = _h3_cfg },
{ .compatible = "allwinner,sun50i-a64-sid", .data = _a64_cfg },
{ .compatible = "allwinner,sun50i-h5-sid", .data = _a64_cfg },
+   { .compatible = "allwinner,sun50i-h6-sid", .data = _h6_cfg },
{/* sentinel */},
 };
 MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
-- 
2.17.0



[RESEND 2/2] arm64: dts: sunxi: h6: Add device node for SID

2019-04-04 Thread Yangtao Li
The device tree binding already lists compatible strings for H6
SoCs, so add a device node for iy.

Signed-off-by: Yangtao Li 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index c9e861a50a63..cbeb587d2eed 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -192,6 +192,11 @@
#reset-cells = <1>;
};
 
+   sid: sid@3006000 {
+   compatible = "allwinner,sun50i-h6-sid";
+   reg = <0x3006000 0x400>;
+   };
+
pio: pinctrl@300b000 {
compatible = "allwinner,sun50i-h6-pinctrl";
reg = <0x0300b000 0x400>;
-- 
2.17.0



[RESEND 0/2] nvmem: sunxi-sid: add SID controller support for H6

2019-04-04 Thread Yangtao Li
Add SID's support for H6.

Yangtao Li (2):
  nvmem: sunxi_sid: Support SID on H6
  arm64: dts: sunxi: h6: Add device node for SID

 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 5 +
 drivers/nvmem/sunxi_sid.c| 6 ++
 2 files changed, 11 insertions(+)

-- 
2.17.0



[RESEND 2/2] arm64: dts: sunxi: h6: Add device node for SID

2019-04-04 Thread Yangtao Li
The device tree binding already lists compatible strings for H6
SoC, so add a device node for it.

Signed-off-by: Yangtao Li 
---
fix typo:
iy->it
0x3006000->0x03006000
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index c9e861a50a63..cbeb587d2eed 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -192,6 +192,11 @@
#reset-cells = <1>;
};
 
+   sid: sid@3006000 {
+   compatible = "allwinner,sun50i-h6-sid";
+   reg = <0x03006000 0x400>;
+   };
+
pio: pinctrl@300b000 {
compatible = "allwinner,sun50i-h6-pinctrl";
reg = <0x0300b000 0x400>;
-- 
2.17.0



[PATCH 2/2] dt-bindings: cpufreq: Document operating-points-v2-sunxi-cpu

2019-04-05 Thread Yangtao Li
Allwinner Process Voltage Scaling Tables defines the voltage and
frequency value  based on the speedbin blown in the efuse combination.
The sunxi-cpufreq-nvmem driver reads the efuse value from the SoC to
provide the OPP framework with required information.
This is used to determine the voltage and frequency value for each
OPP of operating-points-v2 table when it is parsed by the OPP framework.

This change adds documentation for the DT bindings.
The "operating-points-v2-sunxi-cpu" DT extends the "operating-points-v2"
with following parameters:
- nvmem-cells (NVMEM area containig the speedbin information)
- opp-supported-hw: A single 32 bit bitmap value,
  representing compatible HW:
0:  speedbin 0
1:  speedbin 1
2:  speedbin 2
3-31:   unused

Signed-off-by: Yangtao Li 
---
 .../bindings/opp/sunxi-nvmem-cpufreq.txt  | 235 ++
 1 file changed, 235 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt

diff --git a/Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt 
b/Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
new file mode 100644
index ..80201d4e5147
--- /dev/null
+++ b/Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
@@ -0,0 +1,235 @@
+Allwinner Technologies, Inc. NVMEM CPUFreq and OPP bindings
+===
+
+For some SoCs, the CPU frequency subset and voltage value of each OPP
+varies based on the silicon variant in use. Allwinner Process Voltage
+Scaling Tables defines the voltage and frequency value  based on the
+speedbin blown in the efuse combination. The sunxi-cpufreq-nvmem driver
+reads the efuse value from the SoC to provide the OPP framework with
+required information.
+
+Required properties:
+
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be
+   - 'operating-points-v2-sunxi-cpu'.
+- nvmem-cells: A phandle pointing to a nvmem-cells node representing the
+   efuse registers that has information about the
+   speedbin that is used to select the right frequency/voltage
+   value pair.
+   Please refer the for nvmem-cells
+   bindings Documentation/devicetree/bindings/nvmem/nvmem.txt
+   and also examples below.
+
+In every OPP node:
+- opp-supported-hw: A single 32 bit bitmap value, representing compatible HW.
+   Bitmap:
+   0:  speedbin 0
+   1:  speedbin 1
+   2:  speedbin 2
+   3-31:   unused
+
+Example 1:
+-
+
+   cpus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   cpu0: cpu@0 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <0>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu1: cpu@1 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <1>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu2: cpu@2 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <2>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+
+   cpu3: cpu@3 {
+   compatible = "arm,cortex-a53";
+   device_type = "cpu";
+   reg = <3>;
+   enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <

[PATCH 0/2] cpufreq: Add sunxi nvmem based CPU scaling driver

2019-04-05 Thread Yangtao Li
Add sunxi nvmem based CPU scaling driver, refers to qcom-cpufreq-kryo.

Yangtao Li (2):
  cpufreq: Add sunxi nvmem based CPU scaling driver
  dt-bindings: cpufreq: Document operating-points-v2-sunxi-cpu

 .../bindings/opp/sunxi-nvmem-cpufreq.txt  | 235 +
 MAINTAINERS   |   7 +
 drivers/cpufreq/Kconfig.arm   |  10 +
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c  |   2 +
 drivers/cpufreq/sunxi-cpufreq-nvmem.c | 236 ++
 6 files changed, 491 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
 create mode 100644 drivers/cpufreq/sunxi-cpufreq-nvmem.c

-- 
2.17.0



[PATCH 1/2] cpufreq: Add sunxi nvmem based CPU scaling driver

2019-04-05 Thread Yangtao Li
For some SoCs, the CPU frequency subset and voltage value of each OPP
varies based on the silicon variant in use. Allwinner Process Voltage
Scaling Tables defines the voltage and frequency value  based on the
speedbin blown in the efuse combination. The sunxi-cpufreq-nvmem driver
reads the efuse value from the SoC to provide the OPP framework with
required information.

Signed-off-by: Yangtao Li 
---
 MAINTAINERS   |   7 +
 drivers/cpufreq/Kconfig.arm   |  10 ++
 drivers/cpufreq/Makefile  |   1 +
 drivers/cpufreq/cpufreq-dt-platdev.c  |   2 +
 drivers/cpufreq/sunxi-cpufreq-nvmem.c | 236 ++
 5 files changed, 256 insertions(+)
 create mode 100644 drivers/cpufreq/sunxi-cpufreq-nvmem.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 391405091c6b..bfd18ba6aa1a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -667,6 +667,13 @@ S: Maintained
 F: Documentation/i2c/busses/i2c-ali1563
 F: drivers/i2c/busses/i2c-ali1563.c
 
+ALLWINNER CPUFREQ DRIVER
+M: Yangtao Li 
+L: linux...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/opp/sunxi-nvmem-cpufreq.txt
+F: drivers/cpufreq/sunxi-cpufreq-nvmem.c
+
 ALLWINNER SECURITY SYSTEM
 M: Corentin Labbe 
 L: linux-cry...@vger.kernel.org
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 179a1d302f48..25933c4321a7 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -18,6 +18,16 @@ config ACPI_CPPC_CPUFREQ
 
  If in doubt, say N.
 
+config ARM_ALLWINNER_CPUFREQ_NVMEM
+   tristate "Allwinner nvmem based CPUFreq"
+   depends on ARCH_SUNXI
+   depends on NVMEM_SUNXI_SID
+   select PM_OPP
+   help
+ This adds the CPUFreq driver for Allwinner nvmem based SoC.
+
+ If in doubt, say N.
+
 config ARM_ARMADA_37XX_CPUFREQ
tristate "Armada 37xx CPUFreq support"
depends on ARCH_MVEBU && CPUFREQ_DT
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 689b26c6f949..da28de67613c 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_ARM_SCMI_CPUFREQ)+= 
scmi-cpufreq.o
 obj-$(CONFIG_ARM_SCPI_CPUFREQ) += scpi-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)+= spear-cpufreq.o
 obj-$(CONFIG_ARM_STI_CPUFREQ)  += sti-cpufreq.o
+obj-$(CONFIG_ARM_ALLWINNER_CPUFREQ_NVMEM) += sunxi-cpufreq-nvmem.o
 obj-$(CONFIG_ARM_TANGO_CPUFREQ)+= tango-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)  += tegra20-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c 
b/drivers/cpufreq/cpufreq-dt-platdev.c
index 47729a22c159..50e7810f3a28 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -105,6 +105,8 @@ static const struct of_device_id whitelist[] __initconst = {
  * platforms using "operating-points-v2" property.
  */
 static const struct of_device_id blacklist[] __initconst = {
+   { .compatible = "allwinner,sun50i-h6", },
+
{ .compatible = "calxeda,highbank", },
{ .compatible = "calxeda,ecx-2000", },
 
diff --git a/drivers/cpufreq/sunxi-cpufreq-nvmem.c 
b/drivers/cpufreq/sunxi-cpufreq-nvmem.c
new file mode 100644
index ..e189f94592d5
--- /dev/null
+++ b/drivers/cpufreq/sunxi-cpufreq-nvmem.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner CPUFreq nvmem based driver
+ *
+ * Copyright (C) 2019 Yangtao Li 
+ */
+
+/*
+ * For some SoCs, the CPU frequency subset and voltage value of each OPP
+ * varies based on the silicon variant in use. Allwinner Process Voltage
+ * Scaling Tables defines the voltage and frequency value  based on the
+ * speedbin blown in the efuse combination. The sunxi-cpufreq-nvmem driver
+ * reads the efuse value from the SoC to provide the OPP framework with
+ * required information.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct sunxi_cpufreq_soc_data {
+   u32 (*efuse_xlate)(const struct sunxi_cpufreq_soc_data *soc_data,
+  u32 efuse);
+   u32 nvmem_mask;
+   u32 nvmem_shift;
+};
+
+static struct platform_device *cpufreq_dt_pdev, *sunxi_cpufreq_pdev;
+
+static u32 sun50i_efuse_xlate(const struct sunxi_cpufreq_soc_data *soc_data,
+ u32 efuse)
+{
+   return 1 << (efuse >> soc_data->nvmem_shift) & soc_data->nvmem_mask;
+}
+
+/**
+ * sunxi_cpufreq_get_efuse() - Parse and return efuse value present on SoC
+ * @soc_data: pointer to sunxi_cpufreq_soc_data context
+ * @versions: Set to the value parsed from efuse
+ *
+ * Returns 0 if success.
+ */
+static int sunxi_cpufreq_get_efuse(const struct sunxi_cpufreq_soc_data 
*soc_data,
+ 

[PATVH v2 2/4] arm64: dts: allwinner: h6: pine: Add CPU supply regulator

2019-02-15 Thread Yangtao Li
The original pine use the dcdca to supply the CPU cores. According
to the axp805 spec, the range of dcdca is 0.6 to 1.1v, 1.12 to 1.52v.
In order to support more CPU frequency, slightly increase the voltage
maximum and minimum.

In fact, in sunxi's sdk, the actual minimum and maximum voltage of the
cpu is smaller or larger than the datasheet.

For some better quality ic, the minimum voltage can be smaller. For
some poor quality ic, the maximum voltage needs to be increased a
little.

Signed-off-by: Yangtao Li 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
index bdb8470fc8dc..95c81250c2b3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
@@ -213,8 +213,8 @@
 
reg_dcdca: dcdca {
regulator-always-on;
-   regulator-min-microvolt = <81>;
-   regulator-max-microvolt = <108>;
+   regulator-min-microvolt = <80>;
+   regulator-max-microvolt = <116>;
regulator-name = "vdd-cpu";
};
 
@@ -251,6 +251,10 @@
};
 };
 
+ {
+   cpu-supply = <_dcdca>;
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_ph_pins>;
-- 
2.17.0



[PATVH v2 4/4] arm64: dts: allwinner: h6: Add CPU Operating Performance Points table

2019-02-15 Thread Yangtao Li
Add an OPP (Operating Performance Points) table for the CPU cores to
enable DVFS (Dynamic Voltage & Frequency Scaling) on the H6. This
information comes from github.

When the four CPUs are running at 1.8 GHz, 100% busy, it is easy to heat
up and make the system restart. And currently H6 does not support the
thermal driver, can not get the temperature information of the cpu to
control the highest frequency. So temporarily remove the opp of 1.8GHz.

When the four CPUs operate at 1.4 GHz, 100% busy, the temperature is
stable at about 90 degrees, and the system can still operate normally.

Signed-off-by: Yangtao Li 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 55 
 1 file changed, 55 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 723f5d991a74..84fb47062fe6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -28,6 +28,8 @@
enable-method = "psci";
clocks = < CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
};
 
cpu1: cpu@1 {
@@ -37,6 +39,8 @@
enable-method = "psci";
clocks = < CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
};
 
cpu2: cpu@2 {
@@ -46,6 +50,8 @@
enable-method = "psci";
clocks = < CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
};
 
cpu3: cpu@3 {
@@ -55,6 +61,55 @@
enable-method = "psci";
clocks = < CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+   };
+
+   cpu_opp_table: opp_table {
+   compatible = "operating-points-v2";
+   opp-shared;
+
+   opp@48000 {
+   opp-hz = /bits/ 64 <48000>;
+   opp-microvolt = <80 80 88>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@72000 {
+   opp-hz = /bits/ 64 <72000>;
+   opp-microvolt = <80 80 88>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@81600 {
+   opp-hz = /bits/ 64 <81600>;
+   opp-microvolt = <80 80 88>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@88800 {
+   opp-hz = /bits/ 64 <88800>;
+   opp-microvolt = <80 80 94>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@108000 {
+   opp-hz = /bits/ 64 <108000>;
+   opp-microvolt = <84 84 106>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@132000 {
+   opp-hz = /bits/ 64 <132000>;
+   opp-microvolt = <90 90 116>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@148800 {
+   opp-hz = /bits/ 64 <148800>;
+   opp-microvolt = <96 96 116>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
};
 
-- 
2.17.0



[PATVH v2 1/4] arm64: dts: allwinner: h6: orangepi: Add CPU supply regulator

2019-02-15 Thread Yangtao Li
The original orangepi use the dcdca to supply the CPU cores. According
to the axp805 spec, the range of dcdca is 0.6 to 1.1v, 1.12 to 1.52v.
In order to support more CPU frequency, slightly increase the voltage
maximum and minimum.

In fact, in sunxi's sdk, the actual minimum and maximum voltage of the
cpu is smaller or larger than the datasheet.

For some better quality ic, the minimum voltage can be smaller.
For some poor quality ic, the maximum voltage needs to be increased a
little.

Signed-off-by: Yangtao Li 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
index b2526dac2fcf..e7aebaf91ede 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
@@ -159,8 +159,8 @@
 
reg_dcdca: dcdca {
regulator-always-on;
-   regulator-min-microvolt = <81>;
-   regulator-max-microvolt = <108>;
+   regulator-min-microvolt = <80>;
+   regulator-max-microvolt = <116>;
regulator-name = "vdd-cpu";
};
 
@@ -191,6 +191,10 @@
};
 };
 
+ {
+   cpu-supply = <_dcdca>;
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_ph_pins>;
-- 
2.17.0



[PATVH v2 0/4] arm64: dts: allwinner: h6: Enable CPU

2019-02-15 Thread Yangtao Li
Add the cpufreq support of h6, source of information is as follows.

h6 cpu opp info:
https://github.com/Allwinner-Homlet/H6-BSP4.9-linux/blob/master/arch/arm64/boot/dts/sunxi/sun50iw6p1.dtsi

axp805 spec:
http://linux-sunxi.org/images/b/bc/AXP805_Datasheet_V1.0_en.pdf

Yangtao Li (4):
  arm64: dts: allwinner: h6: orangepi: Add CPU supply regulator
  arm64: dts: allwinner: h6: pine: Add CPU supply regulator
  arm64: dts: allwinner: h6: Add clock to CPU cores
  arm64: dts: allwinner: h6: Add CPU Operating Performance Points table

 .../dts/allwinner/sun50i-h6-orangepi.dtsi |  8 ++-
 .../boot/dts/allwinner/sun50i-h6-pine-h64.dts |  8 ++-
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 63 +++
 3 files changed, 75 insertions(+), 4 deletions(-)

-- 
2.17.0



[PATVH v2 3/4] arm64: dts: allwinner: h6: Add clock to CPU cores

2019-02-15 Thread Yangtao Li
The ARM CPU cores are fed by the CPU clock from the CCU. Add a
reference to the clock for each CPU core, along with the clock
transition latency.

Signed-off-by: Yangtao Li 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index d93a7add67e7..723f5d991a74 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -26,6 +26,8 @@
device_type = "cpu";
reg = <0>;
enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
 
cpu1: cpu@1 {
@@ -33,6 +35,8 @@
device_type = "cpu";
reg = <1>;
enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
 
cpu2: cpu@2 {
@@ -40,6 +44,8 @@
device_type = "cpu";
reg = <2>;
enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
 
cpu3: cpu@3 {
@@ -47,6 +53,8 @@
device_type = "cpu";
reg = <3>;
enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
};
 
-- 
2.17.0



[PATCH v3 0/4] arm64: dts: allwinner: h6: Enable CPU DVFS(cpufreq)

2019-02-15 Thread Yangtao Li
Add the cpufreq information of h6 to dts, source of information is as follows.

h6 cpu opp info:
https://github.com/Allwinner-Homlet/H6-BSP4.9-linux/blob/master/arch/arm64/boot/dts/sunxi/sun50iw6p1.dtsi

axp805 spec:
http://linux-sunxi.org/images/b/bc/AXP805_Datasheet_V1.0_en.pdf

Yangtao Li (4):
  arm64: dts: allwinner: h6: orangepi: Add CPU supply regulator
  arm64: dts: allwinner: h6: pine: Add CPU supply regulator
  arm64: dts: allwinner: h6: Add clock to CPU cores
  arm64: dts: allwinner: h6: Add CPU Operating Performance Points table

---
v3:
-only update changelog between version 
v2:
-remove the opp of 1.8GHz
-update changelog

I tested the opp table on two H6 boards(with the same axp805 pmu),
but not the pine board or orangepi board.
---

 .../dts/allwinner/sun50i-h6-orangepi.dtsi |  8 ++-
 .../boot/dts/allwinner/sun50i-h6-pine-h64.dts |  8 ++-
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 63 +++
 3 files changed, 75 insertions(+), 4 deletions(-)

-- 
2.17.0



[PATCH v3 1/4] arm64: dts: allwinner: h6: orangepi: Add CPU supply regulator

2019-02-15 Thread Yangtao Li
The original orangepi use the dcdca to supply the CPU cores. According
to the axp805 spec, the range of dcdca is 0.6 to 1.1v, 1.12 to 1.52v.
In order to support more CPU frequency, slightly increase the voltage
maximum and minimum.

In fact, in sunxi's sdk, the actual minimum and maximum voltage of the
cpu is smaller or larger than the datasheet.

For some better quality ic, the minimum voltage can be smaller.
For some poor quality ic, the maximum voltage needs to be increased a
little.

Signed-off-by: Yangtao Li 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
index b2526dac2fcf..e7aebaf91ede 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
@@ -159,8 +159,8 @@
 
reg_dcdca: dcdca {
regulator-always-on;
-   regulator-min-microvolt = <81>;
-   regulator-max-microvolt = <108>;
+   regulator-min-microvolt = <80>;
+   regulator-max-microvolt = <116>;
regulator-name = "vdd-cpu";
};
 
@@ -191,6 +191,10 @@
};
 };
 
+ {
+   cpu-supply = <_dcdca>;
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_ph_pins>;
-- 
2.17.0



[PATCH v3 4/4] arm64: dts: allwinner: h6: Add CPU Operating Performance Points table

2019-02-15 Thread Yangtao Li
Add an OPP (Operating Performance Points) table for the CPU cores to
enable DVFS (Dynamic Voltage & Frequency Scaling) on the H6. This
information comes from github.

When the four CPUs are running at 1.8 GHz, 100% busy, it is easy to heat
up and make the system restart. And currently H6 does not support the
thermal driver, can not get the temperature information of the cpu to
control the highest frequency. So temporarily remove the opp of 1.8GHz.

When the four CPUs operate at 1.4 GHz, 100% busy, the temperature is
stable at about 90 degrees, and the system can still operate normally.

Signed-off-by: Yangtao Li 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 55 
 1 file changed, 55 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 723f5d991a74..84fb47062fe6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -28,6 +28,8 @@
enable-method = "psci";
clocks = < CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
};
 
cpu1: cpu@1 {
@@ -37,6 +39,8 @@
enable-method = "psci";
clocks = < CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
};
 
cpu2: cpu@2 {
@@ -46,6 +50,8 @@
enable-method = "psci";
clocks = < CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
};
 
cpu3: cpu@3 {
@@ -55,6 +61,55 @@
enable-method = "psci";
clocks = < CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
+   operating-points-v2 = <_opp_table>;
+   #cooling-cells = <2>;
+   };
+   };
+
+   cpu_opp_table: opp_table {
+   compatible = "operating-points-v2";
+   opp-shared;
+
+   opp@48000 {
+   opp-hz = /bits/ 64 <48000>;
+   opp-microvolt = <80 80 88>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@72000 {
+   opp-hz = /bits/ 64 <72000>;
+   opp-microvolt = <80 80 88>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@81600 {
+   opp-hz = /bits/ 64 <81600>;
+   opp-microvolt = <80 80 88>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@88800 {
+   opp-hz = /bits/ 64 <88800>;
+   opp-microvolt = <80 80 94>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@108000 {
+   opp-hz = /bits/ 64 <108000>;
+   opp-microvolt = <84 84 106>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@132000 {
+   opp-hz = /bits/ 64 <132000>;
+   opp-microvolt = <90 90 116>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
+   };
+
+   opp@148800 {
+   opp-hz = /bits/ 64 <148800>;
+   opp-microvolt = <96 96 116>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
};
 
-- 
2.17.0



[PATCH v3 3/4] arm64: dts: allwinner: h6: Add clock to CPU cores

2019-02-15 Thread Yangtao Li
The ARM CPU cores are fed by the CPU clock from the CCU. Add a
reference to the clock for each CPU core, along with the clock
transition latency.

Signed-off-by: Yangtao Li 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index d93a7add67e7..723f5d991a74 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -26,6 +26,8 @@
device_type = "cpu";
reg = <0>;
enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
 
cpu1: cpu@1 {
@@ -33,6 +35,8 @@
device_type = "cpu";
reg = <1>;
enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
 
cpu2: cpu@2 {
@@ -40,6 +44,8 @@
device_type = "cpu";
reg = <2>;
enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
 
cpu3: cpu@3 {
@@ -47,6 +53,8 @@
device_type = "cpu";
reg = <3>;
enable-method = "psci";
+   clocks = < CLK_CPUX>;
+   clock-latency-ns = <244144>; /* 8 32k periods */
};
};
 
-- 
2.17.0



[PATCH v3 2/4] arm64: dts: allwinner: h6: pine: Add CPU supply regulator

2019-02-15 Thread Yangtao Li
The original pine use the dcdca to supply the CPU cores. According
to the axp805 spec, the range of dcdca is 0.6 to 1.1v, 1.12 to 1.52v.
In order to support more CPU frequency, slightly increase the voltage
maximum and minimum.

In fact, in sunxi's sdk, the actual minimum and maximum voltage of the
cpu is smaller or larger than the datasheet.

For some better quality ic, the minimum voltage can be smaller. For
some poor quality ic, the maximum voltage needs to be increased a
little.

Signed-off-by: Yangtao Li 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
index bdb8470fc8dc..95c81250c2b3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
@@ -213,8 +213,8 @@
 
reg_dcdca: dcdca {
regulator-always-on;
-   regulator-min-microvolt = <81>;
-   regulator-max-microvolt = <108>;
+   regulator-min-microvolt = <80>;
+   regulator-max-microvolt = <116>;
regulator-name = "vdd-cpu";
};
 
@@ -251,6 +251,10 @@
};
 };
 
+ {
+   cpu-supply = <_dcdca>;
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_ph_pins>;
-- 
2.17.0



[PATCH 0/3] PM / devfreq: do some cleanup

2019-02-16 Thread Yangtao Li
The informations come from the coccinelle tool.

drivers/devfreq/tegra-devfreq.c:577:5-8: Unneeded variable: "ret".
Return "0" on line 603
drivers/devfreq/rk3399_dmc.c:325:2-3: Unneeded semicolon
drivers/devfreq/event/rockchip-dfi.c:214:2-3: Unneeded semicolon

Yangtao Li (3):
  PM / devfreq: rk3399_dmc: remove unneeded semicolon
  PM / devfreq: rockchip-dfi: remove unneeded semicolon
  PM / devfreq: tegra: remove unneeded variable

 drivers/devfreq/event/rockchip-dfi.c | 2 +-
 drivers/devfreq/rk3399_dmc.c | 2 +-
 drivers/devfreq/tegra-devfreq.c  | 7 ++-
 3 files changed, 4 insertions(+), 7 deletions(-)

-- 
2.17.0



[PATCH 2/3] PM / devfreq: rockchip-dfi: remove unneeded semicolon

2019-02-16 Thread Yangtao Li
The semicolon is unneeded, so remove it.

Signed-off-by: Yangtao Li 
---
 drivers/devfreq/event/rockchip-dfi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/event/rockchip-dfi.c 
b/drivers/devfreq/event/rockchip-dfi.c
index 22b113363ffc..fcbf76ebf55d 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -211,7 +211,7 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
if (IS_ERR(data->clk)) {
dev_err(dev, "Cannot get the clk dmc_clk\n");
return PTR_ERR(data->clk);
-   };
+   }
 
/* try to find the optional reference to the pmu syscon */
node = of_parse_phandle(np, "rockchip,pmu", 0);
-- 
2.17.0



[PATCH 1/3] PM / devfreq: rk3399_dmc: remove unneeded semicolon

2019-02-16 Thread Yangtao Li
The semicolon is unneeded, so remove it.

Signed-off-by: Yangtao Li 
---
 drivers/devfreq/rk3399_dmc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index e795ad2b3f6b..a228dad2bee4 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -322,7 +322,7 @@ static int rk3399_dmcfreq_probe(struct platform_device 
*pdev)
 
dev_err(dev, "Cannot get the clk dmc_clk\n");
return PTR_ERR(data->dmc_clk);
-   };
+   }
 
data->edev = devfreq_event_get_edev_by_phandle(dev, 0);
if (IS_ERR(data->edev))
-- 
2.17.0



[PATCH 3/3] PM / devfreq: tegra: remove unneeded variable

2019-02-16 Thread Yangtao Li
This variable is not used after initialization, so
remove it. And in order to unify the code style,
move the location where the dev_get_drvdata is called
by the way.

Signed-off-by: Yangtao Li 
---
 drivers/devfreq/tegra-devfreq.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/devfreq/tegra-devfreq.c b/drivers/devfreq/tegra-devfreq.c
index c59d2eee5d30..c89ba7b834ff 100644
--- a/drivers/devfreq/tegra-devfreq.c
+++ b/drivers/devfreq/tegra-devfreq.c
@@ -573,10 +573,7 @@ static int tegra_governor_get_target(struct devfreq 
*devfreq,
 static int tegra_governor_event_handler(struct devfreq *devfreq,
unsigned int event, void *data)
 {
-   struct tegra_devfreq *tegra;
-   int ret = 0;
-
-   tegra = dev_get_drvdata(devfreq->dev.parent);
+   struct tegra_devfreq *tegra = dev_get_drvdata(devfreq->dev.parent);
 
switch (event) {
case DEVFREQ_GOV_START:
@@ -600,7 +597,7 @@ static int tegra_governor_event_handler(struct devfreq 
*devfreq,
break;
}
 
-   return ret;
+   return 0;
 }
 
 static struct devfreq_governor tegra_devfreq_governor = {
-- 
2.17.0



[PATCH 0/2] cpufreq: do some cleanup

2019-02-16 Thread Yangtao Li
The informations come from the coccinelle tool.

drivers/cpufreq/longhaul.c:854:2-3: Unneeded semicolon
drivers/cpufreq/pcc-cpufreq.c:271:2-3: Unneeded semicolon

Yangtao Li (2):
  cpufreq: pcc-cpufreq: remove unneeded semicolon
  cpufreq: longhaul: remove unneeded semicolon

 drivers/cpufreq/longhaul.c| 2 +-
 drivers/cpufreq/pcc-cpufreq.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

-- 
2.17.0



[PATCH 2/2] cpufreq: longhaul: remove unneeded semicolon

2019-02-16 Thread Yangtao Li
The semicolon is unneeded, so remove it.

Signed-off-by: Yangtao Li 
---
 drivers/cpufreq/longhaul.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index 279bd9e9fa95..fb546e0d0356 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -851,7 +851,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
case TYPE_POWERSAVER:
pr_cont("Powersaver supported\n");
break;
-   };
+   }
 
/* Doesn't hurt */
longhaul_setup_southbridge();
-- 
2.17.0



[PATCH 1/2] cpufreq: pcc-cpufreq: remove unneeded semicolon

2019-02-16 Thread Yangtao Li
The semicolon is unneeded, so remove it.

Signed-off-by: Yangtao Li 
---
 drivers/cpufreq/pcc-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c
index 099a849396f6..1e5e64643c3a 100644
--- a/drivers/cpufreq/pcc-cpufreq.c
+++ b/drivers/cpufreq/pcc-cpufreq.c
@@ -268,7 +268,7 @@ static int pcc_get_offset(int cpu)
if (!pccp || pccp->type != ACPI_TYPE_PACKAGE) {
ret = -ENODEV;
goto out_free;
-   };
+   }
 
offset = &(pccp->package.elements[0]);
if (!offset || offset->type != ACPI_TYPE_INTEGER) {
-- 
2.17.0



[PATCH] cpufreq: speedstep: convert BUG() to BUG_ON()

2019-02-16 Thread Yangtao Li
To fix coccinelle WARNING.

WARNING: Use BUG_ON instead of if condition followed by BUG.

Signed-off-by: Yangtao Li 
---
 drivers/cpufreq/speedstep-ich.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c
index fbbcb88db061..5d8a09b82efb 100644
--- a/drivers/cpufreq/speedstep-ich.c
+++ b/drivers/cpufreq/speedstep-ich.c
@@ -243,8 +243,7 @@ static unsigned int speedstep_get(unsigned int cpu)
unsigned int speed;
 
/* You're supposed to ensure CPU is online. */
-   if (smp_call_function_single(cpu, get_freq_data, , 1) != 0)
-   BUG();
+   BUG_ON(smp_call_function_single(cpu, get_freq_data, , 1));
 
pr_debug("detected %u kHz as current frequency\n", speed);
return speed;
-- 
2.17.0



[PATCH] cpufreq: scmi: fix use-after-free in scmi_cpufreq_exit()

2019-02-16 Thread Yangtao Li
This issue was detected with the help of Coccinelle. So
change the order of function calls to fix it.

Fixes: 1690d8bb91e37 (cpufreq: scpi/scmi: Fix freeing of dynamic OPPs)

Signed-off-by: Yangtao Li 
---
 drivers/cpufreq/scmi-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index 242c3370544e..9ed46d188cb5 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -187,8 +187,8 @@ static int scmi_cpufreq_exit(struct cpufreq_policy *policy)
 
cpufreq_cooling_unregister(priv->cdev);
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, >freq_table);
-   kfree(priv);
dev_pm_opp_remove_all_dynamic(priv->cpu_dev);
+   kfree(priv);
 
return 0;
 }
-- 
2.17.0



[PATCH] cpufreq: powernv: fix missing check of return value in init_powernv_pstates()

2019-02-16 Thread Yangtao Li
kmalloc() could fail, so insert a check of its return value. And
if it fails, returns -ENOMEM.

And remove (struct pstate_idx_revmap_data *) to fix coccinelle WARNING
by the way.

WARNING: casting value returned by memory allocation function to (struct
pstate_idx_revmap_data *) is useless.

Signed-off-by: Yangtao Li 
---
 drivers/cpufreq/powernv-cpufreq.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/powernv-cpufreq.c 
b/drivers/cpufreq/powernv-cpufreq.c
index 7e7ad3879c4e..d2230812fa4b 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -244,6 +244,7 @@ static int init_powernv_pstates(void)
u32 len_ids, len_freqs;
u32 pstate_min, pstate_max, pstate_nominal;
u32 pstate_turbo, pstate_ultra_turbo;
+   int rc = -ENODEV;
 
power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
if (!power_mgt) {
@@ -327,8 +328,11 @@ static int init_powernv_pstates(void)
powernv_freqs[i].frequency = freq * 1000; /* kHz */
powernv_freqs[i].driver_data = id & 0xFF;
 
-   revmap_data = (struct pstate_idx_revmap_data *)
- kmalloc(sizeof(*revmap_data), GFP_KERNEL);
+   revmap_data = kmalloc(sizeof(*revmap_data), GFP_KERNEL);
+   if (!revmap_data) {
+   rc = -ENOMEM;
+   goto out;
+   }
 
revmap_data->pstate_id = id & 0xFF;
revmap_data->cpufreq_table_idx = i;
@@ -357,7 +361,7 @@ static int init_powernv_pstates(void)
return 0;
 out:
of_node_put(power_mgt);
-   return -ENODEV;
+   return rc;
 }
 
 /* Returns the CPU frequency corresponding to the pstate_id. */
-- 
2.17.0



[PATCH 1/5] nvmem: sunxi-sid: fix wrong description in kernel doc

2019-02-17 Thread Yangtao Li
qfprom->sunxi-sid

Signed-off-by: Yangtao Li 
---
 Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt 
b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
index 99c4ba6a3f61..d37017e343b1 100644
--- a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
+++ b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
@@ -12,7 +12,7 @@ Required properties:
 - reg: Should contain registers location and length
 
 = Data cells =
-Are child nodes of qfprom, bindings of which as described in
+Are child nodes of sunxi-sid, bindings of which as described in
 bindings/nvmem/nvmem.txt
 
 Example for sun4i:
-- 
2.17.0



[PATCH 0/5] nvmem: sunxi-sid: add SID controller support for H5 and H6

2019-02-17 Thread Yangtao Li
Add SID controller support for H5 and H6, and do some
cleanup without functional changes.

Yangtao Li (5):
  nvmem: sunxi-sid: fix wrong description in kernel doc
  nvmem: sunxi-sid: add support for H5's SID controller
  nvmem: sunxi-sid: add binding for H6's SID controller
  nvmem: sunxi-sid: add support for H6's SID controller
  nvmem: sunxi-sid: convert to SPDX license tags

 .../bindings/nvmem/allwinner,sunxi-sid.txt|  3 ++-
 drivers/nvmem/sunxi_sid.c | 23 +++
 2 files changed, 15 insertions(+), 11 deletions(-)

-- 
2.17.0



[PATCH 2/5] nvmem: sunxi-sid: add support for H5's SID controller

2019-02-17 Thread Yangtao Li
Add support for H5's SID controller.

Signed-off-by: Yangtao Li 
---
 drivers/nvmem/sunxi_sid.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 570a2e354f30..036029e90921 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -219,11 +219,17 @@ static const struct sunxi_sid_cfg sun50i_a64_cfg = {
.size = 0x100,
 };
 
+static const struct sunxi_sid_cfg sun50i_h5_cfg = {
+   .value_offset = 0x200,
+   .size = 0x100,
+};
+
 static const struct of_device_id sunxi_sid_of_match[] = {
{ .compatible = "allwinner,sun4i-a10-sid", .data = _a10_cfg },
{ .compatible = "allwinner,sun7i-a20-sid", .data = _a20_cfg },
{ .compatible = "allwinner,sun8i-h3-sid", .data = _h3_cfg },
{ .compatible = "allwinner,sun50i-a64-sid", .data = _a64_cfg },
+   { .compatible = "allwinner,sun50i-h5-sid", .data = _h5_cfg },
{/* sentinel */},
 };
 MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
-- 
2.17.0



[PATCH 5/5] nvmem: sunxi-sid: convert to SPDX license tags

2019-02-17 Thread Yangtao Li
Updates license to use SPDX-License-Identifier.

Signed-off-by: Yangtao Li 
---
 drivers/nvmem/sunxi_sid.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 8692b58d76ce..f56c9f713cb4 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Allwinner sunXi SoCs Security ID support.
  *
  * Copyright (c) 2013 Oliver Schinagl 
  * Copyright (C) 2014 Maxime Ripard 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include 
-- 
2.17.0



[PATCH 3/5] nvmem: sunxi-sid: add binding for H6's SID controller

2019-02-17 Thread Yangtao Li
Add a binding for H6's SID controller.

Signed-off-by: Yangtao Li 
---
 Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt 
b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
index d37017e343b1..cfb18b4ef8f7 100644
--- a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
+++ b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
@@ -8,6 +8,7 @@ Required properties:
   "allwinner,sun8i-h3-sid"
   "allwinner,sun50i-a64-sid"
   "allwinner,sun50i-h5-sid"
+  "allwinner,sun50i-h6-sid"
 
 - reg: Should contain registers location and length
 
-- 
2.17.0



[PATCH 4/5] nvmem: sunxi-sid: add support for H6's SID controller

2019-02-17 Thread Yangtao Li
Add support for H6's SID controller. It supports 4K-bit
EFUSE, bigger than before.

Signed-off-by: Yangtao Li 
---
 drivers/nvmem/sunxi_sid.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 036029e90921..8692b58d76ce 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -224,12 +224,18 @@ static const struct sunxi_sid_cfg sun50i_h5_cfg = {
.size = 0x100,
 };
 
+static const struct sunxi_sid_cfg sun50i_h6_cfg = {
+   .value_offset = 0x200,
+   .size = 0x200,
+};
+
 static const struct of_device_id sunxi_sid_of_match[] = {
{ .compatible = "allwinner,sun4i-a10-sid", .data = _a10_cfg },
{ .compatible = "allwinner,sun7i-a20-sid", .data = _a20_cfg },
{ .compatible = "allwinner,sun8i-h3-sid", .data = _h3_cfg },
{ .compatible = "allwinner,sun50i-a64-sid", .data = _a64_cfg },
{ .compatible = "allwinner,sun50i-h5-sid", .data = _h5_cfg },
+   { .compatible = "allwinner,sun50i-h6-sid", .data = _h6_cfg },
{/* sentinel */},
 };
 MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
-- 
2.17.0



[PATCH] clocksource: arm_arch_timer: remove unneeded pr_fmt macro

2019-03-05 Thread Yangtao Li
After this commit ded24019b6b6f(clocksource: arm_arch_timer: clean up
printk usage), the previous macro is redundant, so delete it.

And move the new macro to the previous position.

Signed-off-by: Yangtao Li 
---
 drivers/clocksource/arm_arch_timer.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c 
b/drivers/clocksource/arm_arch_timer.c
index 9a7d4dc00b6e..675243eb8cd4 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -9,7 +9,7 @@
  * published by the Free Software Foundation.
  */
 
-#define pr_fmt(fmt)"arm_arch_timer: " fmt
+#define pr_fmt(fmt)"arch_timer: " fmt
 
 #include 
 #include 
@@ -33,9 +33,6 @@
 
 #include 
 
-#undef pr_fmt
-#define pr_fmt(fmt) "arch_timer: " fmt
-
 #define CNTTIDR0x08
 #define CNTTIDR_VIRT(n)(BIT(1) << ((n) * 4))
 
-- 
2.17.0



[PATCH] of: thermal: Improve print information

2019-02-23 Thread Yangtao Li
Define pr_fmt macro to add a prefix to the message,
this can make the thermal log better recognized.

Before:

[0.602672] nfc: nfc_init: NFC Core ver 0.1
[0.602828] NET: Registered protocol family 39
[0.603435] clocksource: Switched to clocksource mct-frc
[0.746216] failed to build thermal zone cpu-thermal: -22
[0.746451] NET: Registered protocol family 2

After:

[0.602804] NET: Registered protocol family 39
[0.603463] clocksource: Switched to clocksource mct-frc
[0.746309] thermal_sys: failed to build thermal zone cpu-thermal: -22
[0.746545] NET: Registered protocol family 2

Signed-off-by: Yangtao Li 
---
 drivers/thermal/of-thermal.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index 4bfdb4a1e47d..02b5e78f027b 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -5,6 +5,9 @@
  *  Copyright (C) 2013 Texas Instruments
  *  Copyright (C) 2013 Eduardo Valentin 
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include 
 #include 
 #include 
-- 
2.17.0



[PATCH] cpuidle: fix description of exit latency in cpuidle.rst

2019-01-22 Thread Yangtao Li
Exit latency is the time from exiting the idle state to execute
the first instruction. This place may be a typo , so fix it.

Signed-off-by: Yangtao Li 
---
 Documentation/admin-guide/pm/cpuidle.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/pm/cpuidle.rst 
b/Documentation/admin-guide/pm/cpuidle.rst
index 106379e2619f..3ca2ca60ff91 100644
--- a/Documentation/admin-guide/pm/cpuidle.rst
+++ b/Documentation/admin-guide/pm/cpuidle.rst
@@ -134,7 +134,7 @@ substantial), in order to save more energy than it would 
save by entering one of
 the shallower idle states instead.  [The "depth" of an idle state roughly
 corresponds to the power drawn by the processor in that state.]  The exit
 latency, in turn, is the maximum time it will take a CPU asking the processor
-hardware to enter an idle state to start executing the first instruction after 
a
+hardware to exit an idle state to start executing the first instruction after a
 wakeup from that state.  Note that in general the exit latency also must cover
 the time needed to enter the given state in case the wakeup occurs when the
 hardware is entering it and it must be entered completely to be exited in an
-- 
2.17.0



[PATCH] PM / wakeup: fix comment of pm_wakeup_dev_event()

2019-01-23 Thread Yangtao Li
This brings the kernel doc in line with the function signature.

Signed-off-by: Yangtao Li 
---
 drivers/base/power/wakeup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index 5fa1898755a3..f1fee72ed970 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -783,7 +783,7 @@ void pm_wakeup_ws_event(struct wakeup_source *ws, unsigned 
int msec, bool hard)
 EXPORT_SYMBOL_GPL(pm_wakeup_ws_event);
 
 /**
- * pm_wakeup_event - Notify the PM core of a wakeup event.
+ * pm_wakeup_dev_event - Notify the PM core of a wakeup event.
  * @dev: Device the wakeup event is related to.
  * @msec: Anticipated event processing time (in milliseconds).
  * @hard: If set, abort suspends in progress and wake up from suspend-to-idle.
-- 
2.17.0



[PATCH] PM / devfreq: fix mem leak and missing check of return value in devfreq_add_device()

2019-01-18 Thread Yangtao Li
'devfreq' is malloced in devfreq_add_device() and should be freed in
the error handling cases, otherwise it will cause memory leak.

devm_kzalloc() could fail, so insert a check of its return value. And
if it fails, returns -ENOMEM.

Signed-off-by: Yangtao Li 
---
 drivers/devfreq/devfreq.c | 33 ++---
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 0ae3de76833b..fe6c157cb7e0 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -651,7 +651,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
mutex_unlock(>lock);
err = set_freq_table(devfreq);
if (err < 0)
-   goto err_out;
+   goto err_dev;
mutex_lock(>lock);
}
 
@@ -683,16 +683,27 @@ struct devfreq *devfreq_add_device(struct device *dev,
goto err_out;
}
 
-   devfreq->trans_table =
-   devm_kzalloc(>dev,
-array3_size(sizeof(unsigned int),
-devfreq->profile->max_state,
-devfreq->profile->max_state),
-GFP_KERNEL);
+   devfreq->trans_table = devm_kzalloc(>dev,
+   array3_size(sizeof(unsigned int),
+   devfreq->profile->max_state,
+   devfreq->profile->max_state),
+   GFP_KERNEL);
+   if (!devfreq->trans_table) {
+   mutex_unlock(>lock);
+   err = -ENOMEM;
+   goto err_devfreq;
+   }
+
devfreq->time_in_state = devm_kcalloc(>dev,
-   devfreq->profile->max_state,
-   sizeof(unsigned long),
-   GFP_KERNEL);
+ devfreq->profile->max_state,
+ sizeof(unsigned long),
+ GFP_KERNEL);
+   if (!devfreq->time_in_state) {
+   mutex_unlock(>lock);
+   err = -ENOMEM;
+   goto err_devfreq;
+   }
+
devfreq->last_stat_updated = jiffies;
 
srcu_init_notifier_head(>transition_notifier_list);
@@ -726,7 +737,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
 
 err_init:
mutex_unlock(_list_lock);
-
+err_devfreq:
devfreq_remove_device(devfreq);
devfreq = NULL;
 err_dev:
-- 
2.17.0



[PATCH 2/3] PM / devfreq: fix missing check of return value in devfreq_add_device()

2019-01-19 Thread Yangtao Li
devm_kzalloc() could fail, so insert a check of its return value. And
if it fails, returns -ENOMEM.

Signed-off-by: Yangtao Li 
---
 drivers/devfreq/devfreq.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 076b1c2f40a4..923889229a0b 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -688,10 +688,22 @@ struct devfreq *devfreq_add_device(struct device *dev,
devfreq->profile->max_state,
devfreq->profile->max_state),
GFP_KERNEL);
+   if (!devfreq->trans_table) {
+   mutex_unlock(>lock);
+   err = -ENOMEM;
+   goto err_devfreq;
+   }
+
devfreq->time_in_state = devm_kcalloc(>dev,
  devfreq->profile->max_state,
  sizeof(unsigned long),
  GFP_KERNEL);
+   if (!devfreq->time_in_state) {
+   mutex_unlock(>lock);
+   err = -ENOMEM;
+   goto err_devfreq;
+   }
+
devfreq->last_stat_updated = jiffies;
 
srcu_init_notifier_head(>transition_notifier_list);
@@ -725,7 +737,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
 
 err_init:
mutex_unlock(_list_lock);
-
+err_devfreq:
devfreq_remove_device(devfreq);
devfreq = NULL;
 err_dev:
-- 
2.17.0



[PATCH 1/3] PM / devfreq: fix indentation in devfreq_add_device()

2019-01-19 Thread Yangtao Li
To beautify the code format.

Signed-off-by: Yangtao Li 
---
 drivers/devfreq/devfreq.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 0ae3de76833b..076b1c2f40a4 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -683,16 +683,15 @@ struct devfreq *devfreq_add_device(struct device *dev,
goto err_out;
}
 
-   devfreq->trans_table =
-   devm_kzalloc(>dev,
-array3_size(sizeof(unsigned int),
-devfreq->profile->max_state,
-devfreq->profile->max_state),
-GFP_KERNEL);
+   devfreq->trans_table = devm_kzalloc(>dev,
+   array3_size(sizeof(unsigned int),
+   devfreq->profile->max_state,
+   devfreq->profile->max_state),
+   GFP_KERNEL);
devfreq->time_in_state = devm_kcalloc(>dev,
-   devfreq->profile->max_state,
-   sizeof(unsigned long),
-   GFP_KERNEL);
+ devfreq->profile->max_state,
+ sizeof(unsigned long),
+ GFP_KERNEL);
devfreq->last_stat_updated = jiffies;
 
srcu_init_notifier_head(>transition_notifier_list);
-- 
2.17.0



[PATCH 3/3] PM / devfreq: fix mem leak in devfreq_add_device()

2019-01-19 Thread Yangtao Li
'devfreq' is malloced in devfreq_add_device() and should be freed in
the error handling cases, otherwise it will cause memory leak.

Signed-off-by: Yangtao Li 
---
 drivers/devfreq/devfreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 923889229a0b..fe6c157cb7e0 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -651,7 +651,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
mutex_unlock(>lock);
err = set_freq_table(devfreq);
if (err < 0)
-   goto err_out;
+   goto err_dev;
mutex_lock(>lock);
}
 
-- 
2.17.0



[PATCH] clockevents: decrement reference count when device_register() fail

2019-01-21 Thread Yangtao Li
device_register() may fail, use put_device() giving up the refconut
to avoid refcount leak.

Signed-off-by: Yangtao Li 
---
 kernel/time/clockevents.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 5e77662dd2d9..7b691dc97349 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -719,7 +719,9 @@ static __init int tick_broadcast_init_sysfs(void)
 {
int err = device_register(_bc_dev);
 
-   if (!err)
+   if (err)
+   put_device(_bc_dev);
+   else
err = device_create_file(_bc_dev, 
_attr_current_device);
return err;
 }
@@ -746,8 +748,10 @@ static int __init tick_init_sysfs(void)
err = device_create_file(dev, _attr_current_device);
if (!err)
err = device_create_file(dev, _attr_unbind_device);
-   if (err)
+   if (err) {
+   put_device(dev);
return err;
+   }
}
return tick_broadcast_init_sysfs();
 }
-- 
2.17.0



[PATCH] clocksource: decrement reference count when device_register() fail

2019-01-21 Thread Yangtao Li
device_register() may fail, use put_device() giving up the refconut
to avoid refcount leak.

Signed-off-by: Yangtao Li 
---
 kernel/time/clocksource.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 3bcc19ceb073..0a830fedc7ef 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -1183,8 +1183,11 @@ static int __init init_clocksource_sysfs(void)
 {
int error = subsys_system_register(_subsys, NULL);
 
-   if (!error)
+   if (!error) {
error = device_register(_clocksource);
+   if (error)
+   put_device(_clocksource);
+   }
 
return error;
 }
-- 
2.17.0



[PATCH] dmaengine: remove DBGFS_FUNC_DECL()

2018-11-30 Thread Yangtao Li
We already have the DEFINE_SHOW_ATTRIBUTE,There is no need to define
such a macro,so remove DBGFS_FUNC_DECL.Also use macro to simplify some
code.

Signed-off-by: Yangtao Li 
---
 drivers/dma/amba-pl08x.c | 14 ++
 drivers/dma/mic_x100_dma.c   | 22 +++---
 drivers/dma/pxa_dma.c| 24 
 drivers/dma/qcom/hidma_dbg.c | 33 ++---
 4 files changed, 23 insertions(+), 70 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 97483df1f82e..fc8c2bab563c 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -2505,24 +2505,14 @@ static int pl08x_debugfs_show(struct seq_file *s, void 
*data)
return 0;
 }
 
-static int pl08x_debugfs_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, pl08x_debugfs_show, inode->i_private);
-}
-
-static const struct file_operations pl08x_debugfs_operations = {
-   .open   = pl08x_debugfs_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pl08x_debugfs);
 
 static void init_pl08x_debugfs(struct pl08x_driver_data *pl08x)
 {
/* Expose a simple debugfs interface to view all clocks */
(void) debugfs_create_file(dev_name(>adev->dev),
S_IFREG | S_IRUGO, NULL, pl08x,
-   _debugfs_operations);
+   _debugfs_fops);
 }
 
 #else
diff --git a/drivers/dma/mic_x100_dma.c b/drivers/dma/mic_x100_dma.c
index adfd316db1a8..6a91e28d537d 100644
--- a/drivers/dma/mic_x100_dma.c
+++ b/drivers/dma/mic_x100_dma.c
@@ -676,7 +676,7 @@ static void mic_dma_dev_unreg(struct mic_dma_device 
*mic_dma_dev)
 }
 
 /* DEBUGFS CODE */
-static int mic_dma_reg_seq_show(struct seq_file *s, void *pos)
+static int mic_dma_reg_show(struct seq_file *s, void *pos)
 {
struct mic_dma_device *mic_dma_dev = s->private;
int i, chan_num, first_chan = mic_dma_dev->start_ch;
@@ -707,23 +707,7 @@ static int mic_dma_reg_seq_show(struct seq_file *s, void 
*pos)
return 0;
 }
 
-static int mic_dma_reg_debug_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, mic_dma_reg_seq_show, inode->i_private);
-}
-
-static int mic_dma_reg_debug_release(struct inode *inode, struct file *file)
-{
-   return single_release(inode, file);
-}
-
-static const struct file_operations mic_dma_reg_ops = {
-   .owner   = THIS_MODULE,
-   .open= mic_dma_reg_debug_open,
-   .read= seq_read,
-   .llseek  = seq_lseek,
-   .release = mic_dma_reg_debug_release
-};
+DEFINE_SHOW_ATTRIBUTE(mic_dma_reg);
 
 /* Debugfs parent dir */
 static struct dentry *mic_dma_dbg;
@@ -747,7 +731,7 @@ static int mic_dma_driver_probe(struct mbus_device *mbdev)
if (mic_dma_dev->dbg_dir)
debugfs_create_file("mic_dma_reg", 0444,
mic_dma_dev->dbg_dir, mic_dma_dev,
-   _dma_reg_ops);
+   _dma_reg_fops);
}
return 0;
 }
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index 825725057e00..8e1e1b07d32f 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -189,7 +189,7 @@ bool pxad_filter_fn(struct dma_chan *chan, void *param);
 #include 
 #include 
 
-static int dbg_show_requester_chan(struct seq_file *s, void *p)
+static int requester_chan_show(struct seq_file *s, void *p)
 {
struct pxad_phy *phy = s->private;
int i;
@@ -220,7 +220,7 @@ static int is_phys_valid(unsigned long addr)
 #define PXA_DCSR_STR(flag) (dcsr & PXA_DCSR_##flag ? #flag" " : "")
 #define PXA_DCMD_STR(flag) (dcmd & PXA_DCMD_##flag ? #flag" " : "")
 
-static int dbg_show_descriptors(struct seq_file *s, void *p)
+static int descriptors_show(struct seq_file *s, void *p)
 {
struct pxad_phy *phy = s->private;
int i, max_show = 20, burst, width;
@@ -263,7 +263,7 @@ static int dbg_show_descriptors(struct seq_file *s, void *p)
return 0;
 }
 
-static int dbg_show_chan_state(struct seq_file *s, void *p)
+static int chan_state_show(struct seq_file *s, void *p)
 {
struct pxad_phy *phy = s->private;
u32 dcsr, dcmd;
@@ -306,7 +306,7 @@ static int dbg_show_chan_state(struct seq_file *s, void *p)
return 0;
 }
 
-static int dbg_show_state(struct seq_file *s, void *p)
+static int state_show(struct seq_file *s, void *p)
 {
struct pxad_device *pdev = s->private;
 
@@ -329,10 +329,10 @@ static const struct file_operations dbg_fops_##name = { \
.release= single_release, \
 }
 
-DBGFS_FUNC_DECL(state);
-DBGFS_FUNC_DECL(chan_state);
-DBGFS_FUNC_DECL(descriptors);
-DBGFS_FUNC_DECL(requester_chan);
+DEFINE_SHOW_ATTRIBUTE(state);
+

[PATCH] gpio: ks8695: Change to use DEFINE_SHOW_ATTRIBUTE macro

2018-11-30 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
---
 drivers/gpio/gpio-ks8695.c | 15 +++
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/gpio/gpio-ks8695.c b/drivers/gpio/gpio-ks8695.c
index 55d562e1278e..d6d6140ffc40 100644
--- a/drivers/gpio/gpio-ks8695.c
+++ b/drivers/gpio/gpio-ks8695.c
@@ -282,22 +282,13 @@ static int ks8695_gpio_show(struct seq_file *s, void 
*unused)
return 0;
 }
 
-static int ks8695_gpio_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, ks8695_gpio_show, NULL);
-}
-
-static const struct file_operations ks8695_gpio_operations = {
-   .open   = ks8695_gpio_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(ks8695_gpio);
 
 static int __init ks8695_gpio_debugfs_init(void)
 {
/* /sys/kernel/debug/ks8695_gpio */
-   (void) debugfs_create_file("ks8695_gpio", S_IFREG | S_IRUGO, NULL, 
NULL, _gpio_operations);
+   debugfs_create_file("ks8695_gpio", S_IFREG | S_IRUGO, NULL, NULL,
+   _gpio_fops);
return 0;
 }
 postcore_initcall(ks8695_gpio_debugfs_init);
-- 
2.17.0



[PATCH] pinctrl: Change to use DEFINE_SHOW_ATTRIBUTE macro

2018-11-30 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
---
 drivers/pinctrl/pinconf.c | 29 -
 drivers/pinctrl/pinmux.c  | 29 -
 2 files changed, 8 insertions(+), 50 deletions(-)

diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c
index d3fe14394b73..2c7229380f08 100644
--- a/drivers/pinctrl/pinconf.c
+++ b/drivers/pinctrl/pinconf.c
@@ -366,29 +366,8 @@ static int pinconf_groups_show(struct seq_file *s, void 
*what)
return 0;
 }
 
-static int pinconf_pins_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, pinconf_pins_show, inode->i_private);
-}
-
-static int pinconf_groups_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, pinconf_groups_show, inode->i_private);
-}
-
-static const struct file_operations pinconf_pins_ops = {
-   .open   = pinconf_pins_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
-static const struct file_operations pinconf_groups_ops = {
-   .open   = pinconf_groups_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pinconf_pins);
+DEFINE_SHOW_ATTRIBUTE(pinconf_groups);
 
 #define MAX_NAME_LEN 15
 
@@ -613,9 +592,9 @@ void pinconf_init_device_debugfs(struct dentry *devroot,
 struct pinctrl_dev *pctldev)
 {
debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO,
-   devroot, pctldev, _pins_ops);
+   devroot, pctldev, _pins_fops);
debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
-   devroot, pctldev, _groups_ops);
+   devroot, pctldev, _groups_fops);
debugfs_create_file("pinconf-config",  (S_IRUGO | S_IWUSR | S_IWGRP),
devroot, pctldev, _dbg_pinconfig_fops);
 }
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 5780442c068b..4d0cc1889dd9 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -644,37 +644,16 @@ void pinmux_show_setting(struct seq_file *s,
   setting->data.mux.func);
 }
 
-static int pinmux_functions_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, pinmux_functions_show, inode->i_private);
-}
-
-static int pinmux_pins_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, pinmux_pins_show, inode->i_private);
-}
-
-static const struct file_operations pinmux_functions_ops = {
-   .open   = pinmux_functions_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
-
-static const struct file_operations pinmux_pins_ops = {
-   .open   = pinmux_pins_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pinmux_functions);
+DEFINE_SHOW_ATTRIBUTE(pinmux_pins);
 
 void pinmux_init_device_debugfs(struct dentry *devroot,
 struct pinctrl_dev *pctldev)
 {
debugfs_create_file("pinmux-functions", S_IFREG | S_IRUGO,
-   devroot, pctldev, _functions_ops);
+   devroot, pctldev, _functions_fops);
debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO,
-   devroot, pctldev, _pins_ops);
+   devroot, pctldev, _pins_fops);
 }
 
 #endif /* CONFIG_DEBUG_FS */
-- 
2.17.0



[PATCH] ACPI, APEI, EINJ: Change to use DEFINE_SHOW_ATTRIBUTE macro

2018-11-30 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
---
 drivers/acpi/apei/einj.c | 12 +---
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index b38737c83a24..fcccbfdbdd1a 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -607,17 +607,7 @@ static int available_error_type_show(struct seq_file *m, 
void *v)
return 0;
 }
 
-static int available_error_type_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, available_error_type_show, NULL);
-}
-
-static const struct file_operations available_error_type_fops = {
-   .open   = available_error_type_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(available_error_type);
 
 static int error_type_get(void *data, u64 *val)
 {
-- 
2.17.0



[PATCH] binder: remove BINDER_DEBUG_ENTRY()

2018-11-30 Thread Yangtao Li
We already have the DEFINE_SHOW_ATTRIBUTE.There is no need to define
such a macro,so remove BINDER_DEBUG_ENTRY.

Signed-off-by: Yangtao Li 
---
 drivers/android/binder.c | 48 ++--
 1 file changed, 17 insertions(+), 31 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index cb30a524d16d..5496b8e07234 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -94,22 +94,8 @@ static struct dentry *binder_debugfs_dir_entry_root;
 static struct dentry *binder_debugfs_dir_entry_proc;
 static atomic_t binder_last_id;
 
-#define BINDER_DEBUG_ENTRY(name) \
-static int binder_##name##_open(struct inode *inode, struct file *file) \
-{ \
-   return single_open(file, binder_##name##_show, inode->i_private); \
-} \
-\
-static const struct file_operations binder_##name##_fops = { \
-   .owner = THIS_MODULE, \
-   .open = binder_##name##_open, \
-   .read = seq_read, \
-   .llseek = seq_lseek, \
-   .release = single_release, \
-}
-
-static int binder_proc_show(struct seq_file *m, void *unused);
-BINDER_DEBUG_ENTRY(proc);
+static int proc_show(struct seq_file *m, void *unused);
+DEFINE_SHOW_ATTRIBUTE(proc);
 
 /* This is only defined in include/asm-arm/sizes.h */
 #ifndef SZ_1K
@@ -4964,7 +4950,7 @@ static int binder_open(struct inode *nodp, struct file 
*filp)
proc->debugfs_entry = debugfs_create_file(strbuf, 0444,
binder_debugfs_dir_entry_proc,
(void *)(unsigned long)proc->pid,
-   _proc_fops);
+   _fops);
}
 
return 0;
@@ -5592,7 +5578,7 @@ static void print_binder_proc_stats(struct seq_file *m,
 }
 
 
-static int binder_state_show(struct seq_file *m, void *unused)
+static int state_show(struct seq_file *m, void *unused)
 {
struct binder_proc *proc;
struct binder_node *node;
@@ -5631,7 +5617,7 @@ static int binder_state_show(struct seq_file *m, void 
*unused)
return 0;
 }
 
-static int binder_stats_show(struct seq_file *m, void *unused)
+static int stats_show(struct seq_file *m, void *unused)
 {
struct binder_proc *proc;
 
@@ -5647,7 +5633,7 @@ static int binder_stats_show(struct seq_file *m, void 
*unused)
return 0;
 }
 
-static int binder_transactions_show(struct seq_file *m, void *unused)
+static int transactions_show(struct seq_file *m, void *unused)
 {
struct binder_proc *proc;
 
@@ -5660,7 +5646,7 @@ static int binder_transactions_show(struct seq_file *m, 
void *unused)
return 0;
 }
 
-static int binder_proc_show(struct seq_file *m, void *unused)
+static int proc_show(struct seq_file *m, void *unused)
 {
struct binder_proc *itr;
int pid = (unsigned long)m->private;
@@ -5703,7 +5689,7 @@ static void print_binder_transaction_log_entry(struct 
seq_file *m,
"\n" : " (incomplete)\n");
 }
 
-static int binder_transaction_log_show(struct seq_file *m, void *unused)
+static int transaction_log_show(struct seq_file *m, void *unused)
 {
struct binder_transaction_log *log = m->private;
unsigned int log_cur = atomic_read(>cur);
@@ -5735,10 +5721,10 @@ static const struct file_operations binder_fops = {
.release = binder_release,
 };
 
-BINDER_DEBUG_ENTRY(state);
-BINDER_DEBUG_ENTRY(stats);
-BINDER_DEBUG_ENTRY(transactions);
-BINDER_DEBUG_ENTRY(transaction_log);
+DEFINE_SHOW_ATTRIBUTE(state);
+DEFINE_SHOW_ATTRIBUTE(stats);
+DEFINE_SHOW_ATTRIBUTE(transactions);
+DEFINE_SHOW_ATTRIBUTE(transaction_log);
 
 static int __init init_binder_device(const char *name)
 {
@@ -5792,27 +5778,27 @@ static int __init binder_init(void)
0444,
binder_debugfs_dir_entry_root,
NULL,
-   _state_fops);
+   _fops);
debugfs_create_file("stats",
0444,
binder_debugfs_dir_entry_root,
NULL,
-   _stats_fops);
+   _fops);
debugfs_create_file("transactions",
0444,
binder_debugfs_dir_entry_root,
NULL,
-   _transactions_fops);
+   _fops);
debugfs_create_file("transaction_log",
0444,
binder_debugfs_dir_entry_root,
_transaction_log,
-   _transaction_log_fops);
+   _log_fops);
debugfs_create_fil

[PATCH] driver core: remove define_genpd_open_function() and define_genpd_debugfs_fops()

2018-11-30 Thread Yangtao Li
We already have the DEFINE_SHOW_ATTRIBUTE,There is no need to define such
a macro,so remove define_genpd_open_function and define_genpd_debugfs_fops.
Also use DEFINE_SHOW_ATTRIBUTE to simplify somecode.

Signed-off-by: Yangtao Li 
---
 drivers/base/component.c  | 12 +
 drivers/base/power/domain.c   | 71 +--
 drivers/base/regmap/regcache-rbtree.c | 12 +
 drivers/base/regmap/regmap-debugfs.c  | 12 +
 4 files changed, 27 insertions(+), 80 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index e8d676fad0c9..ddcea8739c12 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -85,17 +85,7 @@ static int component_devices_show(struct seq_file *s, void 
*data)
return 0;
 }
 
-static int component_devices_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, component_devices_show, inode->i_private);
-}
-
-static const struct file_operations component_devices_fops = {
-   .open = component_devices_open,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(component_devices);
 
 static int __init component_debug_init(void)
 {
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 7f38a92b444a..10a61d6147d0 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2671,7 +2671,7 @@ static int genpd_summary_one(struct seq_file *s,
return 0;
 }
 
-static int genpd_summary_show(struct seq_file *s, void *data)
+static int summary_show(struct seq_file *s, void *data)
 {
struct generic_pm_domain *genpd;
int ret = 0;
@@ -2694,7 +2694,7 @@ static int genpd_summary_show(struct seq_file *s, void 
*data)
return ret;
 }
 
-static int genpd_status_show(struct seq_file *s, void *data)
+static int status_show(struct seq_file *s, void *data)
 {
static const char * const status_lookup[] = {
[GPD_STATE_ACTIVE] = "on",
@@ -2721,7 +2721,7 @@ static int genpd_status_show(struct seq_file *s, void 
*data)
return ret;
 }
 
-static int genpd_sub_domains_show(struct seq_file *s, void *data)
+static int sub_domains_show(struct seq_file *s, void *data)
 {
struct generic_pm_domain *genpd = s->private;
struct gpd_link *link;
@@ -2738,7 +2738,7 @@ static int genpd_sub_domains_show(struct seq_file *s, 
void *data)
return ret;
 }
 
-static int genpd_idle_states_show(struct seq_file *s, void *data)
+static int idle_states_show(struct seq_file *s, void *data)
 {
struct generic_pm_domain *genpd = s->private;
unsigned int i;
@@ -2767,7 +2767,7 @@ static int genpd_idle_states_show(struct seq_file *s, 
void *data)
return ret;
 }
 
-static int genpd_active_time_show(struct seq_file *s, void *data)
+static int active_time_show(struct seq_file *s, void *data)
 {
struct generic_pm_domain *genpd = s->private;
ktime_t delta = 0;
@@ -2787,7 +2787,7 @@ static int genpd_active_time_show(struct seq_file *s, 
void *data)
return ret;
 }
 
-static int genpd_total_idle_time_show(struct seq_file *s, void *data)
+static int total_idle_time_show(struct seq_file *s, void *data)
 {
struct generic_pm_domain *genpd = s->private;
ktime_t delta = 0, total = 0;
@@ -2815,7 +2815,7 @@ static int genpd_total_idle_time_show(struct seq_file *s, 
void *data)
 }
 
 
-static int genpd_devices_show(struct seq_file *s, void *data)
+static int devices_show(struct seq_file *s, void *data)
 {
struct generic_pm_domain *genpd = s->private;
struct pm_domain_data *pm_data;
@@ -2841,7 +2841,7 @@ static int genpd_devices_show(struct seq_file *s, void 
*data)
return ret;
 }
 
-static int genpd_perf_state_show(struct seq_file *s, void *data)
+static int perf_state_show(struct seq_file *s, void *data)
 {
struct generic_pm_domain *genpd = s->private;
 
@@ -2854,37 +2854,14 @@ static int genpd_perf_state_show(struct seq_file *s, 
void *data)
return 0;
 }
 
-#define define_genpd_open_function(name) \
-static int genpd_##name##_open(struct inode *inode, struct file *file) \
-{ \
-   return single_open(file, genpd_##name##_show, inode->i_private); \
-}
-
-define_genpd_open_function(summary);
-define_genpd_open_function(status);
-define_genpd_open_function(sub_domains);
-define_genpd_open_function(idle_states);
-define_genpd_open_function(active_time);
-define_genpd_open_function(total_idle_time);
-define_genpd_open_function(devices);
-define_genpd_open_function(perf_state);
-
-#define define_genpd_debugfs_fops(name) \
-static const struct file_operations genpd_##name##_fops = { \
-   .open = genpd_##name##_open, \
-   .read = seq_read, \
-   .llseek = seq_lseek, \
-   .release = single_release, \
-}
-
-define_genpd_debugfs_fops(summary);
-define_genpd_debugfs_fops(status);
-define_genpd_debugfs_fops(sub_domains);
-def

[PATCH] drivers/fmc: Change to use DEFINE_SHOW_ATTRIBUTE macro

2018-11-30 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
---
 drivers/fmc/fmc-debug.c | 21 +++--
 1 file changed, 3 insertions(+), 18 deletions(-)

diff --git a/drivers/fmc/fmc-debug.c b/drivers/fmc/fmc-debug.c
index 32930722770c..c923d076c807 100644
--- a/drivers/fmc/fmc-debug.c
+++ b/drivers/fmc/fmc-debug.c
@@ -114,7 +114,7 @@ static void fmc_sdb_dump_recursive(struct fmc_device *fmc, 
struct seq_file *s,
}
 }
 
-static int fmc_sdb_dump(struct seq_file *s, void *offset)
+static int fmc_sdb_dump_show(struct seq_file *s, void *offset)
 {
struct fmc_device *fmc = s->private;
 
@@ -131,22 +131,7 @@ static int fmc_sdb_dump(struct seq_file *s, void *offset)
return 0;
 }
 
-
-static int fmc_sdb_dump_open(struct inode *inode, struct file *file)
-{
-   struct fmc_device *fmc = inode->i_private;
-
-   return single_open(file, fmc_sdb_dump, fmc);
-}
-
-
-const struct file_operations fmc_dbgfs_sdb_dump = {
-   .owner = THIS_MODULE,
-   .open  = fmc_sdb_dump_open,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(fmc_sdb_dump);
 
 int fmc_debug_init(struct fmc_device *fmc)
 {
@@ -158,7 +143,7 @@ int fmc_debug_init(struct fmc_device *fmc)
 
fmc->dbg_sdb_dump = debugfs_create_file(FMC_DBG_SDB_DUMP, 0444,
fmc->dbg_dir, fmc,
-   _dbgfs_sdb_dump);
+   _sdb_dump_fops);
if (IS_ERR_OR_NULL(fmc->dbg_sdb_dump))
pr_err("FMC: Cannot create debugfs file %s\n",
   FMC_DBG_SDB_DUMP);
-- 
2.17.0



[PATCH] bus: mvebu-mbus: Change to use DEFINE_SHOW_ATTRIBUTE macro

2018-11-30 Thread Yangtao Li
Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.

Signed-off-by: Yangtao Li 
---
 drivers/bus/mvebu-mbus.c | 24 ++--
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
index 5b2a11a88951..3aaaf484857f 100644
--- a/drivers/bus/mvebu-mbus.c
+++ b/drivers/bus/mvebu-mbus.c
@@ -470,17 +470,7 @@ static int mvebu_sdram_debug_show(struct seq_file *seq, 
void *v)
return mbus->soc->show_cpu_target(mbus, seq, v);
 }
 
-static int mvebu_sdram_debug_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, mvebu_sdram_debug_show, inode->i_private);
-}
-
-static const struct file_operations mvebu_sdram_debug_fops = {
-   .open = mvebu_sdram_debug_open,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(mvebu_sdram_debug);
 
 static int mvebu_devs_debug_show(struct seq_file *seq, void *v)
 {
@@ -520,17 +510,7 @@ static int mvebu_devs_debug_show(struct seq_file *seq, 
void *v)
return 0;
 }
 
-static int mvebu_devs_debug_open(struct inode *inode, struct file *file)
-{
-   return single_open(file, mvebu_devs_debug_show, inode->i_private);
-}
-
-static const struct file_operations mvebu_devs_debug_fops = {
-   .open = mvebu_devs_debug_open,
-   .read = seq_read,
-   .llseek = seq_lseek,
-   .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(mvebu_devs_debug);
 
 /*
  * SoC-specific functions and definitions
-- 
2.17.0



<    1   2   3   4   5   >