[PATCH v6 3/3] platform/x86: Enable Atom PMC platform clocks

2016-12-09 Thread Irina Tirdea
The BayTrail and CherryTrail platforms provide platform clocks
through their Power Management Controller (PMC).

The SoC supports up to 6 clocks (PMC_PLT_CLK[5:0]) with a
frequency of either 19.2 MHz (PLL) or 25 MHz (XTAL) for BayTrail
an a frequency of 19.2 MHz (XTAL) for CherryTrail. These clocks
are available for general system use, where appropriate. For example,
the usage for platform clocks suggested in the datasheet is the
following:
  PLT_CLK[2:0] - Camera
  PLT_CLK[3] - Audio Codec
  PLT_CLK[4] -
  PLT_CLK[5] - COMMs

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
---
 drivers/platform/x86/Kconfig   |  1 +
 drivers/platform/x86/pmc_atom.c| 78 --
 include/linux/platform_data/x86/pmc_atom.h |  3 ++
 3 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 21dce1e..c1b07ed 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1032,3 +1032,4 @@ endif # X86_PLATFORM_DEVICES
 config PMC_ATOM
def_bool y
 depends on PCI
+   select COMMON_CLK
diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
index b53fbc1..324c44f 100644
--- a/drivers/platform/x86/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -22,6 +22,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 struct pmc_bit_map {
const char *name;
@@ -36,6 +38,11 @@ struct pmc_reg_map {
const struct pmc_bit_map *pss;
 };
 
+struct pmc_data {
+   const struct pmc_reg_map *map;
+   const struct pmc_clk *clks;
+};
+
 struct pmc_dev {
u32 base_addr;
void __iomem *regmap;
@@ -49,6 +56,29 @@ struct pmc_dev {
 static struct pmc_dev pmc_device;
 static u32 acpi_base_addr;
 
+static const struct pmc_clk byt_clks[] = {
+   {
+   .name = "xtal",
+   .freq = 2500,
+   .parent_name = NULL,
+   },
+   {
+   .name = "pll",
+   .freq = 1920,
+   .parent_name = "xtal",
+   },
+   {},
+};
+
+static const struct pmc_clk cht_clks[] = {
+   {
+   .name = "xtal",
+   .freq = 1920,
+   .parent_name = NULL,
+   },
+   {},
+};
+
 static const struct pmc_bit_map d3_sts_0_map[] = {
{"LPSS1_F0_DMA",BIT_LPSS1_F0_DMA},
{"LPSS1_F1_PWM1",   BIT_LPSS1_F1_PWM1},
@@ -168,6 +198,16 @@ struct pmc_dev {
.pss= cht_pss_map,
 };
 
+static const struct pmc_data byt_data = {
+   .map = _reg_map,
+   .clks = byt_clks,
+};
+
+static const struct pmc_data cht_data = {
+   .map = _reg_map,
+   .clks = cht_clks,
+};
+
 static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
 {
return readl(pmc->regmap + reg_offset);
@@ -381,10 +421,36 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc)
 }
 #endif /* CONFIG_DEBUG_FS */
 
+static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap,
+ const struct pmc_data *pmc_data)
+{
+   struct platform_device *clkdev;
+   struct pmc_clk_data *clk_data;
+
+   clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+   if (!clk_data)
+   return -ENOMEM;
+
+   clk_data->base = pmc_regmap + PMC_CLK_CTL_0;
+   clk_data->clks = pmc_data->clks;
+
+   clkdev = platform_device_register_data(>dev, "clk-byt-plt", -1,
+  clk_data, sizeof(*clk_data));
+   if (IS_ERR(clkdev)) {
+   kfree(clk_data);
+   return PTR_ERR(clkdev);
+   }
+
+   kfree(clk_data);
+
+   return 0;
+}
+
 static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
struct pmc_dev *pmc = _device;
-   const struct pmc_reg_map *map = (struct pmc_reg_map *)ent->driver_data;
+   const struct pmc_data *data = (struct pmc_data *)ent->driver_data;
+   const struct pmc_reg_map *map = data->map;
int ret;
 
/* Obtain ACPI base address */
@@ -413,6 +479,12 @@ static int pmc_setup_dev(struct pci_dev *pdev, const 
struct pci_device_id *ent)
if (ret)
dev_warn(>dev, "debugfs register failed\n");
 
+   /* Register platform clocks - PMC_PLT_CLK [5:0] */
+   ret = pmc_setup_clks(pdev, pmc->regmap, data);
+   if (ret)
+   dev_warn(>dev, "platform clocks register failed: %d\n",
+ret);
+
pmc->init = true;
return ret;
 }
@@ -423,8 +495,8 @@ static int pmc_setup_dev(struct pci_dev *pdev, const struct 
pci_device_id *ent)
  * used by pci_match_id() call below.
  */
 static const struct pci_device_id pmc_pci_ids[] = {
-   { PCI_VDEVICE(

[PATCH v6 3/3] platform/x86: Enable Atom PMC platform clocks

2016-12-09 Thread Irina Tirdea
The BayTrail and CherryTrail platforms provide platform clocks
through their Power Management Controller (PMC).

The SoC supports up to 6 clocks (PMC_PLT_CLK[5:0]) with a
frequency of either 19.2 MHz (PLL) or 25 MHz (XTAL) for BayTrail
an a frequency of 19.2 MHz (XTAL) for CherryTrail. These clocks
are available for general system use, where appropriate. For example,
the usage for platform clocks suggested in the datasheet is the
following:
  PLT_CLK[2:0] - Camera
  PLT_CLK[3] - Audio Codec
  PLT_CLK[4] -
  PLT_CLK[5] - COMMs

Signed-off-by: Irina Tirdea 
Signed-off-by: Pierre-Louis Bossart 
---
 drivers/platform/x86/Kconfig   |  1 +
 drivers/platform/x86/pmc_atom.c| 78 --
 include/linux/platform_data/x86/pmc_atom.h |  3 ++
 3 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 21dce1e..c1b07ed 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1032,3 +1032,4 @@ endif # X86_PLATFORM_DEVICES
 config PMC_ATOM
def_bool y
 depends on PCI
+   select COMMON_CLK
diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
index b53fbc1..324c44f 100644
--- a/drivers/platform/x86/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -22,6 +22,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 struct pmc_bit_map {
const char *name;
@@ -36,6 +38,11 @@ struct pmc_reg_map {
const struct pmc_bit_map *pss;
 };
 
+struct pmc_data {
+   const struct pmc_reg_map *map;
+   const struct pmc_clk *clks;
+};
+
 struct pmc_dev {
u32 base_addr;
void __iomem *regmap;
@@ -49,6 +56,29 @@ struct pmc_dev {
 static struct pmc_dev pmc_device;
 static u32 acpi_base_addr;
 
+static const struct pmc_clk byt_clks[] = {
+   {
+   .name = "xtal",
+   .freq = 2500,
+   .parent_name = NULL,
+   },
+   {
+   .name = "pll",
+   .freq = 1920,
+   .parent_name = "xtal",
+   },
+   {},
+};
+
+static const struct pmc_clk cht_clks[] = {
+   {
+   .name = "xtal",
+   .freq = 1920,
+   .parent_name = NULL,
+   },
+   {},
+};
+
 static const struct pmc_bit_map d3_sts_0_map[] = {
{"LPSS1_F0_DMA",BIT_LPSS1_F0_DMA},
{"LPSS1_F1_PWM1",   BIT_LPSS1_F1_PWM1},
@@ -168,6 +198,16 @@ struct pmc_dev {
.pss= cht_pss_map,
 };
 
+static const struct pmc_data byt_data = {
+   .map = _reg_map,
+   .clks = byt_clks,
+};
+
+static const struct pmc_data cht_data = {
+   .map = _reg_map,
+   .clks = cht_clks,
+};
+
 static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
 {
return readl(pmc->regmap + reg_offset);
@@ -381,10 +421,36 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc)
 }
 #endif /* CONFIG_DEBUG_FS */
 
+static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap,
+ const struct pmc_data *pmc_data)
+{
+   struct platform_device *clkdev;
+   struct pmc_clk_data *clk_data;
+
+   clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+   if (!clk_data)
+   return -ENOMEM;
+
+   clk_data->base = pmc_regmap + PMC_CLK_CTL_0;
+   clk_data->clks = pmc_data->clks;
+
+   clkdev = platform_device_register_data(>dev, "clk-byt-plt", -1,
+  clk_data, sizeof(*clk_data));
+   if (IS_ERR(clkdev)) {
+   kfree(clk_data);
+   return PTR_ERR(clkdev);
+   }
+
+   kfree(clk_data);
+
+   return 0;
+}
+
 static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
struct pmc_dev *pmc = _device;
-   const struct pmc_reg_map *map = (struct pmc_reg_map *)ent->driver_data;
+   const struct pmc_data *data = (struct pmc_data *)ent->driver_data;
+   const struct pmc_reg_map *map = data->map;
int ret;
 
/* Obtain ACPI base address */
@@ -413,6 +479,12 @@ static int pmc_setup_dev(struct pci_dev *pdev, const 
struct pci_device_id *ent)
if (ret)
dev_warn(>dev, "debugfs register failed\n");
 
+   /* Register platform clocks - PMC_PLT_CLK [5:0] */
+   ret = pmc_setup_clks(pdev, pmc->regmap, data);
+   if (ret)
+   dev_warn(>dev, "platform clocks register failed: %d\n",
+ret);
+
pmc->init = true;
return ret;
 }
@@ -423,8 +495,8 @@ static int pmc_setup_dev(struct pci_dev *pdev, const struct 
pci_device_id *ent)
  * used by pci_match_id() call below.
  */
 static const struct pci_device_id pmc_pci_ids[] = {
-   { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_VLV_PMC), 
(kernel_ulong_t)_reg_map },
- 

[PATCH v6 1/3] clk: x86: Add Atom PMC platform clocks

2016-12-09 Thread Irina Tirdea
The BayTrail and CherryTrail platforms provide platform clocks
through their Power Management Controller (PMC).

The SoC supports up to 6 clocks (PMC_PLT_CLK[5:0]) with a
frequency of either 19.2 MHz (PLL) or 25 MHz (XTAL) for BayTrail
and a frequency of 19.2 MHz (XTAL) for CherryTrail. These clocks
are available for general system use, where appropriate, and each
have Control & Frequency register fields associated with them.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
---
 drivers/clk/x86/Makefile  |   3 +
 drivers/clk/x86/clk-byt-plt.c | 380 ++
 include/linux/platform_data/x86/clk-byt-plt.h |  31 +++
 3 files changed, 414 insertions(+)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 create mode 100644 include/linux/platform_data/x86/clk-byt-plt.h

diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile
index 0478138..bf7c132 100644
--- a/drivers/clk/x86/Makefile
+++ b/drivers/clk/x86/Makefile
@@ -1,2 +1,5 @@
 clk-x86-lpss-objs  := clk-lpt.o
 obj-$(CONFIG_X86_INTEL_LPSS)   += clk-x86-lpss.o
+ifeq ($(CONFIG_COMMON_CLK), y)
+obj-$(CONFIG_PMC_ATOM) += clk-byt-plt.o
+endif
diff --git a/drivers/clk/x86/clk-byt-plt.c b/drivers/clk/x86/clk-byt-plt.c
new file mode 100644
index 000..2303e0d
--- /dev/null
+++ b/drivers/clk/x86/clk-byt-plt.c
@@ -0,0 +1,380 @@
+/*
+ * Intel Atom platform clocks driver for BayTrail and CherryTrail SoC.
+ *
+ * Copyright (C) 2016, Intel Corporation
+ * Author: Irina Tirdea <irina.tir...@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PLT_CLK_NAME_BASE  "pmc_plt_clk_"
+#define PLT_CLK_DRIVER_NAME"clk-byt-plt"
+
+#define PMC_CLK_CTL_SIZE   4
+#define PMC_CLK_NUM6
+#define PMC_MASK_CLK_CTL   GENMASK(1, 0)
+#define PMC_MASK_CLK_FREQ  BIT(2)
+#define PMC_CLK_CTL_GATED_ON_D30x0
+#define PMC_CLK_CTL_FORCE_ON   0x1
+#define PMC_CLK_CTL_FORCE_OFF  0x2
+#define PMC_CLK_CTL_RESERVED   0x3
+#define PMC_CLK_FREQ_XTAL  0x0 /* 25 MHz */
+#define PMC_CLK_FREQ_PLL   0x4 /* 19.2 MHz */
+
+struct clk_plt_fixed {
+   struct clk_hw *clk;
+   struct clk_lookup *lookup;
+};
+
+struct clk_plt {
+   struct clk_hw hw;
+   void __iomem *reg;
+   struct clk_lookup *lookup;
+   spinlock_t lock;
+};
+
+#define to_clk_plt(_hw) container_of(_hw, struct clk_plt, hw)
+
+struct clk_plt_data {
+   struct clk_plt_fixed **parents;
+   u8 nparents;
+   struct clk_plt *clks[PMC_CLK_NUM];
+};
+
+static inline int plt_reg_to_parent(int reg)
+{
+   switch (reg & PMC_MASK_CLK_FREQ) {
+   case PMC_CLK_FREQ_XTAL:
+   return 0;   /* index 0 in parents[] */
+   case PMC_CLK_FREQ_PLL:
+   return 1;   /* index 1 in parents[] */
+   }
+
+   return 0;
+}
+
+static inline int plt_parent_to_reg(int index)
+{
+   switch (index) {
+   case 0: /* index 0 in parents[] */
+   return PMC_CLK_FREQ_XTAL;
+   case 1: /* index 0 in parents[] */
+   return PMC_CLK_FREQ_PLL;
+   }
+
+   return PMC_CLK_FREQ_XTAL;
+}
+
+static inline int plt_reg_to_enabled(int reg)
+{
+   switch (reg & PMC_MASK_CLK_CTL) {
+   case PMC_CLK_CTL_GATED_ON_D3:
+   case PMC_CLK_CTL_FORCE_ON:
+   return 1;   /* enabled */
+   case PMC_CLK_CTL_FORCE_OFF:
+   case PMC_CLK_CTL_RESERVED:
+   default:
+   return 0;   /* disabled */
+   }
+}
+
+static void plt_clk_reg_update(struct clk_plt *clk, u32 mask, u32 val)
+{
+   u32 orig, tmp;
+   unsigned long flags = 0;
+
+   spin_lock_irqsave(>lock, flags);
+
+   orig = readl(clk->reg);
+
+   tmp = orig & ~mask;
+   tmp |= val & mask;
+
+   if (tmp != orig)
+   writel(tmp, clk->reg);
+
+   spin_unlock_irqrestore(>lock, flags);
+}
+
+static int plt_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct clk_plt *clk = to_clk_plt(hw);
+
+   plt_clk_reg_update(clk, PMC_MASK_CLK_FREQ, plt_parent_to_reg(index));
+
+   return 0;
+}
+
+static u8 plt_clk_get_parent(struct clk_hw *hw)
+{
+   struct clk_plt *clk = to_clk_plt(hw);
+   u32 value;
+
+   value = readl(clk->reg);
+
+   return plt_reg_to_parent(value);
+}
+
+static int plt_clk_enable(struct clk_hw *hw)
+{
+

[PATCH v6 1/3] clk: x86: Add Atom PMC platform clocks

2016-12-09 Thread Irina Tirdea
The BayTrail and CherryTrail platforms provide platform clocks
through their Power Management Controller (PMC).

The SoC supports up to 6 clocks (PMC_PLT_CLK[5:0]) with a
frequency of either 19.2 MHz (PLL) or 25 MHz (XTAL) for BayTrail
and a frequency of 19.2 MHz (XTAL) for CherryTrail. These clocks
are available for general system use, where appropriate, and each
have Control & Frequency register fields associated with them.

Signed-off-by: Irina Tirdea 
Signed-off-by: Pierre-Louis Bossart 
---
 drivers/clk/x86/Makefile  |   3 +
 drivers/clk/x86/clk-byt-plt.c | 380 ++
 include/linux/platform_data/x86/clk-byt-plt.h |  31 +++
 3 files changed, 414 insertions(+)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 create mode 100644 include/linux/platform_data/x86/clk-byt-plt.h

diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile
index 0478138..bf7c132 100644
--- a/drivers/clk/x86/Makefile
+++ b/drivers/clk/x86/Makefile
@@ -1,2 +1,5 @@
 clk-x86-lpss-objs  := clk-lpt.o
 obj-$(CONFIG_X86_INTEL_LPSS)   += clk-x86-lpss.o
+ifeq ($(CONFIG_COMMON_CLK), y)
+obj-$(CONFIG_PMC_ATOM) += clk-byt-plt.o
+endif
diff --git a/drivers/clk/x86/clk-byt-plt.c b/drivers/clk/x86/clk-byt-plt.c
new file mode 100644
index 000..2303e0d
--- /dev/null
+++ b/drivers/clk/x86/clk-byt-plt.c
@@ -0,0 +1,380 @@
+/*
+ * Intel Atom platform clocks driver for BayTrail and CherryTrail SoC.
+ *
+ * Copyright (C) 2016, Intel Corporation
+ * Author: Irina Tirdea 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PLT_CLK_NAME_BASE  "pmc_plt_clk_"
+#define PLT_CLK_DRIVER_NAME"clk-byt-plt"
+
+#define PMC_CLK_CTL_SIZE   4
+#define PMC_CLK_NUM6
+#define PMC_MASK_CLK_CTL   GENMASK(1, 0)
+#define PMC_MASK_CLK_FREQ  BIT(2)
+#define PMC_CLK_CTL_GATED_ON_D30x0
+#define PMC_CLK_CTL_FORCE_ON   0x1
+#define PMC_CLK_CTL_FORCE_OFF  0x2
+#define PMC_CLK_CTL_RESERVED   0x3
+#define PMC_CLK_FREQ_XTAL  0x0 /* 25 MHz */
+#define PMC_CLK_FREQ_PLL   0x4 /* 19.2 MHz */
+
+struct clk_plt_fixed {
+   struct clk_hw *clk;
+   struct clk_lookup *lookup;
+};
+
+struct clk_plt {
+   struct clk_hw hw;
+   void __iomem *reg;
+   struct clk_lookup *lookup;
+   spinlock_t lock;
+};
+
+#define to_clk_plt(_hw) container_of(_hw, struct clk_plt, hw)
+
+struct clk_plt_data {
+   struct clk_plt_fixed **parents;
+   u8 nparents;
+   struct clk_plt *clks[PMC_CLK_NUM];
+};
+
+static inline int plt_reg_to_parent(int reg)
+{
+   switch (reg & PMC_MASK_CLK_FREQ) {
+   case PMC_CLK_FREQ_XTAL:
+   return 0;   /* index 0 in parents[] */
+   case PMC_CLK_FREQ_PLL:
+   return 1;   /* index 1 in parents[] */
+   }
+
+   return 0;
+}
+
+static inline int plt_parent_to_reg(int index)
+{
+   switch (index) {
+   case 0: /* index 0 in parents[] */
+   return PMC_CLK_FREQ_XTAL;
+   case 1: /* index 0 in parents[] */
+   return PMC_CLK_FREQ_PLL;
+   }
+
+   return PMC_CLK_FREQ_XTAL;
+}
+
+static inline int plt_reg_to_enabled(int reg)
+{
+   switch (reg & PMC_MASK_CLK_CTL) {
+   case PMC_CLK_CTL_GATED_ON_D3:
+   case PMC_CLK_CTL_FORCE_ON:
+   return 1;   /* enabled */
+   case PMC_CLK_CTL_FORCE_OFF:
+   case PMC_CLK_CTL_RESERVED:
+   default:
+   return 0;   /* disabled */
+   }
+}
+
+static void plt_clk_reg_update(struct clk_plt *clk, u32 mask, u32 val)
+{
+   u32 orig, tmp;
+   unsigned long flags = 0;
+
+   spin_lock_irqsave(>lock, flags);
+
+   orig = readl(clk->reg);
+
+   tmp = orig & ~mask;
+   tmp |= val & mask;
+
+   if (tmp != orig)
+   writel(tmp, clk->reg);
+
+   spin_unlock_irqrestore(>lock, flags);
+}
+
+static int plt_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct clk_plt *clk = to_clk_plt(hw);
+
+   plt_clk_reg_update(clk, PMC_MASK_CLK_FREQ, plt_parent_to_reg(index));
+
+   return 0;
+}
+
+static u8 plt_clk_get_parent(struct clk_hw *hw)
+{
+   struct clk_plt *clk = to_clk_plt(hw);
+   u32 value;
+
+   value = readl(clk->reg);
+
+   return plt_reg_to_parent(value);
+}
+
+static int plt_clk_enable(struct clk_hw *hw)
+{
+   struct clk_plt *clk = to_clk_plt(hw);
+
+   plt_clk_reg_update(clk, PMC_MASK_CLK_CTL, PMC_C

[PATCH v6 2/3] arch/x86/platform/atom: Move pmc_atom to drivers/platform/x86

2016-12-09 Thread Irina Tirdea
The pmc_atom driver does not contain any architecture specific
code. It only enables the SOC Power Management Controller Driver
for BayTrail and CherryTrail platforms.

Move the pmc_atom driver from arch/x86/platform/atom to
drivers/platform/x86.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 arch/x86/Kconfig | 4 
 arch/x86/platform/atom/Makefile  | 1 -
 drivers/acpi/acpi_lpss.c | 2 +-
 drivers/platform/x86/Kconfig | 4 
 drivers/platform/x86/Makefile| 1 +
 {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c  | 3 +--
 {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h | 0
 7 files changed, 7 insertions(+), 8 deletions(-)
 rename {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c (99%)
 rename {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h 
(100%)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bada636..5a009f0 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2753,10 +2753,6 @@ config X86_DMA_REMAP
bool
depends on STA2X11
 
-config PMC_ATOM
-   def_bool y
-depends on PCI
-
 source "net/Kconfig"
 
 source "drivers/Kconfig"
diff --git a/arch/x86/platform/atom/Makefile b/arch/x86/platform/atom/Makefile
index 40983f5..57be88f 100644
--- a/arch/x86/platform/atom/Makefile
+++ b/arch/x86/platform/atom/Makefile
@@ -1,2 +1 @@
-obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
 obj-$(CONFIG_PUNIT_ATOM_DEBUG) += punit_atom_debug.o
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 373657f..3e4c566 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -31,7 +32,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #define LPSS_ADDR(desc) ((unsigned long))
 
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index b8a21d7..21dce1e 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1028,3 +1028,7 @@ config INTEL_TELEMETRY
  directly via debugfs files. Various tools may use
  this interface for SoC state monitoring.
 endif # X86_PLATFORM_DEVICES
+
+config PMC_ATOM
+   def_bool y
+depends on PCI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 2efa86d..8568d74 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -71,3 +71,4 @@ obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
   intel_telemetry_pltdrv.o \
   intel_telemetry_debugfs.o
 obj-$(CONFIG_INTEL_PMC_CORE)+= intel_pmc_core.o
+obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
diff --git a/arch/x86/platform/atom/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
similarity index 99%
rename from arch/x86/platform/atom/pmc_atom.c
rename to drivers/platform/x86/pmc_atom.c
index 964ff4f..b53fbc1 100644
--- a/arch/x86/platform/atom/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -21,8 +21,7 @@
 #include 
 #include 
 #include 
-
-#include 
+#include 
 
 struct pmc_bit_map {
const char *name;
diff --git a/arch/x86/include/asm/pmc_atom.h 
b/include/linux/platform_data/x86/pmc_atom.h
similarity index 100%
rename from arch/x86/include/asm/pmc_atom.h
rename to include/linux/platform_data/x86/pmc_atom.h
-- 
1.9.1



[PATCH v6 2/3] arch/x86/platform/atom: Move pmc_atom to drivers/platform/x86

2016-12-09 Thread Irina Tirdea
The pmc_atom driver does not contain any architecture specific
code. It only enables the SOC Power Management Controller Driver
for BayTrail and CherryTrail platforms.

Move the pmc_atom driver from arch/x86/platform/atom to
drivers/platform/x86.

Signed-off-by: Irina Tirdea 
---
 arch/x86/Kconfig | 4 
 arch/x86/platform/atom/Makefile  | 1 -
 drivers/acpi/acpi_lpss.c | 2 +-
 drivers/platform/x86/Kconfig | 4 
 drivers/platform/x86/Makefile| 1 +
 {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c  | 3 +--
 {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h | 0
 7 files changed, 7 insertions(+), 8 deletions(-)
 rename {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c (99%)
 rename {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h 
(100%)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bada636..5a009f0 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2753,10 +2753,6 @@ config X86_DMA_REMAP
bool
depends on STA2X11
 
-config PMC_ATOM
-   def_bool y
-depends on PCI
-
 source "net/Kconfig"
 
 source "drivers/Kconfig"
diff --git a/arch/x86/platform/atom/Makefile b/arch/x86/platform/atom/Makefile
index 40983f5..57be88f 100644
--- a/arch/x86/platform/atom/Makefile
+++ b/arch/x86/platform/atom/Makefile
@@ -1,2 +1 @@
-obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
 obj-$(CONFIG_PUNIT_ATOM_DEBUG) += punit_atom_debug.o
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 373657f..3e4c566 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -31,7 +32,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #define LPSS_ADDR(desc) ((unsigned long))
 
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index b8a21d7..21dce1e 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1028,3 +1028,7 @@ config INTEL_TELEMETRY
  directly via debugfs files. Various tools may use
  this interface for SoC state monitoring.
 endif # X86_PLATFORM_DEVICES
+
+config PMC_ATOM
+   def_bool y
+depends on PCI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 2efa86d..8568d74 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -71,3 +71,4 @@ obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
   intel_telemetry_pltdrv.o \
   intel_telemetry_debugfs.o
 obj-$(CONFIG_INTEL_PMC_CORE)+= intel_pmc_core.o
+obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
diff --git a/arch/x86/platform/atom/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
similarity index 99%
rename from arch/x86/platform/atom/pmc_atom.c
rename to drivers/platform/x86/pmc_atom.c
index 964ff4f..b53fbc1 100644
--- a/arch/x86/platform/atom/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -21,8 +21,7 @@
 #include 
 #include 
 #include 
-
-#include 
+#include 
 
 struct pmc_bit_map {
const char *name;
diff --git a/arch/x86/include/asm/pmc_atom.h 
b/include/linux/platform_data/x86/pmc_atom.h
similarity index 100%
rename from arch/x86/include/asm/pmc_atom.h
rename to include/linux/platform_data/x86/pmc_atom.h
-- 
1.9.1



[PATCH v6 0/3] Add platform clock for BayTrail platforms

2016-12-09 Thread Irina Tirdea
These patches specifically enable the audio MCLK required by Baytrail CR
devices. It is the remaining part of a bigger set of patches
(already merged in Mark's tree) that enable sound for Baytrail CR devices
(especially Asus T100TAF) [1]. They include the clock driver and enabling
the clock in the pmc_atom code (along with moving of the non-architectural
pmc_atom driver code into drivers/platform/x86).

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2016-August/111704.html

Changes from v5:
 - fix build error reported by kbuild test robot
 - split the clk driver code from x86 platform changes

Changes from v4:
 - move the pmc_atom driver from arch/x86/platform/atom to
drivers/platform/x86

Changes from v3:
 - replace devm_kzalloc with devm_kcalloc
 - add x86 architecture maintainers

Changes from v2:
 - move clk platform data structures to a separate include file
 - store clk_hw pointer for the fixed rate clocks

Changes from v1:
 - register the clk device as child of pmc device
 - pass iomem pointer from pmc driver to clk driver to avoid using
pmc_atom_read()/write() and use readl/writel API instead
 - use devm_clk_hw_register/clkdev_hw_create instead of
clk_register/clkdev_create

Irina Tirdea (3):
  clk: x86: Add Atom PMC platform clocks
  arch/x86/platform/atom: Move pmc_atom to drivers/platform/x86
  platform/x86: Enable Atom PMC platform clocks

 arch/x86/Kconfig   |   4 -
 arch/x86/platform/atom/Makefile|   1 -
 drivers/acpi/acpi_lpss.c   |   2 +-
 drivers/clk/x86/Makefile   |   3 +
 drivers/clk/x86/clk-byt-plt.c  | 380 +
 drivers/platform/x86/Kconfig   |   5 +
 drivers/platform/x86/Makefile  |   1 +
 .../atom => drivers/platform/x86}/pmc_atom.c   |  81 -
 include/linux/platform_data/x86/clk-byt-plt.h  |  31 ++
 .../linux/platform_data/x86}/pmc_atom.h|   3 +
 10 files changed, 500 insertions(+), 11 deletions(-)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 rename {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c (88%)
 create mode 100644 include/linux/platform_data/x86/clk-byt-plt.h
 rename {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h 
(98%)

-- 
1.9.1



[PATCH v6 0/3] Add platform clock for BayTrail platforms

2016-12-09 Thread Irina Tirdea
These patches specifically enable the audio MCLK required by Baytrail CR
devices. It is the remaining part of a bigger set of patches
(already merged in Mark's tree) that enable sound for Baytrail CR devices
(especially Asus T100TAF) [1]. They include the clock driver and enabling
the clock in the pmc_atom code (along with moving of the non-architectural
pmc_atom driver code into drivers/platform/x86).

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2016-August/111704.html

Changes from v5:
 - fix build error reported by kbuild test robot
 - split the clk driver code from x86 platform changes

Changes from v4:
 - move the pmc_atom driver from arch/x86/platform/atom to
drivers/platform/x86

Changes from v3:
 - replace devm_kzalloc with devm_kcalloc
 - add x86 architecture maintainers

Changes from v2:
 - move clk platform data structures to a separate include file
 - store clk_hw pointer for the fixed rate clocks

Changes from v1:
 - register the clk device as child of pmc device
 - pass iomem pointer from pmc driver to clk driver to avoid using
pmc_atom_read()/write() and use readl/writel API instead
 - use devm_clk_hw_register/clkdev_hw_create instead of
clk_register/clkdev_create

Irina Tirdea (3):
  clk: x86: Add Atom PMC platform clocks
  arch/x86/platform/atom: Move pmc_atom to drivers/platform/x86
  platform/x86: Enable Atom PMC platform clocks

 arch/x86/Kconfig   |   4 -
 arch/x86/platform/atom/Makefile|   1 -
 drivers/acpi/acpi_lpss.c   |   2 +-
 drivers/clk/x86/Makefile   |   3 +
 drivers/clk/x86/clk-byt-plt.c  | 380 +
 drivers/platform/x86/Kconfig   |   5 +
 drivers/platform/x86/Makefile  |   1 +
 .../atom => drivers/platform/x86}/pmc_atom.c   |  81 -
 include/linux/platform_data/x86/clk-byt-plt.h  |  31 ++
 .../linux/platform_data/x86}/pmc_atom.h|   3 +
 10 files changed, 500 insertions(+), 11 deletions(-)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 rename {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c (88%)
 create mode 100644 include/linux/platform_data/x86/clk-byt-plt.h
 rename {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h 
(98%)

-- 
1.9.1



[PATCH v5 1/2] arch/x86/platform/atom: Move pmc_atom to drivers/platform/x86

2016-12-07 Thread Irina Tirdea
The pmc_atom driver does not contain any architecture specific
code. It only enables the SOC Power Management Controller Driver
for BayTrail and CherryTrail platforms.

Move the pmc_atom driver from arch/x86/platform/atom to
drivers/platform/x86.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 arch/x86/Kconfig | 4 
 arch/x86/platform/atom/Makefile  | 1 -
 drivers/acpi/acpi_lpss.c | 2 +-
 drivers/platform/x86/Kconfig | 5 +
 drivers/platform/x86/Makefile| 1 +
 {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c  | 3 +--
 {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h | 0
 7 files changed, 8 insertions(+), 8 deletions(-)
 rename {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c (99%)
 rename {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h 
(100%)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bada636..5a009f0 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2753,10 +2753,6 @@ config X86_DMA_REMAP
bool
depends on STA2X11
 
-config PMC_ATOM
-   def_bool y
-depends on PCI
-
 source "net/Kconfig"
 
 source "drivers/Kconfig"
diff --git a/arch/x86/platform/atom/Makefile b/arch/x86/platform/atom/Makefile
index 40983f5..57be88f 100644
--- a/arch/x86/platform/atom/Makefile
+++ b/arch/x86/platform/atom/Makefile
@@ -1,2 +1 @@
-obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
 obj-$(CONFIG_PUNIT_ATOM_DEBUG) += punit_atom_debug.o
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 373657f..3e4c566 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -31,7 +32,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #define LPSS_ADDR(desc) ((unsigned long))
 
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index b8a21d7..7b74c53 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1027,4 +1027,9 @@ config INTEL_TELEMETRY
  used to get various SoC events and parameters
  directly via debugfs files. Various tools may use
  this interface for SoC state monitoring.
+
+config PMC_ATOM
+   def_bool y
+depends on PCI
+
 endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 2efa86d..8568d74 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -71,3 +71,4 @@ obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
   intel_telemetry_pltdrv.o \
   intel_telemetry_debugfs.o
 obj-$(CONFIG_INTEL_PMC_CORE)+= intel_pmc_core.o
+obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
diff --git a/arch/x86/platform/atom/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
similarity index 99%
rename from arch/x86/platform/atom/pmc_atom.c
rename to drivers/platform/x86/pmc_atom.c
index 964ff4f..b53fbc1 100644
--- a/arch/x86/platform/atom/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -21,8 +21,7 @@
 #include 
 #include 
 #include 
-
-#include 
+#include 
 
 struct pmc_bit_map {
const char *name;
diff --git a/arch/x86/include/asm/pmc_atom.h 
b/include/linux/platform_data/x86/pmc_atom.h
similarity index 100%
rename from arch/x86/include/asm/pmc_atom.h
rename to include/linux/platform_data/x86/pmc_atom.h
-- 
1.9.1



[PATCH v5 1/2] arch/x86/platform/atom: Move pmc_atom to drivers/platform/x86

2016-12-07 Thread Irina Tirdea
The pmc_atom driver does not contain any architecture specific
code. It only enables the SOC Power Management Controller Driver
for BayTrail and CherryTrail platforms.

Move the pmc_atom driver from arch/x86/platform/atom to
drivers/platform/x86.

Signed-off-by: Irina Tirdea 
---
 arch/x86/Kconfig | 4 
 arch/x86/platform/atom/Makefile  | 1 -
 drivers/acpi/acpi_lpss.c | 2 +-
 drivers/platform/x86/Kconfig | 5 +
 drivers/platform/x86/Makefile| 1 +
 {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c  | 3 +--
 {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h | 0
 7 files changed, 8 insertions(+), 8 deletions(-)
 rename {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c (99%)
 rename {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h 
(100%)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bada636..5a009f0 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2753,10 +2753,6 @@ config X86_DMA_REMAP
bool
depends on STA2X11
 
-config PMC_ATOM
-   def_bool y
-depends on PCI
-
 source "net/Kconfig"
 
 source "drivers/Kconfig"
diff --git a/arch/x86/platform/atom/Makefile b/arch/x86/platform/atom/Makefile
index 40983f5..57be88f 100644
--- a/arch/x86/platform/atom/Makefile
+++ b/arch/x86/platform/atom/Makefile
@@ -1,2 +1 @@
-obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
 obj-$(CONFIG_PUNIT_ATOM_DEBUG) += punit_atom_debug.o
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 373657f..3e4c566 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -31,7 +32,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #define LPSS_ADDR(desc) ((unsigned long))
 
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index b8a21d7..7b74c53 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1027,4 +1027,9 @@ config INTEL_TELEMETRY
  used to get various SoC events and parameters
  directly via debugfs files. Various tools may use
  this interface for SoC state monitoring.
+
+config PMC_ATOM
+   def_bool y
+depends on PCI
+
 endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 2efa86d..8568d74 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -71,3 +71,4 @@ obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
   intel_telemetry_pltdrv.o \
   intel_telemetry_debugfs.o
 obj-$(CONFIG_INTEL_PMC_CORE)+= intel_pmc_core.o
+obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
diff --git a/arch/x86/platform/atom/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
similarity index 99%
rename from arch/x86/platform/atom/pmc_atom.c
rename to drivers/platform/x86/pmc_atom.c
index 964ff4f..b53fbc1 100644
--- a/arch/x86/platform/atom/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -21,8 +21,7 @@
 #include 
 #include 
 #include 
-
-#include 
+#include 
 
 struct pmc_bit_map {
const char *name;
diff --git a/arch/x86/include/asm/pmc_atom.h 
b/include/linux/platform_data/x86/pmc_atom.h
similarity index 100%
rename from arch/x86/include/asm/pmc_atom.h
rename to include/linux/platform_data/x86/pmc_atom.h
-- 
1.9.1



[PATCH v5 0/2] Add platform clock for BayTrail platforms

2016-12-07 Thread Irina Tirdea
These patches specifically enable the audio MCLK required by Baytrail CR
devices. It is the remaining part of a bigger set of patches
(already merged in Mark's tree) that enable sound for Baytrail CR devices
(especially Asus T100TAF) [1]. They include the clock driver and a move
of the non-architectural pmc_atom driver code into drivers/platform/x86.

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2016-August/111704.html

Changes from v4:
 - move the pmc_atom driver from arch/x86/platform/atom to
drivers/platform/x86

Changes from v3:
 - replace devm_kzalloc with devm_kcalloc
 - add x86 architecture maintainers

Changes from v2:
 - move clk platform data structures to a separate include file
 - store clk_hw pointer for the fixed rate clocks

Changes from v1:
 - register the clk device as child of pmc device
 - pass iomem pointer from pmc driver to clk driver to avoid using
pmc_atom_read()/write() and use readl/writel API instead
 - use devm_clk_hw_register/clkdev_hw_create instead of
clk_register/clkdev_create

Irina Tirdea (2):
  arch/x86/platform/atom: Move pmc_atom to drivers/platform/x86
  clk: x86: Add Atom PMC platform clocks

 arch/x86/Kconfig   |   4 -
 arch/x86/platform/atom/Makefile|   1 -
 drivers/acpi/acpi_lpss.c   |   2 +-
 drivers/clk/x86/Makefile   |   1 +
 drivers/clk/x86/clk-byt-plt.c  | 380 +
 drivers/platform/x86/Kconfig   |   6 +
 drivers/platform/x86/Makefile  |   1 +
 .../atom => drivers/platform/x86}/pmc_atom.c   |  81 -
 include/linux/platform_data/x86/clk-byt-plt.h  |  31 ++
 .../linux/platform_data/x86}/pmc_atom.h|   3 +
 10 files changed, 499 insertions(+), 11 deletions(-)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 rename {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c (88%)
 create mode 100644 include/linux/platform_data/x86/clk-byt-plt.h
 rename {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h 
(98%)

-- 
1.9.1



[PATCH v5 0/2] Add platform clock for BayTrail platforms

2016-12-07 Thread Irina Tirdea
These patches specifically enable the audio MCLK required by Baytrail CR
devices. It is the remaining part of a bigger set of patches
(already merged in Mark's tree) that enable sound for Baytrail CR devices
(especially Asus T100TAF) [1]. They include the clock driver and a move
of the non-architectural pmc_atom driver code into drivers/platform/x86.

[1] http://mailman.alsa-project.org/pipermail/alsa-devel/2016-August/111704.html

Changes from v4:
 - move the pmc_atom driver from arch/x86/platform/atom to
drivers/platform/x86

Changes from v3:
 - replace devm_kzalloc with devm_kcalloc
 - add x86 architecture maintainers

Changes from v2:
 - move clk platform data structures to a separate include file
 - store clk_hw pointer for the fixed rate clocks

Changes from v1:
 - register the clk device as child of pmc device
 - pass iomem pointer from pmc driver to clk driver to avoid using
pmc_atom_read()/write() and use readl/writel API instead
 - use devm_clk_hw_register/clkdev_hw_create instead of
clk_register/clkdev_create

Irina Tirdea (2):
  arch/x86/platform/atom: Move pmc_atom to drivers/platform/x86
  clk: x86: Add Atom PMC platform clocks

 arch/x86/Kconfig   |   4 -
 arch/x86/platform/atom/Makefile|   1 -
 drivers/acpi/acpi_lpss.c   |   2 +-
 drivers/clk/x86/Makefile   |   1 +
 drivers/clk/x86/clk-byt-plt.c  | 380 +
 drivers/platform/x86/Kconfig   |   6 +
 drivers/platform/x86/Makefile  |   1 +
 .../atom => drivers/platform/x86}/pmc_atom.c   |  81 -
 include/linux/platform_data/x86/clk-byt-plt.h  |  31 ++
 .../linux/platform_data/x86}/pmc_atom.h|   3 +
 10 files changed, 499 insertions(+), 11 deletions(-)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 rename {arch/x86/platform/atom => drivers/platform/x86}/pmc_atom.c (88%)
 create mode 100644 include/linux/platform_data/x86/clk-byt-plt.h
 rename {arch/x86/include/asm => include/linux/platform_data/x86}/pmc_atom.h 
(98%)

-- 
1.9.1



[PATCH v5 2/2] clk: x86: Add Atom PMC platform clocks

2016-12-07 Thread Irina Tirdea
The BayTrail and CherryTrail platforms provide platform clocks
through their Power Management Controller (PMC).

The SoC supports up to 6 clocks (PMC_PLT_CLK[5:0]) with a
frequency of either 19.2 MHz (PLL) or 25 MHz (XTAL) for BayTrail
an a frequency of 19.2 MHz (XTAL) for CherryTrail. These clocks
are available for general system use, where appropriate, and each
have Control & Frequency register fields associated with them.

For example, the usage for platform clocks suggested in the datasheet
is the following:
  PLT_CLK[2:0] - Camera
  PLT_CLK[3] - Audio Codec
  PLT_CLK[4] -
  PLT_CLK[5] - COMMs

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
---
 drivers/clk/x86/Makefile  |   1 +
 drivers/clk/x86/clk-byt-plt.c | 380 ++
 drivers/platform/x86/Kconfig  |   1 +
 drivers/platform/x86/pmc_atom.c   |  78 +-
 include/linux/platform_data/x86/clk-byt-plt.h |  31 +++
 include/linux/platform_data/x86/pmc_atom.h|   3 +
 6 files changed, 491 insertions(+), 3 deletions(-)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 create mode 100644 include/linux/platform_data/x86/clk-byt-plt.h

diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile
index 0478138..cbdc8cc 100644
--- a/drivers/clk/x86/Makefile
+++ b/drivers/clk/x86/Makefile
@@ -1,2 +1,3 @@
 clk-x86-lpss-objs  := clk-lpt.o
 obj-$(CONFIG_X86_INTEL_LPSS)   += clk-x86-lpss.o
+obj-$(CONFIG_PMC_ATOM) += clk-byt-plt.o
diff --git a/drivers/clk/x86/clk-byt-plt.c b/drivers/clk/x86/clk-byt-plt.c
new file mode 100644
index 000..2303e0d
--- /dev/null
+++ b/drivers/clk/x86/clk-byt-plt.c
@@ -0,0 +1,380 @@
+/*
+ * Intel Atom platform clocks driver for BayTrail and CherryTrail SoC.
+ *
+ * Copyright (C) 2016, Intel Corporation
+ * Author: Irina Tirdea <irina.tir...@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PLT_CLK_NAME_BASE  "pmc_plt_clk_"
+#define PLT_CLK_DRIVER_NAME"clk-byt-plt"
+
+#define PMC_CLK_CTL_SIZE   4
+#define PMC_CLK_NUM6
+#define PMC_MASK_CLK_CTL   GENMASK(1, 0)
+#define PMC_MASK_CLK_FREQ  BIT(2)
+#define PMC_CLK_CTL_GATED_ON_D30x0
+#define PMC_CLK_CTL_FORCE_ON   0x1
+#define PMC_CLK_CTL_FORCE_OFF  0x2
+#define PMC_CLK_CTL_RESERVED   0x3
+#define PMC_CLK_FREQ_XTAL  0x0 /* 25 MHz */
+#define PMC_CLK_FREQ_PLL   0x4 /* 19.2 MHz */
+
+struct clk_plt_fixed {
+   struct clk_hw *clk;
+   struct clk_lookup *lookup;
+};
+
+struct clk_plt {
+   struct clk_hw hw;
+   void __iomem *reg;
+   struct clk_lookup *lookup;
+   spinlock_t lock;
+};
+
+#define to_clk_plt(_hw) container_of(_hw, struct clk_plt, hw)
+
+struct clk_plt_data {
+   struct clk_plt_fixed **parents;
+   u8 nparents;
+   struct clk_plt *clks[PMC_CLK_NUM];
+};
+
+static inline int plt_reg_to_parent(int reg)
+{
+   switch (reg & PMC_MASK_CLK_FREQ) {
+   case PMC_CLK_FREQ_XTAL:
+   return 0;   /* index 0 in parents[] */
+   case PMC_CLK_FREQ_PLL:
+   return 1;   /* index 1 in parents[] */
+   }
+
+   return 0;
+}
+
+static inline int plt_parent_to_reg(int index)
+{
+   switch (index) {
+   case 0: /* index 0 in parents[] */
+   return PMC_CLK_FREQ_XTAL;
+   case 1: /* index 0 in parents[] */
+   return PMC_CLK_FREQ_PLL;
+   }
+
+   return PMC_CLK_FREQ_XTAL;
+}
+
+static inline int plt_reg_to_enabled(int reg)
+{
+   switch (reg & PMC_MASK_CLK_CTL) {
+   case PMC_CLK_CTL_GATED_ON_D3:
+   case PMC_CLK_CTL_FORCE_ON:
+   return 1;   /* enabled */
+   case PMC_CLK_CTL_FORCE_OFF:
+   case PMC_CLK_CTL_RESERVED:
+   default:
+   return 0;   /* disabled */
+   }
+}
+
+static void plt_clk_reg_update(struct clk_plt *clk, u32 mask, u32 val)
+{
+   u32 orig, tmp;
+   unsigned long flags = 0;
+
+   spin_lock_irqsave(>lock, flags);
+
+   orig = readl(clk->reg);
+
+   tmp = orig & ~mask;
+   tmp |= val & mask;
+
+   if (tmp != orig)
+   writel(tmp, clk->reg);
+
+   spin_unlock_irqrestore(>lock, flags);
+}
+
+static int plt_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct clk_plt *clk = to_clk_plt(hw);
+
+   plt_clk_reg_update

[PATCH v5 2/2] clk: x86: Add Atom PMC platform clocks

2016-12-07 Thread Irina Tirdea
The BayTrail and CherryTrail platforms provide platform clocks
through their Power Management Controller (PMC).

The SoC supports up to 6 clocks (PMC_PLT_CLK[5:0]) with a
frequency of either 19.2 MHz (PLL) or 25 MHz (XTAL) for BayTrail
an a frequency of 19.2 MHz (XTAL) for CherryTrail. These clocks
are available for general system use, where appropriate, and each
have Control & Frequency register fields associated with them.

For example, the usage for platform clocks suggested in the datasheet
is the following:
  PLT_CLK[2:0] - Camera
  PLT_CLK[3] - Audio Codec
  PLT_CLK[4] -
  PLT_CLK[5] - COMMs

Signed-off-by: Irina Tirdea 
Signed-off-by: Pierre-Louis Bossart 
---
 drivers/clk/x86/Makefile  |   1 +
 drivers/clk/x86/clk-byt-plt.c | 380 ++
 drivers/platform/x86/Kconfig  |   1 +
 drivers/platform/x86/pmc_atom.c   |  78 +-
 include/linux/platform_data/x86/clk-byt-plt.h |  31 +++
 include/linux/platform_data/x86/pmc_atom.h|   3 +
 6 files changed, 491 insertions(+), 3 deletions(-)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 create mode 100644 include/linux/platform_data/x86/clk-byt-plt.h

diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile
index 0478138..cbdc8cc 100644
--- a/drivers/clk/x86/Makefile
+++ b/drivers/clk/x86/Makefile
@@ -1,2 +1,3 @@
 clk-x86-lpss-objs  := clk-lpt.o
 obj-$(CONFIG_X86_INTEL_LPSS)   += clk-x86-lpss.o
+obj-$(CONFIG_PMC_ATOM) += clk-byt-plt.o
diff --git a/drivers/clk/x86/clk-byt-plt.c b/drivers/clk/x86/clk-byt-plt.c
new file mode 100644
index 000..2303e0d
--- /dev/null
+++ b/drivers/clk/x86/clk-byt-plt.c
@@ -0,0 +1,380 @@
+/*
+ * Intel Atom platform clocks driver for BayTrail and CherryTrail SoC.
+ *
+ * Copyright (C) 2016, Intel Corporation
+ * Author: Irina Tirdea 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PLT_CLK_NAME_BASE  "pmc_plt_clk_"
+#define PLT_CLK_DRIVER_NAME"clk-byt-plt"
+
+#define PMC_CLK_CTL_SIZE   4
+#define PMC_CLK_NUM6
+#define PMC_MASK_CLK_CTL   GENMASK(1, 0)
+#define PMC_MASK_CLK_FREQ  BIT(2)
+#define PMC_CLK_CTL_GATED_ON_D30x0
+#define PMC_CLK_CTL_FORCE_ON   0x1
+#define PMC_CLK_CTL_FORCE_OFF  0x2
+#define PMC_CLK_CTL_RESERVED   0x3
+#define PMC_CLK_FREQ_XTAL  0x0 /* 25 MHz */
+#define PMC_CLK_FREQ_PLL   0x4 /* 19.2 MHz */
+
+struct clk_plt_fixed {
+   struct clk_hw *clk;
+   struct clk_lookup *lookup;
+};
+
+struct clk_plt {
+   struct clk_hw hw;
+   void __iomem *reg;
+   struct clk_lookup *lookup;
+   spinlock_t lock;
+};
+
+#define to_clk_plt(_hw) container_of(_hw, struct clk_plt, hw)
+
+struct clk_plt_data {
+   struct clk_plt_fixed **parents;
+   u8 nparents;
+   struct clk_plt *clks[PMC_CLK_NUM];
+};
+
+static inline int plt_reg_to_parent(int reg)
+{
+   switch (reg & PMC_MASK_CLK_FREQ) {
+   case PMC_CLK_FREQ_XTAL:
+   return 0;   /* index 0 in parents[] */
+   case PMC_CLK_FREQ_PLL:
+   return 1;   /* index 1 in parents[] */
+   }
+
+   return 0;
+}
+
+static inline int plt_parent_to_reg(int index)
+{
+   switch (index) {
+   case 0: /* index 0 in parents[] */
+   return PMC_CLK_FREQ_XTAL;
+   case 1: /* index 0 in parents[] */
+   return PMC_CLK_FREQ_PLL;
+   }
+
+   return PMC_CLK_FREQ_XTAL;
+}
+
+static inline int plt_reg_to_enabled(int reg)
+{
+   switch (reg & PMC_MASK_CLK_CTL) {
+   case PMC_CLK_CTL_GATED_ON_D3:
+   case PMC_CLK_CTL_FORCE_ON:
+   return 1;   /* enabled */
+   case PMC_CLK_CTL_FORCE_OFF:
+   case PMC_CLK_CTL_RESERVED:
+   default:
+   return 0;   /* disabled */
+   }
+}
+
+static void plt_clk_reg_update(struct clk_plt *clk, u32 mask, u32 val)
+{
+   u32 orig, tmp;
+   unsigned long flags = 0;
+
+   spin_lock_irqsave(>lock, flags);
+
+   orig = readl(clk->reg);
+
+   tmp = orig & ~mask;
+   tmp |= val & mask;
+
+   if (tmp != orig)
+   writel(tmp, clk->reg);
+
+   spin_unlock_irqrestore(>lock, flags);
+}
+
+static int plt_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct clk_plt *clk = to_clk_plt(hw);
+
+   plt_clk_reg_update(clk, PMC_MASK_CLK_FREQ, plt_parent_to_reg(index));
+
+   return 0;
+}
+
+static u8 plt_clk_get_parent(struct clk

[RESEND PATCH v4] clk: x86: Add Atom PMC platform clocks

2016-10-17 Thread Irina Tirdea
The BayTrail and CherryTrail platforms provide platform clocks
through their Power Management Controller (PMC).

The SoC supports up to 6 clocks (PMC_PLT_CLK[5:0]) with a
frequency of either 19.2 MHz (PLL) or 25 MHz (XTAL) for BayTrail
an a frequency of 19.2 MHz (XTAL) for CherryTrail. These clocks
are available for general system use, where appropriate, and each
have Control & Frequency register fields associated with them.

For example, the usage for platform clocks suggested in the datasheet
is the following:
  PLT_CLK[2:0] - Camera
  PLT_CLK[3] - Audio Codec
  PLT_CLK[4] -
  PLT_CLK[5] - COMMs

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
---
Hi,

This patch specifically enables the audio MCLK required by Baytrail CR
devices (support already merged in Mark's tree).

The patch has already been reviewed by Stephen Boyd [1].
The only remaining question is the one pointed out by Stephen:
"Will there be problems if this merges through clk tree? If so we
could take the clk driver part and the platform data include part
could be duplicated into both trees. Or clk tree could be pulled
into x86?" [1]

Ingo, can you help answer this question (or point me to the right person)?
I am not sure what the process should be in this case.

Thank you,
Irina

[1] http://www.spinics.net/lists/alsa-devel/msg54832.html

Changes from v3:
 - replace devm_kzalloc with devm_kcalloc
 - add x86 architecture maintainers

Changes from v2:
 - move clk platform data structures to a separate include file
 - store clk_hw pointer for the fixed rate clocks

Changes from v1:
 - register the clk device as child of pmc device
 - pass iomem pointer from pmc driver to clk driver to avoid using
pmc_atom_read()/write() and use readl/writel API instead
 - use devm_clk_hw_register/clkdev_hw_create instead of
clk_register/clkdev_create

 arch/x86/Kconfig  |   1 +
 arch/x86/include/asm/pmc_atom.h   |   3 +
 arch/x86/platform/atom/pmc_atom.c |  78 +-
 drivers/clk/x86/Makefile  |   1 +
 drivers/clk/x86/clk-byt-plt.c | 380 ++
 include/linux/platform_data/clk-byt-plt.h |  31 +++
 6 files changed, 491 insertions(+), 3 deletions(-)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 create mode 100644 include/linux/platform_data/clk-byt-plt.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bada636..233898e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2756,6 +2756,7 @@ config X86_DMA_REMAP
 config PMC_ATOM
def_bool y
 depends on PCI
+   select COMMON_CLK
 
 source "net/Kconfig"
 
diff --git a/arch/x86/include/asm/pmc_atom.h b/arch/x86/include/asm/pmc_atom.h
index aa8744c..2d310cf 100644
--- a/arch/x86/include/asm/pmc_atom.h
+++ b/arch/x86/include/asm/pmc_atom.h
@@ -50,6 +50,9 @@
BIT_ORED_DEDICATED_IRQ_GPSC | \
BIT_SHARED_IRQ_GPSS)
 
+/* Platform clock control registers */
+#define PMC_CLK_CTL_0  0x60
+
 /* The timers acumulate time spent in sleep state */
 #definePMC_S0IR_TMR0x80
 #definePMC_S0I1_TMR0x84
diff --git a/arch/x86/platform/atom/pmc_atom.c 
b/arch/x86/platform/atom/pmc_atom.c
index 964ff4f..b353893 100644
--- a/arch/x86/platform/atom/pmc_atom.c
+++ b/arch/x86/platform/atom/pmc_atom.c
@@ -21,6 +21,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -37,6 +39,11 @@ struct pmc_reg_map {
const struct pmc_bit_map *pss;
 };
 
+struct pmc_data {
+   const struct pmc_reg_map *map;
+   const struct pmc_clk *clks;
+};
+
 struct pmc_dev {
u32 base_addr;
void __iomem *regmap;
@@ -50,6 +57,29 @@ struct pmc_dev {
 static struct pmc_dev pmc_device;
 static u32 acpi_base_addr;
 
+static const struct pmc_clk byt_clks[] = {
+   {
+   .name = "xtal",
+   .freq = 2500,
+   .parent_name = NULL,
+   },
+   {
+   .name = "pll",
+   .freq = 1920,
+   .parent_name = "xtal",
+   },
+   {},
+};
+
+static const struct pmc_clk cht_clks[] = {
+   {
+   .name = "xtal",
+   .freq = 1920,
+   .parent_name = NULL,
+   },
+   {},
+};
+
 static const struct pmc_bit_map d3_sts_0_map[] = {
{"LPSS1_F0_DMA",BIT_LPSS1_F0_DMA},
{"LPSS1_F1_PWM1",   BIT_LPSS1_F1_PWM1},
@@ -169,6 +199,16 @@ struct pmc_dev {
.pss= cht_pss_map,
 };
 
+static const struct pmc_data byt_data = {
+   .map = _reg_map,
+   .clks = byt_clks,
+};
+
+static const struct pmc_data cht_data = {
+   .map = _reg_map,
+   .clks = cht_clks,
+};
+
 static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
 {
re

[RESEND PATCH v4] clk: x86: Add Atom PMC platform clocks

2016-10-17 Thread Irina Tirdea
The BayTrail and CherryTrail platforms provide platform clocks
through their Power Management Controller (PMC).

The SoC supports up to 6 clocks (PMC_PLT_CLK[5:0]) with a
frequency of either 19.2 MHz (PLL) or 25 MHz (XTAL) for BayTrail
an a frequency of 19.2 MHz (XTAL) for CherryTrail. These clocks
are available for general system use, where appropriate, and each
have Control & Frequency register fields associated with them.

For example, the usage for platform clocks suggested in the datasheet
is the following:
  PLT_CLK[2:0] - Camera
  PLT_CLK[3] - Audio Codec
  PLT_CLK[4] -
  PLT_CLK[5] - COMMs

Signed-off-by: Irina Tirdea 
Signed-off-by: Pierre-Louis Bossart 
---
Hi,

This patch specifically enables the audio MCLK required by Baytrail CR
devices (support already merged in Mark's tree).

The patch has already been reviewed by Stephen Boyd [1].
The only remaining question is the one pointed out by Stephen:
"Will there be problems if this merges through clk tree? If so we
could take the clk driver part and the platform data include part
could be duplicated into both trees. Or clk tree could be pulled
into x86?" [1]

Ingo, can you help answer this question (or point me to the right person)?
I am not sure what the process should be in this case.

Thank you,
Irina

[1] http://www.spinics.net/lists/alsa-devel/msg54832.html

Changes from v3:
 - replace devm_kzalloc with devm_kcalloc
 - add x86 architecture maintainers

Changes from v2:
 - move clk platform data structures to a separate include file
 - store clk_hw pointer for the fixed rate clocks

Changes from v1:
 - register the clk device as child of pmc device
 - pass iomem pointer from pmc driver to clk driver to avoid using
pmc_atom_read()/write() and use readl/writel API instead
 - use devm_clk_hw_register/clkdev_hw_create instead of
clk_register/clkdev_create

 arch/x86/Kconfig  |   1 +
 arch/x86/include/asm/pmc_atom.h   |   3 +
 arch/x86/platform/atom/pmc_atom.c |  78 +-
 drivers/clk/x86/Makefile  |   1 +
 drivers/clk/x86/clk-byt-plt.c | 380 ++
 include/linux/platform_data/clk-byt-plt.h |  31 +++
 6 files changed, 491 insertions(+), 3 deletions(-)
 create mode 100644 drivers/clk/x86/clk-byt-plt.c
 create mode 100644 include/linux/platform_data/clk-byt-plt.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bada636..233898e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2756,6 +2756,7 @@ config X86_DMA_REMAP
 config PMC_ATOM
def_bool y
 depends on PCI
+   select COMMON_CLK
 
 source "net/Kconfig"
 
diff --git a/arch/x86/include/asm/pmc_atom.h b/arch/x86/include/asm/pmc_atom.h
index aa8744c..2d310cf 100644
--- a/arch/x86/include/asm/pmc_atom.h
+++ b/arch/x86/include/asm/pmc_atom.h
@@ -50,6 +50,9 @@
BIT_ORED_DEDICATED_IRQ_GPSC | \
BIT_SHARED_IRQ_GPSS)
 
+/* Platform clock control registers */
+#define PMC_CLK_CTL_0  0x60
+
 /* The timers acumulate time spent in sleep state */
 #definePMC_S0IR_TMR0x80
 #definePMC_S0I1_TMR0x84
diff --git a/arch/x86/platform/atom/pmc_atom.c 
b/arch/x86/platform/atom/pmc_atom.c
index 964ff4f..b353893 100644
--- a/arch/x86/platform/atom/pmc_atom.c
+++ b/arch/x86/platform/atom/pmc_atom.c
@@ -21,6 +21,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -37,6 +39,11 @@ struct pmc_reg_map {
const struct pmc_bit_map *pss;
 };
 
+struct pmc_data {
+   const struct pmc_reg_map *map;
+   const struct pmc_clk *clks;
+};
+
 struct pmc_dev {
u32 base_addr;
void __iomem *regmap;
@@ -50,6 +57,29 @@ struct pmc_dev {
 static struct pmc_dev pmc_device;
 static u32 acpi_base_addr;
 
+static const struct pmc_clk byt_clks[] = {
+   {
+   .name = "xtal",
+   .freq = 2500,
+   .parent_name = NULL,
+   },
+   {
+   .name = "pll",
+   .freq = 1920,
+   .parent_name = "xtal",
+   },
+   {},
+};
+
+static const struct pmc_clk cht_clks[] = {
+   {
+   .name = "xtal",
+   .freq = 1920,
+   .parent_name = NULL,
+   },
+   {},
+};
+
 static const struct pmc_bit_map d3_sts_0_map[] = {
{"LPSS1_F0_DMA",BIT_LPSS1_F0_DMA},
{"LPSS1_F1_PWM1",   BIT_LPSS1_F1_PWM1},
@@ -169,6 +199,16 @@ struct pmc_dev {
.pss= cht_pss_map,
 };
 
+static const struct pmc_data byt_data = {
+   .map = _reg_map,
+   .clks = byt_clks,
+};
+
+static const struct pmc_data cht_data = {
+   .map = _reg_map,
+   .clks = cht_clks,
+};
+
 static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
 {
return readl(pmc->regmap + reg_offset);
@@ -382,10 +422,36 @@ static int

[PATCH v12 0/5] Goodix touchscreen enhancements

2016-09-10 Thread Irina Tirdea
This is an update for a previous set of patches [1] with enhancements
for the Goodix touchscreens. The first 3 patches are leftovers from
the previous patchset (with minor changes due to rebase), while the
last 2 patches are new.

Thanks,
Irina

[1] https://lkml.org/lkml/2015/11/19/241

Changes in v12:
 - add documentation for configuration firmware update
 - minor changes due to rebase
 - add 2 new patches to fix reset sequence and add support for gt9157

Previous changes:
  https://lkml.org/lkml/2015/11/19/241

Irina Tirdea (5):
  Input: goodix - add sysfs interface to dump config
  Input: goodix - add support for ESD
  Input: goodix - add runtime power management support
  Input: goodix - fix reset sequence
  Input: goodix - add support for gt9157

 .../bindings/input/touchscreen/goodix.txt  |   5 +
 Documentation/input/goodix.txt |  84 +
 drivers/input/touchscreen/goodix.c | 346 +++--
 3 files changed, 415 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/input/goodix.txt

-- 
1.9.1



[PATCH v12 3/5] Input: goodix - add runtime power management support

2016-09-10 Thread Irina Tirdea
Add support for runtime power management so that the device is
turned off when not used (when the userspace holds no open
handles of the input device). The device uses autosuspend with a
default delay of 2 seconds, so the device will suspend if no
handles to it are open for 2 seconds.

The runtime management support is only available if the gpio pins
are properly initialized from ACPI/DT.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/input/touchscreen/goodix.c | 156 +
 1 file changed, 142 insertions(+), 14 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index cf39dc4..182ff9c 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct goodix_ts_data {
@@ -51,6 +52,10 @@ struct goodix_ts_data {
unsigned long irq_flags;
atomic_t esd_timeout;
struct delayed_work esd_work;
+   bool suspended;
+   atomic_t open_count;
+   /* Protects power management calls and access to suspended flag */
+   struct mutex mutex;
 };
 
 #define GOODIX_GPIO_INT_NAME   "irq"
@@ -81,6 +86,8 @@ struct goodix_ts_data {
 #define MAX_CONTACTS_LOC   5
 #define TRIGGER_LOC6
 
+#define GOODIX_AUTOSUSPEND_DELAY_MS2000
+
 static const unsigned long goodix_irq_flags[] = {
IRQ_TYPE_EDGE_RISING,
IRQ_TYPE_EDGE_FALLING,
@@ -198,6 +205,29 @@ static int goodix_get_cfg_len(u16 id)
}
 }
 
+static int goodix_set_power_state(struct goodix_ts_data *ts, bool on)
+{
+   int error;
+
+   if (on) {
+   error = pm_runtime_get_sync(>client->dev);
+   } else {
+   pm_runtime_mark_last_busy(>client->dev);
+   error = pm_runtime_put_autosuspend(>client->dev);
+   }
+
+   if (error < 0) {
+   dev_err(>client->dev,
+   "failed to change power state to %d\n", on);
+   if (on)
+   pm_runtime_put_noidle(>client->dev);
+
+   return error;
+   }
+
+   return 0;
+}
+
 static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
 {
int touch_num;
@@ -444,6 +474,10 @@ static ssize_t goodix_dump_config_show(struct device *dev,
 
wait_for_completion(>firmware_loading_complete);
 
+   error = goodix_set_power_state(ts, true);
+   if (error)
+   return error;
+
error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA,
config, ts->cfg_len);
if (error) {
@@ -452,6 +486,8 @@ static ssize_t goodix_dump_config_show(struct device *dev,
return error;
}
 
+   goodix_set_power_state(ts, false);
+
for (i = 0; i < ts->cfg_len; i++)
count += scnprintf(buf + count, PAGE_SIZE - count, "%02x ",
   config[i]);
@@ -548,11 +584,13 @@ static ssize_t goodix_esd_timeout_store(struct device 
*dev,
return error;
 
esd_timeout = atomic_read(>esd_timeout);
-   if (esd_timeout && !new_esd_timeout)
+   if (esd_timeout && !new_esd_timeout &&
+   pm_runtime_active(>client->dev))
goodix_disable_esd(ts);
 
atomic_set(>esd_timeout, new_esd_timeout);
-   if (!esd_timeout && new_esd_timeout)
+   if (!esd_timeout && new_esd_timeout &&
+   pm_runtime_active(>client->dev))
goodix_enable_esd(ts);
 
return count;
@@ -573,6 +611,34 @@ static const struct attribute_group goodix_attr_group = {
.attrs = goodix_attrs,
 };
 
+static int goodix_open(struct input_dev *input_dev)
+{
+   struct goodix_ts_data *ts = input_get_drvdata(input_dev);
+   int error;
+
+   if (!ts->gpiod_int || !ts->gpiod_rst)
+   return 0;
+
+   wait_for_completion(>firmware_loading_complete);
+
+   error = goodix_set_power_state(ts, true);
+   if (error)
+   return error;
+   atomic_inc(>open_count);
+   return 0;
+}
+
+static void goodix_close(struct input_dev *input_dev)
+{
+   struct goodix_ts_data *ts = input_get_drvdata(input_dev);
+
+   if (!ts->gpiod_int || !ts->gpiod_rst)
+   return;
+
+   goodix_set_power_state(ts, false);
+   atomic_dec(>open_count);
+}
+
 /**
  * goodix_get_gpio_config - Get GPIO config from ACPI/DT
  *
@@ -754,6 +820,9 @@ static int goodix_request_input_dev(struct goodix_ts_data 
*ts)
ts->input_dev->id.vendor = 0x0416;
ts->input_dev->id.product = ts->id;
ts->input_dev->id.version = ts->version;
+   ts->input_dev->open = goodix_open;
+   ts->input_dev->close = goo

[PATCH v12 0/5] Goodix touchscreen enhancements

2016-09-10 Thread Irina Tirdea
This is an update for a previous set of patches [1] with enhancements
for the Goodix touchscreens. The first 3 patches are leftovers from
the previous patchset (with minor changes due to rebase), while the
last 2 patches are new.

Thanks,
Irina

[1] https://lkml.org/lkml/2015/11/19/241

Changes in v12:
 - add documentation for configuration firmware update
 - minor changes due to rebase
 - add 2 new patches to fix reset sequence and add support for gt9157

Previous changes:
  https://lkml.org/lkml/2015/11/19/241

Irina Tirdea (5):
  Input: goodix - add sysfs interface to dump config
  Input: goodix - add support for ESD
  Input: goodix - add runtime power management support
  Input: goodix - fix reset sequence
  Input: goodix - add support for gt9157

 .../bindings/input/touchscreen/goodix.txt  |   5 +
 Documentation/input/goodix.txt |  84 +
 drivers/input/touchscreen/goodix.c | 346 +++--
 3 files changed, 415 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/input/goodix.txt

-- 
1.9.1



[PATCH v12 3/5] Input: goodix - add runtime power management support

2016-09-10 Thread Irina Tirdea
Add support for runtime power management so that the device is
turned off when not used (when the userspace holds no open
handles of the input device). The device uses autosuspend with a
default delay of 2 seconds, so the device will suspend if no
handles to it are open for 2 seconds.

The runtime management support is only available if the gpio pins
are properly initialized from ACPI/DT.

Signed-off-by: Irina Tirdea 
---
 drivers/input/touchscreen/goodix.c | 156 +
 1 file changed, 142 insertions(+), 14 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index cf39dc4..182ff9c 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct goodix_ts_data {
@@ -51,6 +52,10 @@ struct goodix_ts_data {
unsigned long irq_flags;
atomic_t esd_timeout;
struct delayed_work esd_work;
+   bool suspended;
+   atomic_t open_count;
+   /* Protects power management calls and access to suspended flag */
+   struct mutex mutex;
 };
 
 #define GOODIX_GPIO_INT_NAME   "irq"
@@ -81,6 +86,8 @@ struct goodix_ts_data {
 #define MAX_CONTACTS_LOC   5
 #define TRIGGER_LOC6
 
+#define GOODIX_AUTOSUSPEND_DELAY_MS2000
+
 static const unsigned long goodix_irq_flags[] = {
IRQ_TYPE_EDGE_RISING,
IRQ_TYPE_EDGE_FALLING,
@@ -198,6 +205,29 @@ static int goodix_get_cfg_len(u16 id)
}
 }
 
+static int goodix_set_power_state(struct goodix_ts_data *ts, bool on)
+{
+   int error;
+
+   if (on) {
+   error = pm_runtime_get_sync(>client->dev);
+   } else {
+   pm_runtime_mark_last_busy(>client->dev);
+   error = pm_runtime_put_autosuspend(>client->dev);
+   }
+
+   if (error < 0) {
+   dev_err(>client->dev,
+   "failed to change power state to %d\n", on);
+   if (on)
+   pm_runtime_put_noidle(>client->dev);
+
+   return error;
+   }
+
+   return 0;
+}
+
 static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
 {
int touch_num;
@@ -444,6 +474,10 @@ static ssize_t goodix_dump_config_show(struct device *dev,
 
wait_for_completion(>firmware_loading_complete);
 
+   error = goodix_set_power_state(ts, true);
+   if (error)
+   return error;
+
error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA,
config, ts->cfg_len);
if (error) {
@@ -452,6 +486,8 @@ static ssize_t goodix_dump_config_show(struct device *dev,
return error;
}
 
+   goodix_set_power_state(ts, false);
+
for (i = 0; i < ts->cfg_len; i++)
count += scnprintf(buf + count, PAGE_SIZE - count, "%02x ",
   config[i]);
@@ -548,11 +584,13 @@ static ssize_t goodix_esd_timeout_store(struct device 
*dev,
return error;
 
esd_timeout = atomic_read(>esd_timeout);
-   if (esd_timeout && !new_esd_timeout)
+   if (esd_timeout && !new_esd_timeout &&
+   pm_runtime_active(>client->dev))
goodix_disable_esd(ts);
 
atomic_set(>esd_timeout, new_esd_timeout);
-   if (!esd_timeout && new_esd_timeout)
+   if (!esd_timeout && new_esd_timeout &&
+   pm_runtime_active(>client->dev))
goodix_enable_esd(ts);
 
return count;
@@ -573,6 +611,34 @@ static const struct attribute_group goodix_attr_group = {
.attrs = goodix_attrs,
 };
 
+static int goodix_open(struct input_dev *input_dev)
+{
+   struct goodix_ts_data *ts = input_get_drvdata(input_dev);
+   int error;
+
+   if (!ts->gpiod_int || !ts->gpiod_rst)
+   return 0;
+
+   wait_for_completion(>firmware_loading_complete);
+
+   error = goodix_set_power_state(ts, true);
+   if (error)
+   return error;
+   atomic_inc(>open_count);
+   return 0;
+}
+
+static void goodix_close(struct input_dev *input_dev)
+{
+   struct goodix_ts_data *ts = input_get_drvdata(input_dev);
+
+   if (!ts->gpiod_int || !ts->gpiod_rst)
+   return;
+
+   goodix_set_power_state(ts, false);
+   atomic_dec(>open_count);
+}
+
 /**
  * goodix_get_gpio_config - Get GPIO config from ACPI/DT
  *
@@ -754,6 +820,9 @@ static int goodix_request_input_dev(struct goodix_ts_data 
*ts)
ts->input_dev->id.vendor = 0x0416;
ts->input_dev->id.product = ts->id;
ts->input_dev->id.version = ts->version;
+   ts->input_dev->open = goodix_open;
+   ts->input_dev->close = goodix_close;
+   input

[PATCH v12 5/5] Input: goodix - add support for gt9157

2016-09-10 Thread Irina Tirdea
Goodix touchscreen GT9157 has the same basic functionality
as GT911 touchscreen. This is based on Goodix datasheets
for GT911 and GT9157 and on Goodix driver gt9xx.c for
Android (publicly available in Android kernel trees for
various devices).

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 Documentation/devicetree/bindings/input/touchscreen/goodix.txt | 1 +
 drivers/input/touchscreen/goodix.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt 
b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
index ef5f42d..421b7d5 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
@@ -5,6 +5,7 @@ Required properties:
  - compatible  : Should be "goodix,gt911"
 or "goodix,gt9110"
 or "goodix,gt912"
+or "goodix,gt9157"
 or "goodix,gt927"
 or "goodix,gt9271"
 or "goodix,gt928"
diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 6fba804..bd4dd4b 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -192,6 +192,7 @@ static int goodix_get_cfg_len(u16 id)
case 911:
case 9271:
case 9110:
+   case 9157:
case 927:
case 928:
return GOODIX_CONFIG_911_LENGTH;
@@ -1168,6 +1169,7 @@ static const struct of_device_id goodix_of_match[] = {
{ .compatible = "goodix,gt911" },
{ .compatible = "goodix,gt9110" },
{ .compatible = "goodix,gt912" },
+   { .compatible = "goodix,gt9157" },
{ .compatible = "goodix,gt927" },
{ .compatible = "goodix,gt9271" },
{ .compatible = "goodix,gt928" },
-- 
1.9.1



[PATCH v12 5/5] Input: goodix - add support for gt9157

2016-09-10 Thread Irina Tirdea
Goodix touchscreen GT9157 has the same basic functionality
as GT911 touchscreen. This is based on Goodix datasheets
for GT911 and GT9157 and on Goodix driver gt9xx.c for
Android (publicly available in Android kernel trees for
various devices).

Signed-off-by: Irina Tirdea 
---
 Documentation/devicetree/bindings/input/touchscreen/goodix.txt | 1 +
 drivers/input/touchscreen/goodix.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt 
b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
index ef5f42d..421b7d5 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
@@ -5,6 +5,7 @@ Required properties:
  - compatible  : Should be "goodix,gt911"
 or "goodix,gt9110"
 or "goodix,gt912"
+or "goodix,gt9157"
 or "goodix,gt927"
 or "goodix,gt9271"
 or "goodix,gt928"
diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 6fba804..bd4dd4b 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -192,6 +192,7 @@ static int goodix_get_cfg_len(u16 id)
case 911:
case 9271:
case 9110:
+   case 9157:
case 927:
case 928:
return GOODIX_CONFIG_911_LENGTH;
@@ -1168,6 +1169,7 @@ static const struct of_device_id goodix_of_match[] = {
{ .compatible = "goodix,gt911" },
{ .compatible = "goodix,gt9110" },
{ .compatible = "goodix,gt912" },
+   { .compatible = "goodix,gt9157" },
{ .compatible = "goodix,gt927" },
{ .compatible = "goodix,gt9271" },
{ .compatible = "goodix,gt928" },
-- 
1.9.1



[PATCH v12 1/5] Input: goodix - add sysfs interface to dump config

2016-09-10 Thread Irina Tirdea
Goodix devices have a configuration information register area that
specifies various parameters for the device. The configuration information
has a specific format described in the Goodix datasheet. It includes X/Y
resolution, maximum supported touch points, interrupt flags, various
sesitivity factors and settings for advanced features (like gesture
recognition).

Export a sysfs interface that would allow reading the configuration
information. The default device configuration can be used as a starting
point for creating a valid configuration firmware used by the device at
init time to update its configuration.

This sysfs interface will be exported only if the gpio pins are properly
initialized from ACPI/DT.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 Documentation/input/goodix.txt | 84 ++
 drivers/input/touchscreen/goodix.c | 64 ++---
 2 files changed, 143 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/input/goodix.txt

diff --git a/Documentation/input/goodix.txt b/Documentation/input/goodix.txt
new file mode 100644
index 000..f9be1e2
--- /dev/null
+++ b/Documentation/input/goodix.txt
@@ -0,0 +1,84 @@
+Goodix touchscreen driver
+=
+
+How to update configuration firmware
+=
+
+Goodix touchscreen devices have a set of registers that specify configuration
+information for the device. The configuration information has a specific format
+described in the Goodix datasheet. It includes X/Y resolution, maximum
+supported touch points, interrupt flags, various sesitivity factors and
+settings for advanced features (like gesture recognition).
+
+The devices have an initial default configuration that can be read through
+the sysfs interface (/sys/class/input/inputX/device/dump_config). This default
+configuration can be used as a starting point for creating a new configuration
+firmware file. At init, the driver will read the configuration firmware file
+and update the device configuration.
+
+This configuration can be accesed only if both interrupt and reset gpio pins
+are connected and properly configured through ACPI _DSD/DT properties.
+
+Below are instructions on how to generate a valid configuration starting from
+the device default configuration.
+
+1. Dump the default configuration of the device to a file:
+  $ cat /sys/class/input/inputX/device/dump_config > goodix__cfg
+
+2. Make the needed changes to the configuration (e.g. change resolution of
+x/y axes, maximum reported touch points, switch X,Y axes, etc.). For more
+details check the Goodix datasheet for format of Configuration Registers.
+
+3. Generate a valid configuration starting from  goodix__cfg.
+After making changes, you need to recompute the checksum of the entire
+configuration data, set Config_Fresh to 1 and generate the binary config
+firmware image. This can be done using a helper script similar to the
+one below:
+
+#!/bin/bash
+
+if [[ $# -lt 1 ]]; then
+echo "$0 fw_filename"
+exit 1
+fi
+
+file_in="$1"
+file_out_bin=${file_in}.bin
+
+print_val ()
+{
+val="$1"
+printf "0x%.2x" "$val" | xxd -r -p >> ${file_out_bin}
+}
+
+rm -f ${file_out_bin}
+
+size=`cat ${file_in} | wc -w`
+
+checksum=0
+i=1
+for val in `cat ${file_in}`; do
+val="0x$val"
+if [[ $i == $size ]]; then
+   # Config_Fresh
+   print_val 0x01
+elif [[ $i == $((size-1)) ]]; then
+   # Config_Chksum
+   checksum=$(( (~ checksum + 1) & 0xFF))
+   print_val $checksum
+else
+   checksum=$((checksum + val))
+   print_val $val
+fi
+i=$((i+1))
+done
+
+echo "Wrote ${file_out_bin}"
+
+4. Copy the binary config firmware in the appropriate location
+(e.g. /lib/firmware), using the name goodix__cfg.bin (e.g. for gt911,
+use goodix_911_cfg.bin).
+
+5. Check that the new firmware was successfully written to the device
+after reboot. Config_Fresh is reset to 0 after a successful update of the
+configuration.
diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 240b16f..2447b73 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -430,6 +430,40 @@ static int goodix_reset(struct goodix_ts_data *ts)
return 0;
 }
 
+static ssize_t goodix_dump_config_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct goodix_ts_data *ts = dev_get_drvdata(dev);
+   u8 config[GOODIX_CONFIG_MAX_LENGTH];
+   int error, count = 0, i;
+
+   wait_for_completion(>firmware_loading_complete);
+
+   error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA,
+   config, ts->cfg_len);
+   if (error) {
+   dev_warn(>client->dev,
+"Error read

[PATCH v12 2/5] Input: goodix - add support for ESD

2016-09-10 Thread Irina Tirdea
Add ESD (Electrostatic Discharge) protection mechanism.

The driver enables ESD protection in HW and checks a register
to determine if ESD occurred. If ESD is signalled by the HW,
the driver will reset the device.

The ESD poll time (in ms) can be set through the sysfs property
esd_timeout. If it is set to 0, ESD protection is disabled.
Recommended value is 2000 ms. The initial value for ESD timeout
can be set through esd-recovery-timeout-ms ACPI/DT property.
If there is no such property defined, ESD protection is disabled.
For ACPI 5.1, the property can be specified using _DSD properties:
 Device (STAC)
 {
 Name (_HID, "GDIX1001")
 ...

 Name (_DSD,  Package ()
 {
 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
 Package ()
 {
 Package (2) { "esd-recovery-timeout-ms", Package(1) { 2000 }},
 ...
 }
 })
 }

The ESD protection mechanism is only available if the gpio pins
are properly initialized from ACPI/DT.

This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
Acked-by: Rob Herring <r...@kernel.org>
---
 .../bindings/input/touchscreen/goodix.txt  |   4 +
 drivers/input/touchscreen/goodix.c | 130 -
 2 files changed, 132 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt 
b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
index c98757a..ef5f42d 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
@@ -18,6 +18,10 @@ Optional properties:
  - irq-gpios   : GPIO pin used for IRQ. The driver uses the
  interrupt gpio pin as output to reset the device.
  - reset-gpios : GPIO pin used for reset
+ - esd-recovery-timeout-ms : ESD poll time (in milli seconds) for the driver to
+check if ESD occurred and in that case reset the
+device. ESD is disabled if this property is not set
+or is set to 0.
 
  - touchscreen-inverted-x  : X axis is inverted (boolean)
  - touchscreen-inverted-y  : Y axis is inverted (boolean)
diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 2447b73..cf39dc4 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -49,10 +49,13 @@ struct goodix_ts_data {
const char *cfg_name;
struct completion firmware_loading_complete;
unsigned long irq_flags;
+   atomic_t esd_timeout;
+   struct delayed_work esd_work;
 };
 
 #define GOODIX_GPIO_INT_NAME   "irq"
 #define GOODIX_GPIO_RST_NAME   "reset"
+#define GOODIX_DEVICE_ESD_TIMEOUT_PROPERTY "esd-recovery-timeout-ms"
 
 #define GOODIX_MAX_HEIGHT  4096
 #define GOODIX_MAX_WIDTH   4096
@@ -67,6 +70,8 @@ struct goodix_ts_data {
 /* Register defines */
 #define GOODIX_REG_COMMAND 0x8040
 #define GOODIX_CMD_SCREEN_OFF  0x05
+#define GOODIX_CMD_ESD_ENABLED 0xAA
+#define GOODIX_REG_ESD_CHECK   0x8041
 
 #define GOODIX_READ_COOR_ADDR  0x814E
 #define GOODIX_REG_CONFIG_DATA 0x8047
@@ -453,10 +458,114 @@ static ssize_t goodix_dump_config_show(struct device 
*dev,
return count;
 }
 
+static void goodix_disable_esd(struct goodix_ts_data *ts)
+{
+   if (!atomic_read(>esd_timeout))
+   return;
+   cancel_delayed_work_sync(>esd_work);
+}
+
+static int goodix_enable_esd(struct goodix_ts_data *ts)
+{
+   int error, esd_timeout;
+
+   esd_timeout = atomic_read(>esd_timeout);
+   if (!esd_timeout)
+   return 0;
+
+   error = goodix_i2c_write_u8(ts->client, GOODIX_REG_ESD_CHECK,
+   GOODIX_CMD_ESD_ENABLED);
+   if (error) {
+   dev_err(>client->dev, "Failed to enable ESD: %d\n", error);
+   return error;
+   }
+
+   schedule_delayed_work(>esd_work, round_jiffies_relative(
+ msecs_to_jiffies(esd_timeout)));
+   return 0;
+}
+
+static void goodix_esd_work(struct work_struct *work)
+{
+   struct goodix_ts_data *ts = container_of(work, struct goodix_ts_data,
+esd_work.work);
+   int retries = 3, error;
+   u8 esd_data[2];
+   const struct firmware *cfg = NULL;
+
+   wait_for_completion(>firmware_loading_complete);
+
+   while (--retries) {
+   error = goodix_i2c_read(ts->client, GOODIX_REG_COMMAND,
+   esd_data, sizeof(esd_data));
+

[PATCH v12 2/5] Input: goodix - add support for ESD

2016-09-10 Thread Irina Tirdea
Add ESD (Electrostatic Discharge) protection mechanism.

The driver enables ESD protection in HW and checks a register
to determine if ESD occurred. If ESD is signalled by the HW,
the driver will reset the device.

The ESD poll time (in ms) can be set through the sysfs property
esd_timeout. If it is set to 0, ESD protection is disabled.
Recommended value is 2000 ms. The initial value for ESD timeout
can be set through esd-recovery-timeout-ms ACPI/DT property.
If there is no such property defined, ESD protection is disabled.
For ACPI 5.1, the property can be specified using _DSD properties:
 Device (STAC)
 {
 Name (_HID, "GDIX1001")
 ...

 Name (_DSD,  Package ()
 {
 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
 Package ()
 {
 Package (2) { "esd-recovery-timeout-ms", Package(1) { 2000 }},
 ...
 }
 })
 }

The ESD protection mechanism is only available if the gpio pins
are properly initialized from ACPI/DT.

This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).

Signed-off-by: Irina Tirdea 
Acked-by: Rob Herring 
---
 .../bindings/input/touchscreen/goodix.txt  |   4 +
 drivers/input/touchscreen/goodix.c | 130 -
 2 files changed, 132 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt 
b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
index c98757a..ef5f42d 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
@@ -18,6 +18,10 @@ Optional properties:
  - irq-gpios   : GPIO pin used for IRQ. The driver uses the
  interrupt gpio pin as output to reset the device.
  - reset-gpios : GPIO pin used for reset
+ - esd-recovery-timeout-ms : ESD poll time (in milli seconds) for the driver to
+check if ESD occurred and in that case reset the
+device. ESD is disabled if this property is not set
+or is set to 0.
 
  - touchscreen-inverted-x  : X axis is inverted (boolean)
  - touchscreen-inverted-y  : Y axis is inverted (boolean)
diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 2447b73..cf39dc4 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -49,10 +49,13 @@ struct goodix_ts_data {
const char *cfg_name;
struct completion firmware_loading_complete;
unsigned long irq_flags;
+   atomic_t esd_timeout;
+   struct delayed_work esd_work;
 };
 
 #define GOODIX_GPIO_INT_NAME   "irq"
 #define GOODIX_GPIO_RST_NAME   "reset"
+#define GOODIX_DEVICE_ESD_TIMEOUT_PROPERTY "esd-recovery-timeout-ms"
 
 #define GOODIX_MAX_HEIGHT  4096
 #define GOODIX_MAX_WIDTH   4096
@@ -67,6 +70,8 @@ struct goodix_ts_data {
 /* Register defines */
 #define GOODIX_REG_COMMAND 0x8040
 #define GOODIX_CMD_SCREEN_OFF  0x05
+#define GOODIX_CMD_ESD_ENABLED 0xAA
+#define GOODIX_REG_ESD_CHECK   0x8041
 
 #define GOODIX_READ_COOR_ADDR  0x814E
 #define GOODIX_REG_CONFIG_DATA 0x8047
@@ -453,10 +458,114 @@ static ssize_t goodix_dump_config_show(struct device 
*dev,
return count;
 }
 
+static void goodix_disable_esd(struct goodix_ts_data *ts)
+{
+   if (!atomic_read(>esd_timeout))
+   return;
+   cancel_delayed_work_sync(>esd_work);
+}
+
+static int goodix_enable_esd(struct goodix_ts_data *ts)
+{
+   int error, esd_timeout;
+
+   esd_timeout = atomic_read(>esd_timeout);
+   if (!esd_timeout)
+   return 0;
+
+   error = goodix_i2c_write_u8(ts->client, GOODIX_REG_ESD_CHECK,
+   GOODIX_CMD_ESD_ENABLED);
+   if (error) {
+   dev_err(>client->dev, "Failed to enable ESD: %d\n", error);
+   return error;
+   }
+
+   schedule_delayed_work(>esd_work, round_jiffies_relative(
+ msecs_to_jiffies(esd_timeout)));
+   return 0;
+}
+
+static void goodix_esd_work(struct work_struct *work)
+{
+   struct goodix_ts_data *ts = container_of(work, struct goodix_ts_data,
+esd_work.work);
+   int retries = 3, error;
+   u8 esd_data[2];
+   const struct firmware *cfg = NULL;
+
+   wait_for_completion(>firmware_loading_complete);
+
+   while (--retries) {
+   error = goodix_i2c_read(ts->client, GOODIX_REG_COMMAND,
+   esd_data, sizeof(esd_data));
+   if (error)
+   cont

[PATCH v12 1/5] Input: goodix - add sysfs interface to dump config

2016-09-10 Thread Irina Tirdea
Goodix devices have a configuration information register area that
specifies various parameters for the device. The configuration information
has a specific format described in the Goodix datasheet. It includes X/Y
resolution, maximum supported touch points, interrupt flags, various
sesitivity factors and settings for advanced features (like gesture
recognition).

Export a sysfs interface that would allow reading the configuration
information. The default device configuration can be used as a starting
point for creating a valid configuration firmware used by the device at
init time to update its configuration.

This sysfs interface will be exported only if the gpio pins are properly
initialized from ACPI/DT.

Signed-off-by: Irina Tirdea 
---
 Documentation/input/goodix.txt | 84 ++
 drivers/input/touchscreen/goodix.c | 64 ++---
 2 files changed, 143 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/input/goodix.txt

diff --git a/Documentation/input/goodix.txt b/Documentation/input/goodix.txt
new file mode 100644
index 000..f9be1e2
--- /dev/null
+++ b/Documentation/input/goodix.txt
@@ -0,0 +1,84 @@
+Goodix touchscreen driver
+=
+
+How to update configuration firmware
+=
+
+Goodix touchscreen devices have a set of registers that specify configuration
+information for the device. The configuration information has a specific format
+described in the Goodix datasheet. It includes X/Y resolution, maximum
+supported touch points, interrupt flags, various sesitivity factors and
+settings for advanced features (like gesture recognition).
+
+The devices have an initial default configuration that can be read through
+the sysfs interface (/sys/class/input/inputX/device/dump_config). This default
+configuration can be used as a starting point for creating a new configuration
+firmware file. At init, the driver will read the configuration firmware file
+and update the device configuration.
+
+This configuration can be accesed only if both interrupt and reset gpio pins
+are connected and properly configured through ACPI _DSD/DT properties.
+
+Below are instructions on how to generate a valid configuration starting from
+the device default configuration.
+
+1. Dump the default configuration of the device to a file:
+  $ cat /sys/class/input/inputX/device/dump_config > goodix__cfg
+
+2. Make the needed changes to the configuration (e.g. change resolution of
+x/y axes, maximum reported touch points, switch X,Y axes, etc.). For more
+details check the Goodix datasheet for format of Configuration Registers.
+
+3. Generate a valid configuration starting from  goodix__cfg.
+After making changes, you need to recompute the checksum of the entire
+configuration data, set Config_Fresh to 1 and generate the binary config
+firmware image. This can be done using a helper script similar to the
+one below:
+
+#!/bin/bash
+
+if [[ $# -lt 1 ]]; then
+echo "$0 fw_filename"
+exit 1
+fi
+
+file_in="$1"
+file_out_bin=${file_in}.bin
+
+print_val ()
+{
+val="$1"
+printf "0x%.2x" "$val" | xxd -r -p >> ${file_out_bin}
+}
+
+rm -f ${file_out_bin}
+
+size=`cat ${file_in} | wc -w`
+
+checksum=0
+i=1
+for val in `cat ${file_in}`; do
+val="0x$val"
+if [[ $i == $size ]]; then
+   # Config_Fresh
+   print_val 0x01
+elif [[ $i == $((size-1)) ]]; then
+   # Config_Chksum
+   checksum=$(( (~ checksum + 1) & 0xFF))
+   print_val $checksum
+else
+   checksum=$((checksum + val))
+   print_val $val
+fi
+i=$((i+1))
+done
+
+echo "Wrote ${file_out_bin}"
+
+4. Copy the binary config firmware in the appropriate location
+(e.g. /lib/firmware), using the name goodix__cfg.bin (e.g. for gt911,
+use goodix_911_cfg.bin).
+
+5. Check that the new firmware was successfully written to the device
+after reboot. Config_Fresh is reset to 0 after a successful update of the
+configuration.
diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 240b16f..2447b73 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -430,6 +430,40 @@ static int goodix_reset(struct goodix_ts_data *ts)
return 0;
 }
 
+static ssize_t goodix_dump_config_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct goodix_ts_data *ts = dev_get_drvdata(dev);
+   u8 config[GOODIX_CONFIG_MAX_LENGTH];
+   int error, count = 0, i;
+
+   wait_for_completion(>firmware_loading_complete);
+
+   error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA,
+   config, ts->cfg_len);
+   if (error) {
+   dev_warn(>client->dev,
+"Error reading config (%d)\n",  error

[PATCH v12 4/5] Input: goodix - fix reset sequence

2016-09-10 Thread Irina Tirdea
According to the Goodix datasheet, the reset sequence will leave
the reset line set to output high. To end the selection of the I2C
address, we just need to set the input line to low for at least
50 ms and then set it to input floating (already implemented by
goodix_int_sync).

Remove setting the reset line to input from the reset sequence,
since that is not reflected in the datasheet.

This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).

Suggested-by: Troy Kisky <troy.ki...@boundarydevices.com>
Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/input/touchscreen/goodix.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 182ff9c..6fba804 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -454,10 +454,6 @@ static int goodix_reset(struct goodix_ts_data *ts)
usleep_range(6000, 1);  /* T4: > 5ms */
 
/* end select I2C slave addr */
-   error = gpiod_direction_input(ts->gpiod_rst);
-   if (error)
-   return error;
-
error = goodix_int_sync(ts);
if (error)
return error;
-- 
1.9.1



[PATCH v12 4/5] Input: goodix - fix reset sequence

2016-09-10 Thread Irina Tirdea
According to the Goodix datasheet, the reset sequence will leave
the reset line set to output high. To end the selection of the I2C
address, we just need to set the input line to low for at least
50 ms and then set it to input floating (already implemented by
goodix_int_sync).

Remove setting the reset line to input from the reset sequence,
since that is not reflected in the datasheet.

This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).

Suggested-by: Troy Kisky 
Signed-off-by: Irina Tirdea 
---
 drivers/input/touchscreen/goodix.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 182ff9c..6fba804 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -454,10 +454,6 @@ static int goodix_reset(struct goodix_ts_data *ts)
usleep_range(6000, 1);  /* T4: > 5ms */
 
/* end select I2C slave addr */
-   error = gpiod_direction_input(ts->gpiod_rst);
-   if (error)
-   return error;
-
error = goodix_int_sync(ts);
if (error)
return error;
-- 
1.9.1



[RFC PATCH v2 0/3] Add ACPI support for pinctrl configuration

2016-04-05 Thread Irina Tirdea
This is a proposal for adding ACPI support for pin controller
configuration.

It has been developed to enable the MinnowBoard and IoT community
by providing an easy way to specify pin multiplexing and
pin configuration.

This proposal is based on using _DSD properties to specify device
states and configuration nodes and it follows closely the device
tree model. Device states are defined using the Device Properties
format and the configuration nodes are defined using the
Hierarchical Properties Extension format. The generic properties
for the configuration nodes are the same as the ones for device
tree, while pincontroller drivers can also define custom ones.

Changes from v1:
 - address code review comments regarding coding style, documentation
and fixes
 - rewrote patch 3 ("pinctrl: Parse GpioInt/GpioIo resources") to
avoid using triple pointers
 - define pinconf_generic_dt_node_to_map since it is used by pinctrl
sirf driver
 - add dependency on PINCONF_GENERIC to the entire ACPI parsing code
 - dropped first patch from the series since it got merged
("pinctrl: Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map")

Irina Tirdea (3):
  pinctrl: pinconf-generic: Add ACPI support
  pinctrl: Add ACPI support
  pinctrl: Parse GpioInt/GpioIo resources

 Documentation/acpi/pinctrl-properties.txt | 292 +
 drivers/acpi/property.c   |   8 +-
 drivers/base/property.c   |  36 ++-
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/acpi.c| 519 ++
 drivers/pinctrl/acpi.h|  32 ++
 drivers/pinctrl/core.c|  26 ++
 drivers/pinctrl/core.h|   2 +
 drivers/pinctrl/pinconf-generic.c | 121 ---
 include/linux/acpi.h  |   4 +-
 include/linux/pinctrl/pinconf-generic.h   |  35 +-
 include/linux/property.h  |   9 +
 12 files changed, 1010 insertions(+), 75 deletions(-)
 create mode 100644 Documentation/acpi/pinctrl-properties.txt
 create mode 100644 drivers/pinctrl/acpi.c
 create mode 100644 drivers/pinctrl/acpi.h

-- 
1.9.1



[RFC PATCH v2 0/3] Add ACPI support for pinctrl configuration

2016-04-05 Thread Irina Tirdea
This is a proposal for adding ACPI support for pin controller
configuration.

It has been developed to enable the MinnowBoard and IoT community
by providing an easy way to specify pin multiplexing and
pin configuration.

This proposal is based on using _DSD properties to specify device
states and configuration nodes and it follows closely the device
tree model. Device states are defined using the Device Properties
format and the configuration nodes are defined using the
Hierarchical Properties Extension format. The generic properties
for the configuration nodes are the same as the ones for device
tree, while pincontroller drivers can also define custom ones.

Changes from v1:
 - address code review comments regarding coding style, documentation
and fixes
 - rewrote patch 3 ("pinctrl: Parse GpioInt/GpioIo resources") to
avoid using triple pointers
 - define pinconf_generic_dt_node_to_map since it is used by pinctrl
sirf driver
 - add dependency on PINCONF_GENERIC to the entire ACPI parsing code
 - dropped first patch from the series since it got merged
("pinctrl: Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map")

Irina Tirdea (3):
  pinctrl: pinconf-generic: Add ACPI support
  pinctrl: Add ACPI support
  pinctrl: Parse GpioInt/GpioIo resources

 Documentation/acpi/pinctrl-properties.txt | 292 +
 drivers/acpi/property.c   |   8 +-
 drivers/base/property.c   |  36 ++-
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/acpi.c| 519 ++
 drivers/pinctrl/acpi.h|  32 ++
 drivers/pinctrl/core.c|  26 ++
 drivers/pinctrl/core.h|   2 +
 drivers/pinctrl/pinconf-generic.c | 121 ---
 include/linux/acpi.h  |   4 +-
 include/linux/pinctrl/pinconf-generic.h   |  35 +-
 include/linux/property.h  |   9 +
 12 files changed, 1010 insertions(+), 75 deletions(-)
 create mode 100644 Documentation/acpi/pinctrl-properties.txt
 create mode 100644 drivers/pinctrl/acpi.c
 create mode 100644 drivers/pinctrl/acpi.h

-- 
1.9.1



[RFC PATCH v2 1/3] pinctrl: pinconf-generic: Add ACPI support

2016-04-05 Thread Irina Tirdea
Add ACPI support for the generic device tree properties.
Convert the pinconf generic code to handle both ACPI and
device tree by using the fwnode_property API. Also include
renaming device tree references in names of functions and
structures from 'dt' to 'fwnode'.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/acpi/property.c |   8 +--
 drivers/base/property.c |  36 --
 drivers/pinctrl/pinconf-generic.c   | 121 +++-
 include/linux/acpi.h|   4 +-
 include/linux/pinctrl/pinconf-generic.h |  35 +
 include/linux/property.h|   9 +++
 6 files changed, 138 insertions(+), 75 deletions(-)

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index f2fd3fe..b10f935 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -794,13 +794,13 @@ int acpi_node_prop_read(struct fwnode_handle *fwnode,  
const char *propname,
 
 /**
  * acpi_get_next_subnode - Return the next child node handle for a device.
- * @dev: Device to find the next child node for.
+ * @fwnode: Handle to the device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
  */
-struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode,
struct fwnode_handle *child)
 {
-   struct acpi_device *adev = ACPI_COMPANION(dev);
+   struct acpi_device *adev = to_acpi_device_node(fwnode);
struct list_head *head, *next;
 
if (!adev)
@@ -816,7 +816,7 @@ struct fwnode_handle *acpi_get_next_subnode(struct device 
*dev,
next = adev->node.next;
if (next == head) {
child = NULL;
-   adev = ACPI_COMPANION(dev);
+   adev = to_acpi_device_node(fwnode);
goto nondev;
}
adev = list_entry(next, struct acpi_device, node);
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 9b1a65d..153a316 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -859,24 +859,37 @@ int device_add_property_set(struct device *dev, const 
struct property_set *pset)
 EXPORT_SYMBOL_GPL(device_add_property_set);
 
 /**
- * device_get_next_child_node - Return the next child node handle for a device
- * @dev: Device to find the next child node for.
+ * fwnode_get_next_child_node - Return the next child node handle for a device
+ * @fwnode: Handle to the device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
  */
-struct fwnode_handle *device_get_next_child_node(struct device *dev,
+struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
 struct fwnode_handle *child)
 {
-   if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+   if (IS_ENABLED(CONFIG_OF) && to_of_node(fwnode)) {
struct device_node *node;
 
-   node = of_get_next_available_child(dev->of_node, 
to_of_node(child));
+   node = of_get_next_available_child(to_of_node(fwnode),
+  to_of_node(child));
if (node)
return >fwnode;
} else if (IS_ENABLED(CONFIG_ACPI)) {
-   return acpi_get_next_subnode(dev, child);
+   return acpi_get_next_subnode(fwnode, child);
}
return NULL;
 }
+EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
+
+/**
+ * device_get_next_child_node - Return the next child node handle for a device
+ * @dev: Device to find the next child node for.
+ * @child: Handle to one of the device's child nodes or a null handle.
+ */
+struct fwnode_handle *device_get_next_child_node(struct device *dev,
+struct fwnode_handle *child)
+{
+   return fwnode_get_next_child_node(dev_fwnode(dev), child);
+}
 EXPORT_SYMBOL_GPL(device_get_next_child_node);
 
 /**
@@ -1016,3 +1029,14 @@ void *device_get_mac_address(struct device *dev, char 
*addr, int alen)
return device_get_mac_addr(dev, "address", addr, alen);
 }
 EXPORT_SYMBOL(device_get_mac_address);
+
+const char *fwnode_get_name(struct fwnode_handle *fwnode)
+{
+   if (is_of_node(fwnode))
+   return of_node_full_name(to_of_node(fwnode));
+   else if (is_acpi_node(fwnode))
+   return acpi_dev_name(to_acpi_device_node(fwnode));
+
+   return NULL;
+}
+EXPORT_SYMBOL(fwnode_get_name);
diff --git a/drivers/pinctrl/pinconf-generic.c 
b/drivers/pinctrl/pinconf-generic.c
index d5bf9fa..52ef250 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -2

[RFC PATCH v2 1/3] pinctrl: pinconf-generic: Add ACPI support

2016-04-05 Thread Irina Tirdea
Add ACPI support for the generic device tree properties.
Convert the pinconf generic code to handle both ACPI and
device tree by using the fwnode_property API. Also include
renaming device tree references in names of functions and
structures from 'dt' to 'fwnode'.

Signed-off-by: Irina Tirdea 
---
 drivers/acpi/property.c |   8 +--
 drivers/base/property.c |  36 --
 drivers/pinctrl/pinconf-generic.c   | 121 +++-
 include/linux/acpi.h|   4 +-
 include/linux/pinctrl/pinconf-generic.h |  35 +
 include/linux/property.h|   9 +++
 6 files changed, 138 insertions(+), 75 deletions(-)

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index f2fd3fe..b10f935 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -794,13 +794,13 @@ int acpi_node_prop_read(struct fwnode_handle *fwnode,  
const char *propname,
 
 /**
  * acpi_get_next_subnode - Return the next child node handle for a device.
- * @dev: Device to find the next child node for.
+ * @fwnode: Handle to the device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
  */
-struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode,
struct fwnode_handle *child)
 {
-   struct acpi_device *adev = ACPI_COMPANION(dev);
+   struct acpi_device *adev = to_acpi_device_node(fwnode);
struct list_head *head, *next;
 
if (!adev)
@@ -816,7 +816,7 @@ struct fwnode_handle *acpi_get_next_subnode(struct device 
*dev,
next = adev->node.next;
if (next == head) {
child = NULL;
-   adev = ACPI_COMPANION(dev);
+   adev = to_acpi_device_node(fwnode);
goto nondev;
}
adev = list_entry(next, struct acpi_device, node);
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 9b1a65d..153a316 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -859,24 +859,37 @@ int device_add_property_set(struct device *dev, const 
struct property_set *pset)
 EXPORT_SYMBOL_GPL(device_add_property_set);
 
 /**
- * device_get_next_child_node - Return the next child node handle for a device
- * @dev: Device to find the next child node for.
+ * fwnode_get_next_child_node - Return the next child node handle for a device
+ * @fwnode: Handle to the device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
  */
-struct fwnode_handle *device_get_next_child_node(struct device *dev,
+struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
 struct fwnode_handle *child)
 {
-   if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+   if (IS_ENABLED(CONFIG_OF) && to_of_node(fwnode)) {
struct device_node *node;
 
-   node = of_get_next_available_child(dev->of_node, 
to_of_node(child));
+   node = of_get_next_available_child(to_of_node(fwnode),
+  to_of_node(child));
if (node)
return >fwnode;
} else if (IS_ENABLED(CONFIG_ACPI)) {
-   return acpi_get_next_subnode(dev, child);
+   return acpi_get_next_subnode(fwnode, child);
}
return NULL;
 }
+EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
+
+/**
+ * device_get_next_child_node - Return the next child node handle for a device
+ * @dev: Device to find the next child node for.
+ * @child: Handle to one of the device's child nodes or a null handle.
+ */
+struct fwnode_handle *device_get_next_child_node(struct device *dev,
+struct fwnode_handle *child)
+{
+   return fwnode_get_next_child_node(dev_fwnode(dev), child);
+}
 EXPORT_SYMBOL_GPL(device_get_next_child_node);
 
 /**
@@ -1016,3 +1029,14 @@ void *device_get_mac_address(struct device *dev, char 
*addr, int alen)
return device_get_mac_addr(dev, "address", addr, alen);
 }
 EXPORT_SYMBOL(device_get_mac_address);
+
+const char *fwnode_get_name(struct fwnode_handle *fwnode)
+{
+   if (is_of_node(fwnode))
+   return of_node_full_name(to_of_node(fwnode));
+   else if (is_acpi_node(fwnode))
+   return acpi_dev_name(to_acpi_device_node(fwnode));
+
+   return NULL;
+}
+EXPORT_SYMBOL(fwnode_get_name);
diff --git a/drivers/pinctrl/pinconf-generic.c 
b/drivers/pinctrl/pinconf-generic.c
index d5bf9fa..52ef250 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -21,6 +21,7 @@
 #include 
 #in

[RFC PATCH v2 3/3] pinctrl: Parse GpioInt/GpioIo resources

2016-04-05 Thread Irina Tirdea
Parse GpioInt/GpioIo ACPI resources and use the pin configuration
information to generate pin controller maps. These maps are associated
with the "default" state, only if this state is defined in the _DSD
of the acpi device.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 Documentation/acpi/pinctrl-properties.txt |   8 ++
 drivers/pinctrl/acpi.c| 184 ++
 2 files changed, 192 insertions(+)

diff --git a/Documentation/acpi/pinctrl-properties.txt 
b/Documentation/acpi/pinctrl-properties.txt
index 9cdf6fa..3f949d4 100644
--- a/Documentation/acpi/pinctrl-properties.txt
+++ b/Documentation/acpi/pinctrl-properties.txt
@@ -275,6 +275,14 @@ Pinctrl "sleep" state provides power management 
capabilities to the device that
 conflict with ACPI power management methods. Special care must be taken when 
using
 the "sleep" state not to create conflicts with the existing ACPI configuration.
 
+== GpioInt()/GpioIo() _CRS resources ==
+
+If the device has any GpioInt/GpioIo _CRS ACPI resources, they are parsed so
+that the pin configuration information is used (e.g. PullUp/PullDown/PullNone).
+The pin configuration from GpioInt/GpioIo will be associated with the "default"
+state, only if such a state is defined in the _DSD of the device. If no
+"default" state is defined, the GPIO configuration from _CRS will be ignored.
+
 == References ==
 
 [1] Documentation/pinctrl.txt
diff --git a/drivers/pinctrl/acpi.c b/drivers/pinctrl/acpi.c
index 0ddacaf..3b8f824 100644
--- a/drivers/pinctrl/acpi.c
+++ b/drivers/pinctrl/acpi.c
@@ -42,6 +42,17 @@ struct pinctrl_acpi_map {
unsigned num_maps;
 };
 
+struct acpi_gpio_lookup {
+   unsigned int index;
+   bool found;
+   unsigned int n;
+   struct pinctrl *p;
+   char *statename;
+};
+
+/* For now we only handle acpi pin config values */
+#define ACPI_MAX_CFGS 1
+
 static void acpi_maps_list_dh(acpi_handle handle, void *data)
 {
/* The address of this function is used as a key. */
@@ -152,6 +163,166 @@ static int acpi_remember_or_free_map(struct pinctrl *p, 
const char *statename,
return pinctrl_register_map(map, num_maps, false);
 }
 
+static int acpi_parse_gpio_config(const struct acpi_resource_gpio *agpio,
+ unsigned long **configs,
+ unsigned int *nconfigs)
+{
+   enum pin_config_param param;
+   int ret;
+
+   /* Parse configs from GpioInt/GpioIo ACPI resource */
+   *nconfigs = 0;
+   *configs = kcalloc(ACPI_MAX_CFGS, sizeof(*configs), GFP_KERNEL);
+   if (!*configs)
+   return -ENOMEM;
+
+   /* For now, only parse pin_config */
+   switch (agpio->pin_config) {
+   case ACPI_PIN_CONFIG_DEFAULT:
+   param = PIN_CONFIG_BIAS_PULL_PIN_DEFAULT;
+   break;
+   case ACPI_PIN_CONFIG_PULLUP:
+   param = PIN_CONFIG_BIAS_PULL_UP;
+   break;
+   case ACPI_PIN_CONFIG_PULLDOWN:
+   param = PIN_CONFIG_BIAS_PULL_DOWN;
+   break;
+   case ACPI_PIN_CONFIG_NOPULL:
+   param = PIN_CONFIG_BIAS_DISABLE;
+   break;
+   default:
+   ret = -EINVAL;
+   goto exit_free;
+   }
+   *configs[*nconfigs] = pinconf_to_config_packed(param,
+ param == PIN_CONFIG_BIAS_DISABLE ? 0 : 1);
+   (*nconfigs)++;
+
+   return 0;
+
+exit_free:
+   kfree(*configs);
+   return ret;
+}
+
+static int acpi_gpio_to_map(struct acpi_resource *ares, void *data)
+{
+   unsigned num_maps = 0, reserved_maps = 0;
+   struct acpi_gpio_lookup *lookup = data;
+   const struct acpi_resource_gpio *agpio;
+   acpi_handle pctrl_handle = NULL;
+   struct pinctrl_map *map = NULL;
+   struct pinctrl_dev *pctldev;
+   unsigned int nconfigs, i;
+   unsigned long *configs;
+   acpi_status status;
+   const char *pin;
+   int ret;
+
+   if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
+   return 1;
+   if (lookup->n++ != lookup->index || lookup->found)
+   return 1;
+
+   agpio = >data.gpio;
+
+   /* Get configs from ACPI GPIO resource */
+   ret = acpi_parse_gpio_config(agpio, , );
+   if (ret)
+   return ret;
+
+   /* Get pinctrl reference from GPIO resource */
+   status = acpi_get_handle(NULL, agpio->resource_source.string_ptr,
+_handle);
+   if (ACPI_FAILURE(status) || !pctrl_handle) {
+   ret = -EINVAL;
+   goto exit_free_configs;
+   }
+
+   /* Find the pin controller */
+   pctldev = get_pinctrl_dev_from_acpi(pctrl_handle);
+   if (!pctldev) {
+   ret = -EINVAL;
+   goto exit_free_configs;
+   }
+
+   /* Allocate space for maps and pinct

[RFC PATCH v2 2/3] pinctrl: Add ACPI support

2016-04-05 Thread Irina Tirdea
Add ACPI support for pin controller properties. These are
based on ACPI _DSD properties and follow the device tree
model based on states and node configurations. The states
are defined as _DSD properties and configuration nodes
are defined using the _DSD Hierarchical Properties Extension.

A configuration node supports the generic device tree properties.

The implementation is based on device tree code from devicetree.c.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 Documentation/acpi/pinctrl-properties.txt | 284 +
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/acpi.c| 335 ++
 drivers/pinctrl/acpi.h|  32 +++
 drivers/pinctrl/core.c|  26 +++
 drivers/pinctrl/core.h|   2 +
 6 files changed, 680 insertions(+)
 create mode 100644 Documentation/acpi/pinctrl-properties.txt
 create mode 100644 drivers/pinctrl/acpi.c
 create mode 100644 drivers/pinctrl/acpi.h

diff --git a/Documentation/acpi/pinctrl-properties.txt 
b/Documentation/acpi/pinctrl-properties.txt
new file mode 100644
index 000..9cdf6fa
--- /dev/null
+++ b/Documentation/acpi/pinctrl-properties.txt
@@ -0,0 +1,284 @@
+= _DSD Device Properties related to pin controllers =
+
+== Introduction ==
+
+This document is an extension of the pin control subsystem in Linux [1]
+and provides a way to describe pin controller properties in ACPI. It is
+based on the Device Specific Data (_DSD) configuration object [2] that
+was introduced in ACPI 5.1.
+
+Pin controllers are hardware modules that control pins by allowing pin
+multiplexing and configuration. Pin multiplexing allows using the same
+physical pins for multiple functions; for example, one pin or group of pins
+may be used for the I2C bus, SPI bus or as general-purpose GPIO pin. Pin
+configuration allows setting various properties such as pull-up/down,
+tri-state, drive-strength, etc.
+
+Hardware modules whose signals are affected by pin configuration are
+designated client devices. For a client device to operate correctly,
+certain pin controllers must set up certain specific pin configurations.
+Some client devices need a single static pin configuration, e.g. set up
+during initialization. Others need to reconfigure pins at run-time,
+for example to tri-state pins when the device is inactive. Hence, each
+client device can define a set of named states. Each named state is
+mapped to a pin controller configuration that describes the pin multiplexing
+or configuration for that state.
+
+In ACPI, each pin controller and each client device is represented as an
+ACPI device, just like any other hardware module. The pin controller
+properties are defined using _DSD properties [2] under these devices.
+The named states are defined using Device Properties UUID [3] under the
+ACPI client device. The configuration nodes are defined using Hierarchical
+Properties Extension UUID [4] and are split between the ACPI client device
+and the pin controller device. The configuration nodes contain properties
+that describe pin multiplexing or configuration that very similar to the
+ones used for device tree [5].
+
+== Example ==
+
+For example, let's consider an accelerometer connected to the I2C bus on
+a platform with a Baytrail pin controller. The accelerometer uses 2 GPIO
+pins for I2C (SDA, SCL) and one GPIO pin for interrupt.
+
+The name for the pins, groups and functions used are the ones defined in the
+pin controller driver, in the same way as it is done for device tree [5].
+
+For the I2C pins, the pin controller driver defines one group called
+"i2c5_grp" that can be multiplexed with functions "i2c" or "gpio".
+In our case, we need to select function "i2c" for group "i2c5_grp" in
+the ACPI description.
+
+For the GPIO pin, the pin controller driver defines the name "GPIO_S50"
+for the pin with index 0 that we use. We need to configure this pin to
+pull-down with pull strength of 1 Ohms. We might also want to disable
+the bias for the GPIO interrupt pin when entering sleep.
+
+Here is an ASL example for this device:
+
+  // Pin controller device
+  Scope (_SB.GPO0)
+  {
+  Name (MUX0, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+  Package()
+  {
+  Package (2) {"function", "i2c"},
+  Package (2) {"groups", Package () {"i2c5_grp"}},
+  }
+  })
+
+  Name (CFG0, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+  Package()
+  {
+  Package (2) {"pins", Package () {"GPIO_S50"}},
+  Package (2) {"bias-pull-down", 1},
+  }
+  })
+
+  Name (CFG1, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8

[RFC PATCH v2 3/3] pinctrl: Parse GpioInt/GpioIo resources

2016-04-05 Thread Irina Tirdea
Parse GpioInt/GpioIo ACPI resources and use the pin configuration
information to generate pin controller maps. These maps are associated
with the "default" state, only if this state is defined in the _DSD
of the acpi device.

Signed-off-by: Irina Tirdea 
---
 Documentation/acpi/pinctrl-properties.txt |   8 ++
 drivers/pinctrl/acpi.c| 184 ++
 2 files changed, 192 insertions(+)

diff --git a/Documentation/acpi/pinctrl-properties.txt 
b/Documentation/acpi/pinctrl-properties.txt
index 9cdf6fa..3f949d4 100644
--- a/Documentation/acpi/pinctrl-properties.txt
+++ b/Documentation/acpi/pinctrl-properties.txt
@@ -275,6 +275,14 @@ Pinctrl "sleep" state provides power management 
capabilities to the device that
 conflict with ACPI power management methods. Special care must be taken when 
using
 the "sleep" state not to create conflicts with the existing ACPI configuration.
 
+== GpioInt()/GpioIo() _CRS resources ==
+
+If the device has any GpioInt/GpioIo _CRS ACPI resources, they are parsed so
+that the pin configuration information is used (e.g. PullUp/PullDown/PullNone).
+The pin configuration from GpioInt/GpioIo will be associated with the "default"
+state, only if such a state is defined in the _DSD of the device. If no
+"default" state is defined, the GPIO configuration from _CRS will be ignored.
+
 == References ==
 
 [1] Documentation/pinctrl.txt
diff --git a/drivers/pinctrl/acpi.c b/drivers/pinctrl/acpi.c
index 0ddacaf..3b8f824 100644
--- a/drivers/pinctrl/acpi.c
+++ b/drivers/pinctrl/acpi.c
@@ -42,6 +42,17 @@ struct pinctrl_acpi_map {
unsigned num_maps;
 };
 
+struct acpi_gpio_lookup {
+   unsigned int index;
+   bool found;
+   unsigned int n;
+   struct pinctrl *p;
+   char *statename;
+};
+
+/* For now we only handle acpi pin config values */
+#define ACPI_MAX_CFGS 1
+
 static void acpi_maps_list_dh(acpi_handle handle, void *data)
 {
/* The address of this function is used as a key. */
@@ -152,6 +163,166 @@ static int acpi_remember_or_free_map(struct pinctrl *p, 
const char *statename,
return pinctrl_register_map(map, num_maps, false);
 }
 
+static int acpi_parse_gpio_config(const struct acpi_resource_gpio *agpio,
+ unsigned long **configs,
+ unsigned int *nconfigs)
+{
+   enum pin_config_param param;
+   int ret;
+
+   /* Parse configs from GpioInt/GpioIo ACPI resource */
+   *nconfigs = 0;
+   *configs = kcalloc(ACPI_MAX_CFGS, sizeof(*configs), GFP_KERNEL);
+   if (!*configs)
+   return -ENOMEM;
+
+   /* For now, only parse pin_config */
+   switch (agpio->pin_config) {
+   case ACPI_PIN_CONFIG_DEFAULT:
+   param = PIN_CONFIG_BIAS_PULL_PIN_DEFAULT;
+   break;
+   case ACPI_PIN_CONFIG_PULLUP:
+   param = PIN_CONFIG_BIAS_PULL_UP;
+   break;
+   case ACPI_PIN_CONFIG_PULLDOWN:
+   param = PIN_CONFIG_BIAS_PULL_DOWN;
+   break;
+   case ACPI_PIN_CONFIG_NOPULL:
+   param = PIN_CONFIG_BIAS_DISABLE;
+   break;
+   default:
+   ret = -EINVAL;
+   goto exit_free;
+   }
+   *configs[*nconfigs] = pinconf_to_config_packed(param,
+ param == PIN_CONFIG_BIAS_DISABLE ? 0 : 1);
+   (*nconfigs)++;
+
+   return 0;
+
+exit_free:
+   kfree(*configs);
+   return ret;
+}
+
+static int acpi_gpio_to_map(struct acpi_resource *ares, void *data)
+{
+   unsigned num_maps = 0, reserved_maps = 0;
+   struct acpi_gpio_lookup *lookup = data;
+   const struct acpi_resource_gpio *agpio;
+   acpi_handle pctrl_handle = NULL;
+   struct pinctrl_map *map = NULL;
+   struct pinctrl_dev *pctldev;
+   unsigned int nconfigs, i;
+   unsigned long *configs;
+   acpi_status status;
+   const char *pin;
+   int ret;
+
+   if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
+   return 1;
+   if (lookup->n++ != lookup->index || lookup->found)
+   return 1;
+
+   agpio = >data.gpio;
+
+   /* Get configs from ACPI GPIO resource */
+   ret = acpi_parse_gpio_config(agpio, , );
+   if (ret)
+   return ret;
+
+   /* Get pinctrl reference from GPIO resource */
+   status = acpi_get_handle(NULL, agpio->resource_source.string_ptr,
+_handle);
+   if (ACPI_FAILURE(status) || !pctrl_handle) {
+   ret = -EINVAL;
+   goto exit_free_configs;
+   }
+
+   /* Find the pin controller */
+   pctldev = get_pinctrl_dev_from_acpi(pctrl_handle);
+   if (!pctldev) {
+   ret = -EINVAL;
+   goto exit_free_configs;
+   }
+
+   /* Allocate space for maps and pinctrl_dev

[RFC PATCH v2 2/3] pinctrl: Add ACPI support

2016-04-05 Thread Irina Tirdea
Add ACPI support for pin controller properties. These are
based on ACPI _DSD properties and follow the device tree
model based on states and node configurations. The states
are defined as _DSD properties and configuration nodes
are defined using the _DSD Hierarchical Properties Extension.

A configuration node supports the generic device tree properties.

The implementation is based on device tree code from devicetree.c.

Signed-off-by: Irina Tirdea 
---
 Documentation/acpi/pinctrl-properties.txt | 284 +
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/acpi.c| 335 ++
 drivers/pinctrl/acpi.h|  32 +++
 drivers/pinctrl/core.c|  26 +++
 drivers/pinctrl/core.h|   2 +
 6 files changed, 680 insertions(+)
 create mode 100644 Documentation/acpi/pinctrl-properties.txt
 create mode 100644 drivers/pinctrl/acpi.c
 create mode 100644 drivers/pinctrl/acpi.h

diff --git a/Documentation/acpi/pinctrl-properties.txt 
b/Documentation/acpi/pinctrl-properties.txt
new file mode 100644
index 000..9cdf6fa
--- /dev/null
+++ b/Documentation/acpi/pinctrl-properties.txt
@@ -0,0 +1,284 @@
+= _DSD Device Properties related to pin controllers =
+
+== Introduction ==
+
+This document is an extension of the pin control subsystem in Linux [1]
+and provides a way to describe pin controller properties in ACPI. It is
+based on the Device Specific Data (_DSD) configuration object [2] that
+was introduced in ACPI 5.1.
+
+Pin controllers are hardware modules that control pins by allowing pin
+multiplexing and configuration. Pin multiplexing allows using the same
+physical pins for multiple functions; for example, one pin or group of pins
+may be used for the I2C bus, SPI bus or as general-purpose GPIO pin. Pin
+configuration allows setting various properties such as pull-up/down,
+tri-state, drive-strength, etc.
+
+Hardware modules whose signals are affected by pin configuration are
+designated client devices. For a client device to operate correctly,
+certain pin controllers must set up certain specific pin configurations.
+Some client devices need a single static pin configuration, e.g. set up
+during initialization. Others need to reconfigure pins at run-time,
+for example to tri-state pins when the device is inactive. Hence, each
+client device can define a set of named states. Each named state is
+mapped to a pin controller configuration that describes the pin multiplexing
+or configuration for that state.
+
+In ACPI, each pin controller and each client device is represented as an
+ACPI device, just like any other hardware module. The pin controller
+properties are defined using _DSD properties [2] under these devices.
+The named states are defined using Device Properties UUID [3] under the
+ACPI client device. The configuration nodes are defined using Hierarchical
+Properties Extension UUID [4] and are split between the ACPI client device
+and the pin controller device. The configuration nodes contain properties
+that describe pin multiplexing or configuration that very similar to the
+ones used for device tree [5].
+
+== Example ==
+
+For example, let's consider an accelerometer connected to the I2C bus on
+a platform with a Baytrail pin controller. The accelerometer uses 2 GPIO
+pins for I2C (SDA, SCL) and one GPIO pin for interrupt.
+
+The name for the pins, groups and functions used are the ones defined in the
+pin controller driver, in the same way as it is done for device tree [5].
+
+For the I2C pins, the pin controller driver defines one group called
+"i2c5_grp" that can be multiplexed with functions "i2c" or "gpio".
+In our case, we need to select function "i2c" for group "i2c5_grp" in
+the ACPI description.
+
+For the GPIO pin, the pin controller driver defines the name "GPIO_S50"
+for the pin with index 0 that we use. We need to configure this pin to
+pull-down with pull strength of 1 Ohms. We might also want to disable
+the bias for the GPIO interrupt pin when entering sleep.
+
+Here is an ASL example for this device:
+
+  // Pin controller device
+  Scope (_SB.GPO0)
+  {
+  Name (MUX0, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+  Package()
+  {
+  Package (2) {"function", "i2c"},
+  Package (2) {"groups", Package () {"i2c5_grp"}},
+  }
+  })
+
+  Name (CFG0, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+  Package()
+  {
+  Package (2) {"pins", Package () {"GPIO_S50"}},
+  Package (2) {"bias-pull-down", 1},
+  }
+  })
+
+  Name (CFG1, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc

[RFC PATCH 2/4] pinctrl: pinconf-generic: Add ACPI support

2016-03-31 Thread Irina Tirdea
Add ACPI support for the generic device tree properties.
Convert the pinconf generic code to handle both ACPI and
device tree by using the fwnode_property API. Also include
renaming device tree references in names of functions and
structures from 'dt' to 'fwnode'.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/acpi/property.c |   8 +--
 drivers/base/property.c |  36 --
 drivers/pinctrl/pinconf-generic.c   | 121 +++-
 include/linux/acpi.h|   4 +-
 include/linux/pinctrl/pinconf-generic.h |  27 ---
 include/linux/property.h|   9 +++
 6 files changed, 130 insertions(+), 75 deletions(-)

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index f2fd3fe..b10f935 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -794,13 +794,13 @@ int acpi_node_prop_read(struct fwnode_handle *fwnode,  
const char *propname,
 
 /**
  * acpi_get_next_subnode - Return the next child node handle for a device.
- * @dev: Device to find the next child node for.
+ * @fwnode: Handle to the device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
  */
-struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode,
struct fwnode_handle *child)
 {
-   struct acpi_device *adev = ACPI_COMPANION(dev);
+   struct acpi_device *adev = to_acpi_device_node(fwnode);
struct list_head *head, *next;
 
if (!adev)
@@ -816,7 +816,7 @@ struct fwnode_handle *acpi_get_next_subnode(struct device 
*dev,
next = adev->node.next;
if (next == head) {
child = NULL;
-   adev = ACPI_COMPANION(dev);
+   adev = to_acpi_device_node(fwnode);
goto nondev;
}
adev = list_entry(next, struct acpi_device, node);
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 9b1a65d..153a316 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -859,24 +859,37 @@ int device_add_property_set(struct device *dev, const 
struct property_set *pset)
 EXPORT_SYMBOL_GPL(device_add_property_set);
 
 /**
- * device_get_next_child_node - Return the next child node handle for a device
- * @dev: Device to find the next child node for.
+ * fwnode_get_next_child_node - Return the next child node handle for a device
+ * @fwnode: Handle to the device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
  */
-struct fwnode_handle *device_get_next_child_node(struct device *dev,
+struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
 struct fwnode_handle *child)
 {
-   if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+   if (IS_ENABLED(CONFIG_OF) && to_of_node(fwnode)) {
struct device_node *node;
 
-   node = of_get_next_available_child(dev->of_node, 
to_of_node(child));
+   node = of_get_next_available_child(to_of_node(fwnode),
+  to_of_node(child));
if (node)
return >fwnode;
} else if (IS_ENABLED(CONFIG_ACPI)) {
-   return acpi_get_next_subnode(dev, child);
+   return acpi_get_next_subnode(fwnode, child);
}
return NULL;
 }
+EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
+
+/**
+ * device_get_next_child_node - Return the next child node handle for a device
+ * @dev: Device to find the next child node for.
+ * @child: Handle to one of the device's child nodes or a null handle.
+ */
+struct fwnode_handle *device_get_next_child_node(struct device *dev,
+struct fwnode_handle *child)
+{
+   return fwnode_get_next_child_node(dev_fwnode(dev), child);
+}
 EXPORT_SYMBOL_GPL(device_get_next_child_node);
 
 /**
@@ -1016,3 +1029,14 @@ void *device_get_mac_address(struct device *dev, char 
*addr, int alen)
return device_get_mac_addr(dev, "address", addr, alen);
 }
 EXPORT_SYMBOL(device_get_mac_address);
+
+const char *fwnode_get_name(struct fwnode_handle *fwnode)
+{
+   if (is_of_node(fwnode))
+   return of_node_full_name(to_of_node(fwnode));
+   else if (is_acpi_node(fwnode))
+   return acpi_dev_name(to_acpi_device_node(fwnode));
+
+   return NULL;
+}
+EXPORT_SYMBOL(fwnode_get_name);
diff --git a/drivers/pinctrl/pinconf-generic.c 
b/drivers/pinctrl/pinconf-generic.c
index d5bf9fa..9d1571e 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -2

[RFC PATCH 2/4] pinctrl: pinconf-generic: Add ACPI support

2016-03-31 Thread Irina Tirdea
Add ACPI support for the generic device tree properties.
Convert the pinconf generic code to handle both ACPI and
device tree by using the fwnode_property API. Also include
renaming device tree references in names of functions and
structures from 'dt' to 'fwnode'.

Signed-off-by: Irina Tirdea 
---
 drivers/acpi/property.c |   8 +--
 drivers/base/property.c |  36 --
 drivers/pinctrl/pinconf-generic.c   | 121 +++-
 include/linux/acpi.h|   4 +-
 include/linux/pinctrl/pinconf-generic.h |  27 ---
 include/linux/property.h|   9 +++
 6 files changed, 130 insertions(+), 75 deletions(-)

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index f2fd3fe..b10f935 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -794,13 +794,13 @@ int acpi_node_prop_read(struct fwnode_handle *fwnode,  
const char *propname,
 
 /**
  * acpi_get_next_subnode - Return the next child node handle for a device.
- * @dev: Device to find the next child node for.
+ * @fwnode: Handle to the device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
  */
-struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
+struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode,
struct fwnode_handle *child)
 {
-   struct acpi_device *adev = ACPI_COMPANION(dev);
+   struct acpi_device *adev = to_acpi_device_node(fwnode);
struct list_head *head, *next;
 
if (!adev)
@@ -816,7 +816,7 @@ struct fwnode_handle *acpi_get_next_subnode(struct device 
*dev,
next = adev->node.next;
if (next == head) {
child = NULL;
-   adev = ACPI_COMPANION(dev);
+   adev = to_acpi_device_node(fwnode);
goto nondev;
}
adev = list_entry(next, struct acpi_device, node);
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 9b1a65d..153a316 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -859,24 +859,37 @@ int device_add_property_set(struct device *dev, const 
struct property_set *pset)
 EXPORT_SYMBOL_GPL(device_add_property_set);
 
 /**
- * device_get_next_child_node - Return the next child node handle for a device
- * @dev: Device to find the next child node for.
+ * fwnode_get_next_child_node - Return the next child node handle for a device
+ * @fwnode: Handle to the device to find the next child node for.
  * @child: Handle to one of the device's child nodes or a null handle.
  */
-struct fwnode_handle *device_get_next_child_node(struct device *dev,
+struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
 struct fwnode_handle *child)
 {
-   if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+   if (IS_ENABLED(CONFIG_OF) && to_of_node(fwnode)) {
struct device_node *node;
 
-   node = of_get_next_available_child(dev->of_node, 
to_of_node(child));
+   node = of_get_next_available_child(to_of_node(fwnode),
+  to_of_node(child));
if (node)
return >fwnode;
} else if (IS_ENABLED(CONFIG_ACPI)) {
-   return acpi_get_next_subnode(dev, child);
+   return acpi_get_next_subnode(fwnode, child);
}
return NULL;
 }
+EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
+
+/**
+ * device_get_next_child_node - Return the next child node handle for a device
+ * @dev: Device to find the next child node for.
+ * @child: Handle to one of the device's child nodes or a null handle.
+ */
+struct fwnode_handle *device_get_next_child_node(struct device *dev,
+struct fwnode_handle *child)
+{
+   return fwnode_get_next_child_node(dev_fwnode(dev), child);
+}
 EXPORT_SYMBOL_GPL(device_get_next_child_node);
 
 /**
@@ -1016,3 +1029,14 @@ void *device_get_mac_address(struct device *dev, char 
*addr, int alen)
return device_get_mac_addr(dev, "address", addr, alen);
 }
 EXPORT_SYMBOL(device_get_mac_address);
+
+const char *fwnode_get_name(struct fwnode_handle *fwnode)
+{
+   if (is_of_node(fwnode))
+   return of_node_full_name(to_of_node(fwnode));
+   else if (is_acpi_node(fwnode))
+   return acpi_dev_name(to_acpi_device_node(fwnode));
+
+   return NULL;
+}
+EXPORT_SYMBOL(fwnode_get_name);
diff --git a/drivers/pinctrl/pinconf-generic.c 
b/drivers/pinctrl/pinconf-generic.c
index d5bf9fa..9d1571e 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -21,6 +21,7 @@
 #include 
 #in

[RFC PATCH 4/4] pinctrl: Parse GpioInt/GpioIo resources

2016-03-31 Thread Irina Tirdea
Parse GpioInt/GpioIo ACPI resources and use the pin configuration
information to generate pin controller maps. These maps are associated
with the "default" state, only if this state is defined in the _DSD
of the acpi device.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 Documentation/acpi/pinctrl-properties.txt |   8 ++
 drivers/pinctrl/acpi.c| 229 ++
 2 files changed, 237 insertions(+)

diff --git a/Documentation/acpi/pinctrl-properties.txt 
b/Documentation/acpi/pinctrl-properties.txt
index e93aaaf..8243190 100644
--- a/Documentation/acpi/pinctrl-properties.txt
+++ b/Documentation/acpi/pinctrl-properties.txt
@@ -265,6 +265,14 @@ same way as it is done for device tree [5]. The format for 
the data subnode is:
   configname - name of the pin configuration property
   configval - value of the pin configuration property
 
+== GpioInt()/GpioIo() _CRS resources ==
+
+If the device has any GpioInt/GpioIo _CRS ACPI resources, they are parsed so
+that the pin configuration information is used (e.g. PullUp/PullDown/PullNone).
+The pin configuration from GpioInt/GpioIo will be associated with the "default"
+state, only if such a state is defined in the _DSD of the device. If no
+"default" state is defined, the GPIO configuration from _CRS will be ignored.
+
 == References ==
 
 [1] Documentation/pinctrl.txt
diff --git a/drivers/pinctrl/acpi.c b/drivers/pinctrl/acpi.c
index bed1d88..7199c3d 100644
--- a/drivers/pinctrl/acpi.c
+++ b/drivers/pinctrl/acpi.c
@@ -140,6 +140,224 @@ static int acpi_remember_or_free_map(struct pinctrl *p, 
const char *statename,
return pinctrl_register_map(map, num_maps, false);
 }
 
+#ifdef CONFIG_GENERIC_PINCONF
+struct acpi_gpio_lookup {
+   unsigned int index;
+   bool found;
+   unsigned int n;
+   struct pinctrl_map *map;
+   unsigned num_maps;
+   unsigned reserved_maps;
+   struct pinctrl_dev **pctldevs;
+};
+
+/* For now we only handle acpi pin config values */
+#define ACPI_MAX_CFGS 1
+
+static int acpi_parse_gpio_config(const struct acpi_resource_gpio *agpio,
+ unsigned long **configs,
+ unsigned int *nconfigs)
+{
+   enum pin_config_param param;
+   int ret;
+
+   /* Parse configs from GpioInt/GpioIo ACPI resource */
+   *nconfigs = 0;
+   *configs = kcalloc(ACPI_MAX_CFGS, sizeof(*configs), GFP_KERNEL);
+   if (!*configs)
+   return -ENOMEM;
+
+   /* For now, only parse pin_config */
+   switch (agpio->pin_config) {
+   case ACPI_PIN_CONFIG_DEFAULT:
+   param = PIN_CONFIG_BIAS_PULL_PIN_DEFAULT;
+   break;
+   case ACPI_PIN_CONFIG_PULLUP:
+   param = PIN_CONFIG_BIAS_PULL_UP;
+   break;
+   case ACPI_PIN_CONFIG_PULLDOWN:
+   param = PIN_CONFIG_BIAS_PULL_DOWN;
+   break;
+   case ACPI_PIN_CONFIG_NOPULL:
+   param = PIN_CONFIG_BIAS_DISABLE;
+   break;
+   default:
+   ret = -EINVAL;
+   goto exit_free;
+   }
+   *configs[*nconfigs] = pinconf_to_config_packed(param,
+ param == PIN_CONFIG_BIAS_DISABLE ? 0 : 1);
+   (*nconfigs)++;
+
+   return 0;
+
+exit_free:
+   kfree(*configs);
+   return ret;
+}
+
+static int acpi_gpio_to_map(struct acpi_resource *ares, void *data)
+{
+   struct pinctrl_dev *pctldev, **new_pctldevs;
+   struct acpi_gpio_lookup *lookup = data;
+   const struct acpi_resource_gpio *agpio;
+   acpi_handle pctrl_handle = NULL;
+   unsigned int nconfigs, i;
+   unsigned long *configs;
+   acpi_status status;
+   const char *pin;
+   int ret;
+
+   if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
+   return 1;
+   if (lookup->n++ != lookup->index || lookup->found)
+   return 1;
+
+   agpio = >data.gpio;
+
+   /* Get configs from ACPI GPIO resource */
+   ret = acpi_parse_gpio_config(agpio, , );
+   if (ret)
+   return ret;
+
+   /* Get pinctrl reference from GPIO resource */
+   status = acpi_get_handle(NULL, agpio->resource_source.string_ptr,
+_handle);
+   if (ACPI_FAILURE(status) || !pctrl_handle) {
+   ret = -EINVAL;
+   goto exit_free_configs;
+   }
+
+   /* Find the pin controller */
+   pctldev = get_pinctrl_dev_from_acpi(pctrl_handle);
+   if (!pctldev) {
+   ret = -EINVAL;
+   goto exit_free_configs;
+   }
+
+   /* Allocate space for maps and pinctrl_dev references */
+   ret = pinctrl_utils_reserve_map(pctldev, >map,
+   >reserved_maps,
+   >num_maps,
+   agpio->pin_table

[RFC PATCH 0/4] Add ACPI support for pinctrl configuration

2016-03-31 Thread Irina Tirdea
This is a proposal for adding ACPI support for pin controller
configuration.

It has been developed to enable the MinnowBoard and IoT community
by providing an easy way to specify pin multiplexing and
pin configuration.

This proposal is based on using _DSD properties to specify device
states and configuration nodes and it follows closely the device
tree model. Device states are defined using the Device Properties
format and the configuration nodes are defined using the
Hierarchical Properties Extension format. The generic properties
for the configuration nodes are the same as the ones for device
tree, while pincontroller drivers can also define custom ones.

Irina Tirdea (4):
  pinctrl: Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map
  pinctrl: pinconf-generic: Add ACPI support
  pinctrl: Add ACPI support
  pinctrl: Parse GpioInt/GpioIo resources

 Documentation/acpi/pinctrl-properties.txt| 282 
 drivers/acpi/property.c  |   8 +-
 drivers/base/property.c  |  36 +-
 drivers/pinctrl/Makefile |   1 +
 drivers/pinctrl/acpi.c   | 551 +++
 drivers/pinctrl/acpi.h   |  32 ++
 drivers/pinctrl/bcm/pinctrl-bcm281xx.c   |   2 +-
 drivers/pinctrl/bcm/pinctrl-cygnus-mux.c |   2 +-
 drivers/pinctrl/bcm/pinctrl-iproc-gpio.c |   2 +-
 drivers/pinctrl/bcm/pinctrl-nsp-gpio.c   |   2 +-
 drivers/pinctrl/berlin/berlin.c  |   2 +-
 drivers/pinctrl/core.c   |  26 ++
 drivers/pinctrl/core.h   |   2 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c|   4 +-
 drivers/pinctrl/meson/pinctrl-meson.c|   2 +-
 drivers/pinctrl/nomadik/pinctrl-abx500.c |   4 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik.c|   4 +-
 drivers/pinctrl/pinconf-generic.c| 123 +++--
 drivers/pinctrl/pinctrl-amd.c|   2 +-
 drivers/pinctrl/pinctrl-as3722.c |   2 +-
 drivers/pinctrl/pinctrl-at91-pio4.c  |   4 +-
 drivers/pinctrl/pinctrl-digicolor.c  |   2 +-
 drivers/pinctrl/pinctrl-lpc18xx.c|   2 +-
 drivers/pinctrl/pinctrl-palmas.c |   2 +-
 drivers/pinctrl/pinctrl-pic32.c  |   2 +-
 drivers/pinctrl/pinctrl-pistachio.c  |   2 +-
 drivers/pinctrl/pinctrl-tb10x.c  |   2 +-
 drivers/pinctrl/pinctrl-utils.c  |   4 +-
 drivers/pinctrl/pinctrl-utils.h  |   2 +-
 drivers/pinctrl/pinctrl-zynq.c   |   2 +-
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c |   2 +-
 drivers/pinctrl/qcom/pinctrl-msm.c   |   2 +-
 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c |   2 +-
 drivers/pinctrl/qcom/pinctrl-spmi-mpp.c  |   2 +-
 drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c |   2 +-
 drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c  |   2 +-
 drivers/pinctrl/stm32/pinctrl-stm32.c|   4 +-
 drivers/pinctrl/tegra/pinctrl-tegra-xusb.c   |   2 +-
 drivers/pinctrl/tegra/pinctrl-tegra.c|   4 +-
 drivers/pinctrl/uniphier/pinctrl-uniphier-core.c |   2 +-
 include/linux/acpi.h |   4 +-
 include/linux/pinctrl/pinconf-generic.h  |  27 +-
 include/linux/property.h |   9 +
 43 files changed, 1063 insertions(+), 114 deletions(-)
 create mode 100644 Documentation/acpi/pinctrl-properties.txt
 create mode 100644 drivers/pinctrl/acpi.c
 create mode 100644 drivers/pinctrl/acpi.h

-- 
1.9.1



[RFC PATCH 0/4] Add ACPI support for pinctrl configuration

2016-03-31 Thread Irina Tirdea
This is a proposal for adding ACPI support for pin controller
configuration.

It has been developed to enable the MinnowBoard and IoT community
by providing an easy way to specify pin multiplexing and
pin configuration.

This proposal is based on using _DSD properties to specify device
states and configuration nodes and it follows closely the device
tree model. Device states are defined using the Device Properties
format and the configuration nodes are defined using the
Hierarchical Properties Extension format. The generic properties
for the configuration nodes are the same as the ones for device
tree, while pincontroller drivers can also define custom ones.

Irina Tirdea (4):
  pinctrl: Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map
  pinctrl: pinconf-generic: Add ACPI support
  pinctrl: Add ACPI support
  pinctrl: Parse GpioInt/GpioIo resources

 Documentation/acpi/pinctrl-properties.txt| 282 
 drivers/acpi/property.c  |   8 +-
 drivers/base/property.c  |  36 +-
 drivers/pinctrl/Makefile |   1 +
 drivers/pinctrl/acpi.c   | 551 +++
 drivers/pinctrl/acpi.h   |  32 ++
 drivers/pinctrl/bcm/pinctrl-bcm281xx.c   |   2 +-
 drivers/pinctrl/bcm/pinctrl-cygnus-mux.c |   2 +-
 drivers/pinctrl/bcm/pinctrl-iproc-gpio.c |   2 +-
 drivers/pinctrl/bcm/pinctrl-nsp-gpio.c   |   2 +-
 drivers/pinctrl/berlin/berlin.c  |   2 +-
 drivers/pinctrl/core.c   |  26 ++
 drivers/pinctrl/core.h   |   2 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c|   4 +-
 drivers/pinctrl/meson/pinctrl-meson.c|   2 +-
 drivers/pinctrl/nomadik/pinctrl-abx500.c |   4 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik.c|   4 +-
 drivers/pinctrl/pinconf-generic.c| 123 +++--
 drivers/pinctrl/pinctrl-amd.c|   2 +-
 drivers/pinctrl/pinctrl-as3722.c |   2 +-
 drivers/pinctrl/pinctrl-at91-pio4.c  |   4 +-
 drivers/pinctrl/pinctrl-digicolor.c  |   2 +-
 drivers/pinctrl/pinctrl-lpc18xx.c|   2 +-
 drivers/pinctrl/pinctrl-palmas.c |   2 +-
 drivers/pinctrl/pinctrl-pic32.c  |   2 +-
 drivers/pinctrl/pinctrl-pistachio.c  |   2 +-
 drivers/pinctrl/pinctrl-tb10x.c  |   2 +-
 drivers/pinctrl/pinctrl-utils.c  |   4 +-
 drivers/pinctrl/pinctrl-utils.h  |   2 +-
 drivers/pinctrl/pinctrl-zynq.c   |   2 +-
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c |   2 +-
 drivers/pinctrl/qcom/pinctrl-msm.c   |   2 +-
 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c |   2 +-
 drivers/pinctrl/qcom/pinctrl-spmi-mpp.c  |   2 +-
 drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c |   2 +-
 drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c  |   2 +-
 drivers/pinctrl/stm32/pinctrl-stm32.c|   4 +-
 drivers/pinctrl/tegra/pinctrl-tegra-xusb.c   |   2 +-
 drivers/pinctrl/tegra/pinctrl-tegra.c|   4 +-
 drivers/pinctrl/uniphier/pinctrl-uniphier-core.c |   2 +-
 include/linux/acpi.h |   4 +-
 include/linux/pinctrl/pinconf-generic.h  |  27 +-
 include/linux/property.h |   9 +
 43 files changed, 1063 insertions(+), 114 deletions(-)
 create mode 100644 Documentation/acpi/pinctrl-properties.txt
 create mode 100644 drivers/pinctrl/acpi.c
 create mode 100644 drivers/pinctrl/acpi.h

-- 
1.9.1



[RFC PATCH 4/4] pinctrl: Parse GpioInt/GpioIo resources

2016-03-31 Thread Irina Tirdea
Parse GpioInt/GpioIo ACPI resources and use the pin configuration
information to generate pin controller maps. These maps are associated
with the "default" state, only if this state is defined in the _DSD
of the acpi device.

Signed-off-by: Irina Tirdea 
---
 Documentation/acpi/pinctrl-properties.txt |   8 ++
 drivers/pinctrl/acpi.c| 229 ++
 2 files changed, 237 insertions(+)

diff --git a/Documentation/acpi/pinctrl-properties.txt 
b/Documentation/acpi/pinctrl-properties.txt
index e93aaaf..8243190 100644
--- a/Documentation/acpi/pinctrl-properties.txt
+++ b/Documentation/acpi/pinctrl-properties.txt
@@ -265,6 +265,14 @@ same way as it is done for device tree [5]. The format for 
the data subnode is:
   configname - name of the pin configuration property
   configval - value of the pin configuration property
 
+== GpioInt()/GpioIo() _CRS resources ==
+
+If the device has any GpioInt/GpioIo _CRS ACPI resources, they are parsed so
+that the pin configuration information is used (e.g. PullUp/PullDown/PullNone).
+The pin configuration from GpioInt/GpioIo will be associated with the "default"
+state, only if such a state is defined in the _DSD of the device. If no
+"default" state is defined, the GPIO configuration from _CRS will be ignored.
+
 == References ==
 
 [1] Documentation/pinctrl.txt
diff --git a/drivers/pinctrl/acpi.c b/drivers/pinctrl/acpi.c
index bed1d88..7199c3d 100644
--- a/drivers/pinctrl/acpi.c
+++ b/drivers/pinctrl/acpi.c
@@ -140,6 +140,224 @@ static int acpi_remember_or_free_map(struct pinctrl *p, 
const char *statename,
return pinctrl_register_map(map, num_maps, false);
 }
 
+#ifdef CONFIG_GENERIC_PINCONF
+struct acpi_gpio_lookup {
+   unsigned int index;
+   bool found;
+   unsigned int n;
+   struct pinctrl_map *map;
+   unsigned num_maps;
+   unsigned reserved_maps;
+   struct pinctrl_dev **pctldevs;
+};
+
+/* For now we only handle acpi pin config values */
+#define ACPI_MAX_CFGS 1
+
+static int acpi_parse_gpio_config(const struct acpi_resource_gpio *agpio,
+ unsigned long **configs,
+ unsigned int *nconfigs)
+{
+   enum pin_config_param param;
+   int ret;
+
+   /* Parse configs from GpioInt/GpioIo ACPI resource */
+   *nconfigs = 0;
+   *configs = kcalloc(ACPI_MAX_CFGS, sizeof(*configs), GFP_KERNEL);
+   if (!*configs)
+   return -ENOMEM;
+
+   /* For now, only parse pin_config */
+   switch (agpio->pin_config) {
+   case ACPI_PIN_CONFIG_DEFAULT:
+   param = PIN_CONFIG_BIAS_PULL_PIN_DEFAULT;
+   break;
+   case ACPI_PIN_CONFIG_PULLUP:
+   param = PIN_CONFIG_BIAS_PULL_UP;
+   break;
+   case ACPI_PIN_CONFIG_PULLDOWN:
+   param = PIN_CONFIG_BIAS_PULL_DOWN;
+   break;
+   case ACPI_PIN_CONFIG_NOPULL:
+   param = PIN_CONFIG_BIAS_DISABLE;
+   break;
+   default:
+   ret = -EINVAL;
+   goto exit_free;
+   }
+   *configs[*nconfigs] = pinconf_to_config_packed(param,
+ param == PIN_CONFIG_BIAS_DISABLE ? 0 : 1);
+   (*nconfigs)++;
+
+   return 0;
+
+exit_free:
+   kfree(*configs);
+   return ret;
+}
+
+static int acpi_gpio_to_map(struct acpi_resource *ares, void *data)
+{
+   struct pinctrl_dev *pctldev, **new_pctldevs;
+   struct acpi_gpio_lookup *lookup = data;
+   const struct acpi_resource_gpio *agpio;
+   acpi_handle pctrl_handle = NULL;
+   unsigned int nconfigs, i;
+   unsigned long *configs;
+   acpi_status status;
+   const char *pin;
+   int ret;
+
+   if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
+   return 1;
+   if (lookup->n++ != lookup->index || lookup->found)
+   return 1;
+
+   agpio = >data.gpio;
+
+   /* Get configs from ACPI GPIO resource */
+   ret = acpi_parse_gpio_config(agpio, , );
+   if (ret)
+   return ret;
+
+   /* Get pinctrl reference from GPIO resource */
+   status = acpi_get_handle(NULL, agpio->resource_source.string_ptr,
+_handle);
+   if (ACPI_FAILURE(status) || !pctrl_handle) {
+   ret = -EINVAL;
+   goto exit_free_configs;
+   }
+
+   /* Find the pin controller */
+   pctldev = get_pinctrl_dev_from_acpi(pctrl_handle);
+   if (!pctldev) {
+   ret = -EINVAL;
+   goto exit_free_configs;
+   }
+
+   /* Allocate space for maps and pinctrl_dev references */
+   ret = pinctrl_utils_reserve_map(pctldev, >map,
+   >reserved_maps,
+   >num_maps,
+   agpio->pin_table_length);
+   if (ret < 0)
+  

[RFC PATCH 3/4] pinctrl: Add ACPI support

2016-03-31 Thread Irina Tirdea
Add ACPI support for pin controller properties. These are
based on ACPI _DSD properties and follow the device tree
model based on states and node configurations. The states
are defined as _DSD properties and configuration nodes
are defined using the _DSD Hierarchical Properties Extension.

A configuration node supports the generic device tree properties.

The implementation is based on device tree code from devicetree.c.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 Documentation/acpi/pinctrl-properties.txt | 274 +
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/acpi.c| 322 ++
 drivers/pinctrl/acpi.h|  32 +++
 drivers/pinctrl/core.c|  26 +++
 drivers/pinctrl/core.h|   2 +
 6 files changed, 657 insertions(+)
 create mode 100644 Documentation/acpi/pinctrl-properties.txt
 create mode 100644 drivers/pinctrl/acpi.c
 create mode 100644 drivers/pinctrl/acpi.h

diff --git a/Documentation/acpi/pinctrl-properties.txt 
b/Documentation/acpi/pinctrl-properties.txt
new file mode 100644
index 000..e93aaaf
--- /dev/null
+++ b/Documentation/acpi/pinctrl-properties.txt
@@ -0,0 +1,274 @@
+= _DSD Device Properties related to pin controllers =
+
+== Introduction ==
+
+This document is an extension of the pin control subsystem in Linux [1]
+and provides a way to describe pin controller properties in ACPI. It is
+based on the Device Specific Data (_DSD) configuration object [2] that
+was introduced in ACPI 5.1.
+
+Pin controllers are hardware modules that control pins by allowing pin
+multiplexing and configuration. Pin multiplexing allows using the same
+physical pins for multiple functions; for example, one pin or group of pins
+may be used for the I2C bus, SPI bus or as general-purpose GPIO pin. Pin
+configuration allows setting various properties such as pull-up/down,
+tri-state, drive-strength, etc.
+
+Hardware modules whose signals are affected by pin configuration are
+designated client devices. For a client device to operate correctly,
+certain pin controllers must set up certain specific pin configurations.
+Some client devices need a single static pin configuration, e.g. set up
+during initialization. Others need to reconfigure pins at run-time,
+for example to tri-state pins when the device is inactive. Hence, each
+client device can define a set of named states. Each named state is
+mapped to a pin controller configuration that describes the pin multiplexing
+or configuration for that state.
+
+In ACPI, each pin controller and each client device is represented as an
+ACPI device, just like any other hardware module. The pin controller
+properties are defined using _DSD properties [2] under these devices.
+The named states are defined using Device Properties UUID [3] under the
+ACPI client device. The configuration nodes are defined using Hierarchical
+Properties Extension UUID [4] and are split between the ACPI client device
+and the pin controller device. The configuration nodes contain properties
+that describe pin multiplexing or configuration that very similar to the
+ones used for device tree [5].
+
+== Example ==
+
+For example, let's consider an accelerometer connected to the I2C bus on
+a platform with a Baytrail pin controller. The accelerometer uses 2 GPIO
+pins for I2C (SDA, SCL) and one GPIO pin for interrupt.
+
+The name for the pins, groups and functions used are the ones defined in the
+pin controller driver, in the same way as it is done for device tree [5].
+
+For the I2C pins, the pin controller driver defines one group called
+"i2c5_grp" that can be multiplexed with functions "i2c" or "gpio".
+In our case, we need to select function "i2c" for group "i2c5_grp" in
+the ACPI description.
+
+For the GPIO pin, the pin controller driver defines the name "GPIO_S5[00]"
+for the pin with index 0 that we use. We need to configure this pin to
+pull-down with pull strength of 1 Ohms. We might also want to disable
+the bias for the GPIO interrupt pin when entering sleep.
+
+Here is an ASL example for this device:
+
+  // Pin controller device
+  Scope (_SB.GPO0)
+  {
+  Name (MUX0, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+  Package()
+  {
+  Package (2) {"function", "i2c"},
+  Package (2) {"groups", Package () {"i2c5_grp"}},
+  }
+  })
+
+  Name (CFG0, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+  Package()
+  {
+  Package (2) {"pins", Package () {"GPIO_S5[00]"}},
+  Package (2) {"bias-pull-down", 1},
+  }
+  })
+
+  Name (CFG1, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91

[RFC PATCH 1/4] pinctrl: Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map

2016-03-31 Thread Irina Tirdea
Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map, since
it does not depend on device tree despite the current name. This
will enforce a consistent naming in pinctr-utils.c and will make
it clear it can be called from outside device tree (e.g. from
ACPI handling code).

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/pinctrl/bcm/pinctrl-bcm281xx.c   | 2 +-
 drivers/pinctrl/bcm/pinctrl-cygnus-mux.c | 2 +-
 drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 2 +-
 drivers/pinctrl/bcm/pinctrl-nsp-gpio.c   | 2 +-
 drivers/pinctrl/berlin/berlin.c  | 2 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c| 4 ++--
 drivers/pinctrl/meson/pinctrl-meson.c| 2 +-
 drivers/pinctrl/nomadik/pinctrl-abx500.c | 4 ++--
 drivers/pinctrl/nomadik/pinctrl-nomadik.c| 4 ++--
 drivers/pinctrl/pinconf-generic.c| 2 +-
 drivers/pinctrl/pinctrl-amd.c| 2 +-
 drivers/pinctrl/pinctrl-as3722.c | 2 +-
 drivers/pinctrl/pinctrl-at91-pio4.c  | 4 ++--
 drivers/pinctrl/pinctrl-digicolor.c  | 2 +-
 drivers/pinctrl/pinctrl-lpc18xx.c| 2 +-
 drivers/pinctrl/pinctrl-palmas.c | 2 +-
 drivers/pinctrl/pinctrl-pic32.c  | 2 +-
 drivers/pinctrl/pinctrl-pistachio.c  | 2 +-
 drivers/pinctrl/pinctrl-tb10x.c  | 2 +-
 drivers/pinctrl/pinctrl-utils.c  | 4 ++--
 drivers/pinctrl/pinctrl-utils.h  | 2 +-
 drivers/pinctrl/pinctrl-zynq.c   | 2 +-
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 2 +-
 drivers/pinctrl/qcom/pinctrl-msm.c   | 2 +-
 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 +-
 drivers/pinctrl/qcom/pinctrl-spmi-mpp.c  | 2 +-
 drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c | 2 +-
 drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c  | 2 +-
 drivers/pinctrl/stm32/pinctrl-stm32.c| 4 ++--
 drivers/pinctrl/tegra/pinctrl-tegra-xusb.c   | 2 +-
 drivers/pinctrl/tegra/pinctrl-tegra.c| 4 ++--
 drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 2 +-
 32 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c 
b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c
index c3c692e..f043b83 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c
@@ -1024,7 +1024,7 @@ static struct pinctrl_ops bcm281xx_pinctrl_ops = {
.get_group_pins = bcm281xx_pinctrl_get_group_pins,
.pin_dbg_show = bcm281xx_pinctrl_pin_dbg_show,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
-   .dt_free_map = pinctrl_utils_dt_free_map,
+   .dt_free_map = pinctrl_utils_free_map,
 };
 
 static int bcm281xx_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev)
diff --git a/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c 
b/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
index 9728f3d..f0184dc 100644
--- a/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
+++ b/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
@@ -737,7 +737,7 @@ static const struct pinctrl_ops cygnus_pinctrl_ops = {
.get_group_pins = cygnus_get_group_pins,
.pin_dbg_show = cygnus_pin_dbg_show,
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
-   .dt_free_map = pinctrl_utils_dt_free_map,
+   .dt_free_map = pinctrl_utils_free_map,
 };
 
 static int cygnus_get_functions_count(struct pinctrl_dev *pctrl_dev)
diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c 
b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
index d530ab4..9ed9881 100644
--- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
@@ -379,7 +379,7 @@ static const struct pinctrl_ops iproc_pctrl_ops = {
.get_groups_count = iproc_get_groups_count,
.get_group_name = iproc_get_group_name,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
-   .dt_free_map = pinctrl_utils_dt_free_map,
+   .dt_free_map = pinctrl_utils_free_map,
 };
 
 static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
diff --git a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c 
b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
index ac90043..6c7d5f5 100644
--- a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
@@ -363,7 +363,7 @@ static const struct pinctrl_ops nsp_pctrl_ops = {
.get_groups_count = nsp_get_groups_count,
.get_group_name = nsp_get_group_name,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
-   .dt_free_map = pinctrl_utils_dt_free_map,
+   .dt_free_map = pinctrl_utils_free_map,
 };
 
 static int nsp_gpio_set_slew(struct nsp_gpio *chip, unsigned gpio, u16 slew)
diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c
index 46f2b48..87b17b7 100644
--- a/drivers/pinctrl/berlin/berlin.c
+++ b/drivers/pinctrl/berlin/berlin.c
@@ -104,7 +104,7 @@ static const struct pinct

[RFC PATCH 3/4] pinctrl: Add ACPI support

2016-03-31 Thread Irina Tirdea
Add ACPI support for pin controller properties. These are
based on ACPI _DSD properties and follow the device tree
model based on states and node configurations. The states
are defined as _DSD properties and configuration nodes
are defined using the _DSD Hierarchical Properties Extension.

A configuration node supports the generic device tree properties.

The implementation is based on device tree code from devicetree.c.

Signed-off-by: Irina Tirdea 
---
 Documentation/acpi/pinctrl-properties.txt | 274 +
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/acpi.c| 322 ++
 drivers/pinctrl/acpi.h|  32 +++
 drivers/pinctrl/core.c|  26 +++
 drivers/pinctrl/core.h|   2 +
 6 files changed, 657 insertions(+)
 create mode 100644 Documentation/acpi/pinctrl-properties.txt
 create mode 100644 drivers/pinctrl/acpi.c
 create mode 100644 drivers/pinctrl/acpi.h

diff --git a/Documentation/acpi/pinctrl-properties.txt 
b/Documentation/acpi/pinctrl-properties.txt
new file mode 100644
index 000..e93aaaf
--- /dev/null
+++ b/Documentation/acpi/pinctrl-properties.txt
@@ -0,0 +1,274 @@
+= _DSD Device Properties related to pin controllers =
+
+== Introduction ==
+
+This document is an extension of the pin control subsystem in Linux [1]
+and provides a way to describe pin controller properties in ACPI. It is
+based on the Device Specific Data (_DSD) configuration object [2] that
+was introduced in ACPI 5.1.
+
+Pin controllers are hardware modules that control pins by allowing pin
+multiplexing and configuration. Pin multiplexing allows using the same
+physical pins for multiple functions; for example, one pin or group of pins
+may be used for the I2C bus, SPI bus or as general-purpose GPIO pin. Pin
+configuration allows setting various properties such as pull-up/down,
+tri-state, drive-strength, etc.
+
+Hardware modules whose signals are affected by pin configuration are
+designated client devices. For a client device to operate correctly,
+certain pin controllers must set up certain specific pin configurations.
+Some client devices need a single static pin configuration, e.g. set up
+during initialization. Others need to reconfigure pins at run-time,
+for example to tri-state pins when the device is inactive. Hence, each
+client device can define a set of named states. Each named state is
+mapped to a pin controller configuration that describes the pin multiplexing
+or configuration for that state.
+
+In ACPI, each pin controller and each client device is represented as an
+ACPI device, just like any other hardware module. The pin controller
+properties are defined using _DSD properties [2] under these devices.
+The named states are defined using Device Properties UUID [3] under the
+ACPI client device. The configuration nodes are defined using Hierarchical
+Properties Extension UUID [4] and are split between the ACPI client device
+and the pin controller device. The configuration nodes contain properties
+that describe pin multiplexing or configuration that very similar to the
+ones used for device tree [5].
+
+== Example ==
+
+For example, let's consider an accelerometer connected to the I2C bus on
+a platform with a Baytrail pin controller. The accelerometer uses 2 GPIO
+pins for I2C (SDA, SCL) and one GPIO pin for interrupt.
+
+The name for the pins, groups and functions used are the ones defined in the
+pin controller driver, in the same way as it is done for device tree [5].
+
+For the I2C pins, the pin controller driver defines one group called
+"i2c5_grp" that can be multiplexed with functions "i2c" or "gpio".
+In our case, we need to select function "i2c" for group "i2c5_grp" in
+the ACPI description.
+
+For the GPIO pin, the pin controller driver defines the name "GPIO_S5[00]"
+for the pin with index 0 that we use. We need to configure this pin to
+pull-down with pull strength of 1 Ohms. We might also want to disable
+the bias for the GPIO interrupt pin when entering sleep.
+
+Here is an ASL example for this device:
+
+  // Pin controller device
+  Scope (_SB.GPO0)
+  {
+  Name (MUX0, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+  Package()
+  {
+  Package (2) {"function", "i2c"},
+  Package (2) {"groups", Package () {"i2c5_grp"}},
+  }
+  })
+
+  Name (CFG0, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+  Package()
+  {
+  Package (2) {"pins", Package () {"GPIO_S5[00]"}},
+  Package (2) {"bias-pull-down", 1},
+  }
+  })
+
+  Name (CFG1, Package()
+  {
+  ToUUID("daffd814-6eba-4d8c-8a91-bc9bb

[RFC PATCH 1/4] pinctrl: Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map

2016-03-31 Thread Irina Tirdea
Rename pinctrl_utils_dt_free_map to pinctrl_utils_free_map, since
it does not depend on device tree despite the current name. This
will enforce a consistent naming in pinctr-utils.c and will make
it clear it can be called from outside device tree (e.g. from
ACPI handling code).

Signed-off-by: Irina Tirdea 
---
 drivers/pinctrl/bcm/pinctrl-bcm281xx.c   | 2 +-
 drivers/pinctrl/bcm/pinctrl-cygnus-mux.c | 2 +-
 drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 2 +-
 drivers/pinctrl/bcm/pinctrl-nsp-gpio.c   | 2 +-
 drivers/pinctrl/berlin/berlin.c  | 2 +-
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c| 4 ++--
 drivers/pinctrl/meson/pinctrl-meson.c| 2 +-
 drivers/pinctrl/nomadik/pinctrl-abx500.c | 4 ++--
 drivers/pinctrl/nomadik/pinctrl-nomadik.c| 4 ++--
 drivers/pinctrl/pinconf-generic.c| 2 +-
 drivers/pinctrl/pinctrl-amd.c| 2 +-
 drivers/pinctrl/pinctrl-as3722.c | 2 +-
 drivers/pinctrl/pinctrl-at91-pio4.c  | 4 ++--
 drivers/pinctrl/pinctrl-digicolor.c  | 2 +-
 drivers/pinctrl/pinctrl-lpc18xx.c| 2 +-
 drivers/pinctrl/pinctrl-palmas.c | 2 +-
 drivers/pinctrl/pinctrl-pic32.c  | 2 +-
 drivers/pinctrl/pinctrl-pistachio.c  | 2 +-
 drivers/pinctrl/pinctrl-tb10x.c  | 2 +-
 drivers/pinctrl/pinctrl-utils.c  | 4 ++--
 drivers/pinctrl/pinctrl-utils.h  | 2 +-
 drivers/pinctrl/pinctrl-zynq.c   | 2 +-
 drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 2 +-
 drivers/pinctrl/qcom/pinctrl-msm.c   | 2 +-
 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 +-
 drivers/pinctrl/qcom/pinctrl-spmi-mpp.c  | 2 +-
 drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c | 2 +-
 drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c  | 2 +-
 drivers/pinctrl/stm32/pinctrl-stm32.c| 4 ++--
 drivers/pinctrl/tegra/pinctrl-tegra-xusb.c   | 2 +-
 drivers/pinctrl/tegra/pinctrl-tegra.c| 4 ++--
 drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 2 +-
 32 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c 
b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c
index c3c692e..f043b83 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c
@@ -1024,7 +1024,7 @@ static struct pinctrl_ops bcm281xx_pinctrl_ops = {
.get_group_pins = bcm281xx_pinctrl_get_group_pins,
.pin_dbg_show = bcm281xx_pinctrl_pin_dbg_show,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
-   .dt_free_map = pinctrl_utils_dt_free_map,
+   .dt_free_map = pinctrl_utils_free_map,
 };
 
 static int bcm281xx_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev)
diff --git a/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c 
b/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
index 9728f3d..f0184dc 100644
--- a/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
+++ b/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
@@ -737,7 +737,7 @@ static const struct pinctrl_ops cygnus_pinctrl_ops = {
.get_group_pins = cygnus_get_group_pins,
.pin_dbg_show = cygnus_pin_dbg_show,
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
-   .dt_free_map = pinctrl_utils_dt_free_map,
+   .dt_free_map = pinctrl_utils_free_map,
 };
 
 static int cygnus_get_functions_count(struct pinctrl_dev *pctrl_dev)
diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c 
b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
index d530ab4..9ed9881 100644
--- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
@@ -379,7 +379,7 @@ static const struct pinctrl_ops iproc_pctrl_ops = {
.get_groups_count = iproc_get_groups_count,
.get_group_name = iproc_get_group_name,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
-   .dt_free_map = pinctrl_utils_dt_free_map,
+   .dt_free_map = pinctrl_utils_free_map,
 };
 
 static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
diff --git a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c 
b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
index ac90043..6c7d5f5 100644
--- a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
@@ -363,7 +363,7 @@ static const struct pinctrl_ops nsp_pctrl_ops = {
.get_groups_count = nsp_get_groups_count,
.get_group_name = nsp_get_group_name,
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
-   .dt_free_map = pinctrl_utils_dt_free_map,
+   .dt_free_map = pinctrl_utils_free_map,
 };
 
 static int nsp_gpio_set_slew(struct nsp_gpio *chip, unsigned gpio, u16 slew)
diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c
index 46f2b48..87b17b7 100644
--- a/drivers/pinctrl/berlin/berlin.c
+++ b/drivers/pinctrl/berlin/berlin.c
@@ -104,7 +104,7 @@ static const struct pinctrl_ops berlin_pinctrl_ops

[PATCH v2 1/1] iio: gyro: bmg160: fix endianness when reading axes

2016-03-29 Thread Irina Tirdea
For big endian platforms, reading the axes will return
invalid values.

The device stores each axis value in a 16 bit little
endian register. The driver uses regmap_read_bulk to get
the axis value, resulting in a 16 bit little endian value.
This needs to be converted to cpu endianness to work
on big endian platforms.

Fix endianness for big endian platforms by converting
the values for the axes read from little endian to
cpu.

This is also partially fixed in commit 82d8e5da1a33 ("iio:
accel: bmg160: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---

Changes from v1:
 - pass sizeof(raw_val) to regmap_bulk_read instead of
hardcoded value

 drivers/iio/gyro/bmg160_core.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index bbce3b0..8d3f0b3 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -452,7 +452,7 @@ static int bmg160_get_temp(struct bmg160_data *data, int 
*val)
 static int bmg160_get_axis(struct bmg160_data *data, int axis, int *val)
 {
int ret;
-   unsigned int raw_val;
+   __le16 raw_val;
 
mutex_lock(>mutex);
ret = bmg160_set_power_state(data, true);
@@ -462,7 +462,7 @@ static int bmg160_get_axis(struct bmg160_data *data, int 
axis, int *val)
}
 
ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(axis), _val,
-  2);
+  sizeof(raw_val));
if (ret < 0) {
dev_err(data->dev, "Error reading axis %d\n", axis);
bmg160_set_power_state(data, false);
@@ -470,7 +470,7 @@ static int bmg160_get_axis(struct bmg160_data *data, int 
axis, int *val)
return ret;
}
 
-   *val = sign_extend32(raw_val, 15);
+   *val = sign_extend32(le16_to_cpu(raw_val), 15);
ret = bmg160_set_power_state(data, false);
mutex_unlock(>mutex);
if (ret < 0)
@@ -733,6 +733,7 @@ static const struct iio_event_spec bmg160_event = {
.sign = 's',\
.realbits = 16, \
.storagebits = 16,  \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _event,\
.num_event_specs = 1\
-- 
1.9.1



[PATCH v2 1/1] iio: gyro: bmg160: fix endianness when reading axes

2016-03-29 Thread Irina Tirdea
For big endian platforms, reading the axes will return
invalid values.

The device stores each axis value in a 16 bit little
endian register. The driver uses regmap_read_bulk to get
the axis value, resulting in a 16 bit little endian value.
This needs to be converted to cpu endianness to work
on big endian platforms.

Fix endianness for big endian platforms by converting
the values for the axes read from little endian to
cpu.

This is also partially fixed in commit 82d8e5da1a33 ("iio:
accel: bmg160: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea 
---

Changes from v1:
 - pass sizeof(raw_val) to regmap_bulk_read instead of
hardcoded value

 drivers/iio/gyro/bmg160_core.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index bbce3b0..8d3f0b3 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -452,7 +452,7 @@ static int bmg160_get_temp(struct bmg160_data *data, int 
*val)
 static int bmg160_get_axis(struct bmg160_data *data, int axis, int *val)
 {
int ret;
-   unsigned int raw_val;
+   __le16 raw_val;
 
mutex_lock(>mutex);
ret = bmg160_set_power_state(data, true);
@@ -462,7 +462,7 @@ static int bmg160_get_axis(struct bmg160_data *data, int 
axis, int *val)
}
 
ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(axis), _val,
-  2);
+  sizeof(raw_val));
if (ret < 0) {
dev_err(data->dev, "Error reading axis %d\n", axis);
bmg160_set_power_state(data, false);
@@ -470,7 +470,7 @@ static int bmg160_get_axis(struct bmg160_data *data, int 
axis, int *val)
return ret;
}
 
-   *val = sign_extend32(raw_val, 15);
+   *val = sign_extend32(le16_to_cpu(raw_val), 15);
ret = bmg160_set_power_state(data, false);
mutex_unlock(>mutex);
if (ret < 0)
@@ -733,6 +733,7 @@ static const struct iio_event_spec bmg160_event = {
.sign = 's',\
.realbits = 16, \
.storagebits = 16,  \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _event,\
.num_event_specs = 1\
-- 
1.9.1



[PATCH v2 1/1] iio: accel: bmc150: fix endianness when reading axes

2016-03-29 Thread Irina Tirdea
For big endian platforms, reading the axes will return
invalid values.

The device stores each axis value in a 16 bit little
endian register. The driver uses regmap_read_bulk to get
the axis value, resulting in a 16 bit little endian value.
This needs to be converted to cpu endianness to work
on big endian platforms.

Fix endianness for big endian platforms by converting
the values for the axes read from little endian to
cpu.

This is also partially fixed in commit b6fb9b6d6552 ("iio:
accel: bmc150: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---

Changes from v1:
 - pass sizeof(raw_val) to regmap_bulk_read instead of
hardcoded value

 drivers/iio/accel/bmc150-accel-core.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index c73331f7..2072a31 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -547,7 +547,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data 
*data,
 {
int ret;
int axis = chan->scan_index;
-   unsigned int raw_val;
+   __le16 raw_val;
 
mutex_lock(>mutex);
ret = bmc150_accel_set_power_state(data, true);
@@ -557,14 +557,14 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data 
*data,
}
 
ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
-  _val, 2);
+  _val, sizeof(raw_val));
if (ret < 0) {
dev_err(data->dev, "Error reading axis %d\n", axis);
bmc150_accel_set_power_state(data, false);
mutex_unlock(>mutex);
return ret;
}
-   *val = sign_extend32(raw_val >> chan->scan_type.shift,
+   *val = sign_extend32(le16_to_cpu(raw_val) >> chan->scan_type.shift,
 chan->scan_type.realbits - 1);
ret = bmc150_accel_set_power_state(data, false);
mutex_unlock(>mutex);
@@ -988,6 +988,7 @@ static const struct iio_event_spec bmc150_accel_event = {
.realbits = (bits), \
.storagebits = 16,  \
.shift = 16 - (bits),   \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _accel_event,  \
.num_event_specs = 1\
-- 
1.9.1



[PATCH v2 1/1] iio: accel: bmc150: fix endianness when reading axes

2016-03-29 Thread Irina Tirdea
For big endian platforms, reading the axes will return
invalid values.

The device stores each axis value in a 16 bit little
endian register. The driver uses regmap_read_bulk to get
the axis value, resulting in a 16 bit little endian value.
This needs to be converted to cpu endianness to work
on big endian platforms.

Fix endianness for big endian platforms by converting
the values for the axes read from little endian to
cpu.

This is also partially fixed in commit b6fb9b6d6552 ("iio:
accel: bmc150: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea 
---

Changes from v1:
 - pass sizeof(raw_val) to regmap_bulk_read instead of
hardcoded value

 drivers/iio/accel/bmc150-accel-core.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index c73331f7..2072a31 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -547,7 +547,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data 
*data,
 {
int ret;
int axis = chan->scan_index;
-   unsigned int raw_val;
+   __le16 raw_val;
 
mutex_lock(>mutex);
ret = bmc150_accel_set_power_state(data, true);
@@ -557,14 +557,14 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data 
*data,
}
 
ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
-  _val, 2);
+  _val, sizeof(raw_val));
if (ret < 0) {
dev_err(data->dev, "Error reading axis %d\n", axis);
bmc150_accel_set_power_state(data, false);
mutex_unlock(>mutex);
return ret;
}
-   *val = sign_extend32(raw_val >> chan->scan_type.shift,
+   *val = sign_extend32(le16_to_cpu(raw_val) >> chan->scan_type.shift,
 chan->scan_type.realbits - 1);
ret = bmc150_accel_set_power_state(data, false);
mutex_unlock(>mutex);
@@ -988,6 +988,7 @@ static const struct iio_event_spec bmc150_accel_event = {
.realbits = (bits), \
.storagebits = 16,  \
.shift = 16 - (bits),   \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _accel_event,  \
.num_event_specs = 1\
-- 
1.9.1



[PATCH v3 1/1] iio: accel: bmc150: use common definition for regmap conf

2016-03-29 Thread Irina Tirdea
bmc150_i2c_regmap_conf is defined three times (in bmc150-accel-core.c,
bmc150-accel-i2c.c and and bmc150-accel-spi.c), although the
definition is the same.

Use one common definition for bmc150_i2c_regmap_conf in all
included files.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---

Changes from v2:
 - fix spi build errors

Changes from v1:
  - instead of removing the unused definition from the core,
share it between the i2c and spi files
  - renamed the subject line from "iio: accel: bmc150: remove
unused definition" to better reflect the new change

 drivers/iio/accel/bmc150-accel-core.c | 3 ++-
 drivers/iio/accel/bmc150-accel-i2c.c  | 7 +--
 drivers/iio/accel/bmc150-accel-spi.c  | 8 +---
 drivers/iio/accel/bmc150-accel.h  | 1 +
 4 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index f3d096f..e631ee9 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -246,11 +246,12 @@ static const struct {
   {50, BMC150_ACCEL_SLEEP_500_MS},
   {100, BMC150_ACCEL_SLEEP_1_SEC} };
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
+const struct regmap_config bmc150_regmap_conf = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x3f,
 };
+EXPORT_SYMBOL_GPL(bmc150_regmap_conf);
 
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 enum bmc150_power_modes mode,
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c 
b/drivers/iio/accel/bmc150-accel-i2c.c
index b41404b..8ca8041 100644
--- a/drivers/iio/accel/bmc150-accel-i2c.c
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -28,11 +28,6 @@
 
 #include "bmc150-accel.h"
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 static int bmc150_accel_probe(struct i2c_client *client,
  const struct i2c_device_id *id)
 {
@@ -43,7 +38,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_I2C_BLOCK);
 
-   regmap = devm_regmap_init_i2c(client, _i2c_regmap_conf);
+   regmap = devm_regmap_init_i2c(client, _regmap_conf);
if (IS_ERR(regmap)) {
dev_err(>dev, "Failed to initialize i2c regmap\n");
return PTR_ERR(regmap);
diff --git a/drivers/iio/accel/bmc150-accel-spi.c 
b/drivers/iio/accel/bmc150-accel-spi.c
index 16b66f2..006794a7 100644
--- a/drivers/iio/accel/bmc150-accel-spi.c
+++ b/drivers/iio/accel/bmc150-accel-spi.c
@@ -25,18 +25,12 @@
 
 #include "bmc150-accel.h"
 
-static const struct regmap_config bmc150_spi_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-   .max_register = 0x3f,
-};
-
 static int bmc150_accel_probe(struct spi_device *spi)
 {
struct regmap *regmap;
const struct spi_device_id *id = spi_get_device_id(spi);
 
-   regmap = devm_regmap_init_spi(spi, _spi_regmap_conf);
+   regmap = devm_regmap_init_spi(spi, _regmap_conf);
if (IS_ERR(regmap)) {
dev_err(>dev, "Failed to initialize spi regmap\n");
return PTR_ERR(regmap);
diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
index ba03359..38a8b11 100644
--- a/drivers/iio/accel/bmc150-accel.h
+++ b/drivers/iio/accel/bmc150-accel.h
@@ -16,5 +16,6 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap 
*regmap, int irq,
const char *name, bool block_supported);
 int bmc150_accel_core_remove(struct device *dev);
 extern const struct dev_pm_ops bmc150_accel_pm_ops;
+extern const struct regmap_config bmc150_regmap_conf;
 
 #endif  /* _BMC150_ACCEL_H_ */
-- 
1.9.1



[PATCH v3 1/1] iio: accel: bmc150: use common definition for regmap conf

2016-03-29 Thread Irina Tirdea
bmc150_i2c_regmap_conf is defined three times (in bmc150-accel-core.c,
bmc150-accel-i2c.c and and bmc150-accel-spi.c), although the
definition is the same.

Use one common definition for bmc150_i2c_regmap_conf in all
included files.

Signed-off-by: Irina Tirdea 
---

Changes from v2:
 - fix spi build errors

Changes from v1:
  - instead of removing the unused definition from the core,
share it between the i2c and spi files
  - renamed the subject line from "iio: accel: bmc150: remove
unused definition" to better reflect the new change

 drivers/iio/accel/bmc150-accel-core.c | 3 ++-
 drivers/iio/accel/bmc150-accel-i2c.c  | 7 +--
 drivers/iio/accel/bmc150-accel-spi.c  | 8 +---
 drivers/iio/accel/bmc150-accel.h  | 1 +
 4 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index f3d096f..e631ee9 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -246,11 +246,12 @@ static const struct {
   {50, BMC150_ACCEL_SLEEP_500_MS},
   {100, BMC150_ACCEL_SLEEP_1_SEC} };
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
+const struct regmap_config bmc150_regmap_conf = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x3f,
 };
+EXPORT_SYMBOL_GPL(bmc150_regmap_conf);
 
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 enum bmc150_power_modes mode,
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c 
b/drivers/iio/accel/bmc150-accel-i2c.c
index b41404b..8ca8041 100644
--- a/drivers/iio/accel/bmc150-accel-i2c.c
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -28,11 +28,6 @@
 
 #include "bmc150-accel.h"
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 static int bmc150_accel_probe(struct i2c_client *client,
  const struct i2c_device_id *id)
 {
@@ -43,7 +38,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_I2C_BLOCK);
 
-   regmap = devm_regmap_init_i2c(client, _i2c_regmap_conf);
+   regmap = devm_regmap_init_i2c(client, _regmap_conf);
if (IS_ERR(regmap)) {
dev_err(>dev, "Failed to initialize i2c regmap\n");
return PTR_ERR(regmap);
diff --git a/drivers/iio/accel/bmc150-accel-spi.c 
b/drivers/iio/accel/bmc150-accel-spi.c
index 16b66f2..006794a7 100644
--- a/drivers/iio/accel/bmc150-accel-spi.c
+++ b/drivers/iio/accel/bmc150-accel-spi.c
@@ -25,18 +25,12 @@
 
 #include "bmc150-accel.h"
 
-static const struct regmap_config bmc150_spi_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-   .max_register = 0x3f,
-};
-
 static int bmc150_accel_probe(struct spi_device *spi)
 {
struct regmap *regmap;
const struct spi_device_id *id = spi_get_device_id(spi);
 
-   regmap = devm_regmap_init_spi(spi, _spi_regmap_conf);
+   regmap = devm_regmap_init_spi(spi, _regmap_conf);
if (IS_ERR(regmap)) {
dev_err(>dev, "Failed to initialize spi regmap\n");
return PTR_ERR(regmap);
diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
index ba03359..38a8b11 100644
--- a/drivers/iio/accel/bmc150-accel.h
+++ b/drivers/iio/accel/bmc150-accel.h
@@ -16,5 +16,6 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap 
*regmap, int irq,
const char *name, bool block_supported);
 int bmc150_accel_core_remove(struct device *dev);
 extern const struct dev_pm_ops bmc150_accel_pm_ops;
+extern const struct regmap_config bmc150_regmap_conf;
 
 #endif  /* _BMC150_ACCEL_H_ */
-- 
1.9.1



[PATCH v2 1/1] iio: accel: bmc150: use common definition for regmap conf

2016-03-28 Thread Irina Tirdea
bmc150_i2c_regmap_conf is defined three times (in bmc150-accel-core.c,
bmc150-accel-i2c.c and and bmc150-accel-spi.c), although the
definition is the same.

Use one common definition for bmc150_i2c_regmap_conf in all
included files.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---

Changes from v1:
  - instead of removing the unused definition from the core,
share it between the i2c and spi files
  - renamed the subject line from "iio: accel: bmc150: remove
unused definition" to better reflect the new change

 drivers/iio/accel/bmc150-accel-core.c | 3 ++-
 drivers/iio/accel/bmc150-accel-i2c.c  | 5 -
 drivers/iio/accel/bmc150-accel-spi.c  | 6 --
 drivers/iio/accel/bmc150-accel.h  | 1 +
 4 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index f3d096f..14d0ee6 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -246,11 +246,12 @@ static const struct {
   {50, BMC150_ACCEL_SLEEP_500_MS},
   {100, BMC150_ACCEL_SLEEP_1_SEC} };
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
+const struct regmap_config bmc150_i2c_regmap_conf = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x3f,
 };
+EXPORT_SYMBOL_GPL(bmc150_i2c_regmap_conf);
 
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 enum bmc150_power_modes mode,
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c 
b/drivers/iio/accel/bmc150-accel-i2c.c
index b41404b..4852ecb 100644
--- a/drivers/iio/accel/bmc150-accel-i2c.c
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -28,11 +28,6 @@
 
 #include "bmc150-accel.h"
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 static int bmc150_accel_probe(struct i2c_client *client,
  const struct i2c_device_id *id)
 {
diff --git a/drivers/iio/accel/bmc150-accel-spi.c 
b/drivers/iio/accel/bmc150-accel-spi.c
index 16b66f2..e89f460 100644
--- a/drivers/iio/accel/bmc150-accel-spi.c
+++ b/drivers/iio/accel/bmc150-accel-spi.c
@@ -25,12 +25,6 @@
 
 #include "bmc150-accel.h"
 
-static const struct regmap_config bmc150_spi_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-   .max_register = 0x3f,
-};
-
 static int bmc150_accel_probe(struct spi_device *spi)
 {
struct regmap *regmap;
diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
index ba03359..f2fe611 100644
--- a/drivers/iio/accel/bmc150-accel.h
+++ b/drivers/iio/accel/bmc150-accel.h
@@ -16,5 +16,6 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap 
*regmap, int irq,
const char *name, bool block_supported);
 int bmc150_accel_core_remove(struct device *dev);
 extern const struct dev_pm_ops bmc150_accel_pm_ops;
+extern const struct regmap_config bmc150_i2c_regmap_conf;
 
 #endif  /* _BMC150_ACCEL_H_ */
-- 
1.9.1



[PATCH v2 1/1] iio: accel: bmc150: use common definition for regmap conf

2016-03-28 Thread Irina Tirdea
bmc150_i2c_regmap_conf is defined three times (in bmc150-accel-core.c,
bmc150-accel-i2c.c and and bmc150-accel-spi.c), although the
definition is the same.

Use one common definition for bmc150_i2c_regmap_conf in all
included files.

Signed-off-by: Irina Tirdea 
---

Changes from v1:
  - instead of removing the unused definition from the core,
share it between the i2c and spi files
  - renamed the subject line from "iio: accel: bmc150: remove
unused definition" to better reflect the new change

 drivers/iio/accel/bmc150-accel-core.c | 3 ++-
 drivers/iio/accel/bmc150-accel-i2c.c  | 5 -
 drivers/iio/accel/bmc150-accel-spi.c  | 6 --
 drivers/iio/accel/bmc150-accel.h  | 1 +
 4 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index f3d096f..14d0ee6 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -246,11 +246,12 @@ static const struct {
   {50, BMC150_ACCEL_SLEEP_500_MS},
   {100, BMC150_ACCEL_SLEEP_1_SEC} };
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
+const struct regmap_config bmc150_i2c_regmap_conf = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x3f,
 };
+EXPORT_SYMBOL_GPL(bmc150_i2c_regmap_conf);
 
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 enum bmc150_power_modes mode,
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c 
b/drivers/iio/accel/bmc150-accel-i2c.c
index b41404b..4852ecb 100644
--- a/drivers/iio/accel/bmc150-accel-i2c.c
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -28,11 +28,6 @@
 
 #include "bmc150-accel.h"
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-};
-
 static int bmc150_accel_probe(struct i2c_client *client,
  const struct i2c_device_id *id)
 {
diff --git a/drivers/iio/accel/bmc150-accel-spi.c 
b/drivers/iio/accel/bmc150-accel-spi.c
index 16b66f2..e89f460 100644
--- a/drivers/iio/accel/bmc150-accel-spi.c
+++ b/drivers/iio/accel/bmc150-accel-spi.c
@@ -25,12 +25,6 @@
 
 #include "bmc150-accel.h"
 
-static const struct regmap_config bmc150_spi_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-   .max_register = 0x3f,
-};
-
 static int bmc150_accel_probe(struct spi_device *spi)
 {
struct regmap *regmap;
diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
index ba03359..f2fe611 100644
--- a/drivers/iio/accel/bmc150-accel.h
+++ b/drivers/iio/accel/bmc150-accel.h
@@ -16,5 +16,6 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap 
*regmap, int irq,
const char *name, bool block_supported);
 int bmc150_accel_core_remove(struct device *dev);
 extern const struct dev_pm_ops bmc150_accel_pm_ops;
+extern const struct regmap_config bmc150_i2c_regmap_conf;
 
 #endif  /* _BMC150_ACCEL_H_ */
-- 
1.9.1



[PATCH 1/1] iio: gyro: bmg160: fix buffer read values

2016-03-28 Thread Irina Tirdea
When reading gyroscope axes using iio buffers, the values
returned are always 0. In the interrupt handler, the return
value of the read operation is returned to the user instead
of the value read. Return the value read to the user.

This is also fixed in commit 82d8e5da1a33 ("iio:
accel: bmg160: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/gyro/bmg160_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index 295cf1d..e165ce9 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -781,7 +781,7 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p)
mutex_unlock(>mutex);
goto err;
}
-   data->buffer[i++] = ret;
+   data->buffer[i++] = val;
}
mutex_unlock(>mutex);
 
-- 
1.9.1



[PATCH 1/1] iio: gyro: bmg160: fix buffer read values

2016-03-28 Thread Irina Tirdea
When reading gyroscope axes using iio buffers, the values
returned are always 0. In the interrupt handler, the return
value of the read operation is returned to the user instead
of the value read. Return the value read to the user.

This is also fixed in commit 82d8e5da1a33 ("iio:
accel: bmg160: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea 
---
 drivers/iio/gyro/bmg160_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index 295cf1d..e165ce9 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -781,7 +781,7 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p)
mutex_unlock(>mutex);
goto err;
}
-   data->buffer[i++] = ret;
+   data->buffer[i++] = val;
}
mutex_unlock(>mutex);
 
-- 
1.9.1



[PATCH 1/1] iio: gyro: bmg160: fix endianness when reading axes

2016-03-28 Thread Irina Tirdea
For big endian platforms, reading the axes will return
invalid values.

The device stores each axis value in a 16 bit little
endian register. The driver uses regmap_read_bulk to get
the axis value, resulting in a 16 bit little endian value.
This needs to be converted to cpu endianness to work
on big endian platforms.

Fix endianness for big endian platforms by converting
the values for the axes read from little endian to
cpu.

This is also partially fixed in commit 82d8e5da1a33 ("iio:
accel: bmg160: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/gyro/bmg160_core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index bbce3b0..295cf1d 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -452,7 +452,7 @@ static int bmg160_get_temp(struct bmg160_data *data, int 
*val)
 static int bmg160_get_axis(struct bmg160_data *data, int axis, int *val)
 {
int ret;
-   unsigned int raw_val;
+   __le16 raw_val;
 
mutex_lock(>mutex);
ret = bmg160_set_power_state(data, true);
@@ -470,7 +470,7 @@ static int bmg160_get_axis(struct bmg160_data *data, int 
axis, int *val)
return ret;
}
 
-   *val = sign_extend32(raw_val, 15);
+   *val = sign_extend32(le16_to_cpu(raw_val), 15);
ret = bmg160_set_power_state(data, false);
mutex_unlock(>mutex);
if (ret < 0)
@@ -733,6 +733,7 @@ static const struct iio_event_spec bmg160_event = {
.sign = 's',\
.realbits = 16, \
.storagebits = 16,  \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _event,\
.num_event_specs = 1\
-- 
1.9.1



[PATCH 1/1] iio: gyro: bmg160: fix endianness when reading axes

2016-03-28 Thread Irina Tirdea
For big endian platforms, reading the axes will return
invalid values.

The device stores each axis value in a 16 bit little
endian register. The driver uses regmap_read_bulk to get
the axis value, resulting in a 16 bit little endian value.
This needs to be converted to cpu endianness to work
on big endian platforms.

Fix endianness for big endian platforms by converting
the values for the axes read from little endian to
cpu.

This is also partially fixed in commit 82d8e5da1a33 ("iio:
accel: bmg160: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea 
---
 drivers/iio/gyro/bmg160_core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index bbce3b0..295cf1d 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -452,7 +452,7 @@ static int bmg160_get_temp(struct bmg160_data *data, int 
*val)
 static int bmg160_get_axis(struct bmg160_data *data, int axis, int *val)
 {
int ret;
-   unsigned int raw_val;
+   __le16 raw_val;
 
mutex_lock(>mutex);
ret = bmg160_set_power_state(data, true);
@@ -470,7 +470,7 @@ static int bmg160_get_axis(struct bmg160_data *data, int 
axis, int *val)
return ret;
}
 
-   *val = sign_extend32(raw_val, 15);
+   *val = sign_extend32(le16_to_cpu(raw_val), 15);
ret = bmg160_set_power_state(data, false);
mutex_unlock(>mutex);
if (ret < 0)
@@ -733,6 +733,7 @@ static const struct iio_event_spec bmg160_event = {
.sign = 's',\
.realbits = 16, \
.storagebits = 16,  \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _event,\
.num_event_specs = 1\
-- 
1.9.1



[PATCH 1/1] iio: accel: bmc150: fix endianness when reading axes

2016-03-28 Thread Irina Tirdea
For big endian platforms, reading the axes will return
invalid values.

The device stores each axis value in a 16 bit little
endian register. The driver uses regmap_read_bulk to get
the axis value, resulting in a 16 bit little endian value.
This needs to be converted to cpu endianness to work
on big endian platforms.

Fix endianness for big endian platforms by converting
the values for the axes read from little endian to
cpu.

This is also partially fixed in commit b6fb9b6d6552 ("iio:
accel: bmc150: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/accel/bmc150-accel-core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index c73331f7..5b64c3e 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -547,7 +547,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data 
*data,
 {
int ret;
int axis = chan->scan_index;
-   unsigned int raw_val;
+   __le16 raw_val;
 
mutex_lock(>mutex);
ret = bmc150_accel_set_power_state(data, true);
@@ -564,7 +564,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data 
*data,
mutex_unlock(>mutex);
return ret;
}
-   *val = sign_extend32(raw_val >> chan->scan_type.shift,
+   *val = sign_extend32(le16_to_cpu(raw_val) >> chan->scan_type.shift,
 chan->scan_type.realbits - 1);
ret = bmc150_accel_set_power_state(data, false);
mutex_unlock(>mutex);
@@ -988,6 +988,7 @@ static const struct iio_event_spec bmc150_accel_event = {
.realbits = (bits), \
.storagebits = 16,  \
.shift = 16 - (bits),   \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _accel_event,  \
.num_event_specs = 1\
-- 
1.9.1



[PATCH 1/1] iio: accel: bmc150: fix endianness when reading axes

2016-03-28 Thread Irina Tirdea
For big endian platforms, reading the axes will return
invalid values.

The device stores each axis value in a 16 bit little
endian register. The driver uses regmap_read_bulk to get
the axis value, resulting in a 16 bit little endian value.
This needs to be converted to cpu endianness to work
on big endian platforms.

Fix endianness for big endian platforms by converting
the values for the axes read from little endian to
cpu.

This is also partially fixed in commit b6fb9b6d6552 ("iio:
accel: bmc150: optimize transfers in trigger handler").

Signed-off-by: Irina Tirdea 
---
 drivers/iio/accel/bmc150-accel-core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index c73331f7..5b64c3e 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -547,7 +547,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data 
*data,
 {
int ret;
int axis = chan->scan_index;
-   unsigned int raw_val;
+   __le16 raw_val;
 
mutex_lock(>mutex);
ret = bmc150_accel_set_power_state(data, true);
@@ -564,7 +564,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data 
*data,
mutex_unlock(>mutex);
return ret;
}
-   *val = sign_extend32(raw_val >> chan->scan_type.shift,
+   *val = sign_extend32(le16_to_cpu(raw_val) >> chan->scan_type.shift,
 chan->scan_type.realbits - 1);
ret = bmc150_accel_set_power_state(data, false);
mutex_unlock(>mutex);
@@ -988,6 +988,7 @@ static const struct iio_event_spec bmc150_accel_event = {
.realbits = (bits), \
.storagebits = 16,  \
.shift = 16 - (bits),   \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _accel_event,  \
.num_event_specs = 1\
-- 
1.9.1



[PATCH 1/1] i2c: dln2: Pass forward ACPI companion

2016-03-24 Thread Irina Tirdea
Share the ACPI companion for the platform device with the
i2c adapter, so that the adapter has access to the properties
defined in ACPI tables.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/i2c/busses/i2c-dln2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/i2c/busses/i2c-dln2.c b/drivers/i2c/busses/i2c-dln2.c
index 1600edd..f2eb4f7 100644
--- a/drivers/i2c/busses/i2c-dln2.c
+++ b/drivers/i2c/busses/i2c-dln2.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define DLN2_I2C_MODULE_ID 0x03
 #define DLN2_I2C_CMD(cmd)  DLN2_CMD(cmd, DLN2_I2C_MODULE_ID)
@@ -210,6 +211,7 @@ static int dln2_i2c_probe(struct platform_device *pdev)
dln2->adapter.algo = _i2c_usb_algorithm;
dln2->adapter.quirks = _i2c_quirks;
dln2->adapter.dev.parent = dev;
+   ACPI_COMPANION_SET(>adapter.dev, ACPI_COMPANION(>dev));
dln2->adapter.dev.of_node = dev->of_node;
i2c_set_adapdata(>adapter, dln2);
snprintf(dln2->adapter.name, sizeof(dln2->adapter.name), "%s-%s-%d",
-- 
1.9.1



[PATCH 1/1] i2c: dln2: Pass forward ACPI companion

2016-03-24 Thread Irina Tirdea
Share the ACPI companion for the platform device with the
i2c adapter, so that the adapter has access to the properties
defined in ACPI tables.

Signed-off-by: Irina Tirdea 
---
 drivers/i2c/busses/i2c-dln2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/i2c/busses/i2c-dln2.c b/drivers/i2c/busses/i2c-dln2.c
index 1600edd..f2eb4f7 100644
--- a/drivers/i2c/busses/i2c-dln2.c
+++ b/drivers/i2c/busses/i2c-dln2.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define DLN2_I2C_MODULE_ID 0x03
 #define DLN2_I2C_CMD(cmd)  DLN2_CMD(cmd, DLN2_I2C_MODULE_ID)
@@ -210,6 +211,7 @@ static int dln2_i2c_probe(struct platform_device *pdev)
dln2->adapter.algo = _i2c_usb_algorithm;
dln2->adapter.quirks = _i2c_quirks;
dln2->adapter.dev.parent = dev;
+   ACPI_COMPANION_SET(>adapter.dev, ACPI_COMPANION(>dev));
dln2->adapter.dev.of_node = dev->of_node;
i2c_set_adapdata(>adapter, dln2);
snprintf(dln2->adapter.name, sizeof(dln2->adapter.name), "%s-%s-%d",
-- 
1.9.1



[PATCH 1/6] iio: accel: bmc150: use available_scan_masks

2016-03-24 Thread Irina Tirdea
Use available_scan_masks to allow the iio core to select
the data to send to userspace depending on which axes are
enabled, instead of doing this in the driver's interrupt
handler.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/accel/bmc150-accel-core.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index c73331f7..cc52366 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -138,6 +138,7 @@ enum bmc150_accel_axis {
AXIS_X,
AXIS_Y,
AXIS_Z,
+   AXIS_MAX,
 };
 
 enum bmc150_power_modes {
@@ -1104,6 +1105,10 @@ static const struct iio_info bmc150_accel_info_fifo = {
.driver_module  = THIS_MODULE,
 };
 
+static const unsigned long bmc150_accel_scan_masks[] = {
+   BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
+   0};
+
 static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
 {
struct iio_poll_func *pf = p;
@@ -1113,8 +1118,7 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, 
void *p)
unsigned int raw_val;
 
mutex_lock(>mutex);
-   for_each_set_bit(bit, indio_dev->active_scan_mask,
-indio_dev->masklength) {
+   for (bit = 0; bit < AXIS_MAX; bit++) {
ret = regmap_bulk_read(data->regmap,
   BMC150_ACCEL_AXIS_TO_REG(bit), _val,
   2);
@@ -1574,6 +1578,7 @@ int bmc150_accel_core_probe(struct device *dev, struct 
regmap *regmap, int irq,
indio_dev->channels = data->chip_info->channels;
indio_dev->num_channels = data->chip_info->num_channels;
indio_dev->name = name ? name : data->chip_info->name;
+   indio_dev->available_scan_masks = bmc150_accel_scan_masks;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = _accel_info;
 
-- 
1.9.1



[PATCH 6/6] iio: accel: kxcjk-1013: optimize i2c transfers in trigger handler

2016-03-24 Thread Irina Tirdea
From: Adriana Reus <adriana.r...@intel.com>

Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to
enable/disable the bus at each i2c transfer and must wait for
the enable/disable to happen before sending the data.

When reading data in the trigger handler, the kxcjk-1013 accel driver
does one i2c transfer for each axis. This has an impact on the
frequency of the accelerometer at high sample rates due to additional
delays introduced by the i2c bus at each transfer.

Reading all axis values in one i2c transfer reduces the delays
introduced by the i2c bus. Uses i2c_smbus_read_i2c_block_data_or_emulated
that will fallback to reading each axis as a separate word in case i2c
block read is not supported.

Signed-off-by: Adriana Reus <adriana.r...@intel.com>
Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
Acked-by: Jonathan Cameron <ji...@kernel.org>
Acked-by: Srinivas Pandruvada <srinivas.pandruv...@linux.intel.com>
---
 drivers/iio/accel/kxcjk-1013.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index 3861fe9..4881856 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -923,7 +923,7 @@ static const struct iio_event_spec kxcjk1013_event = {
.realbits = 12, \
.storagebits = 16,  \
.shift = 4, \
-   .endianness = IIO_CPU,  \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _event, \
.num_event_specs = 1\
@@ -961,19 +961,16 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, 
void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct kxcjk1013_data *data = iio_priv(indio_dev);
-   int bit, ret, i = 0;
+   int ret;
 
mutex_lock(>mutex);
-
-   for (bit = 0; bit < AXIS_MAX; bit++) {
-   ret = kxcjk1013_get_acc_reg(data, bit);
-   if (ret < 0) {
-   mutex_unlock(>mutex);
-   goto err;
-   }
-   data->buffer[i++] = ret;
-   }
+   ret = i2c_smbus_read_i2c_block_data_or_emulated(data->client,
+   KXCJK1013_REG_XOUT_L,
+   AXIS_MAX * 2,
+   (u8 *)data->buffer);
mutex_unlock(>mutex);
+   if (ret < 0)
+   goto err;
 
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
   data->timestamp);
-- 
1.9.1



[PATCH 5/6] iio: accel: kxcjk-1013: use available_scan_masks

2016-03-24 Thread Irina Tirdea
From: Adriana Reus <adriana.r...@intel.com>

Use available_scan_masks to allow the iio core to select
the data to send to userspace depending on which axes are
enabled, instead of doing this in the driver's interrupt
handler.

Signed-off-by: Adriana Reus <adriana.r...@intel.com>
Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
Acked-by: Jonathan Cameron <ji...@kernel.org>
Acked-by: Srinivas Pandruvada <srinivas.pandruv...@linux.intel.com>
---
 drivers/iio/accel/kxcjk-1013.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index edec1d0..3861fe9 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -115,6 +115,7 @@ enum kxcjk1013_axis {
AXIS_X,
AXIS_Y,
AXIS_Z,
+   AXIS_MAX,
 };
 
 enum kxcjk1013_mode {
@@ -953,6 +954,8 @@ static const struct iio_info kxcjk1013_info = {
.driver_module  = THIS_MODULE,
 };
 
+static const unsigned long kxcjk1013_scan_masks[] = {0x7, 0};
+
 static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p)
 {
struct iio_poll_func *pf = p;
@@ -962,8 +965,7 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void 
*p)
 
mutex_lock(>mutex);
 
-   for_each_set_bit(bit, indio_dev->active_scan_mask,
-indio_dev->masklength) {
+   for (bit = 0; bit < AXIS_MAX; bit++) {
ret = kxcjk1013_get_acc_reg(data, bit);
if (ret < 0) {
mutex_unlock(>mutex);
@@ -1204,6 +1206,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
indio_dev->dev.parent = >dev;
indio_dev->channels = kxcjk1013_channels;
indio_dev->num_channels = ARRAY_SIZE(kxcjk1013_channels);
+   indio_dev->available_scan_masks = kxcjk1013_scan_masks;
indio_dev->name = name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = _info;
-- 
1.9.1



[PATCH 6/6] iio: accel: kxcjk-1013: optimize i2c transfers in trigger handler

2016-03-24 Thread Irina Tirdea
From: Adriana Reus 

Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to
enable/disable the bus at each i2c transfer and must wait for
the enable/disable to happen before sending the data.

When reading data in the trigger handler, the kxcjk-1013 accel driver
does one i2c transfer for each axis. This has an impact on the
frequency of the accelerometer at high sample rates due to additional
delays introduced by the i2c bus at each transfer.

Reading all axis values in one i2c transfer reduces the delays
introduced by the i2c bus. Uses i2c_smbus_read_i2c_block_data_or_emulated
that will fallback to reading each axis as a separate word in case i2c
block read is not supported.

Signed-off-by: Adriana Reus 
Signed-off-by: Irina Tirdea 
Acked-by: Jonathan Cameron 
Acked-by: Srinivas Pandruvada 
---
 drivers/iio/accel/kxcjk-1013.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index 3861fe9..4881856 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -923,7 +923,7 @@ static const struct iio_event_spec kxcjk1013_event = {
.realbits = 12, \
.storagebits = 16,  \
.shift = 4, \
-   .endianness = IIO_CPU,  \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _event, \
.num_event_specs = 1\
@@ -961,19 +961,16 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, 
void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct kxcjk1013_data *data = iio_priv(indio_dev);
-   int bit, ret, i = 0;
+   int ret;
 
mutex_lock(>mutex);
-
-   for (bit = 0; bit < AXIS_MAX; bit++) {
-   ret = kxcjk1013_get_acc_reg(data, bit);
-   if (ret < 0) {
-   mutex_unlock(>mutex);
-   goto err;
-   }
-   data->buffer[i++] = ret;
-   }
+   ret = i2c_smbus_read_i2c_block_data_or_emulated(data->client,
+   KXCJK1013_REG_XOUT_L,
+   AXIS_MAX * 2,
+   (u8 *)data->buffer);
mutex_unlock(>mutex);
+   if (ret < 0)
+   goto err;
 
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
   data->timestamp);
-- 
1.9.1



[PATCH 5/6] iio: accel: kxcjk-1013: use available_scan_masks

2016-03-24 Thread Irina Tirdea
From: Adriana Reus 

Use available_scan_masks to allow the iio core to select
the data to send to userspace depending on which axes are
enabled, instead of doing this in the driver's interrupt
handler.

Signed-off-by: Adriana Reus 
Signed-off-by: Irina Tirdea 
Acked-by: Jonathan Cameron 
Acked-by: Srinivas Pandruvada 
---
 drivers/iio/accel/kxcjk-1013.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index edec1d0..3861fe9 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -115,6 +115,7 @@ enum kxcjk1013_axis {
AXIS_X,
AXIS_Y,
AXIS_Z,
+   AXIS_MAX,
 };
 
 enum kxcjk1013_mode {
@@ -953,6 +954,8 @@ static const struct iio_info kxcjk1013_info = {
.driver_module  = THIS_MODULE,
 };
 
+static const unsigned long kxcjk1013_scan_masks[] = {0x7, 0};
+
 static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p)
 {
struct iio_poll_func *pf = p;
@@ -962,8 +965,7 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void 
*p)
 
mutex_lock(>mutex);
 
-   for_each_set_bit(bit, indio_dev->active_scan_mask,
-indio_dev->masklength) {
+   for (bit = 0; bit < AXIS_MAX; bit++) {
ret = kxcjk1013_get_acc_reg(data, bit);
if (ret < 0) {
mutex_unlock(>mutex);
@@ -1204,6 +1206,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
indio_dev->dev.parent = >dev;
indio_dev->channels = kxcjk1013_channels;
indio_dev->num_channels = ARRAY_SIZE(kxcjk1013_channels);
+   indio_dev->available_scan_masks = kxcjk1013_scan_masks;
indio_dev->name = name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = _info;
-- 
1.9.1



[PATCH 1/6] iio: accel: bmc150: use available_scan_masks

2016-03-24 Thread Irina Tirdea
Use available_scan_masks to allow the iio core to select
the data to send to userspace depending on which axes are
enabled, instead of doing this in the driver's interrupt
handler.

Signed-off-by: Irina Tirdea 
---
 drivers/iio/accel/bmc150-accel-core.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index c73331f7..cc52366 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -138,6 +138,7 @@ enum bmc150_accel_axis {
AXIS_X,
AXIS_Y,
AXIS_Z,
+   AXIS_MAX,
 };
 
 enum bmc150_power_modes {
@@ -1104,6 +1105,10 @@ static const struct iio_info bmc150_accel_info_fifo = {
.driver_module  = THIS_MODULE,
 };
 
+static const unsigned long bmc150_accel_scan_masks[] = {
+   BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
+   0};
+
 static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
 {
struct iio_poll_func *pf = p;
@@ -1113,8 +1118,7 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, 
void *p)
unsigned int raw_val;
 
mutex_lock(>mutex);
-   for_each_set_bit(bit, indio_dev->active_scan_mask,
-indio_dev->masklength) {
+   for (bit = 0; bit < AXIS_MAX; bit++) {
ret = regmap_bulk_read(data->regmap,
   BMC150_ACCEL_AXIS_TO_REG(bit), _val,
   2);
@@ -1574,6 +1578,7 @@ int bmc150_accel_core_probe(struct device *dev, struct 
regmap *regmap, int irq,
indio_dev->channels = data->chip_info->channels;
indio_dev->num_channels = data->chip_info->num_channels;
indio_dev->name = name ? name : data->chip_info->name;
+   indio_dev->available_scan_masks = bmc150_accel_scan_masks;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = _accel_info;
 
-- 
1.9.1



[PATCH 3/6] iio: gyro: bmg160: use available_scan_masks

2016-03-24 Thread Irina Tirdea
Use available_scan_masks to allow the iio core to select
the data to send to userspace depending on which axes are
enabled, instead of doing this in the driver's interrupt
handler.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/gyro/bmg160_core.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index bbce3b0..8d6e5b1 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -116,6 +116,7 @@ enum bmg160_axis {
AXIS_X,
AXIS_Y,
AXIS_Z,
+   AXIS_MAX,
 };
 
 static const struct {
@@ -763,6 +764,10 @@ static const struct iio_info bmg160_info = {
.driver_module  = THIS_MODULE,
 };
 
+static const unsigned long bmg160_accel_scan_masks[] = {
+   BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
+   0};
+
 static irqreturn_t bmg160_trigger_handler(int irq, void *p)
 {
struct iio_poll_func *pf = p;
@@ -772,8 +777,7 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p)
unsigned int val;
 
mutex_lock(>mutex);
-   for_each_set_bit(bit, indio_dev->active_scan_mask,
-indio_dev->masklength) {
+   for (bit = 0; bit < AXIS_MAX; bit++) {
ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(bit),
   , 2);
if (ret < 0) {
@@ -1019,6 +1023,7 @@ int bmg160_core_probe(struct device *dev, struct regmap 
*regmap, int irq,
indio_dev->channels = bmg160_channels;
indio_dev->num_channels = ARRAY_SIZE(bmg160_channels);
indio_dev->name = name;
+   indio_dev->available_scan_masks = bmg160_accel_scan_masks;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = _info;
 
-- 
1.9.1



[PATCH 4/6] iio: accel: bmg160: optimize transfers in trigger handler

2016-03-24 Thread Irina Tirdea
Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to
enable/disable the bus at each i2c transfer and must wait for
the enable/disable to happen before sending the data.

When reading data in the trigger handler, the bmc150 accel driver does
one bus transfer for each axis. This has an impact on the frequency
of the accelerometer at high sample rates due to additional delays
introduced by the bus at each transfer.

Reading all axis values in one bus transfer reduces the delays
introduced by the bus.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/gyro/bmg160_core.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index 8d6e5b1..43570b8 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -734,6 +734,7 @@ static const struct iio_event_spec bmg160_event = {
.sign = 's',\
.realbits = 16, \
.storagebits = 16,  \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _event,\
.num_event_specs = 1\
@@ -773,20 +774,14 @@ static irqreturn_t bmg160_trigger_handler(int irq, void 
*p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct bmg160_data *data = iio_priv(indio_dev);
-   int bit, ret, i = 0;
-   unsigned int val;
+   int ret;
 
mutex_lock(>mutex);
-   for (bit = 0; bit < AXIS_MAX; bit++) {
-   ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(bit),
-  , 2);
-   if (ret < 0) {
-   mutex_unlock(>mutex);
-   goto err;
-   }
-   data->buffer[i++] = ret;
-   }
+   ret = regmap_bulk_read(data->regmap, BMG160_REG_XOUT_L,
+  data->buffer, AXIS_MAX * 2);
mutex_unlock(>mutex);
+   if (ret < 0)
+   goto err;
 
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
   pf->timestamp);
-- 
1.9.1



[PATCH 0/6] Driver optimizations in trigger handler

2016-03-24 Thread Irina Tirdea
This patchset adds optimization of i2c transactions in trigger handler
for bmc150, bmg160 and kxcjk-1013 drivers. It also introduces the
usage of available_scan_masks.

The code for bmc150 and bmg160 drivers is a rewrite of a previous
version [1] that takes into account the usage of regmap. The code
for kxcjk-1013 is the same as in the previous patch [1],
but included here for merging (since the
i2c_smbus_read_i2c_block_data_or_emulated API has been merged in
the iio tree).

[1] https://lkml.org/lkml/2015/8/12/609

Adriana Reus (2):
  iio: accel: kxcjk-1013: use available_scan_masks
  iio: accel: kxcjk-1013: optimize i2c transfers in trigger handler

Irina Tirdea (4):
  iio: accel: bmc150: use available_scan_masks
  iio: accel: bmc150: optimize transfers in trigger handler
  iio: gyro: bmg160: use available_scan_masks
  iio: accel: bmg160: optimize transfers in trigger handler

 drivers/iio/accel/bmc150-accel-core.c | 25 -
 drivers/iio/accel/kxcjk-1013.c| 24 
 drivers/iio/gyro/bmg160_core.c| 24 
 3 files changed, 36 insertions(+), 37 deletions(-)

-- 
1.9.1



[PATCH 3/6] iio: gyro: bmg160: use available_scan_masks

2016-03-24 Thread Irina Tirdea
Use available_scan_masks to allow the iio core to select
the data to send to userspace depending on which axes are
enabled, instead of doing this in the driver's interrupt
handler.

Signed-off-by: Irina Tirdea 
---
 drivers/iio/gyro/bmg160_core.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index bbce3b0..8d6e5b1 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -116,6 +116,7 @@ enum bmg160_axis {
AXIS_X,
AXIS_Y,
AXIS_Z,
+   AXIS_MAX,
 };
 
 static const struct {
@@ -763,6 +764,10 @@ static const struct iio_info bmg160_info = {
.driver_module  = THIS_MODULE,
 };
 
+static const unsigned long bmg160_accel_scan_masks[] = {
+   BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
+   0};
+
 static irqreturn_t bmg160_trigger_handler(int irq, void *p)
 {
struct iio_poll_func *pf = p;
@@ -772,8 +777,7 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p)
unsigned int val;
 
mutex_lock(>mutex);
-   for_each_set_bit(bit, indio_dev->active_scan_mask,
-indio_dev->masklength) {
+   for (bit = 0; bit < AXIS_MAX; bit++) {
ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(bit),
   , 2);
if (ret < 0) {
@@ -1019,6 +1023,7 @@ int bmg160_core_probe(struct device *dev, struct regmap 
*regmap, int irq,
indio_dev->channels = bmg160_channels;
indio_dev->num_channels = ARRAY_SIZE(bmg160_channels);
indio_dev->name = name;
+   indio_dev->available_scan_masks = bmg160_accel_scan_masks;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = _info;
 
-- 
1.9.1



[PATCH 4/6] iio: accel: bmg160: optimize transfers in trigger handler

2016-03-24 Thread Irina Tirdea
Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to
enable/disable the bus at each i2c transfer and must wait for
the enable/disable to happen before sending the data.

When reading data in the trigger handler, the bmc150 accel driver does
one bus transfer for each axis. This has an impact on the frequency
of the accelerometer at high sample rates due to additional delays
introduced by the bus at each transfer.

Reading all axis values in one bus transfer reduces the delays
introduced by the bus.

Signed-off-by: Irina Tirdea 
---
 drivers/iio/gyro/bmg160_core.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index 8d6e5b1..43570b8 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -734,6 +734,7 @@ static const struct iio_event_spec bmg160_event = {
.sign = 's',\
.realbits = 16, \
.storagebits = 16,  \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _event,\
.num_event_specs = 1\
@@ -773,20 +774,14 @@ static irqreturn_t bmg160_trigger_handler(int irq, void 
*p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct bmg160_data *data = iio_priv(indio_dev);
-   int bit, ret, i = 0;
-   unsigned int val;
+   int ret;
 
mutex_lock(>mutex);
-   for (bit = 0; bit < AXIS_MAX; bit++) {
-   ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(bit),
-  , 2);
-   if (ret < 0) {
-   mutex_unlock(>mutex);
-   goto err;
-   }
-   data->buffer[i++] = ret;
-   }
+   ret = regmap_bulk_read(data->regmap, BMG160_REG_XOUT_L,
+  data->buffer, AXIS_MAX * 2);
mutex_unlock(>mutex);
+   if (ret < 0)
+   goto err;
 
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
   pf->timestamp);
-- 
1.9.1



[PATCH 0/6] Driver optimizations in trigger handler

2016-03-24 Thread Irina Tirdea
This patchset adds optimization of i2c transactions in trigger handler
for bmc150, bmg160 and kxcjk-1013 drivers. It also introduces the
usage of available_scan_masks.

The code for bmc150 and bmg160 drivers is a rewrite of a previous
version [1] that takes into account the usage of regmap. The code
for kxcjk-1013 is the same as in the previous patch [1],
but included here for merging (since the
i2c_smbus_read_i2c_block_data_or_emulated API has been merged in
the iio tree).

[1] https://lkml.org/lkml/2015/8/12/609

Adriana Reus (2):
  iio: accel: kxcjk-1013: use available_scan_masks
  iio: accel: kxcjk-1013: optimize i2c transfers in trigger handler

Irina Tirdea (4):
  iio: accel: bmc150: use available_scan_masks
  iio: accel: bmc150: optimize transfers in trigger handler
  iio: gyro: bmg160: use available_scan_masks
  iio: accel: bmg160: optimize transfers in trigger handler

 drivers/iio/accel/bmc150-accel-core.c | 25 -
 drivers/iio/accel/kxcjk-1013.c| 24 
 drivers/iio/gyro/bmg160_core.c| 24 
 3 files changed, 36 insertions(+), 37 deletions(-)

-- 
1.9.1



[PATCH 2/6] iio: accel: bmc150: optimize transfers in trigger handler

2016-03-24 Thread Irina Tirdea
Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to
enable/disable the bus at each i2c transfer and must wait for
the enable/disable to happen before sending the data.

When reading data in the trigger handler, the bmc150 accel driver does
one bus transfer for each axis. This has an impact on the frequency
of the accelerometer at high sample rates due to additional delays
introduced by the bus at each transfer.

Reading all axis values in one bus transfer reduces the delays
introduced by the bus.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/accel/bmc150-accel-core.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index cc52366..58df97d 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -989,6 +989,7 @@ static const struct iio_event_spec bmc150_accel_event = {
.realbits = (bits), \
.storagebits = 16,  \
.shift = 16 - (bits),   \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _accel_event,  \
.num_event_specs = 1\
@@ -1114,21 +1115,14 @@ static irqreturn_t bmc150_accel_trigger_handler(int 
irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct bmc150_accel_data *data = iio_priv(indio_dev);
-   int bit, ret, i = 0;
-   unsigned int raw_val;
+   int ret;
 
mutex_lock(>mutex);
-   for (bit = 0; bit < AXIS_MAX; bit++) {
-   ret = regmap_bulk_read(data->regmap,
-  BMC150_ACCEL_AXIS_TO_REG(bit), _val,
-  2);
-   if (ret < 0) {
-   mutex_unlock(>mutex);
-   goto err_read;
-   }
-   data->buffer[i++] = raw_val;
-   }
+   ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_REG_XOUT_L,
+  data->buffer, AXIS_MAX * 2);
mutex_unlock(>mutex);
+   if (ret < 0)
+   goto err_read;
 
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
   pf->timestamp);
-- 
1.9.1



[PATCH 2/6] iio: accel: bmc150: optimize transfers in trigger handler

2016-03-24 Thread Irina Tirdea
Some i2c busses (e.g.: Synopsys DesignWare I2C adapter) need to
enable/disable the bus at each i2c transfer and must wait for
the enable/disable to happen before sending the data.

When reading data in the trigger handler, the bmc150 accel driver does
one bus transfer for each axis. This has an impact on the frequency
of the accelerometer at high sample rates due to additional delays
introduced by the bus at each transfer.

Reading all axis values in one bus transfer reduces the delays
introduced by the bus.

Signed-off-by: Irina Tirdea 
---
 drivers/iio/accel/bmc150-accel-core.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index cc52366..58df97d 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -989,6 +989,7 @@ static const struct iio_event_spec bmc150_accel_event = {
.realbits = (bits), \
.storagebits = 16,  \
.shift = 16 - (bits),   \
+   .endianness = IIO_LE,   \
},  \
.event_spec = _accel_event,  \
.num_event_specs = 1\
@@ -1114,21 +1115,14 @@ static irqreturn_t bmc150_accel_trigger_handler(int 
irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct bmc150_accel_data *data = iio_priv(indio_dev);
-   int bit, ret, i = 0;
-   unsigned int raw_val;
+   int ret;
 
mutex_lock(>mutex);
-   for (bit = 0; bit < AXIS_MAX; bit++) {
-   ret = regmap_bulk_read(data->regmap,
-  BMC150_ACCEL_AXIS_TO_REG(bit), _val,
-  2);
-   if (ret < 0) {
-   mutex_unlock(>mutex);
-   goto err_read;
-   }
-   data->buffer[i++] = raw_val;
-   }
+   ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_REG_XOUT_L,
+  data->buffer, AXIS_MAX * 2);
mutex_unlock(>mutex);
+   if (ret < 0)
+   goto err_read;
 
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
   pf->timestamp);
-- 
1.9.1



[PATCH 1/1] iio: fix config watermark initial value

2016-03-24 Thread Irina Tirdea
config structure is set to 0 when updating the buffers, so by
default config->watermark will be 0. When computing the minimum
between config->watermark and the buffer->watermark or
insert_buffer-watermark, this will always be 0 regardless of the
value set by the user for the buffer.

Set as initial value for config->watermark the maximum allowed
value so that the minimum value will always be set from one of the
buffers.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/industrialio-buffer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/industrialio-buffer.c 
b/drivers/iio/industrialio-buffer.c
index b976332..90462fc 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -653,6 +653,7 @@ static int iio_verify_update(struct iio_dev *indio_dev,
unsigned int modes;
 
memset(config, 0, sizeof(*config));
+   config->watermark = ~0;
 
/*
 * If there is just one buffer and we are removing it there is nothing
-- 
1.9.1



[PATCH 1/1] iio: fix config watermark initial value

2016-03-24 Thread Irina Tirdea
config structure is set to 0 when updating the buffers, so by
default config->watermark will be 0. When computing the minimum
between config->watermark and the buffer->watermark or
insert_buffer-watermark, this will always be 0 regardless of the
value set by the user for the buffer.

Set as initial value for config->watermark the maximum allowed
value so that the minimum value will always be set from one of the
buffers.

Signed-off-by: Irina Tirdea 
---
 drivers/iio/industrialio-buffer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/industrialio-buffer.c 
b/drivers/iio/industrialio-buffer.c
index b976332..90462fc 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -653,6 +653,7 @@ static int iio_verify_update(struct iio_dev *indio_dev,
unsigned int modes;
 
memset(config, 0, sizeof(*config));
+   config->watermark = ~0;
 
/*
 * If there is just one buffer and we are removing it there is nothing
-- 
1.9.1



[PATCH 1/1] iio: remove unused gpio consumer.h include

2016-03-24 Thread Irina Tirdea
GPIO handling code has been removed from the drivers (since
this is now handled by the ACPI core) in commit 0f0796509c07 ("iio:
remove gpio interrupt probing from drivers that use a single interrupt").

Remove the include for linux/gpio/consumer.h since it is no longer
used.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/accel/bmc150-accel-core.c  | 1 -
 drivers/iio/accel/kxcjk-1013.c | 1 -
 drivers/iio/accel/mma9553.c| 1 -
 drivers/iio/accel/stk8312.c| 1 -
 drivers/iio/accel/stk8ba50.c   | 1 -
 drivers/iio/imu/kmx61.c| 1 -
 drivers/iio/light/stk3310.c| 1 -
 drivers/iio/magnetometer/bmc150_magn.c | 1 -
 8 files changed, 8 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index feff894..65966e5 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -25,7 +25,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index edec1d0..47305dc 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -20,7 +20,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c
index fa7d362..bb05f3e 100644
--- a/drivers/iio/accel/mma9553.c
+++ b/drivers/iio/accel/mma9553.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c
index 85fe7f7..e31023d 100644
--- a/drivers/iio/accel/stk8312.c
+++ b/drivers/iio/accel/stk8312.c
@@ -11,7 +11,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c
index 5709d9e..300d955 100644
--- a/drivers/iio/accel/stk8ba50.c
+++ b/drivers/iio/accel/stk8ba50.c
@@ -11,7 +11,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c
index e5306b4..2e7dd57 100644
--- a/drivers/iio/imu/kmx61.c
+++ b/drivers/iio/imu/kmx61.c
@@ -14,7 +14,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index 42d334b..9e847f8 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -16,7 +16,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/magnetometer/bmc150_magn.c 
b/drivers/iio/magnetometer/bmc150_magn.c
index ffcb75e..0e9da18 100644
--- a/drivers/iio/magnetometer/bmc150_magn.c
+++ b/drivers/iio/magnetometer/bmc150_magn.c
@@ -23,7 +23,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-- 
1.9.1



[PATCH 1/1] iio: remove unused gpio consumer.h include

2016-03-24 Thread Irina Tirdea
GPIO handling code has been removed from the drivers (since
this is now handled by the ACPI core) in commit 0f0796509c07 ("iio:
remove gpio interrupt probing from drivers that use a single interrupt").

Remove the include for linux/gpio/consumer.h since it is no longer
used.

Signed-off-by: Irina Tirdea 
---
 drivers/iio/accel/bmc150-accel-core.c  | 1 -
 drivers/iio/accel/kxcjk-1013.c | 1 -
 drivers/iio/accel/mma9553.c| 1 -
 drivers/iio/accel/stk8312.c| 1 -
 drivers/iio/accel/stk8ba50.c   | 1 -
 drivers/iio/imu/kmx61.c| 1 -
 drivers/iio/light/stk3310.c| 1 -
 drivers/iio/magnetometer/bmc150_magn.c | 1 -
 8 files changed, 8 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index feff894..65966e5 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -25,7 +25,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index edec1d0..47305dc 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -20,7 +20,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c
index fa7d362..bb05f3e 100644
--- a/drivers/iio/accel/mma9553.c
+++ b/drivers/iio/accel/mma9553.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c
index 85fe7f7..e31023d 100644
--- a/drivers/iio/accel/stk8312.c
+++ b/drivers/iio/accel/stk8312.c
@@ -11,7 +11,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c
index 5709d9e..300d955 100644
--- a/drivers/iio/accel/stk8ba50.c
+++ b/drivers/iio/accel/stk8ba50.c
@@ -11,7 +11,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c
index e5306b4..2e7dd57 100644
--- a/drivers/iio/imu/kmx61.c
+++ b/drivers/iio/imu/kmx61.c
@@ -14,7 +14,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index 42d334b..9e847f8 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -16,7 +16,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/drivers/iio/magnetometer/bmc150_magn.c 
b/drivers/iio/magnetometer/bmc150_magn.c
index ffcb75e..0e9da18 100644
--- a/drivers/iio/magnetometer/bmc150_magn.c
+++ b/drivers/iio/magnetometer/bmc150_magn.c
@@ -23,7 +23,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-- 
1.9.1



[PATCH 1/1] iio: remove gpio interrupt probing from drivers that use a single interrupt

2016-03-24 Thread Irina Tirdea
Commit 845c877009cf014b ("i2c / ACPI: Assign IRQ for devices that have
GpioInt automatically") automatically assigns the first ACPI GPIO
interrupt in client->irq, so we can remove the probing code from
drivers that use only one interrupt.

Commit 0f0796509c07c1c7 ("iio: remove gpio interrupt probing from drivers
that use a single interrupt") removes gpio interrupt probing from most
drivers. This patch cleans the remaining ones.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/accel/mxc4005.c| 29 -
 drivers/iio/gyro/bmg160_core.c | 28 
 2 files changed, 57 deletions(-)

diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c
index e72e218..c23f47a 100644
--- a/drivers/iio/accel/mxc4005.c
+++ b/drivers/iio/accel/mxc4005.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -380,31 +379,6 @@ static const struct iio_trigger_ops mxc4005_trigger_ops = {
.owner = THIS_MODULE,
 };
 
-static int mxc4005_gpio_probe(struct i2c_client *client,
- struct mxc4005_data *data)
-{
-   struct device *dev;
-   struct gpio_desc *gpio;
-   int ret;
-
-   if (!client)
-   return -EINVAL;
-
-   dev = >dev;
-
-   gpio = devm_gpiod_get_index(dev, "mxc4005_int", 0, GPIOD_IN);
-   if (IS_ERR(gpio)) {
-   dev_err(dev, "failed to get acpi gpio index\n");
-   return PTR_ERR(gpio);
-   }
-
-   ret = gpiod_to_irq(gpio);
-
-   dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
-
-   return ret;
-}
-
 static int mxc4005_chip_init(struct mxc4005_data *data)
 {
int ret;
@@ -470,9 +444,6 @@ static int mxc4005_probe(struct i2c_client *client,
return ret;
}
 
-   if (client->irq < 0)
-   client->irq = mxc4005_gpio_probe(client, data);
-
if (client->irq > 0) {
data->dready_trig = devm_iio_trigger_alloc(>dev,
   "%s-dev%d",
diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index bbce3b0..822767c 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -31,7 +30,6 @@
 #include "bmg160.h"
 
 #define BMG160_IRQ_NAME"bmg160_event"
-#define BMG160_GPIO_NAME   "gpio_int"
 
 #define BMG160_REG_CHIP_ID 0x00
 #define BMG160_CHIP_ID_VAL 0x0F
@@ -955,29 +953,6 @@ static const struct iio_buffer_setup_ops 
bmg160_buffer_setup_ops = {
.postdisable = bmg160_buffer_postdisable,
 };
 
-static int bmg160_gpio_probe(struct bmg160_data *data)
-
-{
-   struct device *dev;
-   struct gpio_desc *gpio;
-
-   dev = data->dev;
-
-   /* data ready gpio interrupt pin */
-   gpio = devm_gpiod_get_index(dev, BMG160_GPIO_NAME, 0, GPIOD_IN);
-   if (IS_ERR(gpio)) {
-   dev_err(dev, "acpi gpio get index failed\n");
-   return PTR_ERR(gpio);
-   }
-
-   data->irq = gpiod_to_irq(gpio);
-
-   dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio),
-   data->irq);
-
-   return 0;
-}
-
 static const char *bmg160_match_acpi_device(struct device *dev)
 {
const struct acpi_device_id *id;
@@ -1022,9 +997,6 @@ int bmg160_core_probe(struct device *dev, struct regmap 
*regmap, int irq,
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = _info;
 
-   if (data->irq <= 0)
-   bmg160_gpio_probe(data);
-
if (data->irq > 0) {
ret = devm_request_threaded_irq(dev,
data->irq,
-- 
1.9.1



[PATCH 1/1] iio: remove gpio interrupt probing from drivers that use a single interrupt

2016-03-24 Thread Irina Tirdea
Commit 845c877009cf014b ("i2c / ACPI: Assign IRQ for devices that have
GpioInt automatically") automatically assigns the first ACPI GPIO
interrupt in client->irq, so we can remove the probing code from
drivers that use only one interrupt.

Commit 0f0796509c07c1c7 ("iio: remove gpio interrupt probing from drivers
that use a single interrupt") removes gpio interrupt probing from most
drivers. This patch cleans the remaining ones.

Signed-off-by: Irina Tirdea 
---
 drivers/iio/accel/mxc4005.c| 29 -
 drivers/iio/gyro/bmg160_core.c | 28 
 2 files changed, 57 deletions(-)

diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c
index e72e218..c23f47a 100644
--- a/drivers/iio/accel/mxc4005.c
+++ b/drivers/iio/accel/mxc4005.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -380,31 +379,6 @@ static const struct iio_trigger_ops mxc4005_trigger_ops = {
.owner = THIS_MODULE,
 };
 
-static int mxc4005_gpio_probe(struct i2c_client *client,
- struct mxc4005_data *data)
-{
-   struct device *dev;
-   struct gpio_desc *gpio;
-   int ret;
-
-   if (!client)
-   return -EINVAL;
-
-   dev = >dev;
-
-   gpio = devm_gpiod_get_index(dev, "mxc4005_int", 0, GPIOD_IN);
-   if (IS_ERR(gpio)) {
-   dev_err(dev, "failed to get acpi gpio index\n");
-   return PTR_ERR(gpio);
-   }
-
-   ret = gpiod_to_irq(gpio);
-
-   dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
-
-   return ret;
-}
-
 static int mxc4005_chip_init(struct mxc4005_data *data)
 {
int ret;
@@ -470,9 +444,6 @@ static int mxc4005_probe(struct i2c_client *client,
return ret;
}
 
-   if (client->irq < 0)
-   client->irq = mxc4005_gpio_probe(client, data);
-
if (client->irq > 0) {
data->dready_trig = devm_iio_trigger_alloc(>dev,
   "%s-dev%d",
diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c
index bbce3b0..822767c 100644
--- a/drivers/iio/gyro/bmg160_core.c
+++ b/drivers/iio/gyro/bmg160_core.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -31,7 +30,6 @@
 #include "bmg160.h"
 
 #define BMG160_IRQ_NAME"bmg160_event"
-#define BMG160_GPIO_NAME   "gpio_int"
 
 #define BMG160_REG_CHIP_ID 0x00
 #define BMG160_CHIP_ID_VAL 0x0F
@@ -955,29 +953,6 @@ static const struct iio_buffer_setup_ops 
bmg160_buffer_setup_ops = {
.postdisable = bmg160_buffer_postdisable,
 };
 
-static int bmg160_gpio_probe(struct bmg160_data *data)
-
-{
-   struct device *dev;
-   struct gpio_desc *gpio;
-
-   dev = data->dev;
-
-   /* data ready gpio interrupt pin */
-   gpio = devm_gpiod_get_index(dev, BMG160_GPIO_NAME, 0, GPIOD_IN);
-   if (IS_ERR(gpio)) {
-   dev_err(dev, "acpi gpio get index failed\n");
-   return PTR_ERR(gpio);
-   }
-
-   data->irq = gpiod_to_irq(gpio);
-
-   dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio),
-   data->irq);
-
-   return 0;
-}
-
 static const char *bmg160_match_acpi_device(struct device *dev)
 {
const struct acpi_device_id *id;
@@ -1022,9 +997,6 @@ int bmg160_core_probe(struct device *dev, struct regmap 
*regmap, int irq,
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = _info;
 
-   if (data->irq <= 0)
-   bmg160_gpio_probe(data);
-
if (data->irq > 0) {
ret = devm_request_threaded_irq(dev,
data->irq,
-- 
1.9.1



[PATCH 1/1] iio: accel: bmc150: remove unused definition

2016-03-24 Thread Irina Tirdea
bmc150_i2c_regmap_conf is defined in bmc150-accel-core.c, but
never used here. The definition is needed in bmc150-accel-i2c.c,
where it is again defined.

Remove the unnecessary definition of bmc150_i2c_regmap_conf from
bmc150-accel-core.c and update the one from bmc150-accel-i2c.c
to contain all fields.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/iio/accel/bmc150-accel-core.c | 6 --
 drivers/iio/accel/bmc150-accel-i2c.c  | 1 +
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index c73331f7..feff894 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -246,12 +246,6 @@ static const struct {
   {50, BMC150_ACCEL_SLEEP_500_MS},
   {100, BMC150_ACCEL_SLEEP_1_SEC} };
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-   .max_register = 0x3f,
-};
-
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 enum bmc150_power_modes mode,
 int dur_us)
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c 
b/drivers/iio/accel/bmc150-accel-i2c.c
index b41404b..f0969fe 100644
--- a/drivers/iio/accel/bmc150-accel-i2c.c
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -31,6 +31,7 @@
 static const struct regmap_config bmc150_i2c_regmap_conf = {
.reg_bits = 8,
.val_bits = 8,
+   .max_register = 0x3f,
 };
 
 static int bmc150_accel_probe(struct i2c_client *client,
-- 
1.9.1



[PATCH 1/1] iio: accel: bmc150: remove unused definition

2016-03-24 Thread Irina Tirdea
bmc150_i2c_regmap_conf is defined in bmc150-accel-core.c, but
never used here. The definition is needed in bmc150-accel-i2c.c,
where it is again defined.

Remove the unnecessary definition of bmc150_i2c_regmap_conf from
bmc150-accel-core.c and update the one from bmc150-accel-i2c.c
to contain all fields.

Signed-off-by: Irina Tirdea 
---
 drivers/iio/accel/bmc150-accel-core.c | 6 --
 drivers/iio/accel/bmc150-accel-i2c.c  | 1 +
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index c73331f7..feff894 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -246,12 +246,6 @@ static const struct {
   {50, BMC150_ACCEL_SLEEP_500_MS},
   {100, BMC150_ACCEL_SLEEP_1_SEC} };
 
-static const struct regmap_config bmc150_i2c_regmap_conf = {
-   .reg_bits = 8,
-   .val_bits = 8,
-   .max_register = 0x3f,
-};
-
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 enum bmc150_power_modes mode,
 int dur_us)
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c 
b/drivers/iio/accel/bmc150-accel-i2c.c
index b41404b..f0969fe 100644
--- a/drivers/iio/accel/bmc150-accel-i2c.c
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -31,6 +31,7 @@
 static const struct regmap_config bmc150_i2c_regmap_conf = {
.reg_bits = 8,
.val_bits = 8,
+   .max_register = 0x3f,
 };
 
 static int bmc150_accel_probe(struct i2c_client *client,
-- 
1.9.1



[PATCH 1/1] mfd: core: fix ACPI child matching by _HID/_CID

2016-03-12 Thread Irina Tirdea
If MDF child devices have separate ACPI nodes identified
by _HID/_CID, they will not be assigned the intended
ACPI companion.

acpi_match_device_ids will return 0 if a the child device
matches the _HID/_CID, so this patch changes the matching
condition to check for 0 on success.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/mfd/mfd-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 88bd1b1..409da01 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -107,7 +107,7 @@ static void mfd_acpi_add_device(const struct mfd_cell *cell,
 
strlcpy(ids[0].id, match->pnpid, sizeof(ids[0].id));
list_for_each_entry(child, >children, node) {
-   if (acpi_match_device_ids(child, ids)) {
+   if (!acpi_match_device_ids(child, ids)) {
adev = child;
break;
}
-- 
1.9.1



[PATCH 1/1] mfd: core: fix ACPI child matching by _HID/_CID

2016-03-12 Thread Irina Tirdea
If MDF child devices have separate ACPI nodes identified
by _HID/_CID, they will not be assigned the intended
ACPI companion.

acpi_match_device_ids will return 0 if a the child device
matches the _HID/_CID, so this patch changes the matching
condition to check for 0 on success.

Signed-off-by: Irina Tirdea 
---
 drivers/mfd/mfd-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 88bd1b1..409da01 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -107,7 +107,7 @@ static void mfd_acpi_add_device(const struct mfd_cell *cell,
 
strlcpy(ids[0].id, match->pnpid, sizeof(ids[0].id));
list_for_each_entry(child, >children, node) {
-   if (acpi_match_device_ids(child, ids)) {
+   if (!acpi_match_device_ids(child, ids)) {
adev = child;
break;
}
-- 
1.9.1



[PATCH 1/1] ACPI / property: fix data node parsing in acpi_get_next_subnode

2016-03-12 Thread Irina Tirdea
When an ACPI node has both ACPI device nodes and ACPI data nodes,
acpi_get_next_subnode will return the ACPI data nodes of its last
parsed child.

Make sure that the acpi device that is parsed is the original acpi
node and not any of its children.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/acpi/property.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index 2aee416..f2fd3fe 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -816,6 +816,7 @@ struct fwnode_handle *acpi_get_next_subnode(struct device 
*dev,
next = adev->node.next;
if (next == head) {
child = NULL;
+   adev = ACPI_COMPANION(dev);
goto nondev;
}
adev = list_entry(next, struct acpi_device, node);
-- 
1.9.1



[PATCH 1/1] ACPI / property: fix data node parsing in acpi_get_next_subnode

2016-03-12 Thread Irina Tirdea
When an ACPI node has both ACPI device nodes and ACPI data nodes,
acpi_get_next_subnode will return the ACPI data nodes of its last
parsed child.

Make sure that the acpi device that is parsed is the original acpi
node and not any of its children.

Signed-off-by: Irina Tirdea 
---
 drivers/acpi/property.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index 2aee416..f2fd3fe 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -816,6 +816,7 @@ struct fwnode_handle *acpi_get_next_subnode(struct device 
*dev,
next = adev->node.next;
if (next == head) {
child = NULL;
+   adev = ACPI_COMPANION(dev);
goto nondev;
}
adev = list_entry(next, struct acpi_device, node);
-- 
1.9.1



[PATCH v11 7/8] Input: goodix - add sysfs interface to dump config

2015-11-19 Thread Irina Tirdea
Goodix devices have a configuration information register area that
specify various parameters for the device. The configuration information
has a specific format described in the Goodix datasheet. It includes X/Y
resolution, maximum supported touch points, interrupt flags, various
sesitivity factors and settings for advanced features (like gesture
recognition).

Export a sysfs interface that would allow reading the configuration
information. The default device configuration can be used as a starting
point for creating a valid configuration firmware used by the device at
init time to update its configuration.

This sysfs interface will be exported only if the gpio pins are properly
initialized from ACPI/DT.

Signed-off-by: Irina Tirdea 
Tested-by: Bastien Nocera 
Tested-by: Aleksei Mamlin 
---
 drivers/input/touchscreen/goodix.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 28cbfa9..ea5042f 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -511,12 +511,35 @@ static ssize_t goodix_esd_timeout_store(struct device 
*dev,
return count;
 }
 
+static ssize_t goodix_dump_config_show(struct device *dev,
+  struct device_attribute *attr, char *buf)
+{
+   struct goodix_ts_data *ts = dev_get_drvdata(dev);
+   u8 config[GOODIX_CONFIG_MAX_LENGTH];
+   int error, count = 0, i;
+
+   error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA,
+   config, ts->cfg_len);
+   if (error) {
+   dev_warn(>client->dev,
+"Error reading config (%d)\n",  error);
+   return error;
+   }
+
+   for (i = 0; i < ts->cfg_len; i++)
+   count += scnprintf(buf + count, PAGE_SIZE - count, "%02x ",
+  config[i]);
+   return count;
+}
+
 /* ESD timeout in ms. Default disabled (0). Recommended 2000 ms. */
 static DEVICE_ATTR(esd_timeout, S_IRUGO | S_IWUSR, goodix_esd_timeout_show,
   goodix_esd_timeout_store);
+static DEVICE_ATTR(dump_config, S_IRUGO, goodix_dump_config_show, NULL);
 
 static struct attribute *goodix_attrs[] = {
_attr_esd_timeout.attr,
+   _attr_dump_config.attr,
NULL
 };
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v11 6/8] Input: goodix - add support for ESD

2015-11-19 Thread Irina Tirdea
Add ESD (Electrostatic Discharge) protection mechanism.

The driver enables ESD protection in HW and checks a register
to determine if ESD occurred. If ESD is signalled by the HW,
the driver will reset the device.

The ESD poll time (in ms) can be set through the sysfs property
esd_timeout. If it is set to 0, ESD protection is disabled.
Recommended value is 2000 ms. The initial value for ESD timeout
can be set through esd-recovery-timeout-ms ACPI/DT property.
If there is no such property defined, ESD protection is disabled.
For ACPI 5.1, the property can be specified using _DSD properties:
 Device (STAC)
 {
 Name (_HID, "GDIX1001")
 ...

 Name (_DSD,  Package ()
 {
 ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
 Package ()
 {
 Package (2) { "esd-recovery-timeout-ms", Package(1) { 2000 }},
 ...
 }
 })
 }

The ESD protection mechanism is only available if the gpio pins
are properly initialized from ACPI/DT.

This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).

Signed-off-by: Irina Tirdea 
For the binding: Acked-by: Rob Herring 

Signed-off-by: Irina Tirdea 
---
 .../bindings/input/touchscreen/goodix.txt  |   4 +
 drivers/input/touchscreen/goodix.c | 160 -
 2 files changed, 159 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt 
b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
index c42d2ce..a8492e3 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
@@ -18,6 +18,10 @@ Optional properties:
  - irq-gpios   : GPIO pin used for IRQ. The driver uses the
  interrupt gpio pin as output to reset the device.
  - reset-gpios : GPIO pin used for reset
+ - esd-recovery-timeout-ms : ESD poll time (in milli seconds) for the driver to
+check if ESD occurred and in that case reset the
+device. ESD is disabled if this property is not set
+or is set to 0.
 
 Example:
 
diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 9b7f2ad..28cbfa9 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -46,10 +46,13 @@ struct goodix_ts_data {
char *cfg_name;
struct completion firmware_loading_complete;
unsigned long irq_flags;
+   atomic_t esd_timeout;
+   struct delayed_work esd_work;
 };
 
 #define GOODIX_GPIO_INT_NAME   "irq"
 #define GOODIX_GPIO_RST_NAME   "reset"
+#define GOODIX_DEVICE_ESD_TIMEOUT_PROPERTY "esd-recovery-timeout-ms"
 
 #define GOODIX_MAX_HEIGHT  4096
 #define GOODIX_MAX_WIDTH   4096
@@ -64,6 +67,8 @@ struct goodix_ts_data {
 /* Register defines */
 #define GOODIX_REG_COMMAND 0x8040
 #define GOODIX_CMD_SCREEN_OFF  0x05
+#define GOODIX_CMD_ESD_ENABLED 0xAA
+#define GOODIX_REG_ESD_CHECK   0x8041
 
 #define GOODIX_READ_COOR_ADDR  0x814E
 #define GOODIX_REG_CONFIG_DATA 0x8047
@@ -406,6 +411,119 @@ static int goodix_reset(struct goodix_ts_data *ts)
return goodix_int_sync(ts);
 }
 
+static void goodix_disable_esd(struct goodix_ts_data *ts)
+{
+   if (!atomic_read(>esd_timeout))
+   return;
+   cancel_delayed_work_sync(>esd_work);
+}
+
+static int goodix_enable_esd(struct goodix_ts_data *ts)
+{
+   int error, esd_timeout;
+
+   esd_timeout = atomic_read(>esd_timeout);
+   if (!esd_timeout)
+   return 0;
+
+   error = goodix_i2c_write_u8(ts->client, GOODIX_REG_ESD_CHECK,
+   GOODIX_CMD_ESD_ENABLED);
+   if (error) {
+   dev_err(>client->dev, "Failed to enable ESD: %d\n", error);
+   return error;
+   }
+
+   schedule_delayed_work(>esd_work, round_jiffies_relative(
+ msecs_to_jiffies(esd_timeout)));
+   return 0;
+}
+
+static void goodix_esd_work(struct work_struct *work)
+{
+   struct goodix_ts_data *ts = container_of(work, struct goodix_ts_data,
+esd_work.work);
+   int retries = 3, error;
+   u8 esd_data[2];
+   const struct firmware *cfg = NULL;
+
+   wait_for_completion(>firmware_loading_complete);
+
+   while (--retries) {
+   error = goodix_i2c_read(ts->client, GOODIX_REG_COMMAND,
+   esd_data, sizeof(esd_data));
+   if (error)
+   continue;
+   if (esd_data[0] != GOODIX_CMD_ESD_ENABLE

[PATCH v11 1/8] Input: goodix - use actual config length for each device type

2015-11-19 Thread Irina Tirdea
Each of the Goodix devices supported by this driver has a fixed size for
the configuration information registers. The size varies depending on the
device and is specified in the datasheet.

Use the proper configuration length as specified in the datasheet for
each device model, so we do not read more than the actual size of the
configuration registers.

Signed-off-by: Irina Tirdea 
Acked-by: Bastien Nocera 
Tested-by: Bastien Nocera 
Tested-by: Aleksei Mamlin 
---
 drivers/input/touchscreen/goodix.c | 25 +++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 4d113c9..56d0330 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -36,6 +36,7 @@ struct goodix_ts_data {
unsigned int max_touch_num;
unsigned int int_trigger_type;
bool rotated_screen;
+   int cfg_len;
 };
 
 #define GOODIX_MAX_HEIGHT  4096
@@ -45,6 +46,8 @@ struct goodix_ts_data {
 #define GOODIX_MAX_CONTACTS10
 
 #define GOODIX_CONFIG_MAX_LENGTH   240
+#define GOODIX_CONFIG_911_LENGTH   186
+#define GOODIX_CONFIG_967_LENGTH   228
 
 /* Register defines */
 #define GOODIX_READ_COOR_ADDR  0x814E
@@ -115,6 +118,23 @@ static int goodix_i2c_read(struct i2c_client *client,
return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
 }
 
+static int goodix_get_cfg_len(u16 id)
+{
+   switch (id) {
+   case 911:
+   case 9271:
+   case 9110:
+   case 927:
+   case 928:
+   return GOODIX_CONFIG_911_LENGTH;
+   case 912:
+   case 967:
+   return GOODIX_CONFIG_967_LENGTH;
+   default:
+   return GOODIX_CONFIG_MAX_LENGTH;
+   }
+}
+
 static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
 {
int touch_num;
@@ -230,8 +250,7 @@ static void goodix_read_config(struct goodix_ts_data *ts)
int error;
 
error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA,
-   config,
-   GOODIX_CONFIG_MAX_LENGTH);
+   config, ts->cfg_len);
if (error) {
dev_warn(>client->dev,
 "Error reading config (%d), using defaults\n",
@@ -398,6 +417,8 @@ static int goodix_ts_probe(struct i2c_client *client,
return error;
}
 
+   ts->cfg_len = goodix_get_cfg_len(id_info);
+
goodix_read_config(ts);
 
error = goodix_request_input_dev(ts, version_info, id_info);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v11 4/8] Input: goodix - add power management support

2015-11-19 Thread Irina Tirdea
Implement suspend/resume for goodix driver.

The suspend and resume process uses the gpio pins.
If the device ACPI/DT information does not declare gpio pins,
suspend/resume will not be available for these devices.

This is based on Goodix datasheets for GT911 and GT9271
and on Goodix driver gt9xx.c for Android (publicly available
in Android kernel trees for various devices).

Signed-off-by: Octavian Purdila 
Signed-off-by: Irina Tirdea 
---
 drivers/input/touchscreen/goodix.c | 96 --
 1 file changed, 91 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 0911b0c9..0fd472d 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -45,6 +45,7 @@ struct goodix_ts_data {
u16 version;
char *cfg_name;
struct completion firmware_loading_complete;
+   unsigned long irq_flags;
 };
 
 #define GOODIX_GPIO_INT_NAME   "irq"
@@ -61,6 +62,9 @@ struct goodix_ts_data {
 #define GOODIX_CONFIG_967_LENGTH   228
 
 /* Register defines */
+#define GOODIX_REG_COMMAND 0x8040
+#define GOODIX_CMD_SCREEN_OFF  0x05
+
 #define GOODIX_READ_COOR_ADDR  0x814E
 #define GOODIX_REG_CONFIG_DATA 0x8047
 #define GOODIX_REG_ID  0x8140
@@ -162,6 +166,11 @@ static int goodix_i2c_write(struct i2c_client *client, u16 
reg, const u8 *buf,
return ret < 0 ? ret : (ret != 1 ? -EIO : 0);
 }
 
+static int goodix_i2c_write_u8(struct i2c_client *client, u16 reg, u8 value)
+{
+   return goodix_i2c_write(client, reg, , sizeof(value));
+}
+
 static int goodix_get_cfg_len(u16 id)
 {
switch (id) {
@@ -281,6 +290,18 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void 
*dev_id)
return IRQ_HANDLED;
 }
 
+static void goodix_free_irq(struct goodix_ts_data *ts)
+{
+   devm_free_irq(>client->dev, ts->client->irq, ts);
+}
+
+static int goodix_request_irq(struct goodix_ts_data *ts)
+{
+   return devm_request_threaded_irq(>client->dev, ts->client->irq,
+NULL, goodix_ts_irq_handler,
+ts->irq_flags, ts->client->name, ts);
+}
+
 /**
  * goodix_check_cfg - Checks if config fw is valid
  *
@@ -585,7 +606,6 @@ static int goodix_request_input_dev(struct goodix_ts_data 
*ts)
 static int goodix_configure_dev(struct goodix_ts_data *ts)
 {
int error;
-   unsigned long irq_flags;
 
goodix_read_config(ts);
 
@@ -593,10 +613,8 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
if (error)
return error;
 
-   irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
-   error = devm_request_threaded_irq(>client->dev, ts->client->irq,
- NULL, goodix_ts_irq_handler,
- irq_flags, ts->client->name, ts);
+   ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
+   error = goodix_request_irq(ts);
if (error) {
dev_err(>client->dev, "request IRQ failed: %d\n", error);
return error;
@@ -720,6 +738,73 @@ static int goodix_ts_remove(struct i2c_client *client)
return 0;
 }
 
+static int __maybe_unused goodix_suspend(struct device *dev)
+{
+   struct i2c_client *client = to_i2c_client(dev);
+   struct goodix_ts_data *ts = i2c_get_clientdata(client);
+   int error;
+
+   /* We need gpio pins to suspend/resume */
+   if (!ts->gpiod_int || !ts->gpiod_rst)
+   return 0;
+
+   wait_for_completion(>firmware_loading_complete);
+
+   /* Free IRQ as IRQ pin is used as output in the suspend sequence */
+   goodix_free_irq(ts);
+   /* Output LOW on the INT pin for 5 ms */
+   error = gpiod_direction_output(ts->gpiod_int, 0);
+   if (error) {
+   goodix_request_irq(ts);
+   return error;
+   }
+   usleep_range(5000, 6000);
+
+   error = goodix_i2c_write_u8(ts->client, GOODIX_REG_COMMAND,
+   GOODIX_CMD_SCREEN_OFF);
+   if (error) {
+   dev_err(>client->dev, "Screen off command failed\n");
+   gpiod_direction_input(ts->gpiod_int);
+   goodix_request_irq(ts);
+   return -EAGAIN;
+   }
+
+   /*
+* The datasheet specifies that the interval between sending screen-off
+* command and wake-up should be longer than 58 ms. To avoid waking up
+* sooner, delay 58ms here.
+*/
+   msleep(58);
+   return 0;
+}
+
+static int __maybe_unused goodix_resume(struct device *dev)
+{
+   struct i2c_client *client = to_i2c_client(dev);
+   struct goodix_ts_data *ts = i2c_get_clientdata(client);
+   i

[PATCH v11 0/8] Goodix touchscreen enhancements

2015-11-19 Thread Irina Tirdea
This patchset depends on Dmitry's patch that fixes the
GPIO ACPI API[1], so devm_gpiod_get_optional can be properly
used in the code. 

[1] https://lkml.org/lkml/2015/11/11/465

Changes in v11:
 - renamed irq-gpio and reset-gpio to irq-gpios and reset-gpios
 - added Rob's Acked-by for the binding in patch 6.

Changes in v10:
 - use devm_gpiod_get_optional and no longer ignore errors returned
by it
 - use completion to signal other code paths in the driver that
the config firmware is loaded on the device
 - dropped the patch that ordered the includes

Changes in v9:
 - add GPIOLIB to driver dependencies
 - add Tested-by tag from Bastien and Aleksei

Changes in v8:
 - only allow new functionality for devices that declare named
gpios (using _DSD properties in ACPI or named DT properties)

Changes in v7:
 - add dmi quirk to skip gpio pins setup and functionality that
depends on them for Onda v975w, WinBook TW100 and WinBook TW700.
 - add support for named gpio pins
 - rework the runtime pm patch to fix a couple of issues
 - sort includes using inverse Xmas tree ordering

Changes in v6:
 - skip runtime power manangent calls in open/close if the device
ACPI/DT configuration does not declare interrupt and reset gpio pins.
 - reset the device before starting i2c communication
 - add Bastien's ack to the first 2 patches

Changes in v5:
 - add some more style cleanup (reorder includes, use error instead
of ret for return values)
 - add runtime power management patch

Changes in v4:
 - use dmi quirk to determine the order of irq and reset pins
 - use actual config length depending on device
 - add sysfs interface to dump config
 - initialize esd timeout from ACPI/DT properly

Changes in v3:
 - dropped the first 3 patches that got merged
 - handle -EPROBE_DEFER and -ENOENT for gpio pins
 - skip functionality depending on the gpio pins if the pins are not
properly initialized from ACPI/DT (reset, write config, power management,
ESD)
 - dropped #ifdef CONFIG_PM_SLEEP and annotated with __maybe_unused instead
 - use sysfs property to set ESD timeout instead of ACPI/DT property
 - use request_firmware_nowait to read configuration firmware and use
defaults if firmware is not found
 - use ACPI IDs to determine the order of the GPIO pins in the ACPI tables
(interrupt pin first or reset pin first)

Changes in v2:
 - use request_firmware instead of ACPI/DT property for config
 - dropped "input: goodix: add ACPI IDs for GT911 and GT9271" patch
 - add ACPI DSDT excerpt in commit message where necessary
 - add comments for suspend/resume sleep values
 - dropped the checkpatch fixes that did not make sense
 - added Bastien's ack to the first patch

Irina Tirdea (8):
  Input: goodix - use actual config length for each device type
  Input: goodix - reset device at init
  Input: goodix - write configuration data to device
  Input: goodix - add power management support
  Input: goodix - use goodix_i2c_write_u8 instead of i2c_master_send
  Input: goodix - add support for ESD
  Input: goodix - add sysfs interface to dump config
  Input: goodix - add runtime power management support

 .../bindings/input/touchscreen/goodix.txt  |  13 +
 drivers/input/touchscreen/Kconfig  |   1 +
 drivers/input/touchscreen/goodix.c | 766 -
 3 files changed, 742 insertions(+), 38 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v11 5/8] Input: goodix - use goodix_i2c_write_u8 instead of i2c_master_send

2015-11-19 Thread Irina Tirdea
Use goodix_i2c_write_u8 instead of i2c_master_send to simplify code.

Signed-off-by: Irina Tirdea 
Tested-by: Bastien Nocera 
Tested-by: Aleksei Mamlin 
---
 drivers/input/touchscreen/goodix.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 0fd472d..9b7f2ad 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -275,16 +275,11 @@ static void goodix_process_events(struct goodix_ts_data 
*ts)
  */
 static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
 {
-   static const u8 end_cmd[] = {
-   GOODIX_READ_COOR_ADDR >> 8,
-   GOODIX_READ_COOR_ADDR & 0xff,
-   0
-   };
struct goodix_ts_data *ts = dev_id;
 
goodix_process_events(ts);
 
-   if (i2c_master_send(ts->client, end_cmd, sizeof(end_cmd)) < 0)
+   if (goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0) < 0)
dev_err(>client->dev, "I2C write end_cmd error\n");
 
return IRQ_HANDLED;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v11 8/8] Input: goodix - add runtime power management support

2015-11-19 Thread Irina Tirdea
Add support for runtime power management so that the device is
turned off when not used (when the userspace holds no open
handles of the input device). The device uses autosuspend with a
default delay of 2 seconds, so the device will suspend if no
handles to it are open for 2 seconds.

The runtime management support is only available if the gpio pins
are properly initialized from ACPI/DT.

Signed-off-by: Irina Tirdea 
---
 drivers/input/touchscreen/goodix.c | 159 +
 1 file changed, 145 insertions(+), 14 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index ea5042f..a793b8c 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct goodix_ts_data {
@@ -48,6 +49,10 @@ struct goodix_ts_data {
unsigned long irq_flags;
atomic_t esd_timeout;
struct delayed_work esd_work;
+   bool suspended;
+   atomic_t open_count;
+   /* Protects power management calls and access to suspended flag */
+   struct mutex mutex;
 };
 
 #define GOODIX_GPIO_INT_NAME   "irq"
@@ -78,6 +83,8 @@ struct goodix_ts_data {
 #define MAX_CONTACTS_LOC   5
 #define TRIGGER_LOC6
 
+#define GOODIX_AUTOSUSPEND_DELAY_MS2000
+
 static const unsigned long goodix_irq_flags[] = {
IRQ_TYPE_EDGE_RISING,
IRQ_TYPE_EDGE_FALLING,
@@ -193,6 +200,29 @@ static int goodix_get_cfg_len(u16 id)
}
 }
 
+static int goodix_set_power_state(struct goodix_ts_data *ts, bool on)
+{
+   int error;
+
+   if (on) {
+   error = pm_runtime_get_sync(>client->dev);
+   } else {
+   pm_runtime_mark_last_busy(>client->dev);
+   error = pm_runtime_put_autosuspend(>client->dev);
+   }
+
+   if (error < 0) {
+   dev_err(>client->dev,
+   "failed to change power state to %d\n", on);
+   if (on)
+   pm_runtime_put_noidle(>client->dev);
+
+   return error;
+   }
+
+   return 0;
+}
+
 static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
 {
int touch_num;
@@ -501,11 +531,13 @@ static ssize_t goodix_esd_timeout_store(struct device 
*dev,
return error;
 
esd_timeout = atomic_read(>esd_timeout);
-   if (esd_timeout && !new_esd_timeout)
+   if (esd_timeout && !new_esd_timeout &&
+   pm_runtime_active(>client->dev))
goodix_disable_esd(ts);
 
atomic_set(>esd_timeout, new_esd_timeout);
-   if (!esd_timeout && new_esd_timeout)
+   if (!esd_timeout && new_esd_timeout &&
+   pm_runtime_active(>client->dev))
goodix_enable_esd(ts);
 
return count;
@@ -518,17 +550,23 @@ static ssize_t goodix_dump_config_show(struct device *dev,
u8 config[GOODIX_CONFIG_MAX_LENGTH];
int error, count = 0, i;
 
+   error = goodix_set_power_state(ts, true);
+   if (error)
+   return error;
error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA,
config, ts->cfg_len);
if (error) {
dev_warn(>client->dev,
 "Error reading config (%d)\n",  error);
+   goodix_set_power_state(ts, false);
return error;
}
+   goodix_set_power_state(ts, false);
 
for (i = 0; i < ts->cfg_len; i++)
count += scnprintf(buf + count, PAGE_SIZE - count, "%02x ",
   config[i]);
+
return count;
 }
 
@@ -547,6 +585,34 @@ static const struct attribute_group goodix_attr_group = {
.attrs = goodix_attrs,
 };
 
+static int goodix_open(struct input_dev *input_dev)
+{
+   struct goodix_ts_data *ts = input_get_drvdata(input_dev);
+   int error;
+
+   if (!ts->gpiod_int || !ts->gpiod_rst)
+   return 0;
+
+   wait_for_completion(>firmware_loading_complete);
+
+   error = goodix_set_power_state(ts, true);
+   if (error)
+   return error;
+   atomic_inc(>open_count);
+   return 0;
+}
+
+static void goodix_close(struct input_dev *input_dev)
+{
+   struct goodix_ts_data *ts = input_get_drvdata(input_dev);
+
+   if (!ts->gpiod_int || !ts->gpiod_rst)
+   return;
+
+   goodix_set_power_state(ts, false);
+   atomic_dec(>open_count);
+}
+
 /**
  * goodix_get_gpio_config - Get GPIO config from ACPI/DT
  *
@@ -718,6 +784,9 @@ static int goodix_request_input_dev(struct goodix_ts_data 
*ts)
ts->input_dev->id.vendor = 0x0416;
ts->input_dev->id.product = ts->id;
ts->input_dev->id.version = t

[PATCH v11 3/8] Input: goodix - write configuration data to device

2015-11-19 Thread Irina Tirdea
Goodix devices can be configured by writing custom data to the device at
init. The configuration data is read with request_firmware from
"goodix__cfg.bin", where  is the product id read from the device
(e.g.: goodix_911_cfg.bin for Goodix GT911, goodix_9271_cfg.bin for
GT9271).

The configuration information has a specific format described in the Goodix
datasheet. It includes X/Y resolution, maximum supported touch points,
interrupt flags, various sensitivity factors and settings for advanced
features (like gesture recognition).

Before writing the firmware, it is necessary to reset the device. If
the device ACPI/DT information does not declare gpio pins (needed for
reset), writing the firmware will not be available for these devices.

This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).

Signed-off-by: Octavian Purdila 
Signed-off-by: Irina Tirdea 
---
 drivers/input/touchscreen/goodix.c | 247 -
 1 file changed, 215 insertions(+), 32 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 4744032..0911b0c9 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -16,6 +16,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +41,10 @@ struct goodix_ts_data {
int cfg_len;
struct gpio_desc *gpiod_int;
struct gpio_desc *gpiod_rst;
+   u16 id;
+   u16 version;
+   char *cfg_name;
+   struct completion firmware_loading_complete;
 };
 
 #define GOODIX_GPIO_INT_NAME   "irq"
@@ -124,6 +129,39 @@ static int goodix_i2c_read(struct i2c_client *client,
return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
 }
 
+/**
+ * goodix_i2c_write - write data to a register of the i2c slave device.
+ *
+ * @client: i2c device.
+ * @reg: the register to write to.
+ * @buf: raw data buffer to write.
+ * @len: length of the buffer to write
+ */
+static int goodix_i2c_write(struct i2c_client *client, u16 reg, const u8 *buf,
+   unsigned len)
+{
+   u8 *addr_buf;
+   struct i2c_msg msg;
+   int ret;
+
+   addr_buf = kmalloc(len + 2, GFP_KERNEL);
+   if (!addr_buf)
+   return -ENOMEM;
+
+   addr_buf[0] = reg >> 8;
+   addr_buf[1] = reg & 0xFF;
+   memcpy(_buf[2], buf, len);
+
+   msg.flags = 0;
+   msg.addr = client->addr;
+   msg.buf = addr_buf;
+   msg.len = len + 2;
+
+   ret = i2c_transfer(client->adapter, , 1);
+   kfree(addr_buf);
+   return ret < 0 ? ret : (ret != 1 ? -EIO : 0);
+}
+
 static int goodix_get_cfg_len(u16 id)
 {
switch (id) {
@@ -243,6 +281,73 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void 
*dev_id)
return IRQ_HANDLED;
 }
 
+/**
+ * goodix_check_cfg - Checks if config fw is valid
+ *
+ * @ts: goodix_ts_data pointer
+ * @cfg: firmware config data
+ */
+static int goodix_check_cfg(struct goodix_ts_data *ts,
+   const struct firmware *cfg)
+{
+   int i, raw_cfg_len;
+   u8 check_sum = 0;
+
+   if (cfg->size > GOODIX_CONFIG_MAX_LENGTH) {
+   dev_err(>client->dev,
+   "The length of the config fw is not correct");
+   return -EINVAL;
+   }
+
+   raw_cfg_len = cfg->size - 2;
+   for (i = 0; i < raw_cfg_len; i++)
+   check_sum += cfg->data[i];
+   check_sum = (~check_sum) + 1;
+   if (check_sum != cfg->data[raw_cfg_len]) {
+   dev_err(>client->dev,
+   "The checksum of the config fw is not correct");
+   return -EINVAL;
+   }
+
+   if (cfg->data[raw_cfg_len + 1] != 1) {
+   dev_err(>client->dev,
+   "Config fw must have Config_Fresh register set");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+/**
+ * goodix_send_cfg - Write fw config to device
+ *
+ * @ts: goodix_ts_data pointer
+ * @cfg: config firmware to write to device
+ */
+static int goodix_send_cfg(struct goodix_ts_data *ts,
+  const struct firmware *cfg)
+{
+   int error;
+
+   error = goodix_check_cfg(ts, cfg);
+   if (error)
+   return error;
+
+   error = goodix_i2c_write(ts->client, GOODIX_REG_CONFIG_DATA, cfg->data,
+cfg->size);
+   if (error) {
+   dev_err(>client->dev, "Failed to write config data: %d",
+   error);
+   return error;
+   }
+   dev_dbg(>client->dev, "Config sent successfully.");
+
+   /* Let the firmware reconfigure itself, so sleep for 10ms */
+   usleep_range(1, 11000);
+
+  

[PATCH v11 2/8] Input: goodix - reset device at init

2015-11-19 Thread Irina Tirdea
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.

This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).

For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.

For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).

For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...

Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)

GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x,
"\\I2C0", 0x00, ResourceConsumer, ,
 )
 {   // Pin list
 0
 }

GpioIo (Exclusive, PullDown, 0x, 0x,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
 1
}
})
Return (RBUF)
}

Name (_DSD,  Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
    ...
}
}

Signed-off-by: Octavian Purdila 
Signed-off-by: Irina Tirdea 
---
 .../bindings/input/touchscreen/goodix.txt  |   9 ++
 drivers/input/touchscreen/Kconfig  |   1 +
 drivers/input/touchscreen/goodix.c | 101 +
 3 files changed, 111 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt 
b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
index 8ba98ee..c42d2ce 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
@@ -13,6 +13,12 @@ Required properties:
  - interrupt-parent: Interrupt controller to which the chip is connected
  - interrupts  : Interrupt to which the chip is connected
 
+Optional properties:
+
+ - irq-gpios   : GPIO pin used for IRQ. The driver uses the
+ interrupt gpio pin as output to reset the device.
+ - reset-gpios : GPIO pin used for reset
+
 Example:
 
i2c@ {
@@ -23,6 +29,9 @@ Example:
reg = <0x5d>;
interrupt-parent = <>;
interrupts = <0 0>;
+
+   irq-gpios = < 0 0>;
+   reset-gpios = < 1 0>;
};
 
/* ... */
diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index 2ccc522..121a0ac 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -324,6 +324,7 @@ config TOUCHSCREEN_FUJITSU
 config TOUCHSCREEN_GOODIX
tristate "Goodix I2C touchscreen"
depends on I2C
+   depends on GPIOLIB
help
  Say Y here if you have the Goodix touchscreen (such as one
  installed in Onda v975w tablets) connected to your
diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 56d0330..4744032 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -16,6 +16,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,8 +38,13 @@ struct goodix_ts_data {
unsigned int int_trigger_type;
bool rotated_screen;
int cfg_len;
+   struct gpio_desc *gpiod_int;
+   struct gpio_desc *gpiod_rst;
 };
 
+#define GOODIX_GPI

[PATCH v11 5/8] Input: goodix - use goodix_i2c_write_u8 instead of i2c_master_send

2015-11-19 Thread Irina Tirdea
Use goodix_i2c_write_u8 instead of i2c_master_send to simplify code.

Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
Tested-by: Bastien Nocera <had...@hadess.net>
Tested-by: Aleksei Mamlin <mamli...@gmail.com>
---
 drivers/input/touchscreen/goodix.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 0fd472d..9b7f2ad 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -275,16 +275,11 @@ static void goodix_process_events(struct goodix_ts_data 
*ts)
  */
 static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
 {
-   static const u8 end_cmd[] = {
-   GOODIX_READ_COOR_ADDR >> 8,
-   GOODIX_READ_COOR_ADDR & 0xff,
-   0
-   };
struct goodix_ts_data *ts = dev_id;
 
goodix_process_events(ts);
 
-   if (i2c_master_send(ts->client, end_cmd, sizeof(end_cmd)) < 0)
+   if (goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0) < 0)
dev_err(>client->dev, "I2C write end_cmd error\n");
 
return IRQ_HANDLED;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v11 0/8] Goodix touchscreen enhancements

2015-11-19 Thread Irina Tirdea
This patchset depends on Dmitry's patch that fixes the
GPIO ACPI API[1], so devm_gpiod_get_optional can be properly
used in the code. 

[1] https://lkml.org/lkml/2015/11/11/465

Changes in v11:
 - renamed irq-gpio and reset-gpio to irq-gpios and reset-gpios
 - added Rob's Acked-by for the binding in patch 6.

Changes in v10:
 - use devm_gpiod_get_optional and no longer ignore errors returned
by it
 - use completion to signal other code paths in the driver that
the config firmware is loaded on the device
 - dropped the patch that ordered the includes

Changes in v9:
 - add GPIOLIB to driver dependencies
 - add Tested-by tag from Bastien and Aleksei

Changes in v8:
 - only allow new functionality for devices that declare named
gpios (using _DSD properties in ACPI or named DT properties)

Changes in v7:
 - add dmi quirk to skip gpio pins setup and functionality that
depends on them for Onda v975w, WinBook TW100 and WinBook TW700.
 - add support for named gpio pins
 - rework the runtime pm patch to fix a couple of issues
 - sort includes using inverse Xmas tree ordering

Changes in v6:
 - skip runtime power manangent calls in open/close if the device
ACPI/DT configuration does not declare interrupt and reset gpio pins.
 - reset the device before starting i2c communication
 - add Bastien's ack to the first 2 patches

Changes in v5:
 - add some more style cleanup (reorder includes, use error instead
of ret for return values)
 - add runtime power management patch

Changes in v4:
 - use dmi quirk to determine the order of irq and reset pins
 - use actual config length depending on device
 - add sysfs interface to dump config
 - initialize esd timeout from ACPI/DT properly

Changes in v3:
 - dropped the first 3 patches that got merged
 - handle -EPROBE_DEFER and -ENOENT for gpio pins
 - skip functionality depending on the gpio pins if the pins are not
properly initialized from ACPI/DT (reset, write config, power management,
ESD)
 - dropped #ifdef CONFIG_PM_SLEEP and annotated with __maybe_unused instead
 - use sysfs property to set ESD timeout instead of ACPI/DT property
 - use request_firmware_nowait to read configuration firmware and use
defaults if firmware is not found
 - use ACPI IDs to determine the order of the GPIO pins in the ACPI tables
(interrupt pin first or reset pin first)

Changes in v2:
 - use request_firmware instead of ACPI/DT property for config
 - dropped "input: goodix: add ACPI IDs for GT911 and GT9271" patch
 - add ACPI DSDT excerpt in commit message where necessary
 - add comments for suspend/resume sleep values
 - dropped the checkpatch fixes that did not make sense
 - added Bastien's ack to the first patch

Irina Tirdea (8):
  Input: goodix - use actual config length for each device type
  Input: goodix - reset device at init
  Input: goodix - write configuration data to device
  Input: goodix - add power management support
  Input: goodix - use goodix_i2c_write_u8 instead of i2c_master_send
  Input: goodix - add support for ESD
  Input: goodix - add sysfs interface to dump config
  Input: goodix - add runtime power management support

 .../bindings/input/touchscreen/goodix.txt  |  13 +
 drivers/input/touchscreen/Kconfig  |   1 +
 drivers/input/touchscreen/goodix.c | 766 -
 3 files changed, 742 insertions(+), 38 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v11 3/8] Input: goodix - write configuration data to device

2015-11-19 Thread Irina Tirdea
Goodix devices can be configured by writing custom data to the device at
init. The configuration data is read with request_firmware from
"goodix__cfg.bin", where  is the product id read from the device
(e.g.: goodix_911_cfg.bin for Goodix GT911, goodix_9271_cfg.bin for
GT9271).

The configuration information has a specific format described in the Goodix
datasheet. It includes X/Y resolution, maximum supported touch points,
interrupt flags, various sensitivity factors and settings for advanced
features (like gesture recognition).

Before writing the firmware, it is necessary to reset the device. If
the device ACPI/DT information does not declare gpio pins (needed for
reset), writing the firmware will not be available for these devices.

This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).

Signed-off-by: Octavian Purdila <octavian.purd...@intel.com>
Signed-off-by: Irina Tirdea <irina.tir...@intel.com>
---
 drivers/input/touchscreen/goodix.c | 247 -
 1 file changed, 215 insertions(+), 32 deletions(-)

diff --git a/drivers/input/touchscreen/goodix.c 
b/drivers/input/touchscreen/goodix.c
index 4744032..0911b0c9 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -16,6 +16,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -40,6 +41,10 @@ struct goodix_ts_data {
int cfg_len;
struct gpio_desc *gpiod_int;
struct gpio_desc *gpiod_rst;
+   u16 id;
+   u16 version;
+   char *cfg_name;
+   struct completion firmware_loading_complete;
 };
 
 #define GOODIX_GPIO_INT_NAME   "irq"
@@ -124,6 +129,39 @@ static int goodix_i2c_read(struct i2c_client *client,
return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
 }
 
+/**
+ * goodix_i2c_write - write data to a register of the i2c slave device.
+ *
+ * @client: i2c device.
+ * @reg: the register to write to.
+ * @buf: raw data buffer to write.
+ * @len: length of the buffer to write
+ */
+static int goodix_i2c_write(struct i2c_client *client, u16 reg, const u8 *buf,
+   unsigned len)
+{
+   u8 *addr_buf;
+   struct i2c_msg msg;
+   int ret;
+
+   addr_buf = kmalloc(len + 2, GFP_KERNEL);
+   if (!addr_buf)
+   return -ENOMEM;
+
+   addr_buf[0] = reg >> 8;
+   addr_buf[1] = reg & 0xFF;
+   memcpy(_buf[2], buf, len);
+
+   msg.flags = 0;
+   msg.addr = client->addr;
+   msg.buf = addr_buf;
+   msg.len = len + 2;
+
+   ret = i2c_transfer(client->adapter, , 1);
+   kfree(addr_buf);
+   return ret < 0 ? ret : (ret != 1 ? -EIO : 0);
+}
+
 static int goodix_get_cfg_len(u16 id)
 {
switch (id) {
@@ -243,6 +281,73 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void 
*dev_id)
return IRQ_HANDLED;
 }
 
+/**
+ * goodix_check_cfg - Checks if config fw is valid
+ *
+ * @ts: goodix_ts_data pointer
+ * @cfg: firmware config data
+ */
+static int goodix_check_cfg(struct goodix_ts_data *ts,
+   const struct firmware *cfg)
+{
+   int i, raw_cfg_len;
+   u8 check_sum = 0;
+
+   if (cfg->size > GOODIX_CONFIG_MAX_LENGTH) {
+   dev_err(>client->dev,
+   "The length of the config fw is not correct");
+   return -EINVAL;
+   }
+
+   raw_cfg_len = cfg->size - 2;
+   for (i = 0; i < raw_cfg_len; i++)
+   check_sum += cfg->data[i];
+   check_sum = (~check_sum) + 1;
+   if (check_sum != cfg->data[raw_cfg_len]) {
+   dev_err(>client->dev,
+   "The checksum of the config fw is not correct");
+   return -EINVAL;
+   }
+
+   if (cfg->data[raw_cfg_len + 1] != 1) {
+   dev_err(>client->dev,
+   "Config fw must have Config_Fresh register set");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+/**
+ * goodix_send_cfg - Write fw config to device
+ *
+ * @ts: goodix_ts_data pointer
+ * @cfg: config firmware to write to device
+ */
+static int goodix_send_cfg(struct goodix_ts_data *ts,
+  const struct firmware *cfg)
+{
+   int error;
+
+   error = goodix_check_cfg(ts, cfg);
+   if (error)
+   return error;
+
+   error = goodix_i2c_write(ts->client, GOODIX_REG_CONFIG_DATA, cfg->data,
+cfg->size);
+   if (error) {
+   dev_err(>client->dev, "Failed to write config data: %d",
+   error);
+   return error;
+   }
+   dev_dbg(>client->dev, "Config sent successfully.");
+
+   /* Let the firmware reconfigure itself, so sleep for 

  1   2   3   4   5   6   7   8   9   >