[PATCH v3 05/14] metag: use of_platform_default_populate() to populate default bus

2016-04-04 Thread Kefeng Wang
Use helper of_platform_default_populate() in linux/of_platform
when possible, instead of calling of_platform_populate() with
the default match table.

Acked-by: James Hogan 
Cc: James Hogan 
Signed-off-by: Kefeng Wang 
---
 arch/metag/kernel/setup.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/metag/kernel/setup.c b/arch/metag/kernel/setup.c
index 31cf53d..c88f937 100644
--- a/arch/metag/kernel/setup.c
+++ b/arch/metag/kernel/setup.c
@@ -415,8 +415,7 @@ static int __init customize_machine(void)
if (machine_desc->init_machine)
machine_desc->init_machine();
else
-   of_platform_populate(NULL, of_default_bus_match_table, NULL,
-NULL);
+   of_platform_default_populate(NULL, NULL, NULL);
return 0;
 }
 arch_initcall(customize_machine);
-- 
2.6.0.GIT



Re: [PATCH 1/2] qcom: ipq4019: Add regulator support to DK04 device tree

2016-04-04 Thread Andy Gross
On Mon, Apr 04, 2016 at 02:08:10PM -0700, Sreedhar Sambangi wrote:
> This adds the regulator nodes to DK04 device tree to support
> 
> Change-Id: I9c1df0e720a330bf6db1889fd2247f6a70ea6faa
> Signed-off-by: Sreedhar Sambangi 
> ---
>  .../bindings/regulator/ipq4019-regulator.txt  | 19 
> +++
>  arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi | 11 +++
>  2 files changed, 30 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/regulator/ipq4019-regulator.txt
> 
> diff --git 
> a/Documentation/devicetree/bindings/regulator/ipq4019-regulator.txt 
> b/Documentation/devicetree/bindings/regulator/ipq4019-regulator.txt
> new file mode 100644
> index 000..9d934a4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/ipq4019-regulator.txt
> @@ -0,0 +1,19 @@
> +* Qualcomm Technologies, Inc. IPQ4019 regulators
> +
> +Required properties:
> +- compatible : Must be "regulator-ipq4019".
> +- states : Selection of available voltages and corresponding 
> values
> +- reg: Register address for controlling LDO
> +- mask   : Mask value for switching voltages
> +Example:

How many LDOs are there on the IPQ4019?  Can you document all of the supplies?
You can figure this out by looking for the vdd pins in the chip documentation

> +
> + vccq_sd0: regulator@0 {
> + compatible = "qcom,regulator-ipq4019";
> + regulator-name = "SD0 VccQ";
> + regulator-min-microvolt = <180>;
> + regulator-max-microvolt = <300>;
> + states = <300 0x3
> + 180 0x1>;

So there are only 2 states?  No linear range from 1.8 to 3.3?

> + reg = <0x01948000 0x4>;
> + mask = <0x3>;
> + };


[PATCH v3 05/14] metag: use of_platform_default_populate() to populate default bus

2016-04-04 Thread Kefeng Wang
Use helper of_platform_default_populate() in linux/of_platform
when possible, instead of calling of_platform_populate() with
the default match table.

Acked-by: James Hogan 
Cc: James Hogan 
Signed-off-by: Kefeng Wang 
---
 arch/metag/kernel/setup.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/metag/kernel/setup.c b/arch/metag/kernel/setup.c
index 31cf53d..c88f937 100644
--- a/arch/metag/kernel/setup.c
+++ b/arch/metag/kernel/setup.c
@@ -415,8 +415,7 @@ static int __init customize_machine(void)
if (machine_desc->init_machine)
machine_desc->init_machine();
else
-   of_platform_populate(NULL, of_default_bus_match_table, NULL,
-NULL);
+   of_platform_default_populate(NULL, NULL, NULL);
return 0;
 }
 arch_initcall(customize_machine);
-- 
2.6.0.GIT



Re: [PATCH 1/2] qcom: ipq4019: Add regulator support to DK04 device tree

2016-04-04 Thread Andy Gross
On Mon, Apr 04, 2016 at 02:08:10PM -0700, Sreedhar Sambangi wrote:
> This adds the regulator nodes to DK04 device tree to support
> 
> Change-Id: I9c1df0e720a330bf6db1889fd2247f6a70ea6faa
> Signed-off-by: Sreedhar Sambangi 
> ---
>  .../bindings/regulator/ipq4019-regulator.txt  | 19 
> +++
>  arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi | 11 +++
>  2 files changed, 30 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/regulator/ipq4019-regulator.txt
> 
> diff --git 
> a/Documentation/devicetree/bindings/regulator/ipq4019-regulator.txt 
> b/Documentation/devicetree/bindings/regulator/ipq4019-regulator.txt
> new file mode 100644
> index 000..9d934a4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/ipq4019-regulator.txt
> @@ -0,0 +1,19 @@
> +* Qualcomm Technologies, Inc. IPQ4019 regulators
> +
> +Required properties:
> +- compatible : Must be "regulator-ipq4019".
> +- states : Selection of available voltages and corresponding 
> values
> +- reg: Register address for controlling LDO
> +- mask   : Mask value for switching voltages
> +Example:

How many LDOs are there on the IPQ4019?  Can you document all of the supplies?
You can figure this out by looking for the vdd pins in the chip documentation

> +
> + vccq_sd0: regulator@0 {
> + compatible = "qcom,regulator-ipq4019";
> + regulator-name = "SD0 VccQ";
> + regulator-min-microvolt = <180>;
> + regulator-max-microvolt = <300>;
> + states = <300 0x3
> + 180 0x1>;

So there are only 2 states?  No linear range from 1.8 to 3.3?

> + reg = <0x01948000 0x4>;
> + mask = <0x3>;
> + };


[PATCH v3 07/14] nios2: use of_platform_default_populate() to populate default bus

2016-04-04 Thread Kefeng Wang
Use helper of_platform_default_populate() in linux/of_platform
when possible, instead of calling of_platform_populate() with
the default match table.

Cc: Ley Foon Tan 
Signed-off-by: Kefeng Wang 
---
 arch/nios2/platform/platform.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/nios2/platform/platform.c b/arch/nios2/platform/platform.c
index d478773..c62279c 100644
--- a/arch/nios2/platform/platform.c
+++ b/arch/nios2/platform/platform.c
@@ -39,8 +39,7 @@ static int __init nios2_soc_device_init(void)
}
}
 
-   return of_platform_populate(NULL, of_default_bus_match_table,
-   NULL, NULL);
+   return of_platform_default_populate(NULL, NULL, NULL);
 }
 
 device_initcall(nios2_soc_device_init);
-- 
2.6.0.GIT



[PATCH v3 07/14] nios2: use of_platform_default_populate() to populate default bus

2016-04-04 Thread Kefeng Wang
Use helper of_platform_default_populate() in linux/of_platform
when possible, instead of calling of_platform_populate() with
the default match table.

Cc: Ley Foon Tan 
Signed-off-by: Kefeng Wang 
---
 arch/nios2/platform/platform.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/nios2/platform/platform.c b/arch/nios2/platform/platform.c
index d478773..c62279c 100644
--- a/arch/nios2/platform/platform.c
+++ b/arch/nios2/platform/platform.c
@@ -39,8 +39,7 @@ static int __init nios2_soc_device_init(void)
}
}
 
-   return of_platform_populate(NULL, of_default_bus_match_table,
-   NULL, NULL);
+   return of_platform_default_populate(NULL, NULL, NULL);
 }
 
 device_initcall(nios2_soc_device_init);
-- 
2.6.0.GIT



[PATCH v3 00/14] use of_platform_default_populate() to populate default bus

2016-04-04 Thread Kefeng Wang
Use helper of_platform_default_populate() in linux/of_platform
when possible, instead of calling of_platform_populate() with
the default match table.

Then it is possible for driver code build as a module, and no
need to export of_default_bus_match_table anymore.

This patchset is based on Linux 4.6-rc2.

Changes since v2:
- Add more acks
- Update based on v4.6-rc2, of-generic.c in sh and board-artpec6.c in arm
  are considered

Changes since v1:
- Add ack, test and review
- Remove v1 patch 14/15, the similar patch has posted and applied,
  see https://patchwork.kernel.org/patch/8096991/

v1:
- https://lkml.org/lkml/2016/1/26/1123

Kefeng Wang (14):
  arm: use of_platform_default_populate() to populate default bus
  arm64: use of_platform_default_populate() to populate default bus
  mips: use of_platform_default_populate() to populate default bus
  c6x: use of_platform_default_populate() to populate default bus
  metag: use of_platform_default_populate() to populate default bus
  cris: use of_platform_default_populate() to populate default bus
  nios2: use of_platform_default_populate() to populate default bus
  xtensa: use of_platform_default_populate() to populate default bus
  sh: use of_platform_default_populate() to populate default bus
  bus: imx-weim: use of_platform_default_populate() to populate default
bus
  bus: uniphier-system-bus: use of_platform_default_populate() to
populate default bus
  memory: omap-gpmc: use of_platform_default_populate() to populate
default bus
  of: unittest: use of_platform_default_populate() to populate default
bus
  Revert "of/platform: export of_default_bus_match_table"

 arch/arm/kernel/setup.c  | 3 +--
 arch/arm/mach-artpec/board-artpec6.c | 2 +-
 arch/arm/mach-at91/at91rm9200.c  | 2 +-
 arch/arm/mach-at91/at91sam9.c| 2 +-
 arch/arm/mach-at91/sama5.c   | 2 +-
 arch/arm/mach-bcm/board_bcm21664.c   | 2 +-
 arch/arm/mach-bcm/board_bcm281xx.c   | 2 +-
 arch/arm/mach-bcm/board_bcm2835.c| 5 ++---
 arch/arm/mach-cns3xxx/core.c | 3 +--
 arch/arm/mach-davinci/da8xx-dt.c | 3 +--
 arch/arm/mach-exynos/exynos.c| 2 +-
 arch/arm/mach-highbank/highbank.c| 2 +-
 arch/arm/mach-imx/imx27-dt.c | 2 +-
 arch/arm/mach-imx/mach-imx51.c   | 2 +-
 arch/arm/mach-imx/mach-imx53.c   | 2 +-
 arch/arm/mach-imx/mach-imx6q.c   | 2 +-
 arch/arm/mach-imx/mach-imx6sl.c  | 2 +-
 arch/arm/mach-imx/mach-imx6sx.c  | 2 +-
 arch/arm/mach-imx/mach-imx6ul.c  | 2 +-
 arch/arm/mach-imx/mach-imx7d.c   | 2 +-
 arch/arm/mach-integrator/integrator_ap.c | 3 +--
 arch/arm/mach-integrator/integrator_cp.c | 3 +--
 arch/arm/mach-keystone/keystone.c| 2 +-
 arch/arm/mach-lpc32xx/phy3250.c  | 3 +--
 arch/arm/mach-mvebu/board-v7.c   | 2 +-
 arch/arm/mach-mvebu/dove.c   | 2 +-
 arch/arm/mach-mvebu/kirkwood.c   | 2 +-
 arch/arm/mach-mxs/mach-mxs.c | 3 +--
 arch/arm/mach-nspire/nspire.c| 3 +--
 arch/arm/mach-orion5x/board-dt.c | 3 +--
 arch/arm/mach-picoxcell/common.c | 2 +-
 arch/arm/mach-rockchip/rockchip.c| 2 +-
 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c  | 2 +-
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c  | 2 +-
 arch/arm/mach-shmobile/setup-r8a7740.c   | 3 +--
 arch/arm/mach-shmobile/setup-sh73a0.c| 2 +-
 arch/arm/mach-spear/spear1310.c  | 2 +-
 arch/arm/mach-spear/spear1340.c  | 2 +-
 arch/arm/mach-spear/spear300.c   | 3 +--
 arch/arm/mach-spear/spear310.c   | 3 +--
 arch/arm/mach-spear/spear320.c   | 3 +--
 arch/arm/mach-spear/spear6xx.c   | 3 +--
 arch/arm/mach-tegra/tegra.c  | 2 +-
 arch/arm/mach-u300/core.c| 3 +--
 arch/arm/mach-versatile/versatile_dt.c   | 3 +--
 arch/arm/mach-vt8500/vt8500.c| 2 +-
 arch/arm/mach-zynq/common.c  | 2 +-
 arch/arm64/kernel/setup.c| 3 +--
 arch/c6x/platforms/platform.c| 2 +-
 arch/cris/kernel/setup.c | 2 +-
 arch/metag/kernel/setup.c| 3 +--
 arch/mips/ath79/setup.c  | 2 +-
 arch/mips/jz4740/setup.c | 2 +-
 arch/mips/mti-sead3/sead3-setup.c| 2 +-
 arch/mips/pic32/pic32mzda/init.c | 3 +--
 arch/mips/pistachio/init.c   | 2 +-
 arch/mips/xilfpga/init.c | 2 +-
 arch/nios2/platform/platform.c   | 3 +--
 arch/sh/boards/of-generic.c  | 3 +--
 arch/xtensa/kernel/setup.c   | 2 +-
 drivers/bus/imx-weim.c   | 5 ++---
 drivers/bus/uniphier-system-bus.c| 3 +--
 drivers/memory/omap-gpmc.c   | 3 +--
 drivers/of/platform.c| 1 -
 drivers/of/unittest.c| 5 ++---
 65 files changed, 67 insertions(+), 94 deletions(-)

-- 
2.6.0.GIT



[PATCH v3 00/14] use of_platform_default_populate() to populate default bus

2016-04-04 Thread Kefeng Wang
Use helper of_platform_default_populate() in linux/of_platform
when possible, instead of calling of_platform_populate() with
the default match table.

Then it is possible for driver code build as a module, and no
need to export of_default_bus_match_table anymore.

This patchset is based on Linux 4.6-rc2.

Changes since v2:
- Add more acks
- Update based on v4.6-rc2, of-generic.c in sh and board-artpec6.c in arm
  are considered

Changes since v1:
- Add ack, test and review
- Remove v1 patch 14/15, the similar patch has posted and applied,
  see https://patchwork.kernel.org/patch/8096991/

v1:
- https://lkml.org/lkml/2016/1/26/1123

Kefeng Wang (14):
  arm: use of_platform_default_populate() to populate default bus
  arm64: use of_platform_default_populate() to populate default bus
  mips: use of_platform_default_populate() to populate default bus
  c6x: use of_platform_default_populate() to populate default bus
  metag: use of_platform_default_populate() to populate default bus
  cris: use of_platform_default_populate() to populate default bus
  nios2: use of_platform_default_populate() to populate default bus
  xtensa: use of_platform_default_populate() to populate default bus
  sh: use of_platform_default_populate() to populate default bus
  bus: imx-weim: use of_platform_default_populate() to populate default
bus
  bus: uniphier-system-bus: use of_platform_default_populate() to
populate default bus
  memory: omap-gpmc: use of_platform_default_populate() to populate
default bus
  of: unittest: use of_platform_default_populate() to populate default
bus
  Revert "of/platform: export of_default_bus_match_table"

 arch/arm/kernel/setup.c  | 3 +--
 arch/arm/mach-artpec/board-artpec6.c | 2 +-
 arch/arm/mach-at91/at91rm9200.c  | 2 +-
 arch/arm/mach-at91/at91sam9.c| 2 +-
 arch/arm/mach-at91/sama5.c   | 2 +-
 arch/arm/mach-bcm/board_bcm21664.c   | 2 +-
 arch/arm/mach-bcm/board_bcm281xx.c   | 2 +-
 arch/arm/mach-bcm/board_bcm2835.c| 5 ++---
 arch/arm/mach-cns3xxx/core.c | 3 +--
 arch/arm/mach-davinci/da8xx-dt.c | 3 +--
 arch/arm/mach-exynos/exynos.c| 2 +-
 arch/arm/mach-highbank/highbank.c| 2 +-
 arch/arm/mach-imx/imx27-dt.c | 2 +-
 arch/arm/mach-imx/mach-imx51.c   | 2 +-
 arch/arm/mach-imx/mach-imx53.c   | 2 +-
 arch/arm/mach-imx/mach-imx6q.c   | 2 +-
 arch/arm/mach-imx/mach-imx6sl.c  | 2 +-
 arch/arm/mach-imx/mach-imx6sx.c  | 2 +-
 arch/arm/mach-imx/mach-imx6ul.c  | 2 +-
 arch/arm/mach-imx/mach-imx7d.c   | 2 +-
 arch/arm/mach-integrator/integrator_ap.c | 3 +--
 arch/arm/mach-integrator/integrator_cp.c | 3 +--
 arch/arm/mach-keystone/keystone.c| 2 +-
 arch/arm/mach-lpc32xx/phy3250.c  | 3 +--
 arch/arm/mach-mvebu/board-v7.c   | 2 +-
 arch/arm/mach-mvebu/dove.c   | 2 +-
 arch/arm/mach-mvebu/kirkwood.c   | 2 +-
 arch/arm/mach-mxs/mach-mxs.c | 3 +--
 arch/arm/mach-nspire/nspire.c| 3 +--
 arch/arm/mach-orion5x/board-dt.c | 3 +--
 arch/arm/mach-picoxcell/common.c | 2 +-
 arch/arm/mach-rockchip/rockchip.c| 2 +-
 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c  | 2 +-
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c  | 2 +-
 arch/arm/mach-shmobile/setup-r8a7740.c   | 3 +--
 arch/arm/mach-shmobile/setup-sh73a0.c| 2 +-
 arch/arm/mach-spear/spear1310.c  | 2 +-
 arch/arm/mach-spear/spear1340.c  | 2 +-
 arch/arm/mach-spear/spear300.c   | 3 +--
 arch/arm/mach-spear/spear310.c   | 3 +--
 arch/arm/mach-spear/spear320.c   | 3 +--
 arch/arm/mach-spear/spear6xx.c   | 3 +--
 arch/arm/mach-tegra/tegra.c  | 2 +-
 arch/arm/mach-u300/core.c| 3 +--
 arch/arm/mach-versatile/versatile_dt.c   | 3 +--
 arch/arm/mach-vt8500/vt8500.c| 2 +-
 arch/arm/mach-zynq/common.c  | 2 +-
 arch/arm64/kernel/setup.c| 3 +--
 arch/c6x/platforms/platform.c| 2 +-
 arch/cris/kernel/setup.c | 2 +-
 arch/metag/kernel/setup.c| 3 +--
 arch/mips/ath79/setup.c  | 2 +-
 arch/mips/jz4740/setup.c | 2 +-
 arch/mips/mti-sead3/sead3-setup.c| 2 +-
 arch/mips/pic32/pic32mzda/init.c | 3 +--
 arch/mips/pistachio/init.c   | 2 +-
 arch/mips/xilfpga/init.c | 2 +-
 arch/nios2/platform/platform.c   | 3 +--
 arch/sh/boards/of-generic.c  | 3 +--
 arch/xtensa/kernel/setup.c   | 2 +-
 drivers/bus/imx-weim.c   | 5 ++---
 drivers/bus/uniphier-system-bus.c| 3 +--
 drivers/memory/omap-gpmc.c   | 3 +--
 drivers/of/platform.c| 1 -
 drivers/of/unittest.c| 5 ++---
 65 files changed, 67 insertions(+), 94 deletions(-)

-- 
2.6.0.GIT



RE: [PATCH] drivers/idle: make intel_idle.c driver more explicitly non-modular

2016-04-04 Thread Brown, Len


> -Original Message-
> From: rcoch...@linutronix.de [mailto:rcoch...@linutronix.de]
> Sent: Tuesday, April 05, 2016 12:30 AM
> To: Brown, Len
> Cc: Gortmaker, Paul (Wind River); linux-kernel@vger.kernel.org; Len Brown;
> linux...@vger.kernel.org
> Subject: Re: [PATCH] drivers/idle: make intel_idle.c driver more
> explicitly non-modular
> 
> On Tue, Apr 05, 2016 at 04:20:47AM +, Brown, Len wrote:
> > The first idle driver to register with cpuidle wins.
> >
> > intel_idle should always get the opportunity
> > to probe and register before acpi_idle (processor_idle.c)
> >
> > When intel_idle was allowed to be modular,
> > some distros build their kernel and loaded modules
> > such that acpi_idle could probe first.  In such
> > a kernel, intel_idle became dead code.
> >
> > As intel_idle is a small driver, the q  uick fix
> > was to make it Y/N so that it would always probe
> > before acpi_idle, no matter how acpi_idle
> > is build and loaded.
> >
> > Yes, even though intel_idle is a tiny driver, I think
> > it would be good to be able to unload it when it doesn't probe.
> 
> And that means fixing the race with acpi_idle, right?
> 
> > Today, it appears that acpi_idle (acpi/processor_idle.c)
> > is compiled Y/N.
> 
> So it, too, needs work?

"needs" is somewhat subjective.
Some may argue that this driver is so small,
that an effort to save memory might be more effectively
directed elsewhere.  But if the goal is to save the memory
consumed by this driver when the driver doesn't probe,
then yes, it would have to be made modular.

I don't remember what ACPI dependency made it non-modular.
ACPI has some tricky initialization ordering issues
that are BIOS dependent, and sometimes out of our control.

> > No, I do not believe that cpuidle should bother
> > supporting changing idle drivers at run-time.
> 
> Huh?  But you just said, "it would be good to be able to unload it
> when it doesn't probe."

being able to switch the registered driver at run-time
does not require the driver to be modular.

cheers,
-Len




Re: [PATCH 2/2] qcom: ipq4019: Add LDO regulator driver for SDHC controller

2016-04-04 Thread Andy Gross
On Mon, Apr 04, 2016 at 02:08:24PM -0700, Sreedhar Sambangi wrote:
> From: Kirthik Srinivasan 
> 
> Add LDO regulator driver to enable SD /MMC  card to
> switch between 3.0 volts and 1.8 volts
> 
> Change-Id: I66f770878570b1f5b1db044ba626e0f6989acc3f
> Signed-off-by: Kirthik Srinivasan 
> Signed-off-by: Rajith Cherian 
> Signed-off-by: Sreedhar Sambangi 
> ---
>  drivers/regulator/Kconfig |   7 +
>  drivers/regulator/Makefile|   1 +
>  drivers/regulator/ipq4019-regulator.c | 275 
> ++

It'd be good to have the file name have qcom prepended.  See the other qcom
regulators as an example.

>  3 files changed, 283 insertions(+)
>  create mode 100644 drivers/regulator/ipq4019-regulator.c
> 
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index c77dc08..bb44873 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -843,5 +843,12 @@ config REGULATOR_WM8994
> This driver provides support for the voltage regulators on the
> WM8994 CODEC.
>  
> +config REGULATOR_IPQ4019

How bout REGULATOR_QCOM_IPQ4019.
> + tristate "IPQ4019 regulator support"
> + depends on ARCH_QCOM
> + help
> +   This driver provides support for the voltage regulators of the
> +   IPQ40xx devices.
> +
>  endif
>  



> +static int ipq4019_regulator_set_voltage(struct regulator_dev *dev,
> + int min_uV, int max_uV,
> + unsigned *selector)
> +{
> + struct ipq4019_regulator_data *data = rdev_get_drvdata(dev);
> + struct ipq4019_regulator_config *cfg = data->config;
> +
> + int ptr, best_val = INT_MAX, val;
> +
> + for (ptr = 0; ptr < cfg->nr_states; ptr++)
> + if (cfg->states[ptr].range < best_val &&
> + cfg->states[ptr].range >= min_uV &&
> + cfg->states[ptr].range <= max_uV) {
> + best_val = cfg->states[ptr].value;
> + if (selector)
> + *selector = ptr;
> + }
> +
> + if (best_val == INT_MAX)
> + return -EINVAL;
> +
> + val = readl(cfg->base);
> + val  = val & (~(cfg->mask));

val &= mask

> + writel((val | best_val), cfg->base);
> +
> + data->range = cfg->states[ptr].range;
> +
> + return 0;
> +}
> +
> +static int ipq4019_regulator_list_voltage(struct regulator_dev *dev,
> +   unsigned selector)
> +{
> + struct ipq4019_regulator_data *data = rdev_get_drvdata(dev);
> + struct ipq4019_regulator_config *cfg = data->config;
> +
> + if (selector >= cfg->nr_states)
> + return -EINVAL;
> +
> + return cfg->states[selector].range;

If you can define your ranges using LINEAR_RANGE, you can just use the
regulator_list_voltage_linear_range.

> +}
> +
> +static struct regulator_ops ipq4019_regulator_voltage_ops = {
> + .get_voltage = ipq4019_regulator_get_voltage,
> + .set_voltage = ipq4019_regulator_set_voltage,
> + .list_voltage = ipq4019_regulator_list_voltage,

No enable and disable?

> +};
> +
> +static struct ipq4019_regulator_config *
> +of_get_ipq4019_regulator_data(struct device *dev, struct device_node *np, 
> const struct regulator_desc *desc)
> +{
> + struct ipq4019_regulator_config *config;
> + struct property *prop;
> + int proplen, i;
> +
> + config = devm_kzalloc(dev,
> + sizeof(struct ipq4019_regulator_config),
> + GFP_KERNEL);
> + if (!config)
> + return ERR_PTR(-ENOMEM);
> +
> + config->init_data = of_get_regulator_init_data(dev, np, desc);
> + if (!config->init_data)
> + return ERR_PTR(-EINVAL);
> +
> + config->supply_name = config->init_data->constraints.name;
> +
> +
> + /* Fetch states. */
> + prop = of_find_property(np, "states", NULL);
> + if (!prop) {
> + dev_err(dev, "No 'states' property found\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + proplen = prop->length / sizeof(int);
> +
> + config->states = devm_kzalloc(dev,
> + sizeof(struct ipq4019_regulator_state)
> + * (proplen / 2),
> + GFP_KERNEL);
> + if (!config->states)
> + return ERR_PTR(-ENOMEM);
> +
> + for (i = 0; i < proplen / 2; i++) {
> + config->states[i].range =
> + be32_to_cpup((int *)prop->value + (i * 2));
> + config->states[i].value =
> + be32_to_cpup((int *)prop->value + (i * 2 + 1));
> + }
> + config->nr_states = i;

Is it necessary to encode all of this data in the DT?  Is this varied between
boards using the IPQ4019?  Or are these values fixed for this chip?  If they are
fixed, it'd be better to put 

RE: [PATCH] drivers/idle: make intel_idle.c driver more explicitly non-modular

2016-04-04 Thread Brown, Len


> -Original Message-
> From: rcoch...@linutronix.de [mailto:rcoch...@linutronix.de]
> Sent: Tuesday, April 05, 2016 12:30 AM
> To: Brown, Len
> Cc: Gortmaker, Paul (Wind River); linux-kernel@vger.kernel.org; Len Brown;
> linux...@vger.kernel.org
> Subject: Re: [PATCH] drivers/idle: make intel_idle.c driver more
> explicitly non-modular
> 
> On Tue, Apr 05, 2016 at 04:20:47AM +, Brown, Len wrote:
> > The first idle driver to register with cpuidle wins.
> >
> > intel_idle should always get the opportunity
> > to probe and register before acpi_idle (processor_idle.c)
> >
> > When intel_idle was allowed to be modular,
> > some distros build their kernel and loaded modules
> > such that acpi_idle could probe first.  In such
> > a kernel, intel_idle became dead code.
> >
> > As intel_idle is a small driver, the q  uick fix
> > was to make it Y/N so that it would always probe
> > before acpi_idle, no matter how acpi_idle
> > is build and loaded.
> >
> > Yes, even though intel_idle is a tiny driver, I think
> > it would be good to be able to unload it when it doesn't probe.
> 
> And that means fixing the race with acpi_idle, right?
> 
> > Today, it appears that acpi_idle (acpi/processor_idle.c)
> > is compiled Y/N.
> 
> So it, too, needs work?

"needs" is somewhat subjective.
Some may argue that this driver is so small,
that an effort to save memory might be more effectively
directed elsewhere.  But if the goal is to save the memory
consumed by this driver when the driver doesn't probe,
then yes, it would have to be made modular.

I don't remember what ACPI dependency made it non-modular.
ACPI has some tricky initialization ordering issues
that are BIOS dependent, and sometimes out of our control.

> > No, I do not believe that cpuidle should bother
> > supporting changing idle drivers at run-time.
> 
> Huh?  But you just said, "it would be good to be able to unload it
> when it doesn't probe."

being able to switch the registered driver at run-time
does not require the driver to be modular.

cheers,
-Len




Re: [PATCH 2/2] qcom: ipq4019: Add LDO regulator driver for SDHC controller

2016-04-04 Thread Andy Gross
On Mon, Apr 04, 2016 at 02:08:24PM -0700, Sreedhar Sambangi wrote:
> From: Kirthik Srinivasan 
> 
> Add LDO regulator driver to enable SD /MMC  card to
> switch between 3.0 volts and 1.8 volts
> 
> Change-Id: I66f770878570b1f5b1db044ba626e0f6989acc3f
> Signed-off-by: Kirthik Srinivasan 
> Signed-off-by: Rajith Cherian 
> Signed-off-by: Sreedhar Sambangi 
> ---
>  drivers/regulator/Kconfig |   7 +
>  drivers/regulator/Makefile|   1 +
>  drivers/regulator/ipq4019-regulator.c | 275 
> ++

It'd be good to have the file name have qcom prepended.  See the other qcom
regulators as an example.

>  3 files changed, 283 insertions(+)
>  create mode 100644 drivers/regulator/ipq4019-regulator.c
> 
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index c77dc08..bb44873 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -843,5 +843,12 @@ config REGULATOR_WM8994
> This driver provides support for the voltage regulators on the
> WM8994 CODEC.
>  
> +config REGULATOR_IPQ4019

How bout REGULATOR_QCOM_IPQ4019.
> + tristate "IPQ4019 regulator support"
> + depends on ARCH_QCOM
> + help
> +   This driver provides support for the voltage regulators of the
> +   IPQ40xx devices.
> +
>  endif
>  



> +static int ipq4019_regulator_set_voltage(struct regulator_dev *dev,
> + int min_uV, int max_uV,
> + unsigned *selector)
> +{
> + struct ipq4019_regulator_data *data = rdev_get_drvdata(dev);
> + struct ipq4019_regulator_config *cfg = data->config;
> +
> + int ptr, best_val = INT_MAX, val;
> +
> + for (ptr = 0; ptr < cfg->nr_states; ptr++)
> + if (cfg->states[ptr].range < best_val &&
> + cfg->states[ptr].range >= min_uV &&
> + cfg->states[ptr].range <= max_uV) {
> + best_val = cfg->states[ptr].value;
> + if (selector)
> + *selector = ptr;
> + }
> +
> + if (best_val == INT_MAX)
> + return -EINVAL;
> +
> + val = readl(cfg->base);
> + val  = val & (~(cfg->mask));

val &= mask

> + writel((val | best_val), cfg->base);
> +
> + data->range = cfg->states[ptr].range;
> +
> + return 0;
> +}
> +
> +static int ipq4019_regulator_list_voltage(struct regulator_dev *dev,
> +   unsigned selector)
> +{
> + struct ipq4019_regulator_data *data = rdev_get_drvdata(dev);
> + struct ipq4019_regulator_config *cfg = data->config;
> +
> + if (selector >= cfg->nr_states)
> + return -EINVAL;
> +
> + return cfg->states[selector].range;

If you can define your ranges using LINEAR_RANGE, you can just use the
regulator_list_voltage_linear_range.

> +}
> +
> +static struct regulator_ops ipq4019_regulator_voltage_ops = {
> + .get_voltage = ipq4019_regulator_get_voltage,
> + .set_voltage = ipq4019_regulator_set_voltage,
> + .list_voltage = ipq4019_regulator_list_voltage,

No enable and disable?

> +};
> +
> +static struct ipq4019_regulator_config *
> +of_get_ipq4019_regulator_data(struct device *dev, struct device_node *np, 
> const struct regulator_desc *desc)
> +{
> + struct ipq4019_regulator_config *config;
> + struct property *prop;
> + int proplen, i;
> +
> + config = devm_kzalloc(dev,
> + sizeof(struct ipq4019_regulator_config),
> + GFP_KERNEL);
> + if (!config)
> + return ERR_PTR(-ENOMEM);
> +
> + config->init_data = of_get_regulator_init_data(dev, np, desc);
> + if (!config->init_data)
> + return ERR_PTR(-EINVAL);
> +
> + config->supply_name = config->init_data->constraints.name;
> +
> +
> + /* Fetch states. */
> + prop = of_find_property(np, "states", NULL);
> + if (!prop) {
> + dev_err(dev, "No 'states' property found\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + proplen = prop->length / sizeof(int);
> +
> + config->states = devm_kzalloc(dev,
> + sizeof(struct ipq4019_regulator_state)
> + * (proplen / 2),
> + GFP_KERNEL);
> + if (!config->states)
> + return ERR_PTR(-ENOMEM);
> +
> + for (i = 0; i < proplen / 2; i++) {
> + config->states[i].range =
> + be32_to_cpup((int *)prop->value + (i * 2));
> + config->states[i].value =
> + be32_to_cpup((int *)prop->value + (i * 2 + 1));
> + }
> + config->nr_states = i;

Is it necessary to encode all of this data in the DT?  Is this varied between
boards using the IPQ4019?  Or are these values fixed for this chip?  If they are
fixed, it'd be better to put the data in a static structure or see if the
REGULATOR_LINEAR_RANGE would work for you.

> +
> +  

[PATCH v4] serial: 8250_dw: fix wrong logic in dw8250_check_lcr()

2016-04-04 Thread Kefeng Wang
Commit cdcea058e510 ("serial: 8250_dw: Avoid serial_outx code duplicate
with new dw8250_check_lcr()") introduce a wrong logic when write val to
LCR reg. When CONFIG_64BIT enabled, __raw_writeq is used unconditionally.

The __raw_readq/__raw_writeq is introduced by commit bca2092d7897 ("serial:
8250_dw: Use 64-bit access for OCTEON.") for OCTEON, so for !PORT_OCTEON,
we better to use coincident write func.

Fixes: cdcea058e510("serial: 8250_dw: Avoid serial_outx code duplicate with new 
dw8250_check_lcr()")
Signed-off-by: Kefeng Wang 
---

Changes since v3:
- Add patch change log, suggested by Greg Kroah-Hartman.
Changes since v2:
- Add #ifdef CONFIG_64BIT back, ensure it can be built under configuration 
lacking readq/writeq.
Changes since v1:
- Repace '#ifdef CONFIG_64BIT' with IS_ENABLED(CONFIG_64BIT).
- Enrich patch log, and add Fixes tag.
  

 drivers/tty/serial/8250/8250_dw.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_dw.c 
b/drivers/tty/serial/8250/8250_dw.c
index a3fb95d..47d1f3e 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -104,15 +104,16 @@ static void dw8250_check_lcr(struct uart_port *p, int 
value)
dw8250_force_idle(p);
 
 #ifdef CONFIG_64BIT
-   __raw_writeq(value & 0xff, offset);
-#else
+   if (p->type == PORT_OCTEON)
+   __raw_writeq(value & 0xff, offset);
+   else
+#endif
if (p->iotype == UPIO_MEM32)
writel(value, offset);
else if (p->iotype == UPIO_MEM32BE)
iowrite32be(value, offset);
else
writeb(value, offset);
-#endif
}
/*
 * FIXME: this deadlocks if port->lock is already held
-- 
2.6.0.GIT



[PATCH v4] serial: 8250_dw: fix wrong logic in dw8250_check_lcr()

2016-04-04 Thread Kefeng Wang
Commit cdcea058e510 ("serial: 8250_dw: Avoid serial_outx code duplicate
with new dw8250_check_lcr()") introduce a wrong logic when write val to
LCR reg. When CONFIG_64BIT enabled, __raw_writeq is used unconditionally.

The __raw_readq/__raw_writeq is introduced by commit bca2092d7897 ("serial:
8250_dw: Use 64-bit access for OCTEON.") for OCTEON, so for !PORT_OCTEON,
we better to use coincident write func.

Fixes: cdcea058e510("serial: 8250_dw: Avoid serial_outx code duplicate with new 
dw8250_check_lcr()")
Signed-off-by: Kefeng Wang 
---

Changes since v3:
- Add patch change log, suggested by Greg Kroah-Hartman.
Changes since v2:
- Add #ifdef CONFIG_64BIT back, ensure it can be built under configuration 
lacking readq/writeq.
Changes since v1:
- Repace '#ifdef CONFIG_64BIT' with IS_ENABLED(CONFIG_64BIT).
- Enrich patch log, and add Fixes tag.
  

 drivers/tty/serial/8250/8250_dw.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_dw.c 
b/drivers/tty/serial/8250/8250_dw.c
index a3fb95d..47d1f3e 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -104,15 +104,16 @@ static void dw8250_check_lcr(struct uart_port *p, int 
value)
dw8250_force_idle(p);
 
 #ifdef CONFIG_64BIT
-   __raw_writeq(value & 0xff, offset);
-#else
+   if (p->type == PORT_OCTEON)
+   __raw_writeq(value & 0xff, offset);
+   else
+#endif
if (p->iotype == UPIO_MEM32)
writel(value, offset);
else if (p->iotype == UPIO_MEM32BE)
iowrite32be(value, offset);
else
writeb(value, offset);
-#endif
}
/*
 * FIXME: this deadlocks if port->lock is already held
-- 
2.6.0.GIT



RE: [PATCH] mwifiex: add __GFP_REPEAT to skb allocation call

2016-04-04 Thread Amitkumar Karwar
Hi Eric,

Thanks for the comments.

> From: Eric Dumazet [mailto:eric.duma...@gmail.com]
> Sent: Tuesday, March 29, 2016 6:29 PM
> To: Wei-Ning Huang
> Cc: Kalle Valo; Linux Wireless; LKML; Amitkumar Karwar; Nishant
> Sarmukadam; Sameer Nanda; net...@vger.kernel.org; Sonny Rao; Douglas
> Anderson
> Subject: Re: [PATCH] mwifiex: add __GFP_REPEAT to skb allocation call
> 
> On Tue, 2016-03-29 at 17:27 +0800, Wei-Ning Huang wrote:
> > Adding some chromium devs to the thread.
> >
> > In, http://lxr.free-electrons.com/source/mm/page_alloc.c#L3152
> >
> > The default mm retry allocation when 'order <=
> > PAGE_ALLOC_COSTLY_ORDER' of gfp_mask contains __GFP_REPEAT.
> > PAGE_ALLOC_COSTLY_ORDER is defined to be 3. On systems with page size
> > = 4K, this means memory compaction and retry is only done when the
> > size of allocation is <= 32K In mwifiex, the allocation size is 64K.
> 
> 
> 
> >  When we have system with
> > memory fragmentation and allocation failed, there will be no retry.
> > This is why we need to add __GFP_REPEAT here to allow the system to
> > perform memory compaction and retry allocation.
> >
> > Maybe Amit@marvell can comment on if this is a good fix on this issue.
> > I'm also aware that marvell is the progress of implementing
> > scatter/gatter for mwifiex, which can also fix the issue.
> 
> Before SG is implemented, you really need to copy incoming frames into
> smallest chunks (to get lowest skb->truesize) and leave the 64KB
> allocated stuff forever in the driver.

We do have a 64KB pre-allocated buffer for receiving Rx data in our driver.

> 
> __GFP_REPEAT wont really solve the issue.
> 
> It seems the problem comes from the fact that the drivers calls
> dev_kfree_skb_any() after calling mwifiex_deaggr_sdio_pkt(), instead of
> recycling this very precious 64KB skb once memory gets fragmented.

Our one time allocated 64k buffer read from firmware contains multiple data 
chunks. We have a feature called single port aggregation in which firmware 
attaches an aggregated buffer to single port. So sometimes a single data chunk 
can exceed 32k. dev_kfree_skb_any() is called to free those data chunks.

> 
> Another problem is that mwifiex_deaggr_sdio_pkt() uses
> mwifiex_alloc_dma_align_buf() with GFP_KERNEL | GFP_DMA
> 
> Really GFP_DMA makes no sense here, since the skb is going to be
> processed by the stack, which has no such requirement.
> 
> Please use normal skb allocations there.

Sure. I will submit a patch for this.

Regards,
Amitkumar


RE: [PATCH] mwifiex: add __GFP_REPEAT to skb allocation call

2016-04-04 Thread Amitkumar Karwar
Hi Eric,

Thanks for the comments.

> From: Eric Dumazet [mailto:eric.duma...@gmail.com]
> Sent: Tuesday, March 29, 2016 6:29 PM
> To: Wei-Ning Huang
> Cc: Kalle Valo; Linux Wireless; LKML; Amitkumar Karwar; Nishant
> Sarmukadam; Sameer Nanda; net...@vger.kernel.org; Sonny Rao; Douglas
> Anderson
> Subject: Re: [PATCH] mwifiex: add __GFP_REPEAT to skb allocation call
> 
> On Tue, 2016-03-29 at 17:27 +0800, Wei-Ning Huang wrote:
> > Adding some chromium devs to the thread.
> >
> > In, http://lxr.free-electrons.com/source/mm/page_alloc.c#L3152
> >
> > The default mm retry allocation when 'order <=
> > PAGE_ALLOC_COSTLY_ORDER' of gfp_mask contains __GFP_REPEAT.
> > PAGE_ALLOC_COSTLY_ORDER is defined to be 3. On systems with page size
> > = 4K, this means memory compaction and retry is only done when the
> > size of allocation is <= 32K In mwifiex, the allocation size is 64K.
> 
> 
> 
> >  When we have system with
> > memory fragmentation and allocation failed, there will be no retry.
> > This is why we need to add __GFP_REPEAT here to allow the system to
> > perform memory compaction and retry allocation.
> >
> > Maybe Amit@marvell can comment on if this is a good fix on this issue.
> > I'm also aware that marvell is the progress of implementing
> > scatter/gatter for mwifiex, which can also fix the issue.
> 
> Before SG is implemented, you really need to copy incoming frames into
> smallest chunks (to get lowest skb->truesize) and leave the 64KB
> allocated stuff forever in the driver.

We do have a 64KB pre-allocated buffer for receiving Rx data in our driver.

> 
> __GFP_REPEAT wont really solve the issue.
> 
> It seems the problem comes from the fact that the drivers calls
> dev_kfree_skb_any() after calling mwifiex_deaggr_sdio_pkt(), instead of
> recycling this very precious 64KB skb once memory gets fragmented.

Our one time allocated 64k buffer read from firmware contains multiple data 
chunks. We have a feature called single port aggregation in which firmware 
attaches an aggregated buffer to single port. So sometimes a single data chunk 
can exceed 32k. dev_kfree_skb_any() is called to free those data chunks.

> 
> Another problem is that mwifiex_deaggr_sdio_pkt() uses
> mwifiex_alloc_dma_align_buf() with GFP_KERNEL | GFP_DMA
> 
> Really GFP_DMA makes no sense here, since the skb is going to be
> processed by the stack, which has no such requirement.
> 
> Please use normal skb allocations there.

Sure. I will submit a patch for this.

Regards,
Amitkumar


Re: [PATCHv2 6/7] ARM: socfpga: Enable Arria10 OCRAM ECC on startup

2016-04-04 Thread Borislav Petkov
On Tue, Apr 05, 2016 at 12:25:33AM -0500, Thor Thayer wrote:
> I realize that I'm not calling iounmap(ecc_block_base) and I'll fix that in
> the next revision with a goto.

I'm assuming nothing else changes. Because I've applied 1-4 already.

Yes, no?

If no, then please send only an updated version of this patch as a reply
to this thread here.

Thanks.

-- 
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.


Re: [PATCHv2 6/7] ARM: socfpga: Enable Arria10 OCRAM ECC on startup

2016-04-04 Thread Borislav Petkov
On Tue, Apr 05, 2016 at 12:25:33AM -0500, Thor Thayer wrote:
> I realize that I'm not calling iounmap(ecc_block_base) and I'll fix that in
> the next revision with a goto.

I'm assuming nothing else changes. Because I've applied 1-4 already.

Yes, no?

If no, then please send only an updated version of this patch as a reply
to this thread here.

Thanks.

-- 
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.


[PATCH v3 3/9] drm/fsl-dcu: disable clock on initialization failure and remove

2016-04-04 Thread Stefan Agner
Fix error handling during probe by reordering initialization and
adding a error path which disables clock again. Also disable the
clock on remove.

Signed-off-by: Stefan Agner 
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 44 +++
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index e8d9337..f2a9c1b 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -290,6 +290,11 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
if (!fsl_dev)
return -ENOMEM;
 
+   id = of_match_node(fsl_dcu_of_match, pdev->dev.of_node);
+   if (!id)
+   return -ENODEV;
+   fsl_dev->soc = id->data;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "could not get memory IO resource\n");
@@ -308,39 +313,29 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
return -ENXIO;
}
 
+   fsl_dev->regmap = devm_regmap_init_mmio(dev, base,
+   _dcu_regmap_config);
+   if (IS_ERR(fsl_dev->regmap)) {
+   dev_err(dev, "regmap init failed\n");
+   return PTR_ERR(fsl_dev->regmap);
+   }
+
fsl_dev->clk = devm_clk_get(dev, "dcu");
if (IS_ERR(fsl_dev->clk)) {
-   ret = PTR_ERR(fsl_dev->clk);
dev_err(dev, "failed to get dcu clock\n");
-   return ret;
-   }
-   ret = clk_prepare(fsl_dev->clk);
-   if (ret < 0) {
-   dev_err(dev, "failed to prepare dcu clk\n");
-   return ret;
+   return PTR_ERR(fsl_dev->clk);
}
-   ret = clk_enable(fsl_dev->clk);
+   ret = clk_prepare_enable(fsl_dev->clk);
if (ret < 0) {
dev_err(dev, "failed to enable dcu clk\n");
-   clk_unprepare(fsl_dev->clk);
return ret;
}
 
-   fsl_dev->regmap = devm_regmap_init_mmio(dev, base,
-   _dcu_regmap_config);
-   if (IS_ERR(fsl_dev->regmap)) {
-   dev_err(dev, "regmap init failed\n");
-   return PTR_ERR(fsl_dev->regmap);
-   }
-
-   id = of_match_node(fsl_dcu_of_match, pdev->dev.of_node);
-   if (!id)
-   return -ENODEV;
-   fsl_dev->soc = id->data;
-
drm = drm_dev_alloc(driver, dev);
-   if (!drm)
-   return -ENOMEM;
+   if (!drm) {
+   ret = -ENOMEM;
+   goto disable_clk;
+   }
 
fsl_dev->dev = dev;
fsl_dev->drm = drm;
@@ -360,6 +355,8 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
 
 unref:
drm_dev_unref(drm);
+disable_clk:
+   clk_disable_unprepare(fsl_dev->clk);
return ret;
 }
 
@@ -367,6 +364,7 @@ static int fsl_dcu_drm_remove(struct platform_device *pdev)
 {
struct fsl_dcu_drm_device *fsl_dev = platform_get_drvdata(pdev);
 
+   clk_disable_unprepare(fsl_dev->clk);
drm_put_dev(fsl_dev->drm);
 
return 0;
-- 
2.7.4



[PATCH v3 4/9] drm/fsl-dcu: add extra clock for pixel clock

2016-04-04 Thread Stefan Agner
The Vybrid DCU variant has two independent clock inputs, one
for the registers (IPG bus clock) and one for the pixel clock.
Support this distinction in the DCU DRM driver while staying
backward compatible for old device trees.

Signed-off-by: Stefan Agner 
---
 Documentation/devicetree/bindings/display/fsl,dcu.txt | 11 +++
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c|  2 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 16 +++-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h |  1 +
 4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/fsl,dcu.txt 
b/Documentation/devicetree/bindings/display/fsl,dcu.txt
index ebf1be9..2703cf2 100644
--- a/Documentation/devicetree/bindings/display/fsl,dcu.txt
+++ b/Documentation/devicetree/bindings/display/fsl,dcu.txt
@@ -6,8 +6,11 @@ Required properties:
* "fsl,vf610-dcu".
 
 - reg: Address and length of the register set for dcu.
-- clocks:  From common clock binding: handle to dcu clock.
-- clock-names: From common clock binding: Shall be "dcu".
+- clocks:  Handle to "dcu" and "pix" clock (in the order below)
+   This can be the same clock (e.g. LS1021a)
+   See ../clocks/clock-bindings.txt for details.
+- clock-names: Should be "dcu" and "pix"
+   See ../clocks/clock-bindings.txt for details.
 - big-endian   Boolean property, LS1021A DCU registers are big-endian.
 - fsl,panel:   The phandle to panel node.
 
@@ -15,8 +18,8 @@ Examples:
 dcu: dcu@2ce {
compatible = "fsl,ls1021a-dcu";
reg = <0x0 0x2ce 0x0 0x1>;
-   clocks = <_clk 0>;
-   clock-names = "dcu";
+   clocks = <_clk 0>, <_clk 0>;
+   clock-names = "dcu", "pix";
big-endian;
fsl,panel = <>;
 };
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index 35876e3..68f72fb 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -79,7 +79,7 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
unsigned long dcuclk;
 
index = drm_crtc_index(crtc);
-   dcuclk = clk_get_rate(fsl_dev->clk);
+   dcuclk = clk_get_rate(fsl_dev->pix_clk);
div = dcuclk / mode->clock / 1000;
 
/* Configure timings: */
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index f2a9c1b..f80c116 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -331,10 +331,21 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
return ret;
}
 
+   fsl_dev->pix_clk = devm_clk_get(dev, "pix");
+   if (IS_ERR(fsl_dev->pix_clk)) {
+   /* legancy binding, use dcu clock as pixel clock */
+   fsl_dev->pix_clk = fsl_dev->clk;
+   }
+   ret = clk_prepare_enable(fsl_dev->pix_clk);
+   if (ret < 0) {
+   dev_err(dev, "failed to enable pix clk\n");
+   goto disable_clk;
+   }
+
drm = drm_dev_alloc(driver, dev);
if (!drm) {
ret = -ENOMEM;
-   goto disable_clk;
+   goto disable_pix_clk;
}
 
fsl_dev->dev = dev;
@@ -355,6 +366,8 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
 
 unref:
drm_dev_unref(drm);
+disable_pix_clk:
+   clk_disable_unprepare(fsl_dev->pix_clk);
 disable_clk:
clk_disable_unprepare(fsl_dev->clk);
return ret;
@@ -365,6 +378,7 @@ static int fsl_dcu_drm_remove(struct platform_device *pdev)
struct fsl_dcu_drm_device *fsl_dev = platform_get_drvdata(pdev);
 
clk_disable_unprepare(fsl_dev->clk);
+   clk_disable_unprepare(fsl_dev->pix_clk);
drm_put_dev(fsl_dev->drm);
 
return 0;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
index af3a707..f60ec0a 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
@@ -183,6 +183,7 @@ struct fsl_dcu_drm_device {
struct regmap *regmap;
int irq;
struct clk *clk;
+   struct clk *pix_clk;
/*protects hardware register*/
spinlock_t irq_lock;
struct drm_device *drm;
-- 
2.7.4



[PATCH v3 4/9] drm/fsl-dcu: add extra clock for pixel clock

2016-04-04 Thread Stefan Agner
The Vybrid DCU variant has two independent clock inputs, one
for the registers (IPG bus clock) and one for the pixel clock.
Support this distinction in the DCU DRM driver while staying
backward compatible for old device trees.

Signed-off-by: Stefan Agner 
---
 Documentation/devicetree/bindings/display/fsl,dcu.txt | 11 +++
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c|  2 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 16 +++-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h |  1 +
 4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/fsl,dcu.txt 
b/Documentation/devicetree/bindings/display/fsl,dcu.txt
index ebf1be9..2703cf2 100644
--- a/Documentation/devicetree/bindings/display/fsl,dcu.txt
+++ b/Documentation/devicetree/bindings/display/fsl,dcu.txt
@@ -6,8 +6,11 @@ Required properties:
* "fsl,vf610-dcu".
 
 - reg: Address and length of the register set for dcu.
-- clocks:  From common clock binding: handle to dcu clock.
-- clock-names: From common clock binding: Shall be "dcu".
+- clocks:  Handle to "dcu" and "pix" clock (in the order below)
+   This can be the same clock (e.g. LS1021a)
+   See ../clocks/clock-bindings.txt for details.
+- clock-names: Should be "dcu" and "pix"
+   See ../clocks/clock-bindings.txt for details.
 - big-endian   Boolean property, LS1021A DCU registers are big-endian.
 - fsl,panel:   The phandle to panel node.
 
@@ -15,8 +18,8 @@ Examples:
 dcu: dcu@2ce {
compatible = "fsl,ls1021a-dcu";
reg = <0x0 0x2ce 0x0 0x1>;
-   clocks = <_clk 0>;
-   clock-names = "dcu";
+   clocks = <_clk 0>, <_clk 0>;
+   clock-names = "dcu", "pix";
big-endian;
fsl,panel = <>;
 };
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index 35876e3..68f72fb 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -79,7 +79,7 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
unsigned long dcuclk;
 
index = drm_crtc_index(crtc);
-   dcuclk = clk_get_rate(fsl_dev->clk);
+   dcuclk = clk_get_rate(fsl_dev->pix_clk);
div = dcuclk / mode->clock / 1000;
 
/* Configure timings: */
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index f2a9c1b..f80c116 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -331,10 +331,21 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
return ret;
}
 
+   fsl_dev->pix_clk = devm_clk_get(dev, "pix");
+   if (IS_ERR(fsl_dev->pix_clk)) {
+   /* legancy binding, use dcu clock as pixel clock */
+   fsl_dev->pix_clk = fsl_dev->clk;
+   }
+   ret = clk_prepare_enable(fsl_dev->pix_clk);
+   if (ret < 0) {
+   dev_err(dev, "failed to enable pix clk\n");
+   goto disable_clk;
+   }
+
drm = drm_dev_alloc(driver, dev);
if (!drm) {
ret = -ENOMEM;
-   goto disable_clk;
+   goto disable_pix_clk;
}
 
fsl_dev->dev = dev;
@@ -355,6 +366,8 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
 
 unref:
drm_dev_unref(drm);
+disable_pix_clk:
+   clk_disable_unprepare(fsl_dev->pix_clk);
 disable_clk:
clk_disable_unprepare(fsl_dev->clk);
return ret;
@@ -365,6 +378,7 @@ static int fsl_dcu_drm_remove(struct platform_device *pdev)
struct fsl_dcu_drm_device *fsl_dev = platform_get_drvdata(pdev);
 
clk_disable_unprepare(fsl_dev->clk);
+   clk_disable_unprepare(fsl_dev->pix_clk);
drm_put_dev(fsl_dev->drm);
 
return 0;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
index af3a707..f60ec0a 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
@@ -183,6 +183,7 @@ struct fsl_dcu_drm_device {
struct regmap *regmap;
int irq;
struct clk *clk;
+   struct clk *pix_clk;
/*protects hardware register*/
spinlock_t irq_lock;
struct drm_device *drm;
-- 
2.7.4



[PATCH v3 3/9] drm/fsl-dcu: disable clock on initialization failure and remove

2016-04-04 Thread Stefan Agner
Fix error handling during probe by reordering initialization and
adding a error path which disables clock again. Also disable the
clock on remove.

Signed-off-by: Stefan Agner 
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 44 +++
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index e8d9337..f2a9c1b 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -290,6 +290,11 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
if (!fsl_dev)
return -ENOMEM;
 
+   id = of_match_node(fsl_dcu_of_match, pdev->dev.of_node);
+   if (!id)
+   return -ENODEV;
+   fsl_dev->soc = id->data;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "could not get memory IO resource\n");
@@ -308,39 +313,29 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
return -ENXIO;
}
 
+   fsl_dev->regmap = devm_regmap_init_mmio(dev, base,
+   _dcu_regmap_config);
+   if (IS_ERR(fsl_dev->regmap)) {
+   dev_err(dev, "regmap init failed\n");
+   return PTR_ERR(fsl_dev->regmap);
+   }
+
fsl_dev->clk = devm_clk_get(dev, "dcu");
if (IS_ERR(fsl_dev->clk)) {
-   ret = PTR_ERR(fsl_dev->clk);
dev_err(dev, "failed to get dcu clock\n");
-   return ret;
-   }
-   ret = clk_prepare(fsl_dev->clk);
-   if (ret < 0) {
-   dev_err(dev, "failed to prepare dcu clk\n");
-   return ret;
+   return PTR_ERR(fsl_dev->clk);
}
-   ret = clk_enable(fsl_dev->clk);
+   ret = clk_prepare_enable(fsl_dev->clk);
if (ret < 0) {
dev_err(dev, "failed to enable dcu clk\n");
-   clk_unprepare(fsl_dev->clk);
return ret;
}
 
-   fsl_dev->regmap = devm_regmap_init_mmio(dev, base,
-   _dcu_regmap_config);
-   if (IS_ERR(fsl_dev->regmap)) {
-   dev_err(dev, "regmap init failed\n");
-   return PTR_ERR(fsl_dev->regmap);
-   }
-
-   id = of_match_node(fsl_dcu_of_match, pdev->dev.of_node);
-   if (!id)
-   return -ENODEV;
-   fsl_dev->soc = id->data;
-
drm = drm_dev_alloc(driver, dev);
-   if (!drm)
-   return -ENOMEM;
+   if (!drm) {
+   ret = -ENOMEM;
+   goto disable_clk;
+   }
 
fsl_dev->dev = dev;
fsl_dev->drm = drm;
@@ -360,6 +355,8 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
 
 unref:
drm_dev_unref(drm);
+disable_clk:
+   clk_disable_unprepare(fsl_dev->clk);
return ret;
 }
 
@@ -367,6 +364,7 @@ static int fsl_dcu_drm_remove(struct platform_device *pdev)
 {
struct fsl_dcu_drm_device *fsl_dev = platform_get_drvdata(pdev);
 
+   clk_disable_unprepare(fsl_dev->clk);
drm_put_dev(fsl_dev->drm);
 
return 0;
-- 
2.7.4



[PATCH v3 6/9] drm/fsl-dcu: add TCON driver

2016-04-04 Thread Stefan Agner
Add driver for the TCON (timing controller) module. The TCON module
is a separate module attached after the DCU (display controller
unit). Each DCU instance has its own, directly connected TCON
instance. The DCU's RGB and timing signals are passing through
the TCON module. TCON can provide timing signals for raw TFT panels
or operate in a bypass mode which leaves all signals unaltered.

The driver currently only supports the bypass mode.

Acked-by: Rob Herring 
Signed-off-by: Stefan Agner 
---
 .../devicetree/bindings/display/fsl,dcu.txt|   4 +
 .../devicetree/bindings/display/fsl,tcon.txt   |  18 
 MAINTAINERS|   1 +
 drivers/gpu/drm/fsl-dcu/Makefile   |   3 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c  |   3 +
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h  |   1 +
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c  |  11 ++
 drivers/gpu/drm/fsl-dcu/fsl_tcon.c | 111 +
 drivers/gpu/drm/fsl-dcu/fsl_tcon.h |  33 ++
 9 files changed, 184 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/display/fsl,tcon.txt
 create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_tcon.c
 create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_tcon.h

diff --git a/Documentation/devicetree/bindings/display/fsl,dcu.txt 
b/Documentation/devicetree/bindings/display/fsl,dcu.txt
index 2703cf2..ae55cde 100644
--- a/Documentation/devicetree/bindings/display/fsl,dcu.txt
+++ b/Documentation/devicetree/bindings/display/fsl,dcu.txt
@@ -14,6 +14,9 @@ Required properties:
 - big-endian   Boolean property, LS1021A DCU registers are big-endian.
 - fsl,panel:   The phandle to panel node.
 
+Optional properties:
+- fsl,tcon:The phandle to the timing controller node.
+
 Examples:
 dcu: dcu@2ce {
compatible = "fsl,ls1021a-dcu";
@@ -22,4 +25,5 @@ dcu: dcu@2ce {
clock-names = "dcu", "pix";
big-endian;
fsl,panel = <>;
+   fsl,tcon = <>;
 };
diff --git a/Documentation/devicetree/bindings/display/fsl,tcon.txt 
b/Documentation/devicetree/bindings/display/fsl,tcon.txt
new file mode 100644
index 000..6fa4ab6
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/fsl,tcon.txt
@@ -0,0 +1,18 @@
+Device Tree bindings for Freescale TCON Driver
+
+Required properties:
+- compatible:  Should be one of
+   * "fsl,vf610-tcon".
+
+- reg: Address and length of the register set for tcon.
+- clocks:  From common clock binding: handle to tcon ipg clock.
+- clock-names: From common clock binding: Shall be "ipg".
+
+Examples:
+timing-controller@4003d000 {
+   compatible = "fsl,vf610-tcon";
+   reg = <0x4003d000 0x1000>;
+   clocks = < VF610_CLK_TCON0>;
+   clock-names = "ipg";
+   status = "okay";
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index ea1d1de..187c846 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3770,6 +3770,7 @@ L:dri-de...@lists.freedesktop.org
 S: Supported
 F: drivers/gpu/drm/fsl-dcu/
 F: Documentation/devicetree/bindings/display/fsl,dcu.txt
+F: Documentation/devicetree/bindings/display/fsl,tcon.txt
 F: Documentation/devicetree/bindings/display/panel/nec,nl4827hc19_05b.txt
 
 DRM DRIVERS FOR FREESCALE IMX
diff --git a/drivers/gpu/drm/fsl-dcu/Makefile b/drivers/gpu/drm/fsl-dcu/Makefile
index 6ea1523..b35a292 100644
--- a/drivers/gpu/drm/fsl-dcu/Makefile
+++ b/drivers/gpu/drm/fsl-dcu/Makefile
@@ -3,5 +3,6 @@ fsl-dcu-drm-y := fsl_dcu_drm_drv.o \
 fsl_dcu_drm_rgb.o \
 fsl_dcu_drm_plane.o \
 fsl_dcu_drm_crtc.o \
-fsl_dcu_drm_fbdev.o
+fsl_dcu_drm_fbdev.o \
+fsl_tcon.o
 obj-$(CONFIG_DRM_FSL_DCU)  += fsl-dcu-drm.o
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index 093a60b..f62bff2 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -27,6 +27,7 @@
 
 #include "fsl_dcu_drm_crtc.h"
 #include "fsl_dcu_drm_drv.h"
+#include "fsl_tcon.h"
 
 static bool fsl_dcu_drm_is_volatile_reg(struct device *dev, unsigned int reg)
 {
@@ -357,6 +358,8 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
goto unregister_pix_clk;
}
 
+   fsl_dev->tcon = fsl_tcon_init(dev);
+
drm = drm_dev_alloc(driver, dev);
if (!drm) {
ret = -ENOMEM;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
index f60ec0a..c275f90 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
@@ -184,6 +184,7 @@ struct fsl_dcu_drm_device {
int irq;
struct clk *clk;
struct clk *pix_clk;
+   struct fsl_tcon *tcon;
/*protects hardware register*/
   

[PATCH v3 8/9] ARM: dts: vf610-colibri: enable display controller

2016-04-04 Thread Stefan Agner
Enable dcu node which is used by the DCU DRM driver. Assign the 5.7"
EDT panel with VGA resolution which Toradex sells often with the
evaluation board.

Signed-off-by: Stefan Agner 
---
 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 16 +++
 arch/arm/boot/dts/vf-colibri.dtsi | 33 +++
 2 files changed, 49 insertions(+)

diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi 
b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
index ed65e0f..f5d4c78 100644
--- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -18,6 +18,11 @@
clock-frequency = <1600>;
};
 
+   panel: panel {
+   compatible = "edt,et057090dhu";
+   backlight = <>;
+   };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
@@ -53,6 +58,13 @@
status  = "okay";
 };
 
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_dcu0_1>;
+   fsl,panel = <>;
+   status = "okay";
+};
+
  {
status = "okay";
 
@@ -100,6 +112,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
status = "okay";
 };
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi 
b/arch/arm/boot/dts/vf-colibri.dtsi
index 6e556be..5f1847b 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -159,6 +159,39 @@
>;
};
 
+   pinctrl_dcu0_1: dcu0grp_1 {
+   fsl,pins = <
+   VF610_PAD_PTE0__DCU0_HSYNC  0x1902
+   VF610_PAD_PTE1__DCU0_VSYNC  0x1902
+   VF610_PAD_PTE2__DCU0_PCLK   0x1902
+   VF610_PAD_PTE4__DCU0_DE 0x1902
+   VF610_PAD_PTE5__DCU0_R0 0x1902
+   VF610_PAD_PTE6__DCU0_R1 0x1902
+   VF610_PAD_PTE7__DCU0_R2 0x1902
+   VF610_PAD_PTE8__DCU0_R3 0x1902
+   VF610_PAD_PTE9__DCU0_R4 0x1902
+   VF610_PAD_PTE10__DCU0_R50x1902
+   VF610_PAD_PTE11__DCU0_R60x1902
+   VF610_PAD_PTE12__DCU0_R70x1902
+   VF610_PAD_PTE13__DCU0_G00x1902
+   VF610_PAD_PTE14__DCU0_G10x1902
+   VF610_PAD_PTE15__DCU0_G20x1902
+   VF610_PAD_PTE16__DCU0_G30x1902
+   VF610_PAD_PTE17__DCU0_G40x1902
+   VF610_PAD_PTE18__DCU0_G50x1902
+   VF610_PAD_PTE19__DCU0_G60x1902
+   VF610_PAD_PTE20__DCU0_G70x1902
+   VF610_PAD_PTE21__DCU0_B00x1902
+   VF610_PAD_PTE22__DCU0_B10x1902
+   VF610_PAD_PTE23__DCU0_B20x1902
+   VF610_PAD_PTE24__DCU0_B30x1902
+   VF610_PAD_PTE25__DCU0_B40x1902
+   VF610_PAD_PTE26__DCU0_B50x1902
+   VF610_PAD_PTE27__DCU0_B60x1902
+   VF610_PAD_PTE28__DCU0_B70x1902
+   >;
+   };
+
pinctrl_dspi1: dspi1grp {
fsl,pins = <
VF610_PAD_PTD5__DSPI1_CS0   0x33e2
-- 
2.7.4



[PATCH v3 5/9] drm/fsl-dcu: use common clock framework for pixel clock divider

2016-04-04 Thread Stefan Agner
Use the common clock framework to calculate the pixel clock
dividier. The previous implementation rounded down the calculated
factor. Thanks to the CLK_DIVIDER_ROUND_CLOSEST flag using the
common clock framework divider implementation improves the pixel
clock accuracy in some cases. Ontop of that it also allows to see
the actual pixel clock in the sysfs clock summary.

Signed-off-by: Stefan Agner 
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c |  7 ++-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c  | 26 ++
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index 68f72fb..f7b4d87 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -75,12 +75,10 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
struct drm_connector *con = _dev->connector.base;
struct drm_display_mode *mode = >state->mode;
-   unsigned int hbp, hfp, hsw, vbp, vfp, vsw, div, index, pol = 0;
-   unsigned long dcuclk;
+   unsigned int hbp, hfp, hsw, vbp, vfp, vsw, index, pol = 0;
 
index = drm_crtc_index(crtc);
-   dcuclk = clk_get_rate(fsl_dev->pix_clk);
-   div = dcuclk / mode->clock / 1000;
+   clk_set_rate(fsl_dev->pix_clk, mode->clock * 1000);
 
/* Configure timings: */
hbp = mode->htotal - mode->hsync_end;
@@ -111,7 +109,6 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
regmap_write(fsl_dev->regmap, DCU_DISP_SIZE,
 DCU_DISP_SIZE_DELTA_Y(mode->vdisplay) |
 DCU_DISP_SIZE_DELTA_X(mode->hdisplay));
-   regmap_write(fsl_dev->regmap, DCU_DIV_RATIO, div);
regmap_write(fsl_dev->regmap, DCU_SYN_POL, pol);
regmap_write(fsl_dev->regmap, DCU_BGND, DCU_BGND_R(0) |
 DCU_BGND_G(0) | DCU_BGND_B(0));
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index f80c116..093a60b 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -283,6 +283,9 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
struct resource *res;
void __iomem *base;
struct drm_driver *driver = _dcu_drm_driver;
+   struct clk *pix_clk_in;
+   char pix_clk_name[32];
+   const char *pix_clk_in_name;
const struct of_device_id *id;
int ret;
 
@@ -331,15 +334,27 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
return ret;
}
 
-   fsl_dev->pix_clk = devm_clk_get(dev, "pix");
+   pix_clk_in = devm_clk_get(dev, "pix");
+   if (IS_ERR(pix_clk_in)) {
+   /* legancy binding, use dcu clock as pixel clock input */
+   pix_clk_in = fsl_dev->clk;
+   }
+
+   pix_clk_in_name = __clk_get_name(pix_clk_in);
+   snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name);
+   fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name,
+   pix_clk_in_name, 0, base + DCU_DIV_RATIO,
+   0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL);
if (IS_ERR(fsl_dev->pix_clk)) {
-   /* legancy binding, use dcu clock as pixel clock */
-   fsl_dev->pix_clk = fsl_dev->clk;
+   dev_err(dev, "failed to register pix clk\n");
+   ret = PTR_ERR(fsl_dev->pix_clk);
+   goto disable_clk;
}
+
ret = clk_prepare_enable(fsl_dev->pix_clk);
if (ret < 0) {
dev_err(dev, "failed to enable pix clk\n");
-   goto disable_clk;
+   goto unregister_pix_clk;
}
 
drm = drm_dev_alloc(driver, dev);
@@ -368,6 +383,8 @@ unref:
drm_dev_unref(drm);
 disable_pix_clk:
clk_disable_unprepare(fsl_dev->pix_clk);
+unregister_pix_clk:
+   clk_unregister(fsl_dev->pix_clk);
 disable_clk:
clk_disable_unprepare(fsl_dev->clk);
return ret;
@@ -379,6 +396,7 @@ static int fsl_dcu_drm_remove(struct platform_device *pdev)
 
clk_disable_unprepare(fsl_dev->clk);
clk_disable_unprepare(fsl_dev->pix_clk);
+   clk_unregister(fsl_dev->pix_clk);
drm_put_dev(fsl_dev->drm);
 
return 0;
-- 
2.7.4



[PATCH v3 6/9] drm/fsl-dcu: add TCON driver

2016-04-04 Thread Stefan Agner
Add driver for the TCON (timing controller) module. The TCON module
is a separate module attached after the DCU (display controller
unit). Each DCU instance has its own, directly connected TCON
instance. The DCU's RGB and timing signals are passing through
the TCON module. TCON can provide timing signals for raw TFT panels
or operate in a bypass mode which leaves all signals unaltered.

The driver currently only supports the bypass mode.

Acked-by: Rob Herring 
Signed-off-by: Stefan Agner 
---
 .../devicetree/bindings/display/fsl,dcu.txt|   4 +
 .../devicetree/bindings/display/fsl,tcon.txt   |  18 
 MAINTAINERS|   1 +
 drivers/gpu/drm/fsl-dcu/Makefile   |   3 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c  |   3 +
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h  |   1 +
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c  |  11 ++
 drivers/gpu/drm/fsl-dcu/fsl_tcon.c | 111 +
 drivers/gpu/drm/fsl-dcu/fsl_tcon.h |  33 ++
 9 files changed, 184 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/display/fsl,tcon.txt
 create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_tcon.c
 create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_tcon.h

diff --git a/Documentation/devicetree/bindings/display/fsl,dcu.txt 
b/Documentation/devicetree/bindings/display/fsl,dcu.txt
index 2703cf2..ae55cde 100644
--- a/Documentation/devicetree/bindings/display/fsl,dcu.txt
+++ b/Documentation/devicetree/bindings/display/fsl,dcu.txt
@@ -14,6 +14,9 @@ Required properties:
 - big-endian   Boolean property, LS1021A DCU registers are big-endian.
 - fsl,panel:   The phandle to panel node.
 
+Optional properties:
+- fsl,tcon:The phandle to the timing controller node.
+
 Examples:
 dcu: dcu@2ce {
compatible = "fsl,ls1021a-dcu";
@@ -22,4 +25,5 @@ dcu: dcu@2ce {
clock-names = "dcu", "pix";
big-endian;
fsl,panel = <>;
+   fsl,tcon = <>;
 };
diff --git a/Documentation/devicetree/bindings/display/fsl,tcon.txt 
b/Documentation/devicetree/bindings/display/fsl,tcon.txt
new file mode 100644
index 000..6fa4ab6
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/fsl,tcon.txt
@@ -0,0 +1,18 @@
+Device Tree bindings for Freescale TCON Driver
+
+Required properties:
+- compatible:  Should be one of
+   * "fsl,vf610-tcon".
+
+- reg: Address and length of the register set for tcon.
+- clocks:  From common clock binding: handle to tcon ipg clock.
+- clock-names: From common clock binding: Shall be "ipg".
+
+Examples:
+timing-controller@4003d000 {
+   compatible = "fsl,vf610-tcon";
+   reg = <0x4003d000 0x1000>;
+   clocks = < VF610_CLK_TCON0>;
+   clock-names = "ipg";
+   status = "okay";
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index ea1d1de..187c846 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3770,6 +3770,7 @@ L:dri-de...@lists.freedesktop.org
 S: Supported
 F: drivers/gpu/drm/fsl-dcu/
 F: Documentation/devicetree/bindings/display/fsl,dcu.txt
+F: Documentation/devicetree/bindings/display/fsl,tcon.txt
 F: Documentation/devicetree/bindings/display/panel/nec,nl4827hc19_05b.txt
 
 DRM DRIVERS FOR FREESCALE IMX
diff --git a/drivers/gpu/drm/fsl-dcu/Makefile b/drivers/gpu/drm/fsl-dcu/Makefile
index 6ea1523..b35a292 100644
--- a/drivers/gpu/drm/fsl-dcu/Makefile
+++ b/drivers/gpu/drm/fsl-dcu/Makefile
@@ -3,5 +3,6 @@ fsl-dcu-drm-y := fsl_dcu_drm_drv.o \
 fsl_dcu_drm_rgb.o \
 fsl_dcu_drm_plane.o \
 fsl_dcu_drm_crtc.o \
-fsl_dcu_drm_fbdev.o
+fsl_dcu_drm_fbdev.o \
+fsl_tcon.o
 obj-$(CONFIG_DRM_FSL_DCU)  += fsl-dcu-drm.o
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index 093a60b..f62bff2 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -27,6 +27,7 @@
 
 #include "fsl_dcu_drm_crtc.h"
 #include "fsl_dcu_drm_drv.h"
+#include "fsl_tcon.h"
 
 static bool fsl_dcu_drm_is_volatile_reg(struct device *dev, unsigned int reg)
 {
@@ -357,6 +358,8 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
goto unregister_pix_clk;
}
 
+   fsl_dev->tcon = fsl_tcon_init(dev);
+
drm = drm_dev_alloc(driver, dev);
if (!drm) {
ret = -ENOMEM;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
index f60ec0a..c275f90 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
@@ -184,6 +184,7 @@ struct fsl_dcu_drm_device {
int irq;
struct clk *clk;
struct clk *pix_clk;
+   struct fsl_tcon *tcon;
/*protects hardware register*/
spinlock_t irq_lock;

[PATCH v3 8/9] ARM: dts: vf610-colibri: enable display controller

2016-04-04 Thread Stefan Agner
Enable dcu node which is used by the DCU DRM driver. Assign the 5.7"
EDT panel with VGA resolution which Toradex sells often with the
evaluation board.

Signed-off-by: Stefan Agner 
---
 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 16 +++
 arch/arm/boot/dts/vf-colibri.dtsi | 33 +++
 2 files changed, 49 insertions(+)

diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi 
b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
index ed65e0f..f5d4c78 100644
--- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -18,6 +18,11 @@
clock-frequency = <1600>;
};
 
+   panel: panel {
+   compatible = "edt,et057090dhu";
+   backlight = <>;
+   };
+
regulators {
compatible = "simple-bus";
#address-cells = <1>;
@@ -53,6 +58,13 @@
status  = "okay";
 };
 
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_dcu0_1>;
+   fsl,panel = <>;
+   status = "okay";
+};
+
  {
status = "okay";
 
@@ -100,6 +112,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
status = "okay";
 };
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi 
b/arch/arm/boot/dts/vf-colibri.dtsi
index 6e556be..5f1847b 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -159,6 +159,39 @@
>;
};
 
+   pinctrl_dcu0_1: dcu0grp_1 {
+   fsl,pins = <
+   VF610_PAD_PTE0__DCU0_HSYNC  0x1902
+   VF610_PAD_PTE1__DCU0_VSYNC  0x1902
+   VF610_PAD_PTE2__DCU0_PCLK   0x1902
+   VF610_PAD_PTE4__DCU0_DE 0x1902
+   VF610_PAD_PTE5__DCU0_R0 0x1902
+   VF610_PAD_PTE6__DCU0_R1 0x1902
+   VF610_PAD_PTE7__DCU0_R2 0x1902
+   VF610_PAD_PTE8__DCU0_R3 0x1902
+   VF610_PAD_PTE9__DCU0_R4 0x1902
+   VF610_PAD_PTE10__DCU0_R50x1902
+   VF610_PAD_PTE11__DCU0_R60x1902
+   VF610_PAD_PTE12__DCU0_R70x1902
+   VF610_PAD_PTE13__DCU0_G00x1902
+   VF610_PAD_PTE14__DCU0_G10x1902
+   VF610_PAD_PTE15__DCU0_G20x1902
+   VF610_PAD_PTE16__DCU0_G30x1902
+   VF610_PAD_PTE17__DCU0_G40x1902
+   VF610_PAD_PTE18__DCU0_G50x1902
+   VF610_PAD_PTE19__DCU0_G60x1902
+   VF610_PAD_PTE20__DCU0_G70x1902
+   VF610_PAD_PTE21__DCU0_B00x1902
+   VF610_PAD_PTE22__DCU0_B10x1902
+   VF610_PAD_PTE23__DCU0_B20x1902
+   VF610_PAD_PTE24__DCU0_B30x1902
+   VF610_PAD_PTE25__DCU0_B40x1902
+   VF610_PAD_PTE26__DCU0_B50x1902
+   VF610_PAD_PTE27__DCU0_B60x1902
+   VF610_PAD_PTE28__DCU0_B70x1902
+   >;
+   };
+
pinctrl_dspi1: dspi1grp {
fsl,pins = <
VF610_PAD_PTD5__DSPI1_CS0   0x33e2
-- 
2.7.4



[PATCH v3 5/9] drm/fsl-dcu: use common clock framework for pixel clock divider

2016-04-04 Thread Stefan Agner
Use the common clock framework to calculate the pixel clock
dividier. The previous implementation rounded down the calculated
factor. Thanks to the CLK_DIVIDER_ROUND_CLOSEST flag using the
common clock framework divider implementation improves the pixel
clock accuracy in some cases. Ontop of that it also allows to see
the actual pixel clock in the sysfs clock summary.

Signed-off-by: Stefan Agner 
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c |  7 ++-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c  | 26 ++
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index 68f72fb..f7b4d87 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -75,12 +75,10 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
struct drm_connector *con = _dev->connector.base;
struct drm_display_mode *mode = >state->mode;
-   unsigned int hbp, hfp, hsw, vbp, vfp, vsw, div, index, pol = 0;
-   unsigned long dcuclk;
+   unsigned int hbp, hfp, hsw, vbp, vfp, vsw, index, pol = 0;
 
index = drm_crtc_index(crtc);
-   dcuclk = clk_get_rate(fsl_dev->pix_clk);
-   div = dcuclk / mode->clock / 1000;
+   clk_set_rate(fsl_dev->pix_clk, mode->clock * 1000);
 
/* Configure timings: */
hbp = mode->htotal - mode->hsync_end;
@@ -111,7 +109,6 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
regmap_write(fsl_dev->regmap, DCU_DISP_SIZE,
 DCU_DISP_SIZE_DELTA_Y(mode->vdisplay) |
 DCU_DISP_SIZE_DELTA_X(mode->hdisplay));
-   regmap_write(fsl_dev->regmap, DCU_DIV_RATIO, div);
regmap_write(fsl_dev->regmap, DCU_SYN_POL, pol);
regmap_write(fsl_dev->regmap, DCU_BGND, DCU_BGND_R(0) |
 DCU_BGND_G(0) | DCU_BGND_B(0));
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index f80c116..093a60b 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -283,6 +283,9 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
struct resource *res;
void __iomem *base;
struct drm_driver *driver = _dcu_drm_driver;
+   struct clk *pix_clk_in;
+   char pix_clk_name[32];
+   const char *pix_clk_in_name;
const struct of_device_id *id;
int ret;
 
@@ -331,15 +334,27 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
return ret;
}
 
-   fsl_dev->pix_clk = devm_clk_get(dev, "pix");
+   pix_clk_in = devm_clk_get(dev, "pix");
+   if (IS_ERR(pix_clk_in)) {
+   /* legancy binding, use dcu clock as pixel clock input */
+   pix_clk_in = fsl_dev->clk;
+   }
+
+   pix_clk_in_name = __clk_get_name(pix_clk_in);
+   snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name);
+   fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name,
+   pix_clk_in_name, 0, base + DCU_DIV_RATIO,
+   0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL);
if (IS_ERR(fsl_dev->pix_clk)) {
-   /* legancy binding, use dcu clock as pixel clock */
-   fsl_dev->pix_clk = fsl_dev->clk;
+   dev_err(dev, "failed to register pix clk\n");
+   ret = PTR_ERR(fsl_dev->pix_clk);
+   goto disable_clk;
}
+
ret = clk_prepare_enable(fsl_dev->pix_clk);
if (ret < 0) {
dev_err(dev, "failed to enable pix clk\n");
-   goto disable_clk;
+   goto unregister_pix_clk;
}
 
drm = drm_dev_alloc(driver, dev);
@@ -368,6 +383,8 @@ unref:
drm_dev_unref(drm);
 disable_pix_clk:
clk_disable_unprepare(fsl_dev->pix_clk);
+unregister_pix_clk:
+   clk_unregister(fsl_dev->pix_clk);
 disable_clk:
clk_disable_unprepare(fsl_dev->clk);
return ret;
@@ -379,6 +396,7 @@ static int fsl_dcu_drm_remove(struct platform_device *pdev)
 
clk_disable_unprepare(fsl_dev->clk);
clk_disable_unprepare(fsl_dev->pix_clk);
+   clk_unregister(fsl_dev->pix_clk);
drm_put_dev(fsl_dev->drm);
 
return 0;
-- 
2.7.4



[PATCH v3 9/9] ARM: dts: ls1021a: add pix clock to DCU dts node

2016-04-04 Thread Stefan Agner
The DCU IP has distinct clock inputs for register access and the
pixel clocks, at least in some implementations. LS1021a seems to
use the same clock, therefore specify the same clock for "dcu"
and "pix".

Signed-off-by: Stefan Agner 
---
 arch/arm/boot/dts/ls1021a.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 2c84ca2..cd5c76d 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -443,8 +443,9 @@
compatible = "fsl,ls1021a-dcu";
reg = <0x0 0x2ce 0x0 0x1>;
interrupts = ;
-   clocks = <_clk 0>;
-   clock-names = "dcu";
+   clocks = <_clk 0>,
+   <_clk 0>;
+   clock-names = "dcu", "pix";
big-endian;
status = "disabled";
};
-- 
2.7.4



[PATCH v3 7/9] ARM: dts: vf610: add display nodes

2016-04-04 Thread Stefan Agner
Add the dcu and tcon nodes to enable the Display Controller Unit
and Timing Controller in Vybrid's SoC level device-tree file.

Signed-off-by: Stefan Agner 
---
 arch/arm/boot/dts/vfxxx.dtsi | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index a9ceb5b..78e24c6 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -234,6 +234,14 @@
<2000>;
};
 
+   tcon0: timing-controller@4003d000 {
+   compatible = "fsl,vf610-tcon";
+   reg = <0x4003d000 0x1000>;
+   clocks = < VF610_CLK_TCON0>;
+   clock-names = "ipg";
+   status = "disabled";
+   };
+
wdoga5: wdog@4003e000 {
compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
reg = <0x4003e000 0x1000>;
@@ -339,6 +347,17 @@
status = "disabled";
};
 
+   dcu0: dcu@40058000 {
+   compatible = "fsl,vf610-dcu";
+   reg = <0x40058000 0x1200>;
+   interrupts = <30 IRQ_TYPE_LEVEL_HIGH>;
+   clocks = < VF610_CLK_DCU0>,
+   < VF610_CLK_DCU0_DIV>;
+   clock-names = "dcu", "pix";
+   fsl,tcon = <>;
+   status = "disabled";
+   };
+
i2c0: i2c@40066000 {
#address-cells = <1>;
#size-cells = <0>;
-- 
2.7.4



[PATCH v3 9/9] ARM: dts: ls1021a: add pix clock to DCU dts node

2016-04-04 Thread Stefan Agner
The DCU IP has distinct clock inputs for register access and the
pixel clocks, at least in some implementations. LS1021a seems to
use the same clock, therefore specify the same clock for "dcu"
and "pix".

Signed-off-by: Stefan Agner 
---
 arch/arm/boot/dts/ls1021a.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 2c84ca2..cd5c76d 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -443,8 +443,9 @@
compatible = "fsl,ls1021a-dcu";
reg = <0x0 0x2ce 0x0 0x1>;
interrupts = ;
-   clocks = <_clk 0>;
-   clock-names = "dcu";
+   clocks = <_clk 0>,
+   <_clk 0>;
+   clock-names = "dcu", "pix";
big-endian;
status = "disabled";
};
-- 
2.7.4



[PATCH v3 7/9] ARM: dts: vf610: add display nodes

2016-04-04 Thread Stefan Agner
Add the dcu and tcon nodes to enable the Display Controller Unit
and Timing Controller in Vybrid's SoC level device-tree file.

Signed-off-by: Stefan Agner 
---
 arch/arm/boot/dts/vfxxx.dtsi | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index a9ceb5b..78e24c6 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -234,6 +234,14 @@
<2000>;
};
 
+   tcon0: timing-controller@4003d000 {
+   compatible = "fsl,vf610-tcon";
+   reg = <0x4003d000 0x1000>;
+   clocks = < VF610_CLK_TCON0>;
+   clock-names = "ipg";
+   status = "disabled";
+   };
+
wdoga5: wdog@4003e000 {
compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
reg = <0x4003e000 0x1000>;
@@ -339,6 +347,17 @@
status = "disabled";
};
 
+   dcu0: dcu@40058000 {
+   compatible = "fsl,vf610-dcu";
+   reg = <0x40058000 0x1200>;
+   interrupts = <30 IRQ_TYPE_LEVEL_HIGH>;
+   clocks = < VF610_CLK_DCU0>,
+   < VF610_CLK_DCU0_DIV>;
+   clock-names = "dcu", "pix";
+   fsl,tcon = <>;
+   status = "disabled";
+   };
+
i2c0: i2c@40066000 {
#address-cells = <1>;
#size-cells = <0>;
-- 
2.7.4



[PATCH v3 1/9] ARM: imx: clk-vf610: fix DCU clock tree

2016-04-04 Thread Stefan Agner
Similar to an earlier fix for the SAI clocks, the DCU clock hierarchy
mixes the bus clock with the display controllers pixel clock. Tests
have shown that the gates in CCM_CCGR3/9 registers do not control
the DCU pixel clock, but only the register access clock (bus clock).

Fix this by defining the parent clock of VF610_CLK_DCUx to be the bus
clock (ipg_bus).

Since the clock has not been used far, there are no further changes
needed.

Signed-off-by: Stefan Agner 
---
 drivers/clk/imx/clk-vf610.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 0a94d96..426fde2 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -321,11 +321,11 @@ static void __init vf610_clocks_init(struct device_node 
*ccm_node)
clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, 
dcu_sels, 2);
clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", 
CCM_CSCDR3, 19);
clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", 
CCM_CSCDR3, 16, 3);
-   clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, 
CCM_CCGRx_CGn(8));
+   clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "ipg_bus", CCM_CCGR3, 
CCM_CCGRx_CGn(8));
clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, 
dcu_sels, 2);
clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", 
CCM_CSCDR3, 23);
clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", 
CCM_CSCDR3, 20, 3);
-   clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, 
CCM_CCGRx_CGn(8));
+   clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "ipg_bus", CCM_CCGR9, 
CCM_CCGRx_CGn(8));
 
clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, 
esai_sels, 4);
clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", 
CCM_CSCDR2, 30);
-- 
2.7.4



[PATCH v3 1/9] ARM: imx: clk-vf610: fix DCU clock tree

2016-04-04 Thread Stefan Agner
Similar to an earlier fix for the SAI clocks, the DCU clock hierarchy
mixes the bus clock with the display controllers pixel clock. Tests
have shown that the gates in CCM_CCGR3/9 registers do not control
the DCU pixel clock, but only the register access clock (bus clock).

Fix this by defining the parent clock of VF610_CLK_DCUx to be the bus
clock (ipg_bus).

Since the clock has not been used far, there are no further changes
needed.

Signed-off-by: Stefan Agner 
---
 drivers/clk/imx/clk-vf610.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 0a94d96..426fde2 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -321,11 +321,11 @@ static void __init vf610_clocks_init(struct device_node 
*ccm_node)
clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, 
dcu_sels, 2);
clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", 
CCM_CSCDR3, 19);
clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", 
CCM_CSCDR3, 16, 3);
-   clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, 
CCM_CCGRx_CGn(8));
+   clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "ipg_bus", CCM_CCGR3, 
CCM_CCGRx_CGn(8));
clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, 
dcu_sels, 2);
clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", 
CCM_CSCDR3, 23);
clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", 
CCM_CSCDR3, 20, 3);
-   clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, 
CCM_CCGRx_CGn(8));
+   clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "ipg_bus", CCM_CCGR9, 
CCM_CCGRx_CGn(8));
 
clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, 
esai_sels, 4);
clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", 
CCM_CSCDR2, 30);
-- 
2.7.4



[PATCH REPOST] Extend PCIE_BUS_PEER2PEER to set MRSS=128 to fix CNS3xxx BM DMA.

2016-04-04 Thread Krzysztof Halasa
I think this bug needs to be fixed, this way or another.

The platform in question is Cavium CNS3xxx, ARMv6.

A recent patch by Arnd Bergmann (498a92d42596 "ARM: cns3xxx: pci: avoid
potential stack overflow") converted an explicit setting of
PCI_EXP_DEVCTL_READRQ = 0 (i.e., max 128 bytes for bus-mastering PCIe DMA
read request) to:
+pcie_bus_config = PCIE_BUS_PEER2PEER;

with the following commentary:
"The second part is how the driver sets up the Max_Read_Request_Size
value for the first device/function on bus 1, i.e. the device
plugged directly into the PCIe root port.
For all I can tell, this is in fact incomplete, as it does not
perform the same setting on devices attached to a PCIe switch,
or multi-function devices.
The solution for this part fortunately is even easier: if we
just set the global pcie_bus_config variable to PCIE_BUS_PEER2PEER,
all PCIe devices in the system are limited to 128 byte MPS, which
in turn limits the MRRS to 128 bytes for all devices, and we
no longer even need to touch any devices."

The problem is the MRRS setting is never written to the hardware.
I propose the following, though I'm not sure if we can do this safely,
especially given the comments in probe.c. OTOH, this change may be
required in other (all?) cases when the user requests
PCIE_BUS_PEER2PEER.

On this Laguna GW-2388 the following patch fixes BM DMA with:
:00:00.0 PCI bridge: Cavium Networks Device 3400 (rev 01)
:01:00.0 PCI bridge: Texas Instruments XIO2001 PCI Express-to-PCI Bridge
:02:0e.0 (PCI devices behind the bridge, these are doing actual BM xfers)
0001:00:00.0 PCI bridge: Cavium Networks Device 3400 (rev 01 - this is
 the second lane from the CPU)

pci :00:00.0: Max Payload Size set to  128/ 128 (was  128), Max Read Rq  128
pci :01:00.0: Max Payload Size set to  128/ 512 (was  128), Max Read Rq  128
pci 0001:00:00.0: Max Payload Size set to  128/ 128 (was  128), Max Read Rq  128

Signed-off-by: Krzysztof Hałasa 
Fixes: 498a92d42596 ("ARM: cns3xxx: pci: avoid potential stack overflow")

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6d7ab9b..91713b6 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1919,7 +1919,8 @@ static void pcie_write_mrrs(struct pci_dev *dev)
/* In the "safe" case, do not configure the MRRS.  There appear to be
 * issues with setting MRRS to 0 on a number of devices.
 */
-   if (pcie_bus_config != PCIE_BUS_PERFORMANCE)
+   if (pcie_bus_config != PCIE_BUS_PERFORMANCE &&
+   pcie_bus_config != PCIE_BUS_PEER2PEER)
return;
 
/* For Max performance, the MRRS must be set to the largest supported
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2771625..6f5088a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -756,7 +756,7 @@ enum pcie_bus_config_types {
PCIE_BUS_DEFAULT,   /* ensure MPS matches upstream bridge */
PCIE_BUS_SAFE,  /* use largest MPS boot-time devices support */
PCIE_BUS_PERFORMANCE,   /* use MPS and MRRS for best performance */
-   PCIE_BUS_PEER2PEER, /* set MPS = 128 for all devices */
+   PCIE_BUS_PEER2PEER, /* set MPS and MRSS to 128 for all devices */
 };
 
 extern enum pcie_bus_config_types pcie_bus_config;


[PATCH v3 0/9] add TCON and Vybrid support

2016-04-04 Thread Stefan Agner
This patchset adds the missing pieces to make the Freescale
DCU DRM driver work on Freescale Vybrid.

Foremost, it adds support for the timing controller (TCON)
module. The module is between the Display Controller and the
actual output pins. It allows to alter the timings for RAW
TFT displays, but can also operate in a bypass mode. This
change has only support for the bypass mode.

Earlier variants of the DCU DRM driver configured the TCON
module in bypass mode, however this has been removed and
postponed. The last variant with the TCON code was v9:
https://lkml.org/lkml/2015/7/13/242

The patchset also fixes the DCU related clocks in the Vybrid
clock tree and makes use of the common clock framework for
the pixelclock divider.

Testing on LS1021a welcome!

Changes since v2:
- Add second clock ("pix") to ls1021a.dtsi too
- Updated documentation regarding clocks
- Do not warn if TCON is missing as some device do not
  provide it
- Allocate memory after checking for TCON node and return
  -ENOMEM if memory allocation fails
- Add fsl,tcon.txt to MAINTAINERS file

Changes since v1:
- Properly disable clocks on errors
- Create clear seperation of pixel clock and bus clock
- Simplified TCON driver by removing suspend/resume
  capabilities (encoder disable/enable makes sure that
  TCON bypass gets disabled/reenabled on suspend)
- Use common clock framework to create a divider clock
  which represents the DCU internal pixel clock divider

Stefan Agner (9):
  ARM: imx: clk-vf610: fix DCU clock tree
  ARM: imx: clk-vf610: add TCON ipg clock
  drm/fsl-dcu: disable clock on initialization failure and remove
  drm/fsl-dcu: add extra clock for pixel clock
  drm/fsl-dcu: use common clock framework for pixel clock divider
  drm/fsl-dcu: add TCON driver
  ARM: dts: vf610: add display nodes
  ARM: dts: vf610-colibri: enable display controller
  ARM: dts: ls1021a: add pix clock to DCU dts node

 .../devicetree/bindings/display/fsl,dcu.txt|  15 ++-
 .../devicetree/bindings/display/fsl,tcon.txt   |  18 
 MAINTAINERS|   1 +
 arch/arm/boot/dts/ls1021a.dtsi |   5 +-
 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi  |  16 +++
 arch/arm/boot/dts/vf-colibri.dtsi  |  33 ++
 arch/arm/boot/dts/vfxxx.dtsi   |  19 
 drivers/clk/imx/clk-vf610.c|   7 +-
 drivers/gpu/drm/fsl-dcu/Makefile   |   3 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c |   7 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c  |  73 ++
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h  |   2 +
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c  |  11 ++
 drivers/gpu/drm/fsl-dcu/fsl_tcon.c | 111 +
 drivers/gpu/drm/fsl-dcu/fsl_tcon.h |  33 ++
 include/dt-bindings/clock/vf610-clock.h|   4 +-
 16 files changed, 323 insertions(+), 35 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/fsl,tcon.txt
 create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_tcon.c
 create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_tcon.h

-- 
2.7.4



[PATCH v3 2/9] ARM: imx: clk-vf610: add TCON ipg clock

2016-04-04 Thread Stefan Agner
Add the ipg (bus) clock for the TCON modules (Timing Controller). This
module is required by the new DCU DRM driver, since the display signals
pass through TCON.

Signed-off-by: Stefan Agner 
---
 drivers/clk/imx/clk-vf610.c | 3 +++
 include/dt-bindings/clock/vf610-clock.h | 4 +++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 426fde2..43be1cf 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -327,6 +327,9 @@ static void __init vf610_clocks_init(struct device_node 
*ccm_node)
clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", 
CCM_CSCDR3, 20, 3);
clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "ipg_bus", CCM_CCGR9, 
CCM_CCGRx_CGn(8));
 
+   clk[VF610_CLK_TCON0] = imx_clk_gate2("tcon0", "platform_bus", 
CCM_CCGR1, CCM_CCGRx_CGn(13));
+   clk[VF610_CLK_TCON1] = imx_clk_gate2("tcon1", "platform_bus", 
CCM_CCGR7, CCM_CCGRx_CGn(13));
+
clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, 
esai_sels, 4);
clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", 
CCM_CSCDR2, 30);
clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", 
CCM_CSCDR2, 24, 4);
diff --git a/include/dt-bindings/clock/vf610-clock.h 
b/include/dt-bindings/clock/vf610-clock.h
index 56c16aa..fbe17cc 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -195,6 +195,8 @@
 #define VF610_CLK_SNVS 182
 #define VF610_CLK_DAP  183
 #define VF610_CLK_OCOTP 184
-#define VF610_CLK_END  185
+#define VF610_CLK_TCON0185
+#define VF610_CLK_TCON1186
+#define VF610_CLK_END  187
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
-- 
2.7.4



[PATCH REPOST] Extend PCIE_BUS_PEER2PEER to set MRSS=128 to fix CNS3xxx BM DMA.

2016-04-04 Thread Krzysztof Halasa
I think this bug needs to be fixed, this way or another.

The platform in question is Cavium CNS3xxx, ARMv6.

A recent patch by Arnd Bergmann (498a92d42596 "ARM: cns3xxx: pci: avoid
potential stack overflow") converted an explicit setting of
PCI_EXP_DEVCTL_READRQ = 0 (i.e., max 128 bytes for bus-mastering PCIe DMA
read request) to:
+pcie_bus_config = PCIE_BUS_PEER2PEER;

with the following commentary:
"The second part is how the driver sets up the Max_Read_Request_Size
value for the first device/function on bus 1, i.e. the device
plugged directly into the PCIe root port.
For all I can tell, this is in fact incomplete, as it does not
perform the same setting on devices attached to a PCIe switch,
or multi-function devices.
The solution for this part fortunately is even easier: if we
just set the global pcie_bus_config variable to PCIE_BUS_PEER2PEER,
all PCIe devices in the system are limited to 128 byte MPS, which
in turn limits the MRRS to 128 bytes for all devices, and we
no longer even need to touch any devices."

The problem is the MRRS setting is never written to the hardware.
I propose the following, though I'm not sure if we can do this safely,
especially given the comments in probe.c. OTOH, this change may be
required in other (all?) cases when the user requests
PCIE_BUS_PEER2PEER.

On this Laguna GW-2388 the following patch fixes BM DMA with:
:00:00.0 PCI bridge: Cavium Networks Device 3400 (rev 01)
:01:00.0 PCI bridge: Texas Instruments XIO2001 PCI Express-to-PCI Bridge
:02:0e.0 (PCI devices behind the bridge, these are doing actual BM xfers)
0001:00:00.0 PCI bridge: Cavium Networks Device 3400 (rev 01 - this is
 the second lane from the CPU)

pci :00:00.0: Max Payload Size set to  128/ 128 (was  128), Max Read Rq  128
pci :01:00.0: Max Payload Size set to  128/ 512 (was  128), Max Read Rq  128
pci 0001:00:00.0: Max Payload Size set to  128/ 128 (was  128), Max Read Rq  128

Signed-off-by: Krzysztof Hałasa 
Fixes: 498a92d42596 ("ARM: cns3xxx: pci: avoid potential stack overflow")

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6d7ab9b..91713b6 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1919,7 +1919,8 @@ static void pcie_write_mrrs(struct pci_dev *dev)
/* In the "safe" case, do not configure the MRRS.  There appear to be
 * issues with setting MRRS to 0 on a number of devices.
 */
-   if (pcie_bus_config != PCIE_BUS_PERFORMANCE)
+   if (pcie_bus_config != PCIE_BUS_PERFORMANCE &&
+   pcie_bus_config != PCIE_BUS_PEER2PEER)
return;
 
/* For Max performance, the MRRS must be set to the largest supported
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2771625..6f5088a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -756,7 +756,7 @@ enum pcie_bus_config_types {
PCIE_BUS_DEFAULT,   /* ensure MPS matches upstream bridge */
PCIE_BUS_SAFE,  /* use largest MPS boot-time devices support */
PCIE_BUS_PERFORMANCE,   /* use MPS and MRRS for best performance */
-   PCIE_BUS_PEER2PEER, /* set MPS = 128 for all devices */
+   PCIE_BUS_PEER2PEER, /* set MPS and MRSS to 128 for all devices */
 };
 
 extern enum pcie_bus_config_types pcie_bus_config;


[PATCH v3 0/9] add TCON and Vybrid support

2016-04-04 Thread Stefan Agner
This patchset adds the missing pieces to make the Freescale
DCU DRM driver work on Freescale Vybrid.

Foremost, it adds support for the timing controller (TCON)
module. The module is between the Display Controller and the
actual output pins. It allows to alter the timings for RAW
TFT displays, but can also operate in a bypass mode. This
change has only support for the bypass mode.

Earlier variants of the DCU DRM driver configured the TCON
module in bypass mode, however this has been removed and
postponed. The last variant with the TCON code was v9:
https://lkml.org/lkml/2015/7/13/242

The patchset also fixes the DCU related clocks in the Vybrid
clock tree and makes use of the common clock framework for
the pixelclock divider.

Testing on LS1021a welcome!

Changes since v2:
- Add second clock ("pix") to ls1021a.dtsi too
- Updated documentation regarding clocks
- Do not warn if TCON is missing as some device do not
  provide it
- Allocate memory after checking for TCON node and return
  -ENOMEM if memory allocation fails
- Add fsl,tcon.txt to MAINTAINERS file

Changes since v1:
- Properly disable clocks on errors
- Create clear seperation of pixel clock and bus clock
- Simplified TCON driver by removing suspend/resume
  capabilities (encoder disable/enable makes sure that
  TCON bypass gets disabled/reenabled on suspend)
- Use common clock framework to create a divider clock
  which represents the DCU internal pixel clock divider

Stefan Agner (9):
  ARM: imx: clk-vf610: fix DCU clock tree
  ARM: imx: clk-vf610: add TCON ipg clock
  drm/fsl-dcu: disable clock on initialization failure and remove
  drm/fsl-dcu: add extra clock for pixel clock
  drm/fsl-dcu: use common clock framework for pixel clock divider
  drm/fsl-dcu: add TCON driver
  ARM: dts: vf610: add display nodes
  ARM: dts: vf610-colibri: enable display controller
  ARM: dts: ls1021a: add pix clock to DCU dts node

 .../devicetree/bindings/display/fsl,dcu.txt|  15 ++-
 .../devicetree/bindings/display/fsl,tcon.txt   |  18 
 MAINTAINERS|   1 +
 arch/arm/boot/dts/ls1021a.dtsi |   5 +-
 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi  |  16 +++
 arch/arm/boot/dts/vf-colibri.dtsi  |  33 ++
 arch/arm/boot/dts/vfxxx.dtsi   |  19 
 drivers/clk/imx/clk-vf610.c|   7 +-
 drivers/gpu/drm/fsl-dcu/Makefile   |   3 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c |   7 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c  |  73 ++
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h  |   2 +
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c  |  11 ++
 drivers/gpu/drm/fsl-dcu/fsl_tcon.c | 111 +
 drivers/gpu/drm/fsl-dcu/fsl_tcon.h |  33 ++
 include/dt-bindings/clock/vf610-clock.h|   4 +-
 16 files changed, 323 insertions(+), 35 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/fsl,tcon.txt
 create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_tcon.c
 create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_tcon.h

-- 
2.7.4



[PATCH v3 2/9] ARM: imx: clk-vf610: add TCON ipg clock

2016-04-04 Thread Stefan Agner
Add the ipg (bus) clock for the TCON modules (Timing Controller). This
module is required by the new DCU DRM driver, since the display signals
pass through TCON.

Signed-off-by: Stefan Agner 
---
 drivers/clk/imx/clk-vf610.c | 3 +++
 include/dt-bindings/clock/vf610-clock.h | 4 +++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 426fde2..43be1cf 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -327,6 +327,9 @@ static void __init vf610_clocks_init(struct device_node 
*ccm_node)
clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", 
CCM_CSCDR3, 20, 3);
clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "ipg_bus", CCM_CCGR9, 
CCM_CCGRx_CGn(8));
 
+   clk[VF610_CLK_TCON0] = imx_clk_gate2("tcon0", "platform_bus", 
CCM_CCGR1, CCM_CCGRx_CGn(13));
+   clk[VF610_CLK_TCON1] = imx_clk_gate2("tcon1", "platform_bus", 
CCM_CCGR7, CCM_CCGRx_CGn(13));
+
clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, 
esai_sels, 4);
clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", 
CCM_CSCDR2, 30);
clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", 
CCM_CSCDR2, 24, 4);
diff --git a/include/dt-bindings/clock/vf610-clock.h 
b/include/dt-bindings/clock/vf610-clock.h
index 56c16aa..fbe17cc 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -195,6 +195,8 @@
 #define VF610_CLK_SNVS 182
 #define VF610_CLK_DAP  183
 #define VF610_CLK_OCOTP 184
-#define VF610_CLK_END  185
+#define VF610_CLK_TCON0185
+#define VF610_CLK_TCON1186
+#define VF610_CLK_END  187
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
-- 
2.7.4



Re: [PATCH v2] parport: register driver later

2016-04-04 Thread Sudip Mukherjee
On Mon, Mar 07, 2016 at 10:32:55AM -0700, Ross Zwisler wrote:
> On Sun, Mar 06, 2016 at 08:40:10PM +0530, Sudip Mukherjee wrote:
> > If the parport bus is not yet registered and any device using parallel
> > port tries to register with the bus we get a stackdump with a message
> > of Kernel bug.
> > 
> > Reported-by: Fengguang Wu 
> > Cc:  # 4.2+
> > Signed-off-by: Sudip Mukherjee 
> > ---
> > 
> > Hi Ross,
> > Can you please test this patch in your setup. This is a respin of the
> > previous patch in another way.
> 
> Yep, this also solves the issue for me.
> 
> Tested-by: Ross Zwisler 

Hi Greg,
If this patch is ok, can we please have it in v4.6 .
Anyway, the problem patch which this patch tried to fix has already
been reverted by Linus - 
1701f680407c ("Revert "ppdev: use new parport device model"") but we still
can have problem with the other devices that use parport.

BTW, I know you are busy, but in these situations where I need to have
the fix urgently in the tree, is there any other way to solve the purpose?
I feel it was incompetency on my part where Linus had to interfere and
revert a patch even though the fix was already posted.

regards
sudip



Re: [PATCH v2] parport: register driver later

2016-04-04 Thread Sudip Mukherjee
On Mon, Mar 07, 2016 at 10:32:55AM -0700, Ross Zwisler wrote:
> On Sun, Mar 06, 2016 at 08:40:10PM +0530, Sudip Mukherjee wrote:
> > If the parport bus is not yet registered and any device using parallel
> > port tries to register with the bus we get a stackdump with a message
> > of Kernel bug.
> > 
> > Reported-by: Fengguang Wu 
> > Cc:  # 4.2+
> > Signed-off-by: Sudip Mukherjee 
> > ---
> > 
> > Hi Ross,
> > Can you please test this patch in your setup. This is a respin of the
> > previous patch in another way.
> 
> Yep, this also solves the issue for me.
> 
> Tested-by: Ross Zwisler 

Hi Greg,
If this patch is ok, can we please have it in v4.6 .
Anyway, the problem patch which this patch tried to fix has already
been reverted by Linus - 
1701f680407c ("Revert "ppdev: use new parport device model"") but we still
can have problem with the other devices that use parport.

BTW, I know you are busy, but in these situations where I need to have
the fix urgently in the tree, is there any other way to solve the purpose?
I feel it was incompetency on my part where Linus had to interfere and
revert a patch even though the fix was already posted.

regards
sudip



Re: [PATCH] perf config: Fix build with older toolchain.

2016-04-04 Thread Taeung Song

Hi,

On 04/05/2016 07:07 AM, Vinson Lee wrote:

Fix build error on Ubuntu 12.04.5 with GCC 4.6.3.

   CC   util/config.o
util/config.c: In function ‘perf_buildid_config’:
util/config.c:384:15: error: declaration of ‘dirname’ shadows a global 
declaration [-Werror=shadow]


I'm sorry, lately I added perf_buildid_config() but I didn't test by 
gcc-4.6.3



Fixes: 9cb5987c8227 ("perf config: Rework buildid_dir_command_config to 
perf_buildid_config")
Signed-off-by: Vinson Lee 
---
  tools/perf/util/config.c |6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 5c20d783423b..a3d80a05e7a2 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -381,11 +381,11 @@ static int perf_buildid_config(const char *var, const 
char *value)
  {
/* same dir for all commands */
if (!strcmp(var, "buildid.dir")) {
-   const char *dirname = perf_config_dirname(var, value);
+   const char *v = perf_config_dirname(var, value);


Why you use 'v' variable name ?

'v' variable name was used in set_buildid_dir(), too.
But I send a patch renaming 'v' to 'home' because 'home' is more readable.
37194f4 ("perf config: Rename 'v' to 'home' in set_buildid_dir()")
https://lkml.org/lkml/2016/3/27/98

IMHO, I like using 'dir' instead of 'v'.


Thanks,
Taeung



-   if (!dirname)
+   if (!v)
return -1;
-   strncpy(buildid_dir, dirname, MAXPATHLEN-1);
+   strncpy(buildid_dir, v, MAXPATHLEN-1);
buildid_dir[MAXPATHLEN-1] = '\0';
}




Re: [PATCH] perf config: Fix build with older toolchain.

2016-04-04 Thread Taeung Song

Hi,

On 04/05/2016 07:07 AM, Vinson Lee wrote:

Fix build error on Ubuntu 12.04.5 with GCC 4.6.3.

   CC   util/config.o
util/config.c: In function ‘perf_buildid_config’:
util/config.c:384:15: error: declaration of ‘dirname’ shadows a global 
declaration [-Werror=shadow]


I'm sorry, lately I added perf_buildid_config() but I didn't test by 
gcc-4.6.3



Fixes: 9cb5987c8227 ("perf config: Rework buildid_dir_command_config to 
perf_buildid_config")
Signed-off-by: Vinson Lee 
---
  tools/perf/util/config.c |6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 5c20d783423b..a3d80a05e7a2 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -381,11 +381,11 @@ static int perf_buildid_config(const char *var, const 
char *value)
  {
/* same dir for all commands */
if (!strcmp(var, "buildid.dir")) {
-   const char *dirname = perf_config_dirname(var, value);
+   const char *v = perf_config_dirname(var, value);


Why you use 'v' variable name ?

'v' variable name was used in set_buildid_dir(), too.
But I send a patch renaming 'v' to 'home' because 'home' is more readable.
37194f4 ("perf config: Rename 'v' to 'home' in set_buildid_dir()")
https://lkml.org/lkml/2016/3/27/98

IMHO, I like using 'dir' instead of 'v'.


Thanks,
Taeung



-   if (!dirname)
+   if (!v)
return -1;
-   strncpy(buildid_dir, dirname, MAXPATHLEN-1);
+   strncpy(buildid_dir, v, MAXPATHLEN-1);
buildid_dir[MAXPATHLEN-1] = '\0';
}




Re: [PATCH] usb: dwc3: keystone: drop dma_mask configuration

2016-04-04 Thread Felipe Balbi

Hi,

Grygorii Strashko  writes:
> On 04/04/2016 02:45 PM, Felipe Balbi wrote:
>>
>> Hi,
>>
>> Grygorii Strashko  writes:
>>> The Keystone 2 supports DT-boot only, as result dma_mask will be
>>> always configured properly from DT -
>>> of_platform_device_create_pdata()->of_dma_configure(). More over,
>>> dwc3-keystone.c can be built as module and in this case it's unsafe to
>>> assign local variable as dma_mask.
>>>
>>> Hence, remove dma_mask configuration code.
>>>
>>> Cc: Murali Karicheri 
>>> Signed-off-by: Grygorii Strashko 
>>
>> with these two patches from you, does USB Peripheral work on k2 devices ?
>
> I've tried CONFIG_USB_DWC3_GADGET=y + g_zero and k2e was detected
> as gzero dev from Host PC
>
>>
>> I'll drop my k2 changes from my series which I sent on saturday.
>>
>
> Yes, please.

can you test a similar patch to dwc3-omap.c, then ?

-- 
balbi


signature.asc
Description: PGP signature


Re: [PATCH] usb: dwc3: keystone: drop dma_mask configuration

2016-04-04 Thread Felipe Balbi

Hi,

Grygorii Strashko  writes:
> On 04/04/2016 02:45 PM, Felipe Balbi wrote:
>>
>> Hi,
>>
>> Grygorii Strashko  writes:
>>> The Keystone 2 supports DT-boot only, as result dma_mask will be
>>> always configured properly from DT -
>>> of_platform_device_create_pdata()->of_dma_configure(). More over,
>>> dwc3-keystone.c can be built as module and in this case it's unsafe to
>>> assign local variable as dma_mask.
>>>
>>> Hence, remove dma_mask configuration code.
>>>
>>> Cc: Murali Karicheri 
>>> Signed-off-by: Grygorii Strashko 
>>
>> with these two patches from you, does USB Peripheral work on k2 devices ?
>
> I've tried CONFIG_USB_DWC3_GADGET=y + g_zero and k2e was detected
> as gzero dev from Host PC
>
>>
>> I'll drop my k2 changes from my series which I sent on saturday.
>>
>
> Yes, please.

can you test a similar patch to dwc3-omap.c, then ?

-- 
balbi


signature.asc
Description: PGP signature


Re: [PATCHv2 6/7] ARM: socfpga: Enable Arria10 OCRAM ECC on startup

2016-04-04 Thread Thor Thayer

Hi,

On 03/31/2016 01:48 PM, ttha...@opensource.altera.com wrote:

From: Thor Thayer 

Enable ECC for Arria10 On-Chip RAM on machine startup. The ECC has to
be enabled and memory initialized before data is stored in memory
otherwise the ECC will fail on reads.

Signed-off-by: Thor Thayer 
---
v2: Add Arria10 ECC block initialization locally.
---
  arch/arm/mach-socfpga/ocram.c |  128 +
  1 file changed, 128 insertions(+)

diff --git a/arch/arm/mach-socfpga/ocram.c b/arch/arm/mach-socfpga/ocram.c
index 60ec643..d4a524c 100644
--- a/arch/arm/mach-socfpga/ocram.c
+++ b/arch/arm/mach-socfpga/ocram.c
@@ -13,12 +13,15 @@
   * You should have received a copy of the GNU General Public License along 
with
   * this program.  If not, see .
   */
+#include 
  #include 
  #include 
  #include 
  #include 
  #include 

+#include "core.h"
+
  #define ALTR_OCRAM_CLEAR_ECC  0x0018
  #define ALTR_OCRAM_ECC_EN 0x0019

@@ -47,3 +50,128 @@ void socfpga_init_ocram_ecc(void)

iounmap(mapped_ocr_edac_addr);
  }
+
+/* Arria10 OCRAM Section */
+#define ALTR_A10_ECC_CTRL_OFST  0x08
+#define ALTR_A10_OCRAM_ECC_EN_CTL   (BIT(1) | BIT(0))
+#define ALTR_A10_ECC_INITA  BIT(16)
+
+#define ALTR_A10_ECC_INITSTAT_OFST  0x0C
+#define ALTR_A10_ECC_INITCOMPLETEA  BIT(0)
+#define ALTR_A10_ECC_INITCOMPLETEB  BIT(8)
+
+#define ALTR_A10_ECC_ERRINTEN_OFST  0x10
+#define ALTR_A10_ECC_SERRINTEN  BIT(0)
+
+#define ALTR_A10_ECC_INTSTAT_OFST   0x20
+#define ALTR_A10_ECC_SERRPENA   BIT(0)
+#define ALTR_A10_ECC_DERRPENA   BIT(8)
+#define ALTR_A10_ECC_ERRPENA_MASK   (ALTR_A10_ECC_SERRPENA | \
+ALTR_A10_ECC_DERRPENA)
+/* ECC Manager Defines */
+#define A10_SYSMGR_ECC_INTMASK_SET_OFST   0x94
+#define A10_SYSMGR_ECC_INTMASK_CLR_OFST   0x98
+#define A10_SYSMGR_ECC_INTMASK_OCRAM  BIT(1)
+
+#define ALTR_A10_ECC_INIT_WATCHDOG_10US   1
+
+static void ecc_set_bits(u32 bit_mask, void __iomem *ioaddr)
+{
+   u32 value = readl(ioaddr);
+
+   value |= bit_mask;
+   writel(value, ioaddr);
+}
+
+static void ecc_clear_bits(u32 bit_mask, void __iomem *ioaddr)
+{
+   u32 value = readl(ioaddr);
+
+   value &= ~bit_mask;
+   writel(value, ioaddr);
+}
+
+static int ecc_test_bits(u32 bit_mask, void __iomem *ioaddr)
+{
+   u32 value = readl(ioaddr);
+
+   return (value & bit_mask) ? 1 : 0;
+}
+
+/*
+ * This function uses the memory initialization block in the Arria10 ECC
+ * controller to initialize/clear the entire memory data and ECC data.
+ */
+static int altr_init_memory_port(void __iomem *ioaddr)
+{
+   int limit = ALTR_A10_ECC_INIT_WATCHDOG_10US;
+
+   ecc_set_bits(ALTR_A10_ECC_INITA, (ioaddr + ALTR_A10_ECC_CTRL_OFST));
+   while (limit--) {
+   if (ecc_test_bits(ALTR_A10_ECC_INITCOMPLETEA,
+ (ioaddr + ALTR_A10_ECC_INITSTAT_OFST)))
+   break;
+   udelay(1);
+   }
+   if (limit < 0)
+   return -EBUSY;
+
+   /* Clear any pending ECC interrupts */
+   writel(ALTR_A10_ECC_ERRPENA_MASK,
+  (ioaddr + ALTR_A10_ECC_INTSTAT_OFST));
+
+   return 0;
+}
+
+void socfpga_init_arria10_ocram_ecc(void)
+{
+   struct device_node *np;
+   int ret = 0;
+   void __iomem *ecc_block_base;
+
+   if (!sys_manager_base_addr) {
+   pr_err("SOCFPGA: sys-mgr is not initialized\n");
+   return;
+   }
+
+   /* Find the OCRAM EDAC device tree node */
+   np = of_find_compatible_node(NULL, NULL, "altr,socfpga-a10-ocram-ecc");
+   if (!np) {
+   pr_err("Unable to find socfpga-a10-ocram-ecc\n");
+   return;
+   }
+
+   /* Map the ECC Block */
+   ecc_block_base = of_iomap(np, 0);
+   of_node_put(np);
+   if (!ecc_block_base) {
+   pr_err("Unable to map OCRAM ECC block\n");
+   return;
+   }
+
+   /* Disable ECC */
+   writel(ALTR_A10_OCRAM_ECC_EN_CTL,
+  sys_manager_base_addr + A10_SYSMGR_ECC_INTMASK_SET_OFST);
+   ecc_clear_bits(ALTR_A10_ECC_SERRINTEN,
+  (ecc_block_base + ALTR_A10_ECC_ERRINTEN_OFST));
+   ecc_clear_bits(ALTR_A10_OCRAM_ECC_EN_CTL,
+  (ecc_block_base + ALTR_A10_ECC_CTRL_OFST));
+
+   /* Use HW initialization block to initialize memory for ECC */
+   ret = altr_init_memory_port(ecc_block_base);
+   if (ret) {
+   pr_err("ECC: cannot init OCRAM PORTA memory\n");
+   return;


I realize that I'm not calling iounmap(ecc_block_base) and I'll fix that 
in the next revision with a goto.



+   }
+
+   /* Enable ECC */
+   ecc_set_bits(ALTR_A10_OCRAM_ECC_EN_CTL,
+(ecc_block_base + 

Re: [PATCHv2 6/7] ARM: socfpga: Enable Arria10 OCRAM ECC on startup

2016-04-04 Thread Thor Thayer

Hi,

On 03/31/2016 01:48 PM, ttha...@opensource.altera.com wrote:

From: Thor Thayer 

Enable ECC for Arria10 On-Chip RAM on machine startup. The ECC has to
be enabled and memory initialized before data is stored in memory
otherwise the ECC will fail on reads.

Signed-off-by: Thor Thayer 
---
v2: Add Arria10 ECC block initialization locally.
---
  arch/arm/mach-socfpga/ocram.c |  128 +
  1 file changed, 128 insertions(+)

diff --git a/arch/arm/mach-socfpga/ocram.c b/arch/arm/mach-socfpga/ocram.c
index 60ec643..d4a524c 100644
--- a/arch/arm/mach-socfpga/ocram.c
+++ b/arch/arm/mach-socfpga/ocram.c
@@ -13,12 +13,15 @@
   * You should have received a copy of the GNU General Public License along 
with
   * this program.  If not, see .
   */
+#include 
  #include 
  #include 
  #include 
  #include 
  #include 

+#include "core.h"
+
  #define ALTR_OCRAM_CLEAR_ECC  0x0018
  #define ALTR_OCRAM_ECC_EN 0x0019

@@ -47,3 +50,128 @@ void socfpga_init_ocram_ecc(void)

iounmap(mapped_ocr_edac_addr);
  }
+
+/* Arria10 OCRAM Section */
+#define ALTR_A10_ECC_CTRL_OFST  0x08
+#define ALTR_A10_OCRAM_ECC_EN_CTL   (BIT(1) | BIT(0))
+#define ALTR_A10_ECC_INITA  BIT(16)
+
+#define ALTR_A10_ECC_INITSTAT_OFST  0x0C
+#define ALTR_A10_ECC_INITCOMPLETEA  BIT(0)
+#define ALTR_A10_ECC_INITCOMPLETEB  BIT(8)
+
+#define ALTR_A10_ECC_ERRINTEN_OFST  0x10
+#define ALTR_A10_ECC_SERRINTEN  BIT(0)
+
+#define ALTR_A10_ECC_INTSTAT_OFST   0x20
+#define ALTR_A10_ECC_SERRPENA   BIT(0)
+#define ALTR_A10_ECC_DERRPENA   BIT(8)
+#define ALTR_A10_ECC_ERRPENA_MASK   (ALTR_A10_ECC_SERRPENA | \
+ALTR_A10_ECC_DERRPENA)
+/* ECC Manager Defines */
+#define A10_SYSMGR_ECC_INTMASK_SET_OFST   0x94
+#define A10_SYSMGR_ECC_INTMASK_CLR_OFST   0x98
+#define A10_SYSMGR_ECC_INTMASK_OCRAM  BIT(1)
+
+#define ALTR_A10_ECC_INIT_WATCHDOG_10US   1
+
+static void ecc_set_bits(u32 bit_mask, void __iomem *ioaddr)
+{
+   u32 value = readl(ioaddr);
+
+   value |= bit_mask;
+   writel(value, ioaddr);
+}
+
+static void ecc_clear_bits(u32 bit_mask, void __iomem *ioaddr)
+{
+   u32 value = readl(ioaddr);
+
+   value &= ~bit_mask;
+   writel(value, ioaddr);
+}
+
+static int ecc_test_bits(u32 bit_mask, void __iomem *ioaddr)
+{
+   u32 value = readl(ioaddr);
+
+   return (value & bit_mask) ? 1 : 0;
+}
+
+/*
+ * This function uses the memory initialization block in the Arria10 ECC
+ * controller to initialize/clear the entire memory data and ECC data.
+ */
+static int altr_init_memory_port(void __iomem *ioaddr)
+{
+   int limit = ALTR_A10_ECC_INIT_WATCHDOG_10US;
+
+   ecc_set_bits(ALTR_A10_ECC_INITA, (ioaddr + ALTR_A10_ECC_CTRL_OFST));
+   while (limit--) {
+   if (ecc_test_bits(ALTR_A10_ECC_INITCOMPLETEA,
+ (ioaddr + ALTR_A10_ECC_INITSTAT_OFST)))
+   break;
+   udelay(1);
+   }
+   if (limit < 0)
+   return -EBUSY;
+
+   /* Clear any pending ECC interrupts */
+   writel(ALTR_A10_ECC_ERRPENA_MASK,
+  (ioaddr + ALTR_A10_ECC_INTSTAT_OFST));
+
+   return 0;
+}
+
+void socfpga_init_arria10_ocram_ecc(void)
+{
+   struct device_node *np;
+   int ret = 0;
+   void __iomem *ecc_block_base;
+
+   if (!sys_manager_base_addr) {
+   pr_err("SOCFPGA: sys-mgr is not initialized\n");
+   return;
+   }
+
+   /* Find the OCRAM EDAC device tree node */
+   np = of_find_compatible_node(NULL, NULL, "altr,socfpga-a10-ocram-ecc");
+   if (!np) {
+   pr_err("Unable to find socfpga-a10-ocram-ecc\n");
+   return;
+   }
+
+   /* Map the ECC Block */
+   ecc_block_base = of_iomap(np, 0);
+   of_node_put(np);
+   if (!ecc_block_base) {
+   pr_err("Unable to map OCRAM ECC block\n");
+   return;
+   }
+
+   /* Disable ECC */
+   writel(ALTR_A10_OCRAM_ECC_EN_CTL,
+  sys_manager_base_addr + A10_SYSMGR_ECC_INTMASK_SET_OFST);
+   ecc_clear_bits(ALTR_A10_ECC_SERRINTEN,
+  (ecc_block_base + ALTR_A10_ECC_ERRINTEN_OFST));
+   ecc_clear_bits(ALTR_A10_OCRAM_ECC_EN_CTL,
+  (ecc_block_base + ALTR_A10_ECC_CTRL_OFST));
+
+   /* Use HW initialization block to initialize memory for ECC */
+   ret = altr_init_memory_port(ecc_block_base);
+   if (ret) {
+   pr_err("ECC: cannot init OCRAM PORTA memory\n");
+   return;


I realize that I'm not calling iounmap(ecc_block_base) and I'll fix that 
in the next revision with a goto.



+   }
+
+   /* Enable ECC */
+   ecc_set_bits(ALTR_A10_OCRAM_ECC_EN_CTL,
+(ecc_block_base + ALTR_A10_ECC_CTRL_OFST));
+   ecc_set_bits(ALTR_A10_ECC_SERRINTEN,
+

Re: [PATCH v3 2/2] usb:dwc3: pass arch data to xhci-hcd child

2016-04-04 Thread Felipe Balbi
santosh shilimkar  writes:
> On 4/3/2016 11:28 PM, Felipe Balbi wrote:
>> santosh shilimkar  writes:
>>> +Arnd, RMK,
>>>
>>> On 4/1/2016 4:57 AM, Felipe Balbi wrote:

 Hi,

 Grygorii Strashko  writes:
> On 04/01/2016 01:20 PM, Felipe Balbi wrote:
>>>
>>> [...]
>>>
> commit 7ace8fc8219e4cbbfd5b4790390d9a01a2541cdf
> Author: Yoshihiro Shimoda 
> Date:   Mon Jul 13 18:10:05 2015 +0900
>
>   usb: gadget: udc: core: Fix argument of dma_map_single for IOMMU
>
>   The dma_map_single and dma_unmap_single should set 
> "gadget->dev.parent"
>   instead of ">dev" in the first argument because the parent 
> has
>   a udc controller's device pointer.
>   Otherwise, iommu functions are not called in ARM environment.
>
>   Signed-off-by: Yoshihiro Shimoda 
>   Signed-off-by: Felipe Balbi 
>
> Above actually means that DMA configuration code can be dropped from
> usb_add_gadget_udc_release() completely. Right?:

 true, but now I'm not sure what's better: copy all necessary bits from
 parent or just pass the parent device to all DMA API.

 Anybody to shed a light here ?

>>> The expectation is drivers should pass the proper dev pointers and let
>>> core DMA code deal with it since it knows the per device dma properties.
>>
>> okay, so how do you get proper DMA pointers with something like this:
>>
>>  kdwc3_dma_mask = dma_get_mask(dev);
>>  dev->dma_mask = _dma_mask;
>>
>> This doesn't anything.
>>
> Drivers actually needs to touch dma_mask(s) only if the core DMA
> code hasn't populated it it.

that's fair, but when driver _do_ touch it, I'd rather it be useful ;-)

> I see Grygorii pointed out couple of things already.

yeah

-- 
balbi


signature.asc
Description: PGP signature


Re: [PATCH v3 2/2] usb:dwc3: pass arch data to xhci-hcd child

2016-04-04 Thread Felipe Balbi
santosh shilimkar  writes:
> On 4/3/2016 11:28 PM, Felipe Balbi wrote:
>> santosh shilimkar  writes:
>>> +Arnd, RMK,
>>>
>>> On 4/1/2016 4:57 AM, Felipe Balbi wrote:

 Hi,

 Grygorii Strashko  writes:
> On 04/01/2016 01:20 PM, Felipe Balbi wrote:
>>>
>>> [...]
>>>
> commit 7ace8fc8219e4cbbfd5b4790390d9a01a2541cdf
> Author: Yoshihiro Shimoda 
> Date:   Mon Jul 13 18:10:05 2015 +0900
>
>   usb: gadget: udc: core: Fix argument of dma_map_single for IOMMU
>
>   The dma_map_single and dma_unmap_single should set 
> "gadget->dev.parent"
>   instead of ">dev" in the first argument because the parent 
> has
>   a udc controller's device pointer.
>   Otherwise, iommu functions are not called in ARM environment.
>
>   Signed-off-by: Yoshihiro Shimoda 
>   Signed-off-by: Felipe Balbi 
>
> Above actually means that DMA configuration code can be dropped from
> usb_add_gadget_udc_release() completely. Right?:

 true, but now I'm not sure what's better: copy all necessary bits from
 parent or just pass the parent device to all DMA API.

 Anybody to shed a light here ?

>>> The expectation is drivers should pass the proper dev pointers and let
>>> core DMA code deal with it since it knows the per device dma properties.
>>
>> okay, so how do you get proper DMA pointers with something like this:
>>
>>  kdwc3_dma_mask = dma_get_mask(dev);
>>  dev->dma_mask = _dma_mask;
>>
>> This doesn't anything.
>>
> Drivers actually needs to touch dma_mask(s) only if the core DMA
> code hasn't populated it it.

that's fair, but when driver _do_ touch it, I'd rather it be useful ;-)

> I see Grygorii pointed out couple of things already.

yeah

-- 
balbi


signature.asc
Description: PGP signature


Re: [PATCH v10 1/2] printk: Make printk() completely async

2016-04-04 Thread Sergey Senozhatsky
Hello Andrew,

On (04/04/16 15:51), Andrew Morton wrote:
[..]
> The whole idea remains worrisome.  It is definitely making printk()
> less reliable in the vast majority of cases: what happens if the
> scheduler is busted or random memory has been scribbled on, etc.

yes.

well, printk, in some sense, already depend on the scheduler: console
semaphore on its own; cond_resched() from console_unlock() with console_sem
being locked, etc. neither memory corruption is something that printk() can
always handle nicely. I saw logbuf_lock corruption and recursive spin_dump
from vprintk_emit(), was quite dramatic.


> All this downside to handle (afaict) one special case.

well, it's not just to make zillions-of-scsi-disks happy. I'm facing
different scenarios, more general ones, a 'moderate printk abuse'
(combined with slow serial console). printk is not always friendly
and shiny, it has some secrets and it can bite easily (lockups, stalls,
starvations, sched throttling, et cetera), and this is not something
that every developer know.

> Surely there is another way?  For example (but feel free to suggest other
> approaches!) can we put some limit on the number of extra characters which
> the printing task will print?  Once that limit is hit, new printk callers
> will spin until they can get in and do some printing themselves.  Or
> something else?

hm... there are not so many options, I think. this busy wait, depending on
the number of CPUs (and some other factors), can provoke mass softlockups
on other CPUs and a number of bad things. printk() and its deferred version
can be called from any context, so in some cases spinning in printk is as
good as doing console_unlock()->call_concosle_drivers() loop (iow, not really
good). things are not so bad (well, Tetsuo has some issues here though) if
printk() is called from non-atomic context, since now we have cond_resched()
in console_unlock() for console_lock()/console_trylock() callers; but printk()
from atomic context is still a problem -- we need to offload the actual
printing, unless we can guarantee that every atomic printk will be followed
by non-atomic printk (which will do the printing).

> > +   printk.synchronous=
..
> Well, it's good that we have this.
> 
> It would be better if it was runtime-controllable - changing boot
> parameters is a bit of a pain.  In fact with this approach, your
> zillions-of-scsi-disks scenario becomes less problematic: do the async
> offloading during the boot process then switch back to the more
> reliable sync printing late in boot.

well, I can add it if you insist.
my personal opinion is to keep it RO; RO->RW transition is easier than
RW->RO. giving the control over printk behaviour to user space can
potentially be even worse than drop_caches. besides I couldn't clearly
understand based on what observations user space may decide to switch
printk back to sync mode? and what may cause user space to switch printk
back from sync to async... lockups in dmesg output? any hint?

..
> > + * When true, printing to console will happen synchronously.
> > + * The default value on UP systems is 'true'.
> 
> That's rather obvious from the code.  Comments should explain "why",
> not "what".

fair enough.

> > +* By default we print message to console asynchronously so
> 
> Nit: this comment down here shouldn't know what the default is.  That
> should be documented up at the printk_sync definition site.

ok.

> > +* that kernel doesn't get stalled due to slow serial console.
> 
> s/kernel/the kernel/

ok.

> > +* requested by kernel parameter, or when console_verbose() was
> 
> s/kernel/a kernel/

ok.

> 
> > +* called to print everything during panic / oops.
> 
> We're missing a description of *why* console_verbose() is handled
> specially.

ok.

> > -   if (console_trylock())
> > -   console_unlock();
> > +   if (!in_panic && printk_kthread) {
> 
> We don't really need local variable in_panic.  I guess it has some
> documentary value.

just a shorter version of "console_loglevel == CONSOLE_LOGLEVEL_MOTORMOUTH".

> > +
> > +   thread = kthread_run(printk_kthread_func, NULL, "printk");
> 
> This gets normal scheduling policy, so a spinning userspace SCHED_FIFO
> task will block printk for ever.  This seems bad.

yes, using SCHED_RR/FIFO policy here makes sense.

> > +late_initcall(init_printk_kthread);
> 
> Could do with a comment explaining why late_initcall was chosen.

late_initcall was chosen because of workqueue early_initcall, and
I just decided not to change it when I switched from wq to a
dedicated printk kthread. late_initcall seemed to be OK. can do
init_printk_kthread() somewhere in init/main start_kernel().

-ss


Re: [PATCH v10 1/2] printk: Make printk() completely async

2016-04-04 Thread Sergey Senozhatsky
Hello Andrew,

On (04/04/16 15:51), Andrew Morton wrote:
[..]
> The whole idea remains worrisome.  It is definitely making printk()
> less reliable in the vast majority of cases: what happens if the
> scheduler is busted or random memory has been scribbled on, etc.

yes.

well, printk, in some sense, already depend on the scheduler: console
semaphore on its own; cond_resched() from console_unlock() with console_sem
being locked, etc. neither memory corruption is something that printk() can
always handle nicely. I saw logbuf_lock corruption and recursive spin_dump
from vprintk_emit(), was quite dramatic.


> All this downside to handle (afaict) one special case.

well, it's not just to make zillions-of-scsi-disks happy. I'm facing
different scenarios, more general ones, a 'moderate printk abuse'
(combined with slow serial console). printk is not always friendly
and shiny, it has some secrets and it can bite easily (lockups, stalls,
starvations, sched throttling, et cetera), and this is not something
that every developer know.

> Surely there is another way?  For example (but feel free to suggest other
> approaches!) can we put some limit on the number of extra characters which
> the printing task will print?  Once that limit is hit, new printk callers
> will spin until they can get in and do some printing themselves.  Or
> something else?

hm... there are not so many options, I think. this busy wait, depending on
the number of CPUs (and some other factors), can provoke mass softlockups
on other CPUs and a number of bad things. printk() and its deferred version
can be called from any context, so in some cases spinning in printk is as
good as doing console_unlock()->call_concosle_drivers() loop (iow, not really
good). things are not so bad (well, Tetsuo has some issues here though) if
printk() is called from non-atomic context, since now we have cond_resched()
in console_unlock() for console_lock()/console_trylock() callers; but printk()
from atomic context is still a problem -- we need to offload the actual
printing, unless we can guarantee that every atomic printk will be followed
by non-atomic printk (which will do the printing).

> > +   printk.synchronous=
..
> Well, it's good that we have this.
> 
> It would be better if it was runtime-controllable - changing boot
> parameters is a bit of a pain.  In fact with this approach, your
> zillions-of-scsi-disks scenario becomes less problematic: do the async
> offloading during the boot process then switch back to the more
> reliable sync printing late in boot.

well, I can add it if you insist.
my personal opinion is to keep it RO; RO->RW transition is easier than
RW->RO. giving the control over printk behaviour to user space can
potentially be even worse than drop_caches. besides I couldn't clearly
understand based on what observations user space may decide to switch
printk back to sync mode? and what may cause user space to switch printk
back from sync to async... lockups in dmesg output? any hint?

..
> > + * When true, printing to console will happen synchronously.
> > + * The default value on UP systems is 'true'.
> 
> That's rather obvious from the code.  Comments should explain "why",
> not "what".

fair enough.

> > +* By default we print message to console asynchronously so
> 
> Nit: this comment down here shouldn't know what the default is.  That
> should be documented up at the printk_sync definition site.

ok.

> > +* that kernel doesn't get stalled due to slow serial console.
> 
> s/kernel/the kernel/

ok.

> > +* requested by kernel parameter, or when console_verbose() was
> 
> s/kernel/a kernel/

ok.

> 
> > +* called to print everything during panic / oops.
> 
> We're missing a description of *why* console_verbose() is handled
> specially.

ok.

> > -   if (console_trylock())
> > -   console_unlock();
> > +   if (!in_panic && printk_kthread) {
> 
> We don't really need local variable in_panic.  I guess it has some
> documentary value.

just a shorter version of "console_loglevel == CONSOLE_LOGLEVEL_MOTORMOUTH".

> > +
> > +   thread = kthread_run(printk_kthread_func, NULL, "printk");
> 
> This gets normal scheduling policy, so a spinning userspace SCHED_FIFO
> task will block printk for ever.  This seems bad.

yes, using SCHED_RR/FIFO policy here makes sense.

> > +late_initcall(init_printk_kthread);
> 
> Could do with a comment explaining why late_initcall was chosen.

late_initcall was chosen because of workqueue early_initcall, and
I just decided not to change it when I switched from wq to a
dedicated printk kthread. late_initcall seemed to be OK. can do
init_printk_kthread() somewhere in init/main start_kernel().

-ss


[PATCH v4 1/6] xen: sync xen header

2016-04-04 Thread Juergen Gross
Import the actual version of include/xen/interface/sched.h from Xen.

Signed-off-by: Juergen Gross 
---
 include/xen/interface/sched.h | 100 ++
 1 file changed, 82 insertions(+), 18 deletions(-)

diff --git a/include/xen/interface/sched.h b/include/xen/interface/sched.h
index f184909..a4c4d73 100644
--- a/include/xen/interface/sched.h
+++ b/include/xen/interface/sched.h
@@ -3,6 +3,24 @@
  *
  * Scheduler state interactions
  *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
  * Copyright (c) 2005, Keir Fraser 
  */
 
@@ -12,18 +30,30 @@
 #include 
 
 /*
+ * Guest Scheduler Operations
+ *
+ * The SCHEDOP interface provides mechanisms for a guest to interact
+ * with the scheduler, including yield, blocking and shutting itself
+ * down.
+ */
+
+/*
  * The prototype for this hypercall is:
- *  long sched_op_new(int cmd, void *arg)
+ * long HYPERVISOR_sched_op(enum sched_op cmd, void *arg, ...)
+ *
  * @cmd == SCHEDOP_??? (scheduler operation).
  * @arg == Operation-specific extra argument(s), as described below.
+ * ...  == Additional Operation-specific extra arguments, described below.
  *
- * **NOTE**:
- * Versions of Xen prior to 3.0.2 provide only the following legacy version
+ * Versions of Xen prior to 3.0.2 provided only the following legacy version
  * of this hypercall, supporting only the commands yield, block and shutdown:
  *  long sched_op(int cmd, unsigned long arg)
  * @cmd == SCHEDOP_??? (scheduler operation).
  * @arg == 0   (SCHEDOP_yield and SCHEDOP_block)
  *  == SHUTDOWN_* code (SCHEDOP_shutdown)
+ *
+ * This legacy version is available to new guests as:
+ * long HYPERVISOR_sched_op_compat(enum sched_op cmd, unsigned long arg)
  */
 
 /*
@@ -44,12 +74,17 @@
 /*
  * Halt execution of this domain (all VCPUs) and notify the system controller.
  * @arg == pointer to sched_shutdown structure.
+ *
+ * If the sched_shutdown_t reason is SHUTDOWN_suspend then
+ * x86 PV guests must also set RDX (EDX for 32-bit guests) to the MFN
+ * of the guest's start info page.  RDX/EDX is the third hypercall
+ * argument.
+ *
+ * In addition, which reason is SHUTDOWN_suspend this hypercall
+ * returns 1 if suspend was cancelled or the domain was merely
+ * checkpointed, and 0 if it is resuming in a new domain.
  */
 #define SCHEDOP_shutdown2
-struct sched_shutdown {
-unsigned int reason; /* SHUTDOWN_* */
-};
-DEFINE_GUEST_HANDLE_STRUCT(sched_shutdown);
 
 /*
  * Poll a set of event-channel ports. Return when one or more are pending. An
@@ -57,12 +92,6 @@ DEFINE_GUEST_HANDLE_STRUCT(sched_shutdown);
  * @arg == pointer to sched_poll structure.
  */
 #define SCHEDOP_poll3
-struct sched_poll {
-GUEST_HANDLE(evtchn_port_t) ports;
-unsigned int nr_ports;
-uint64_t timeout;
-};
-DEFINE_GUEST_HANDLE_STRUCT(sched_poll);
 
 /*
  * Declare a shutdown for another domain. The main use of this function is
@@ -71,15 +100,11 @@ DEFINE_GUEST_HANDLE_STRUCT(sched_poll);
  * @arg == pointer to sched_remote_shutdown structure.
  */
 #define SCHEDOP_remote_shutdown4
-struct sched_remote_shutdown {
-domid_t domain_id; /* Remote domain ID */
-unsigned int reason;   /* SHUTDOWN_xxx reason */
-};
 
 /*
  * Latch a shutdown code, so that when the domain later shuts down it
  * reports this code to the control tools.
- * @arg == as for SCHEDOP_shutdown.
+ * @arg == sched_shutdown, as for SCHEDOP_shutdown.
  */
 #define SCHEDOP_shutdown_code 5
 
@@ -92,10 +117,47 @@ struct sched_remote_shutdown {
  * With id != 0 and timeout != 0, poke watchdog timer and set new timeout.
  */
 #define SCHEDOP_watchdog6
+
+/*
+ * Override the current vcpu affinity by pinning it to one physical cpu or
+ * undo this override restoring the previous affinity.
+ * @arg == pointer to sched_pin_override structure.
+ *
+ * A negative pcpu value will undo a previous pin override and 

[PATCH v4 5/6] dcdbas: make use of smp_call_on_cpu()

2016-04-04 Thread Juergen Gross
Use smp_call_on_cpu() to raise SMI on cpu 0.
Make call secure by adding get_online_cpus() to avoid e.g. suspend
resume cycles in between.

Signed-off-by: Juergen Gross 
---
V4: add call to get_online_cpus()
---
 drivers/firmware/dcdbas.c | 51 ---
 1 file changed, 26 insertions(+), 25 deletions(-)

diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 829eec8..68e1d38 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -238,33 +239,14 @@ static ssize_t host_control_on_shutdown_store(struct 
device *dev,
return count;
 }
 
-/**
- * dcdbas_smi_request: generate SMI request
- *
- * Called with smi_data_lock.
- */
-int dcdbas_smi_request(struct smi_cmd *smi_cmd)
+static int raise_smi(void *par)
 {
-   cpumask_var_t old_mask;
-   int ret = 0;
+   struct smi_cmd *smi_cmd = par;
 
-   if (smi_cmd->magic != SMI_CMD_MAGIC) {
-   dev_info(_pdev->dev, "%s: invalid magic value\n",
-__func__);
-   return -EBADR;
-   }
-
-   /* SMI requires CPU 0 */
-   if (!alloc_cpumask_var(_mask, GFP_KERNEL))
-   return -ENOMEM;
-
-   cpumask_copy(old_mask, >cpus_allowed);
-   set_cpus_allowed_ptr(current, cpumask_of(0));
if (smp_processor_id() != 0) {
dev_dbg(_pdev->dev, "%s: failed to get CPU 0\n",
__func__);
-   ret = -EBUSY;
-   goto out;
+   return -EBUSY;
}
 
/* generate SMI */
@@ -280,9 +262,28 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd)
: "memory"
);
 
-out:
-   set_cpus_allowed_ptr(current, old_mask);
-   free_cpumask_var(old_mask);
+   return 0;
+}
+/**
+ * dcdbas_smi_request: generate SMI request
+ *
+ * Called with smi_data_lock.
+ */
+int dcdbas_smi_request(struct smi_cmd *smi_cmd)
+{
+   int ret;
+
+   if (smi_cmd->magic != SMI_CMD_MAGIC) {
+   dev_info(_pdev->dev, "%s: invalid magic value\n",
+__func__);
+   return -EBADR;
+   }
+
+   /* SMI requires CPU 0 */
+   get_online_cpus();
+   ret = smp_call_on_cpu(0, true, raise_smi, smi_cmd);
+   put_online_cpus();
+
return ret;
 }
 
-- 
2.6.2



[PATCH v4 3/6] smp: add function to execute a function synchronously on a cpu

2016-04-04 Thread Juergen Gross
On some hardware models (e.g. Dell Studio 1555 laptop) some hardware
related functions (e.g. SMIs) are to be executed on physical cpu 0
only. Instead of open coding such a functionality multiple times in
the kernel add a service function for this purpose. This will enable
the possibility to take special measures in virtualized environments
like Xen, too.

Signed-off-by: Juergen Gross 
---
V4: change return value in case of illegal cpu as requested by Peter Zijlstra
make pinning of vcpu an option as suggested by Peter Zijlstra

V2: instead of manipulating the allowed set of cpus use cpu specific
workqueue as requested by Peter Zijlstra
---
 include/linux/smp.h |  2 ++
 kernel/smp.c| 50 ++
 kernel/up.c | 17 +
 3 files changed, 69 insertions(+)

diff --git a/include/linux/smp.h b/include/linux/smp.h
index c441407..3b5813b 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -196,4 +196,6 @@ extern void arch_enable_nonboot_cpus_end(void);
 
 void smp_setup_processor_id(void);
 
+int smp_call_on_cpu(unsigned int cpu, bool pin, int (*func)(void *), void 
*par);
+
 #endif /* __LINUX_SMP_H */
diff --git a/kernel/smp.c b/kernel/smp.c
index 9388064..357458b 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -740,3 +740,53 @@ void wake_up_all_idle_cpus(void)
preempt_enable();
 }
 EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);
+
+/**
+ * smp_call_on_cpu - Call a function on a specific cpu
+ *
+ * Used to call a function on a specific cpu and wait for it to return.
+ * Optionally make sure the call is done on a specified physical cpu via vcpu
+ * pinning in order to support virtualized environments.
+ */
+struct smp_call_on_cpu_struct {
+   struct work_struct  work;
+   struct completion   done;
+   int (*func)(void *);
+   void*data;
+   int ret;
+   int cpu;
+};
+
+static void smp_call_on_cpu_callback(struct work_struct *work)
+{
+   struct smp_call_on_cpu_struct *sscs;
+
+   sscs = container_of(work, struct smp_call_on_cpu_struct, work);
+   if (sscs->cpu >= 0)
+   hypervisor_pin_vcpu(sscs->cpu);
+   sscs->ret = sscs->func(sscs->data);
+   if (sscs->cpu >= 0)
+   hypervisor_pin_vcpu(-1);
+
+   complete(>done);
+}
+
+int smp_call_on_cpu(unsigned int cpu, bool pin, int (*func)(void *), void *par)
+{
+   struct smp_call_on_cpu_struct sscs = {
+   .work = __WORK_INITIALIZER(sscs.work, smp_call_on_cpu_callback),
+   .done = COMPLETION_INITIALIZER_ONSTACK(sscs.done),
+   .func = func,
+   .data = par,
+   .cpu  = pin ? cpu : -1,
+   };
+
+   if (cpu >= nr_cpu_ids)
+   return -ENXIO;
+
+   queue_work_on(cpu, system_wq, );
+   wait_for_completion();
+
+   return sscs.ret;
+}
+EXPORT_SYMBOL_GPL(smp_call_on_cpu);
diff --git a/kernel/up.c b/kernel/up.c
index 3ccee2b..8266810b 100644
--- a/kernel/up.c
+++ b/kernel/up.c
@@ -83,3 +83,20 @@ void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info),
preempt_enable();
 }
 EXPORT_SYMBOL(on_each_cpu_cond);
+
+int smp_call_on_cpu(unsigned int cpu, bool pin, int (*func)(void *), void *par)
+{
+   int ret;
+
+   if (cpu != 0)
+   return -ENXIO;
+
+   if (pin)
+   hypervisor_pin_vcpu(0);
+   ret = func(par);
+   if (pin)
+   hypervisor_pin_vcpu(-1);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(smp_call_on_cpu);
-- 
2.6.2



[PATCH v4 1/6] xen: sync xen header

2016-04-04 Thread Juergen Gross
Import the actual version of include/xen/interface/sched.h from Xen.

Signed-off-by: Juergen Gross 
---
 include/xen/interface/sched.h | 100 ++
 1 file changed, 82 insertions(+), 18 deletions(-)

diff --git a/include/xen/interface/sched.h b/include/xen/interface/sched.h
index f184909..a4c4d73 100644
--- a/include/xen/interface/sched.h
+++ b/include/xen/interface/sched.h
@@ -3,6 +3,24 @@
  *
  * Scheduler state interactions
  *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
  * Copyright (c) 2005, Keir Fraser 
  */
 
@@ -12,18 +30,30 @@
 #include 
 
 /*
+ * Guest Scheduler Operations
+ *
+ * The SCHEDOP interface provides mechanisms for a guest to interact
+ * with the scheduler, including yield, blocking and shutting itself
+ * down.
+ */
+
+/*
  * The prototype for this hypercall is:
- *  long sched_op_new(int cmd, void *arg)
+ * long HYPERVISOR_sched_op(enum sched_op cmd, void *arg, ...)
+ *
  * @cmd == SCHEDOP_??? (scheduler operation).
  * @arg == Operation-specific extra argument(s), as described below.
+ * ...  == Additional Operation-specific extra arguments, described below.
  *
- * **NOTE**:
- * Versions of Xen prior to 3.0.2 provide only the following legacy version
+ * Versions of Xen prior to 3.0.2 provided only the following legacy version
  * of this hypercall, supporting only the commands yield, block and shutdown:
  *  long sched_op(int cmd, unsigned long arg)
  * @cmd == SCHEDOP_??? (scheduler operation).
  * @arg == 0   (SCHEDOP_yield and SCHEDOP_block)
  *  == SHUTDOWN_* code (SCHEDOP_shutdown)
+ *
+ * This legacy version is available to new guests as:
+ * long HYPERVISOR_sched_op_compat(enum sched_op cmd, unsigned long arg)
  */
 
 /*
@@ -44,12 +74,17 @@
 /*
  * Halt execution of this domain (all VCPUs) and notify the system controller.
  * @arg == pointer to sched_shutdown structure.
+ *
+ * If the sched_shutdown_t reason is SHUTDOWN_suspend then
+ * x86 PV guests must also set RDX (EDX for 32-bit guests) to the MFN
+ * of the guest's start info page.  RDX/EDX is the third hypercall
+ * argument.
+ *
+ * In addition, which reason is SHUTDOWN_suspend this hypercall
+ * returns 1 if suspend was cancelled or the domain was merely
+ * checkpointed, and 0 if it is resuming in a new domain.
  */
 #define SCHEDOP_shutdown2
-struct sched_shutdown {
-unsigned int reason; /* SHUTDOWN_* */
-};
-DEFINE_GUEST_HANDLE_STRUCT(sched_shutdown);
 
 /*
  * Poll a set of event-channel ports. Return when one or more are pending. An
@@ -57,12 +92,6 @@ DEFINE_GUEST_HANDLE_STRUCT(sched_shutdown);
  * @arg == pointer to sched_poll structure.
  */
 #define SCHEDOP_poll3
-struct sched_poll {
-GUEST_HANDLE(evtchn_port_t) ports;
-unsigned int nr_ports;
-uint64_t timeout;
-};
-DEFINE_GUEST_HANDLE_STRUCT(sched_poll);
 
 /*
  * Declare a shutdown for another domain. The main use of this function is
@@ -71,15 +100,11 @@ DEFINE_GUEST_HANDLE_STRUCT(sched_poll);
  * @arg == pointer to sched_remote_shutdown structure.
  */
 #define SCHEDOP_remote_shutdown4
-struct sched_remote_shutdown {
-domid_t domain_id; /* Remote domain ID */
-unsigned int reason;   /* SHUTDOWN_xxx reason */
-};
 
 /*
  * Latch a shutdown code, so that when the domain later shuts down it
  * reports this code to the control tools.
- * @arg == as for SCHEDOP_shutdown.
+ * @arg == sched_shutdown, as for SCHEDOP_shutdown.
  */
 #define SCHEDOP_shutdown_code 5
 
@@ -92,10 +117,47 @@ struct sched_remote_shutdown {
  * With id != 0 and timeout != 0, poke watchdog timer and set new timeout.
  */
 #define SCHEDOP_watchdog6
+
+/*
+ * Override the current vcpu affinity by pinning it to one physical cpu or
+ * undo this override restoring the previous affinity.
+ * @arg == pointer to sched_pin_override structure.
+ *
+ * A negative pcpu value will undo a previous pin override and restore the
+ * previous cpu affinity.
+ * 

[PATCH v4 5/6] dcdbas: make use of smp_call_on_cpu()

2016-04-04 Thread Juergen Gross
Use smp_call_on_cpu() to raise SMI on cpu 0.
Make call secure by adding get_online_cpus() to avoid e.g. suspend
resume cycles in between.

Signed-off-by: Juergen Gross 
---
V4: add call to get_online_cpus()
---
 drivers/firmware/dcdbas.c | 51 ---
 1 file changed, 26 insertions(+), 25 deletions(-)

diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 829eec8..68e1d38 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -238,33 +239,14 @@ static ssize_t host_control_on_shutdown_store(struct 
device *dev,
return count;
 }
 
-/**
- * dcdbas_smi_request: generate SMI request
- *
- * Called with smi_data_lock.
- */
-int dcdbas_smi_request(struct smi_cmd *smi_cmd)
+static int raise_smi(void *par)
 {
-   cpumask_var_t old_mask;
-   int ret = 0;
+   struct smi_cmd *smi_cmd = par;
 
-   if (smi_cmd->magic != SMI_CMD_MAGIC) {
-   dev_info(_pdev->dev, "%s: invalid magic value\n",
-__func__);
-   return -EBADR;
-   }
-
-   /* SMI requires CPU 0 */
-   if (!alloc_cpumask_var(_mask, GFP_KERNEL))
-   return -ENOMEM;
-
-   cpumask_copy(old_mask, >cpus_allowed);
-   set_cpus_allowed_ptr(current, cpumask_of(0));
if (smp_processor_id() != 0) {
dev_dbg(_pdev->dev, "%s: failed to get CPU 0\n",
__func__);
-   ret = -EBUSY;
-   goto out;
+   return -EBUSY;
}
 
/* generate SMI */
@@ -280,9 +262,28 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd)
: "memory"
);
 
-out:
-   set_cpus_allowed_ptr(current, old_mask);
-   free_cpumask_var(old_mask);
+   return 0;
+}
+/**
+ * dcdbas_smi_request: generate SMI request
+ *
+ * Called with smi_data_lock.
+ */
+int dcdbas_smi_request(struct smi_cmd *smi_cmd)
+{
+   int ret;
+
+   if (smi_cmd->magic != SMI_CMD_MAGIC) {
+   dev_info(_pdev->dev, "%s: invalid magic value\n",
+__func__);
+   return -EBADR;
+   }
+
+   /* SMI requires CPU 0 */
+   get_online_cpus();
+   ret = smp_call_on_cpu(0, true, raise_smi, smi_cmd);
+   put_online_cpus();
+
return ret;
 }
 
-- 
2.6.2



[PATCH v4 3/6] smp: add function to execute a function synchronously on a cpu

2016-04-04 Thread Juergen Gross
On some hardware models (e.g. Dell Studio 1555 laptop) some hardware
related functions (e.g. SMIs) are to be executed on physical cpu 0
only. Instead of open coding such a functionality multiple times in
the kernel add a service function for this purpose. This will enable
the possibility to take special measures in virtualized environments
like Xen, too.

Signed-off-by: Juergen Gross 
---
V4: change return value in case of illegal cpu as requested by Peter Zijlstra
make pinning of vcpu an option as suggested by Peter Zijlstra

V2: instead of manipulating the allowed set of cpus use cpu specific
workqueue as requested by Peter Zijlstra
---
 include/linux/smp.h |  2 ++
 kernel/smp.c| 50 ++
 kernel/up.c | 17 +
 3 files changed, 69 insertions(+)

diff --git a/include/linux/smp.h b/include/linux/smp.h
index c441407..3b5813b 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -196,4 +196,6 @@ extern void arch_enable_nonboot_cpus_end(void);
 
 void smp_setup_processor_id(void);
 
+int smp_call_on_cpu(unsigned int cpu, bool pin, int (*func)(void *), void 
*par);
+
 #endif /* __LINUX_SMP_H */
diff --git a/kernel/smp.c b/kernel/smp.c
index 9388064..357458b 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -740,3 +740,53 @@ void wake_up_all_idle_cpus(void)
preempt_enable();
 }
 EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);
+
+/**
+ * smp_call_on_cpu - Call a function on a specific cpu
+ *
+ * Used to call a function on a specific cpu and wait for it to return.
+ * Optionally make sure the call is done on a specified physical cpu via vcpu
+ * pinning in order to support virtualized environments.
+ */
+struct smp_call_on_cpu_struct {
+   struct work_struct  work;
+   struct completion   done;
+   int (*func)(void *);
+   void*data;
+   int ret;
+   int cpu;
+};
+
+static void smp_call_on_cpu_callback(struct work_struct *work)
+{
+   struct smp_call_on_cpu_struct *sscs;
+
+   sscs = container_of(work, struct smp_call_on_cpu_struct, work);
+   if (sscs->cpu >= 0)
+   hypervisor_pin_vcpu(sscs->cpu);
+   sscs->ret = sscs->func(sscs->data);
+   if (sscs->cpu >= 0)
+   hypervisor_pin_vcpu(-1);
+
+   complete(>done);
+}
+
+int smp_call_on_cpu(unsigned int cpu, bool pin, int (*func)(void *), void *par)
+{
+   struct smp_call_on_cpu_struct sscs = {
+   .work = __WORK_INITIALIZER(sscs.work, smp_call_on_cpu_callback),
+   .done = COMPLETION_INITIALIZER_ONSTACK(sscs.done),
+   .func = func,
+   .data = par,
+   .cpu  = pin ? cpu : -1,
+   };
+
+   if (cpu >= nr_cpu_ids)
+   return -ENXIO;
+
+   queue_work_on(cpu, system_wq, );
+   wait_for_completion();
+
+   return sscs.ret;
+}
+EXPORT_SYMBOL_GPL(smp_call_on_cpu);
diff --git a/kernel/up.c b/kernel/up.c
index 3ccee2b..8266810b 100644
--- a/kernel/up.c
+++ b/kernel/up.c
@@ -83,3 +83,20 @@ void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info),
preempt_enable();
 }
 EXPORT_SYMBOL(on_each_cpu_cond);
+
+int smp_call_on_cpu(unsigned int cpu, bool pin, int (*func)(void *), void *par)
+{
+   int ret;
+
+   if (cpu != 0)
+   return -ENXIO;
+
+   if (pin)
+   hypervisor_pin_vcpu(0);
+   ret = func(par);
+   if (pin)
+   hypervisor_pin_vcpu(-1);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(smp_call_on_cpu);
-- 
2.6.2



[PATCH v4 2/6] virt, sched: add generic vcpu pinning support

2016-04-04 Thread Juergen Gross
Add generic virtualization support for pinning the current vcpu to a
specified physical cpu. As this operation isn't performance critical
(a very limited set of operations like BIOS calls and SMIs is expected
to need this) just add a hypervisor specific indirection.

Signed-off-by: Juergen Gross 
---
V4: move this patch some places up in the series
WARN_ONCE in case platform doesn't support pinning as requested by
Peter Zijlstra

V3: use getc_cpu()/put_cpu() as suggested by David Vrabel

V2: adapt to using workqueues
add include/linux/hypervisor.h to hide architecture specific stuff
from generic kernel code

In case paravirt maintainers don't want to be responsible for
include/linux/hypervisor.h I could take it.
---
 MAINTAINERS   |  1 +
 arch/x86/include/asm/hypervisor.h |  4 
 arch/x86/kernel/cpu/hypervisor.c  | 11 +++
 include/linux/hypervisor.h| 17 +
 kernel/smp.c  |  1 +
 kernel/up.c   |  1 +
 6 files changed, 35 insertions(+)
 create mode 100644 include/linux/hypervisor.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2ec5079..959173e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8330,6 +8330,7 @@ S:Supported
 F: Documentation/virtual/paravirt_ops.txt
 F: arch/*/kernel/paravirt*
 F: arch/*/include/asm/paravirt.h
+F: include/linux/hypervisor.h
 
 PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES
 M: Tim Waugh 
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 055ea99..67942b6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -43,6 +43,9 @@ struct hypervisor_x86 {
 
/* X2APIC detection (run once per boot) */
bool(*x2apic_available)(void);
+
+   /* pin current vcpu to specified physical cpu (run rarely) */
+   void(*pin_vcpu)(int);
 };
 
 extern const struct hypervisor_x86 *x86_hyper;
@@ -56,6 +59,7 @@ extern const struct hypervisor_x86 x86_hyper_kvm;
 extern void init_hypervisor(struct cpuinfo_x86 *c);
 extern void init_hypervisor_platform(void);
 extern bool hypervisor_x2apic_available(void);
+extern void hypervisor_pin_vcpu(int cpu);
 #else
 static inline void init_hypervisor(struct cpuinfo_x86 *c) { }
 static inline void init_hypervisor_platform(void) { }
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 73d391a..ff108f8 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -85,3 +85,14 @@ bool __init hypervisor_x2apic_available(void)
   x86_hyper->x2apic_available &&
   x86_hyper->x2apic_available();
 }
+
+void hypervisor_pin_vcpu(int cpu)
+{
+   if (!x86_hyper)
+   return;
+
+   if (x86_hyper->pin_vcpu)
+   x86_hyper->pin_vcpu(cpu);
+   else
+   WARN_ONCE(1, "vcpu pinning requested but not supported!\n");
+}
diff --git a/include/linux/hypervisor.h b/include/linux/hypervisor.h
new file mode 100644
index 000..3fa5ef2
--- /dev/null
+++ b/include/linux/hypervisor.h
@@ -0,0 +1,17 @@
+#ifndef __LINUX_HYPEVISOR_H
+#define __LINUX_HYPEVISOR_H
+
+/*
+ * Generic Hypervisor support
+ * Juergen Gross 
+ */
+
+#ifdef CONFIG_HYPERVISOR_GUEST
+#include 
+#else
+static inline void hypervisor_pin_vcpu(int cpu)
+{
+}
+#endif
+
+#endif /* __LINUX_HYPEVISOR_H */
diff --git a/kernel/smp.c b/kernel/smp.c
index 7416544..9388064 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "smpboot.h"
 
diff --git a/kernel/up.c b/kernel/up.c
index 1760bf3..3ccee2b 100644
--- a/kernel/up.c
+++ b/kernel/up.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 
 int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
int wait)
-- 
2.6.2



[PATCH v4 6/6] hwmon: use smp_call_on_cpu() for dell-smm i8k

2016-04-04 Thread Juergen Gross
Use the smp_call_on_cpu() function to call system management
mode on cpu 0.
Make call secure by adding get_online_cpus() to avoid e.g. suspend
resume cycles in between.

Signed-off-by: Juergen Gross 
---
V4: add call to get_online_cpus()
---
 drivers/hwmon/dell-smm-hwmon.c | 35 ---
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
index c43318d..643f3a1 100644
--- a/drivers/hwmon/dell-smm-hwmon.c
+++ b/drivers/hwmon/dell-smm-hwmon.c
@@ -21,6 +21,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -35,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -130,23 +132,15 @@ static inline const char *i8k_get_dmi_data(int field)
 /*
  * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
  */
-static int i8k_smm(struct smm_regs *regs)
+static int i8k_smm_func(void *par)
 {
int rc;
+   struct smm_regs *regs = par;
int eax = regs->eax;
-   cpumask_var_t old_mask;
 
/* SMM requires CPU 0 */
-   if (!alloc_cpumask_var(_mask, GFP_KERNEL))
-   return -ENOMEM;
-   cpumask_copy(old_mask, >cpus_allowed);
-   rc = set_cpus_allowed_ptr(current, cpumask_of(0));
-   if (rc)
-   goto out;
-   if (smp_processor_id() != 0) {
-   rc = -EBUSY;
-   goto out;
-   }
+   if (smp_processor_id() != 0)
+   return -EBUSY;
 
 #if defined(CONFIG_X86_64)
asm volatile("pushq %%rax\n\t"
@@ -204,13 +198,24 @@ static int i8k_smm(struct smm_regs *regs)
if (rc != 0 || (regs->eax & 0x) == 0x || regs->eax == eax)
rc = -EINVAL;
 
-out:
-   set_cpus_allowed_ptr(current, old_mask);
-   free_cpumask_var(old_mask);
return rc;
 }
 
 /*
+ * Call the System Management Mode BIOS.
+ */
+static int i8k_smm(struct smm_regs *regs)
+{
+   int ret;
+
+   get_online_cpus();
+   ret = smp_call_on_cpu(0, true, i8k_smm_func, regs);
+   put_online_cpus();
+
+   return ret;
+}
+
+/*
  * Read the fan status.
  */
 static int i8k_get_fan_status(int fan)
-- 
2.6.2



[PATCH v4 2/6] virt, sched: add generic vcpu pinning support

2016-04-04 Thread Juergen Gross
Add generic virtualization support for pinning the current vcpu to a
specified physical cpu. As this operation isn't performance critical
(a very limited set of operations like BIOS calls and SMIs is expected
to need this) just add a hypervisor specific indirection.

Signed-off-by: Juergen Gross 
---
V4: move this patch some places up in the series
WARN_ONCE in case platform doesn't support pinning as requested by
Peter Zijlstra

V3: use getc_cpu()/put_cpu() as suggested by David Vrabel

V2: adapt to using workqueues
add include/linux/hypervisor.h to hide architecture specific stuff
from generic kernel code

In case paravirt maintainers don't want to be responsible for
include/linux/hypervisor.h I could take it.
---
 MAINTAINERS   |  1 +
 arch/x86/include/asm/hypervisor.h |  4 
 arch/x86/kernel/cpu/hypervisor.c  | 11 +++
 include/linux/hypervisor.h| 17 +
 kernel/smp.c  |  1 +
 kernel/up.c   |  1 +
 6 files changed, 35 insertions(+)
 create mode 100644 include/linux/hypervisor.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2ec5079..959173e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8330,6 +8330,7 @@ S:Supported
 F: Documentation/virtual/paravirt_ops.txt
 F: arch/*/kernel/paravirt*
 F: arch/*/include/asm/paravirt.h
+F: include/linux/hypervisor.h
 
 PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES
 M: Tim Waugh 
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 055ea99..67942b6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -43,6 +43,9 @@ struct hypervisor_x86 {
 
/* X2APIC detection (run once per boot) */
bool(*x2apic_available)(void);
+
+   /* pin current vcpu to specified physical cpu (run rarely) */
+   void(*pin_vcpu)(int);
 };
 
 extern const struct hypervisor_x86 *x86_hyper;
@@ -56,6 +59,7 @@ extern const struct hypervisor_x86 x86_hyper_kvm;
 extern void init_hypervisor(struct cpuinfo_x86 *c);
 extern void init_hypervisor_platform(void);
 extern bool hypervisor_x2apic_available(void);
+extern void hypervisor_pin_vcpu(int cpu);
 #else
 static inline void init_hypervisor(struct cpuinfo_x86 *c) { }
 static inline void init_hypervisor_platform(void) { }
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 73d391a..ff108f8 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -85,3 +85,14 @@ bool __init hypervisor_x2apic_available(void)
   x86_hyper->x2apic_available &&
   x86_hyper->x2apic_available();
 }
+
+void hypervisor_pin_vcpu(int cpu)
+{
+   if (!x86_hyper)
+   return;
+
+   if (x86_hyper->pin_vcpu)
+   x86_hyper->pin_vcpu(cpu);
+   else
+   WARN_ONCE(1, "vcpu pinning requested but not supported!\n");
+}
diff --git a/include/linux/hypervisor.h b/include/linux/hypervisor.h
new file mode 100644
index 000..3fa5ef2
--- /dev/null
+++ b/include/linux/hypervisor.h
@@ -0,0 +1,17 @@
+#ifndef __LINUX_HYPEVISOR_H
+#define __LINUX_HYPEVISOR_H
+
+/*
+ * Generic Hypervisor support
+ * Juergen Gross 
+ */
+
+#ifdef CONFIG_HYPERVISOR_GUEST
+#include 
+#else
+static inline void hypervisor_pin_vcpu(int cpu)
+{
+}
+#endif
+
+#endif /* __LINUX_HYPEVISOR_H */
diff --git a/kernel/smp.c b/kernel/smp.c
index 7416544..9388064 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "smpboot.h"
 
diff --git a/kernel/up.c b/kernel/up.c
index 1760bf3..3ccee2b 100644
--- a/kernel/up.c
+++ b/kernel/up.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 
 int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
int wait)
-- 
2.6.2



[PATCH v4 6/6] hwmon: use smp_call_on_cpu() for dell-smm i8k

2016-04-04 Thread Juergen Gross
Use the smp_call_on_cpu() function to call system management
mode on cpu 0.
Make call secure by adding get_online_cpus() to avoid e.g. suspend
resume cycles in between.

Signed-off-by: Juergen Gross 
---
V4: add call to get_online_cpus()
---
 drivers/hwmon/dell-smm-hwmon.c | 35 ---
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
index c43318d..643f3a1 100644
--- a/drivers/hwmon/dell-smm-hwmon.c
+++ b/drivers/hwmon/dell-smm-hwmon.c
@@ -21,6 +21,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -35,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -130,23 +132,15 @@ static inline const char *i8k_get_dmi_data(int field)
 /*
  * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
  */
-static int i8k_smm(struct smm_regs *regs)
+static int i8k_smm_func(void *par)
 {
int rc;
+   struct smm_regs *regs = par;
int eax = regs->eax;
-   cpumask_var_t old_mask;
 
/* SMM requires CPU 0 */
-   if (!alloc_cpumask_var(_mask, GFP_KERNEL))
-   return -ENOMEM;
-   cpumask_copy(old_mask, >cpus_allowed);
-   rc = set_cpus_allowed_ptr(current, cpumask_of(0));
-   if (rc)
-   goto out;
-   if (smp_processor_id() != 0) {
-   rc = -EBUSY;
-   goto out;
-   }
+   if (smp_processor_id() != 0)
+   return -EBUSY;
 
 #if defined(CONFIG_X86_64)
asm volatile("pushq %%rax\n\t"
@@ -204,13 +198,24 @@ static int i8k_smm(struct smm_regs *regs)
if (rc != 0 || (regs->eax & 0x) == 0x || regs->eax == eax)
rc = -EINVAL;
 
-out:
-   set_cpus_allowed_ptr(current, old_mask);
-   free_cpumask_var(old_mask);
return rc;
 }
 
 /*
+ * Call the System Management Mode BIOS.
+ */
+static int i8k_smm(struct smm_regs *regs)
+{
+   int ret;
+
+   get_online_cpus();
+   ret = smp_call_on_cpu(0, true, i8k_smm_func, regs);
+   put_online_cpus();
+
+   return ret;
+}
+
+/*
  * Read the fan status.
  */
 static int i8k_get_fan_status(int fan)
-- 
2.6.2



[PATCH v4 4/6] xen: add xen_pin_vcpu() to support calling functions on a dedicated pcpu

2016-04-04 Thread Juergen Gross
Some hardware models (e.g. Dell Studio 1555 laptops) require calls to
the firmware to be issued on cpu 0 only. As Dom0 might have to use
these calls, add xen_pin_vcpu() to achieve this functionality.

In case either the domain doesn't have the privilege to make the
related hypercall or the hypervisor isn't supporting it, issue a
warning once and disable further pinning attempts.

Signed-off-by: Juergen Gross 
---
 arch/x86/xen/enlighten.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 880862c..7907bcf8 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1885,6 +1885,45 @@ static void xen_set_cpu_features(struct cpuinfo_x86 *c)
}
 }
 
+static void xen_pin_vcpu(int cpu)
+{
+   static bool disable_pinning;
+   struct sched_pin_override pin_override;
+   int ret;
+
+   if (disable_pinning)
+   return;
+
+   pin_override.pcpu = cpu;
+   ret = HYPERVISOR_sched_op(SCHEDOP_pin_override, _override);
+   if (cpu < 0)
+   return;
+
+   switch (ret) {
+   case -ENOSYS:
+   pr_warn("The kernel tried to call a function on physical cpu 
%d, but Xen isn't\n"
+   "supporting this. In case of problems you might 
consider vcpu pinning.\n",
+   cpu);
+   disable_pinning = true;
+   break;
+   case -EPERM:
+   WARN(1, "Trying to pin vcpu without having privilege to do 
so\n");
+   disable_pinning = true;
+   break;
+   case -EINVAL:
+   case -EBUSY:
+   pr_warn("The kernel tried to call a function on physical cpu 
%d, but this cpu\n"
+   "seems not to be available. Please check your Xen cpu 
configuration.\n",
+   cpu);
+   break;
+   case 0:
+   break;
+   default:
+   WARN(1, "rc %d while trying to pin vcpu\n", ret);
+   disable_pinning = true;
+   }
+}
+
 const struct hypervisor_x86 x86_hyper_xen = {
.name   = "Xen",
.detect = xen_platform,
@@ -1893,6 +1932,7 @@ const struct hypervisor_x86 x86_hyper_xen = {
 #endif
.x2apic_available   = xen_x2apic_para_available,
.set_cpu_features   = xen_set_cpu_features,
+   .pin_vcpu   = xen_pin_vcpu,
 };
 EXPORT_SYMBOL(x86_hyper_xen);
 
-- 
2.6.2



[PATCH v4 0/6] Support calling functions on dedicated physical cpu

2016-04-04 Thread Juergen Gross
Some hardware (e.g. Dell Studio laptops) require special functions to
be called on physical cpu 0 in order to avoid occasional hangs. When
running as dom0 under Xen this could be achieved only via special boot
parameters (vcpu pinning) limiting the hypervisor in it's scheduling
decisions.

This patch series is adding a generic function to be able to temporarily
pin a (virtual) cpu to a dedicated physical cpu for executing above
mentioned functions on that specific cpu. The drivers (dcdbas and i8k)
requiring this functionality are modified accordingly.

Changes in V4:
- move patches 5 and 6 further up in the series
- patch 2 (was 5): WARN_ONCE in case platform doesn't support pinning
  as requested by Peter Zijlstra
- patch 3 (was 2): change return value in case of illegal cpu as
  requested by Peter Zijlstra
- patch 3 (was 2): make pinning of vcpu an option as suggested by
  Peter Zijlstra
- patches 5 and 6 (were 3 and 4): add call to get_online_cpus()

Changes in V3:
- use get_cpu()/put_cpu() as suggested by David Vrabel

Changes in V2:
- instead of manipulating the allowed set of cpus use cpu specific
  workqueue as requested by Peter Zijlstra
- add include/linux/hypervisor.h to hide architecture specific stuff
  from generic kernel code


Juergen Gross (6):
  xen: sync xen header
  virt, sched: add generic vcpu pinning support
  smp: add function to execute a function synchronously on a cpu
  xen: add xen_pin_vcpu() to support calling functions on a dedicated
pcpu
  dcdbas: make use of smp_call_on_cpu()
  hwmon: use smp_call_on_cpu() for dell-smm i8k

 MAINTAINERS   |   1 +
 arch/x86/include/asm/hypervisor.h |   4 ++
 arch/x86/kernel/cpu/hypervisor.c  |  11 +
 arch/x86/xen/enlighten.c  |  40 +++
 drivers/firmware/dcdbas.c |  51 +--
 drivers/hwmon/dell-smm-hwmon.c|  35 +++--
 include/linux/hypervisor.h|  17 +++
 include/linux/smp.h   |   2 +
 include/xen/interface/sched.h | 100 +++---
 kernel/smp.c  |  51 +++
 kernel/up.c   |  18 +++
 11 files changed, 272 insertions(+), 58 deletions(-)
 create mode 100644 include/linux/hypervisor.h

-- 
2.6.2



[PATCH v4 4/6] xen: add xen_pin_vcpu() to support calling functions on a dedicated pcpu

2016-04-04 Thread Juergen Gross
Some hardware models (e.g. Dell Studio 1555 laptops) require calls to
the firmware to be issued on cpu 0 only. As Dom0 might have to use
these calls, add xen_pin_vcpu() to achieve this functionality.

In case either the domain doesn't have the privilege to make the
related hypercall or the hypervisor isn't supporting it, issue a
warning once and disable further pinning attempts.

Signed-off-by: Juergen Gross 
---
 arch/x86/xen/enlighten.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 880862c..7907bcf8 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1885,6 +1885,45 @@ static void xen_set_cpu_features(struct cpuinfo_x86 *c)
}
 }
 
+static void xen_pin_vcpu(int cpu)
+{
+   static bool disable_pinning;
+   struct sched_pin_override pin_override;
+   int ret;
+
+   if (disable_pinning)
+   return;
+
+   pin_override.pcpu = cpu;
+   ret = HYPERVISOR_sched_op(SCHEDOP_pin_override, _override);
+   if (cpu < 0)
+   return;
+
+   switch (ret) {
+   case -ENOSYS:
+   pr_warn("The kernel tried to call a function on physical cpu 
%d, but Xen isn't\n"
+   "supporting this. In case of problems you might 
consider vcpu pinning.\n",
+   cpu);
+   disable_pinning = true;
+   break;
+   case -EPERM:
+   WARN(1, "Trying to pin vcpu without having privilege to do 
so\n");
+   disable_pinning = true;
+   break;
+   case -EINVAL:
+   case -EBUSY:
+   pr_warn("The kernel tried to call a function on physical cpu 
%d, but this cpu\n"
+   "seems not to be available. Please check your Xen cpu 
configuration.\n",
+   cpu);
+   break;
+   case 0:
+   break;
+   default:
+   WARN(1, "rc %d while trying to pin vcpu\n", ret);
+   disable_pinning = true;
+   }
+}
+
 const struct hypervisor_x86 x86_hyper_xen = {
.name   = "Xen",
.detect = xen_platform,
@@ -1893,6 +1932,7 @@ const struct hypervisor_x86 x86_hyper_xen = {
 #endif
.x2apic_available   = xen_x2apic_para_available,
.set_cpu_features   = xen_set_cpu_features,
+   .pin_vcpu   = xen_pin_vcpu,
 };
 EXPORT_SYMBOL(x86_hyper_xen);
 
-- 
2.6.2



[PATCH v4 0/6] Support calling functions on dedicated physical cpu

2016-04-04 Thread Juergen Gross
Some hardware (e.g. Dell Studio laptops) require special functions to
be called on physical cpu 0 in order to avoid occasional hangs. When
running as dom0 under Xen this could be achieved only via special boot
parameters (vcpu pinning) limiting the hypervisor in it's scheduling
decisions.

This patch series is adding a generic function to be able to temporarily
pin a (virtual) cpu to a dedicated physical cpu for executing above
mentioned functions on that specific cpu. The drivers (dcdbas and i8k)
requiring this functionality are modified accordingly.

Changes in V4:
- move patches 5 and 6 further up in the series
- patch 2 (was 5): WARN_ONCE in case platform doesn't support pinning
  as requested by Peter Zijlstra
- patch 3 (was 2): change return value in case of illegal cpu as
  requested by Peter Zijlstra
- patch 3 (was 2): make pinning of vcpu an option as suggested by
  Peter Zijlstra
- patches 5 and 6 (were 3 and 4): add call to get_online_cpus()

Changes in V3:
- use get_cpu()/put_cpu() as suggested by David Vrabel

Changes in V2:
- instead of manipulating the allowed set of cpus use cpu specific
  workqueue as requested by Peter Zijlstra
- add include/linux/hypervisor.h to hide architecture specific stuff
  from generic kernel code


Juergen Gross (6):
  xen: sync xen header
  virt, sched: add generic vcpu pinning support
  smp: add function to execute a function synchronously on a cpu
  xen: add xen_pin_vcpu() to support calling functions on a dedicated
pcpu
  dcdbas: make use of smp_call_on_cpu()
  hwmon: use smp_call_on_cpu() for dell-smm i8k

 MAINTAINERS   |   1 +
 arch/x86/include/asm/hypervisor.h |   4 ++
 arch/x86/kernel/cpu/hypervisor.c  |  11 +
 arch/x86/xen/enlighten.c  |  40 +++
 drivers/firmware/dcdbas.c |  51 +--
 drivers/hwmon/dell-smm-hwmon.c|  35 +++--
 include/linux/hypervisor.h|  17 +++
 include/linux/smp.h   |   2 +
 include/xen/interface/sched.h | 100 +++---
 kernel/smp.c  |  51 +++
 kernel/up.c   |  18 +++
 11 files changed, 272 insertions(+), 58 deletions(-)
 create mode 100644 include/linux/hypervisor.h

-- 
2.6.2



Re: [PATCH char-misc-linus] misc: mic: Fix randconfig build error

2016-04-04 Thread Sudeep Dutt
On Mon, 2016-04-04 at 21:41 -0700, Greg Kroah-Hartman wrote:
> On Mon, Apr 04, 2016 at 09:32:30PM -0700, Sudeep Dutt wrote:
> > Fixes randconfig build error reported at
> > https://lkml.org/lkml/2016/4/3/135 by ensuring that
> > the VOP driver selects VIRTIO.
> > 
> > Reported-by: Fengguang Wu 
> > Reviewed-by: Ashutosh Dixit 
> > Signed-off-by: Sudeep Dutt 
> > ---
> >  drivers/misc/mic/Kconfig | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
> > index 2e4f3ba..89e5917 100644
> > --- a/drivers/misc/mic/Kconfig
> > +++ b/drivers/misc/mic/Kconfig
> > @@ -132,6 +132,7 @@ config VOP
> > tristate "VOP Driver"
> > depends on 64BIT && PCI && X86 && VOP_BUS
> > select VHOST_RING
> > +   select VIRTIO
> 
> Shouldn't it depend on this instead?

Hi Greg,

The documentation for "config VIRTIO" states that "This option is
selected by any driver which implements the virtio bus". I verified that
this patch fixes the build for the randconfig which was failing earlier.

Thanks,
Sudeep Dutt



Re: [PATCH char-misc-linus] misc: mic: Fix randconfig build error

2016-04-04 Thread Sudeep Dutt
On Mon, 2016-04-04 at 21:41 -0700, Greg Kroah-Hartman wrote:
> On Mon, Apr 04, 2016 at 09:32:30PM -0700, Sudeep Dutt wrote:
> > Fixes randconfig build error reported at
> > https://lkml.org/lkml/2016/4/3/135 by ensuring that
> > the VOP driver selects VIRTIO.
> > 
> > Reported-by: Fengguang Wu 
> > Reviewed-by: Ashutosh Dixit 
> > Signed-off-by: Sudeep Dutt 
> > ---
> >  drivers/misc/mic/Kconfig | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
> > index 2e4f3ba..89e5917 100644
> > --- a/drivers/misc/mic/Kconfig
> > +++ b/drivers/misc/mic/Kconfig
> > @@ -132,6 +132,7 @@ config VOP
> > tristate "VOP Driver"
> > depends on 64BIT && PCI && X86 && VOP_BUS
> > select VHOST_RING
> > +   select VIRTIO
> 
> Shouldn't it depend on this instead?

Hi Greg,

The documentation for "config VIRTIO" states that "This option is
selected by any driver which implements the virtio bus". I verified that
this patch fixes the build for the randconfig which was failing earlier.

Thanks,
Sudeep Dutt



[GIT PULL] extcon fixes for 4.6-rc3

2016-04-04 Thread Chanwoo Choi
Dear Greg,

This is extcon fixes pull request for v4.6-rc3. I add detailed description of
this pull request on below. Please pull extcon with following updates.

Best Regards,
Chanwoo Choi

The following changes since commit 9735a22799b9214d17d3c231fe377fc852f042e9:

  Linux 4.6-rc2 (2016-04-03 09:09:40 -0500)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git 
tags/extcon-fixes-for-4.6-rc3

for you to fetch changes up to f75587b8ca69768c6cf8a38a0b61e68e1bea3d36:

  extcon: palmas: Drop stray IRQF_EARLY_RESUME flag (2016-04-04 08:32:45 +0900)


Update extcon for v4.6-rc3

This patch fixes the following one issue:
- In extcon-palmas.c, the external abort happen when wake-up from suspend state
on BeagleBoard-X15 platform. So, drop the IRQF_EARLY_RESUME flag.


Nishanth Menon (1):
  extcon: palmas: Drop stray IRQF_EARLY_RESUME flag

 drivers/extcon/extcon-palmas.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)


[GIT PULL] extcon fixes for 4.6-rc3

2016-04-04 Thread Chanwoo Choi
Dear Greg,

This is extcon fixes pull request for v4.6-rc3. I add detailed description of
this pull request on below. Please pull extcon with following updates.

Best Regards,
Chanwoo Choi

The following changes since commit 9735a22799b9214d17d3c231fe377fc852f042e9:

  Linux 4.6-rc2 (2016-04-03 09:09:40 -0500)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git 
tags/extcon-fixes-for-4.6-rc3

for you to fetch changes up to f75587b8ca69768c6cf8a38a0b61e68e1bea3d36:

  extcon: palmas: Drop stray IRQF_EARLY_RESUME flag (2016-04-04 08:32:45 +0900)


Update extcon for v4.6-rc3

This patch fixes the following one issue:
- In extcon-palmas.c, the external abort happen when wake-up from suspend state
on BeagleBoard-X15 platform. So, drop the IRQF_EARLY_RESUME flag.


Nishanth Menon (1):
  extcon: palmas: Drop stray IRQF_EARLY_RESUME flag

 drivers/extcon/extcon-palmas.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)


[PATCH net-next 4/8] bpf: support bpf_get_stackid() and bpf_perf_event_output() in tracepoint programs

2016-04-04 Thread Alexei Starovoitov
needs two wrapper functions to fetch 'struct pt_regs *' to convert
tracepoint bpf context into kprobe bpf context to reuse existing
helper functions

Signed-off-by: Alexei Starovoitov 
---
 include/linux/bpf.h  |  1 +
 kernel/bpf/stackmap.c|  2 +-
 kernel/trace/bpf_trace.c | 42 +-
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 21ee41b92e8a..198f6ace70ec 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -160,6 +160,7 @@ struct bpf_array {
 #define MAX_TAIL_CALL_CNT 32
 
 u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
+u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
 void bpf_fd_array_map_clear(struct bpf_map *map);
 bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog 
*fp);
 const struct bpf_func_proto *bpf_get_trace_printk_proto(void);
diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
index 499d9e933f8e..35114725cf30 100644
--- a/kernel/bpf/stackmap.c
+++ b/kernel/bpf/stackmap.c
@@ -116,7 +116,7 @@ free_smap:
return ERR_PTR(err);
 }
 
-static u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5)
+u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5)
 {
struct pt_regs *regs = (struct pt_regs *) (long) r1;
struct bpf_map *map = (struct bpf_map *) (long) r2;
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 3e5ebe3254d2..413ec5614180 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -340,12 +340,52 @@ static struct bpf_prog_type_list kprobe_tl = {
.type   = BPF_PROG_TYPE_KPROBE,
 };
 
+static u64 bpf_perf_event_output_tp(u64 r1, u64 r2, u64 index, u64 r4, u64 
size)
+{
+   /*
+* r1 points to perf tracepoint buffer where first 8 bytes are hidden
+* from bpf program and contain a pointer to 'struct pt_regs'. Fetch it
+* from there and call the same bpf_perf_event_output() helper
+*/
+   u64 ctx = *(long *)r1;
+
+   return bpf_perf_event_output(ctx, r2, index, r4, size);
+}
+
+static const struct bpf_func_proto bpf_perf_event_output_proto_tp = {
+   .func   = bpf_perf_event_output_tp,
+   .gpl_only   = true,
+   .ret_type   = RET_INTEGER,
+   .arg1_type  = ARG_PTR_TO_CTX,
+   .arg2_type  = ARG_CONST_MAP_PTR,
+   .arg3_type  = ARG_ANYTHING,
+   .arg4_type  = ARG_PTR_TO_STACK,
+   .arg5_type  = ARG_CONST_STACK_SIZE,
+};
+
+static u64 bpf_get_stackid_tp(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
+{
+   u64 ctx = *(long *)r1;
+
+   return bpf_get_stackid(ctx, r2, r3, r4, r5);
+}
+
+static const struct bpf_func_proto bpf_get_stackid_proto_tp = {
+   .func   = bpf_get_stackid_tp,
+   .gpl_only   = true,
+   .ret_type   = RET_INTEGER,
+   .arg1_type  = ARG_PTR_TO_CTX,
+   .arg2_type  = ARG_CONST_MAP_PTR,
+   .arg3_type  = ARG_ANYTHING,
+};
+
 static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id 
func_id)
 {
switch (func_id) {
case BPF_FUNC_perf_event_output:
+   return _perf_event_output_proto_tp;
case BPF_FUNC_get_stackid:
-   return NULL;
+   return _get_stackid_proto_tp;
default:
return tracing_func_proto(func_id);
}
-- 
2.8.0



[PATCH net-next 4/8] bpf: support bpf_get_stackid() and bpf_perf_event_output() in tracepoint programs

2016-04-04 Thread Alexei Starovoitov
needs two wrapper functions to fetch 'struct pt_regs *' to convert
tracepoint bpf context into kprobe bpf context to reuse existing
helper functions

Signed-off-by: Alexei Starovoitov 
---
 include/linux/bpf.h  |  1 +
 kernel/bpf/stackmap.c|  2 +-
 kernel/trace/bpf_trace.c | 42 +-
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 21ee41b92e8a..198f6ace70ec 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -160,6 +160,7 @@ struct bpf_array {
 #define MAX_TAIL_CALL_CNT 32
 
 u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
+u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
 void bpf_fd_array_map_clear(struct bpf_map *map);
 bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog 
*fp);
 const struct bpf_func_proto *bpf_get_trace_printk_proto(void);
diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
index 499d9e933f8e..35114725cf30 100644
--- a/kernel/bpf/stackmap.c
+++ b/kernel/bpf/stackmap.c
@@ -116,7 +116,7 @@ free_smap:
return ERR_PTR(err);
 }
 
-static u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5)
+u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5)
 {
struct pt_regs *regs = (struct pt_regs *) (long) r1;
struct bpf_map *map = (struct bpf_map *) (long) r2;
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 3e5ebe3254d2..413ec5614180 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -340,12 +340,52 @@ static struct bpf_prog_type_list kprobe_tl = {
.type   = BPF_PROG_TYPE_KPROBE,
 };
 
+static u64 bpf_perf_event_output_tp(u64 r1, u64 r2, u64 index, u64 r4, u64 
size)
+{
+   /*
+* r1 points to perf tracepoint buffer where first 8 bytes are hidden
+* from bpf program and contain a pointer to 'struct pt_regs'. Fetch it
+* from there and call the same bpf_perf_event_output() helper
+*/
+   u64 ctx = *(long *)r1;
+
+   return bpf_perf_event_output(ctx, r2, index, r4, size);
+}
+
+static const struct bpf_func_proto bpf_perf_event_output_proto_tp = {
+   .func   = bpf_perf_event_output_tp,
+   .gpl_only   = true,
+   .ret_type   = RET_INTEGER,
+   .arg1_type  = ARG_PTR_TO_CTX,
+   .arg2_type  = ARG_CONST_MAP_PTR,
+   .arg3_type  = ARG_ANYTHING,
+   .arg4_type  = ARG_PTR_TO_STACK,
+   .arg5_type  = ARG_CONST_STACK_SIZE,
+};
+
+static u64 bpf_get_stackid_tp(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
+{
+   u64 ctx = *(long *)r1;
+
+   return bpf_get_stackid(ctx, r2, r3, r4, r5);
+}
+
+static const struct bpf_func_proto bpf_get_stackid_proto_tp = {
+   .func   = bpf_get_stackid_tp,
+   .gpl_only   = true,
+   .ret_type   = RET_INTEGER,
+   .arg1_type  = ARG_PTR_TO_CTX,
+   .arg2_type  = ARG_CONST_MAP_PTR,
+   .arg3_type  = ARG_ANYTHING,
+};
+
 static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id 
func_id)
 {
switch (func_id) {
case BPF_FUNC_perf_event_output:
+   return _perf_event_output_proto_tp;
case BPF_FUNC_get_stackid:
-   return NULL;
+   return _get_stackid_proto_tp;
default:
return tracing_func_proto(func_id);
}
-- 
2.8.0



Re: [PATCH v3] serial: 8250_dw: fix wrong logic in dw8250_check_lcr()

2016-04-04 Thread Kefeng Wang


On 2016/4/5 12:02, Greg Kroah-Hartman wrote:
> On Tue, Apr 05, 2016 at 11:32:46AM +0800, Kefeng Wang wrote:
>> Commit cdcea058e510 ("serial: 8250_dw: Avoid serial_outx code duplicate
>> with new dw8250_check_lcr()") introduce a wrong logic when write val to
>> LCR reg. When CONFIG_64BIT enabled, __raw_writeq is used unconditionally.
>>
>> The __raw_readq/__raw_writeq is introduced by commit bca2092d7897 ("serial:
>> 8250_dw: Use 64-bit access for OCTEON.") for OCTEON, so for !PORT_OCTEON,
>> we better to use coincident write func.
>>
>> Fixes: cdcea058e510("serial: 8250_dw: Avoid serial_outx code duplicate with 
>> new dw8250_check_lcr()")
>> Signed-off-by: Kefeng Wang 
>> ---
>> Keep #ifdef CONFIG_64BIT to ensure it built under arch lacking readq/writeq.
>>
>>  drivers/tty/serial/8250/8250_dw.c | 7 ---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> What changed between all of these versions?  Always document that below
> the --- line otherwise I think they are all the same and I'll just
> delete them all :)

Thanks for your guidance, will add log if with different versions to show what 
changes.
> 
> v4 please.

Ok, thanks again.

> 
> thanks,
> 
> greg k-h
> 
> .
> 



[PATCH net-next 3/8] bpf: register BPF_PROG_TYPE_TRACEPOINT program type

2016-04-04 Thread Alexei Starovoitov
register tracepoint bpf program type and let it call the same set
of helper functions as BPF_PROG_TYPE_KPROBE

Signed-off-by: Alexei Starovoitov 
---
 kernel/trace/bpf_trace.c | 45 +++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 3e4ffb3ace5f..3e5ebe3254d2 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -268,7 +268,7 @@ static const struct bpf_func_proto 
bpf_perf_event_output_proto = {
.arg5_type  = ARG_CONST_STACK_SIZE,
 };
 
-static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id 
func_id)
+static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id 
func_id)
 {
switch (func_id) {
case BPF_FUNC_map_lookup_elem:
@@ -295,12 +295,20 @@ static const struct bpf_func_proto 
*kprobe_prog_func_proto(enum bpf_func_id func
return _get_smp_processor_id_proto;
case BPF_FUNC_perf_event_read:
return _perf_event_read_proto;
+   default:
+   return NULL;
+   }
+}
+
+static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id 
func_id)
+{
+   switch (func_id) {
case BPF_FUNC_perf_event_output:
return _perf_event_output_proto;
case BPF_FUNC_get_stackid:
return _get_stackid_proto;
default:
-   return NULL;
+   return tracing_func_proto(func_id);
}
 }
 
@@ -332,9 +340,42 @@ static struct bpf_prog_type_list kprobe_tl = {
.type   = BPF_PROG_TYPE_KPROBE,
 };
 
+static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id 
func_id)
+{
+   switch (func_id) {
+   case BPF_FUNC_perf_event_output:
+   case BPF_FUNC_get_stackid:
+   return NULL;
+   default:
+   return tracing_func_proto(func_id);
+   }
+}
+
+static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type 
type)
+{
+   if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE)
+   return false;
+   if (type != BPF_READ)
+   return false;
+   if (off % size != 0)
+   return false;
+   return true;
+}
+
+static const struct bpf_verifier_ops tracepoint_prog_ops = {
+   .get_func_proto  = tp_prog_func_proto,
+   .is_valid_access = tp_prog_is_valid_access,
+};
+
+static struct bpf_prog_type_list tracepoint_tl = {
+   .ops= _prog_ops,
+   .type   = BPF_PROG_TYPE_TRACEPOINT,
+};
+
 static int __init register_kprobe_prog_ops(void)
 {
bpf_register_prog_type(_tl);
+   bpf_register_prog_type(_tl);
return 0;
 }
 late_initcall(register_kprobe_prog_ops);
-- 
2.8.0



[PATCH net-next 7/8] samples/bpf: tracepoint example

2016-04-04 Thread Alexei Starovoitov
modify offwaketime to work with sched/sched_switch tracepoint
instead of kprobe into finish_task_switch

Signed-off-by: Alexei Starovoitov 
---
 samples/bpf/offwaketime_kern.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/samples/bpf/offwaketime_kern.c b/samples/bpf/offwaketime_kern.c
index c0aa5a9b9c48..983629a31c79 100644
--- a/samples/bpf/offwaketime_kern.c
+++ b/samples/bpf/offwaketime_kern.c
@@ -73,7 +73,7 @@ int waker(struct pt_regs *ctx)
return 0;
 }
 
-static inline int update_counts(struct pt_regs *ctx, u32 pid, u64 delta)
+static inline int update_counts(void *ctx, u32 pid, u64 delta)
 {
struct key_t key = {};
struct wokeby_t *woke;
@@ -100,15 +100,33 @@ static inline int update_counts(struct pt_regs *ctx, u32 
pid, u64 delta)
return 0;
 }
 
+#if 1
+/* taken from /sys/kernel/debug/tracing/events/sched/sched_switch/format */
+struct sched_switch_args {
+   unsigned long long pad;
+   char prev_comm[16];
+   int prev_pid;
+   int prev_prio;
+   long long prev_state;
+   char next_comm[16];
+   int next_pid;
+   int next_prio;
+};
+SEC("tracepoint/sched/sched_switch")
+int oncpu(struct sched_switch_args *ctx)
+{
+   /* record previous thread sleep time */
+   u32 pid = ctx->prev_pid;
+#else
 SEC("kprobe/finish_task_switch")
 int oncpu(struct pt_regs *ctx)
 {
struct task_struct *p = (void *) PT_REGS_PARM1(ctx);
+   /* record previous thread sleep time */
+   u32 pid = _(p->pid);
+#endif
u64 delta, ts, *tsp;
-   u32 pid;
 
-   /* record previous thread sleep time */
-   pid = _(p->pid);
ts = bpf_ktime_get_ns();
bpf_map_update_elem(, , , BPF_ANY);
 
-- 
2.8.0



[PATCH net-next 3/8] bpf: register BPF_PROG_TYPE_TRACEPOINT program type

2016-04-04 Thread Alexei Starovoitov
register tracepoint bpf program type and let it call the same set
of helper functions as BPF_PROG_TYPE_KPROBE

Signed-off-by: Alexei Starovoitov 
---
 kernel/trace/bpf_trace.c | 45 +++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 3e4ffb3ace5f..3e5ebe3254d2 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -268,7 +268,7 @@ static const struct bpf_func_proto 
bpf_perf_event_output_proto = {
.arg5_type  = ARG_CONST_STACK_SIZE,
 };
 
-static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id 
func_id)
+static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id 
func_id)
 {
switch (func_id) {
case BPF_FUNC_map_lookup_elem:
@@ -295,12 +295,20 @@ static const struct bpf_func_proto 
*kprobe_prog_func_proto(enum bpf_func_id func
return _get_smp_processor_id_proto;
case BPF_FUNC_perf_event_read:
return _perf_event_read_proto;
+   default:
+   return NULL;
+   }
+}
+
+static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id 
func_id)
+{
+   switch (func_id) {
case BPF_FUNC_perf_event_output:
return _perf_event_output_proto;
case BPF_FUNC_get_stackid:
return _get_stackid_proto;
default:
-   return NULL;
+   return tracing_func_proto(func_id);
}
 }
 
@@ -332,9 +340,42 @@ static struct bpf_prog_type_list kprobe_tl = {
.type   = BPF_PROG_TYPE_KPROBE,
 };
 
+static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id 
func_id)
+{
+   switch (func_id) {
+   case BPF_FUNC_perf_event_output:
+   case BPF_FUNC_get_stackid:
+   return NULL;
+   default:
+   return tracing_func_proto(func_id);
+   }
+}
+
+static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type 
type)
+{
+   if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE)
+   return false;
+   if (type != BPF_READ)
+   return false;
+   if (off % size != 0)
+   return false;
+   return true;
+}
+
+static const struct bpf_verifier_ops tracepoint_prog_ops = {
+   .get_func_proto  = tp_prog_func_proto,
+   .is_valid_access = tp_prog_is_valid_access,
+};
+
+static struct bpf_prog_type_list tracepoint_tl = {
+   .ops= _prog_ops,
+   .type   = BPF_PROG_TYPE_TRACEPOINT,
+};
+
 static int __init register_kprobe_prog_ops(void)
 {
bpf_register_prog_type(_tl);
+   bpf_register_prog_type(_tl);
return 0;
 }
 late_initcall(register_kprobe_prog_ops);
-- 
2.8.0



[PATCH net-next 7/8] samples/bpf: tracepoint example

2016-04-04 Thread Alexei Starovoitov
modify offwaketime to work with sched/sched_switch tracepoint
instead of kprobe into finish_task_switch

Signed-off-by: Alexei Starovoitov 
---
 samples/bpf/offwaketime_kern.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/samples/bpf/offwaketime_kern.c b/samples/bpf/offwaketime_kern.c
index c0aa5a9b9c48..983629a31c79 100644
--- a/samples/bpf/offwaketime_kern.c
+++ b/samples/bpf/offwaketime_kern.c
@@ -73,7 +73,7 @@ int waker(struct pt_regs *ctx)
return 0;
 }
 
-static inline int update_counts(struct pt_regs *ctx, u32 pid, u64 delta)
+static inline int update_counts(void *ctx, u32 pid, u64 delta)
 {
struct key_t key = {};
struct wokeby_t *woke;
@@ -100,15 +100,33 @@ static inline int update_counts(struct pt_regs *ctx, u32 
pid, u64 delta)
return 0;
 }
 
+#if 1
+/* taken from /sys/kernel/debug/tracing/events/sched/sched_switch/format */
+struct sched_switch_args {
+   unsigned long long pad;
+   char prev_comm[16];
+   int prev_pid;
+   int prev_prio;
+   long long prev_state;
+   char next_comm[16];
+   int next_pid;
+   int next_prio;
+};
+SEC("tracepoint/sched/sched_switch")
+int oncpu(struct sched_switch_args *ctx)
+{
+   /* record previous thread sleep time */
+   u32 pid = ctx->prev_pid;
+#else
 SEC("kprobe/finish_task_switch")
 int oncpu(struct pt_regs *ctx)
 {
struct task_struct *p = (void *) PT_REGS_PARM1(ctx);
+   /* record previous thread sleep time */
+   u32 pid = _(p->pid);
+#endif
u64 delta, ts, *tsp;
-   u32 pid;
 
-   /* record previous thread sleep time */
-   pid = _(p->pid);
ts = bpf_ktime_get_ns();
bpf_map_update_elem(, , , BPF_ANY);
 
-- 
2.8.0



Re: [PATCH v3] serial: 8250_dw: fix wrong logic in dw8250_check_lcr()

2016-04-04 Thread Kefeng Wang


On 2016/4/5 12:02, Greg Kroah-Hartman wrote:
> On Tue, Apr 05, 2016 at 11:32:46AM +0800, Kefeng Wang wrote:
>> Commit cdcea058e510 ("serial: 8250_dw: Avoid serial_outx code duplicate
>> with new dw8250_check_lcr()") introduce a wrong logic when write val to
>> LCR reg. When CONFIG_64BIT enabled, __raw_writeq is used unconditionally.
>>
>> The __raw_readq/__raw_writeq is introduced by commit bca2092d7897 ("serial:
>> 8250_dw: Use 64-bit access for OCTEON.") for OCTEON, so for !PORT_OCTEON,
>> we better to use coincident write func.
>>
>> Fixes: cdcea058e510("serial: 8250_dw: Avoid serial_outx code duplicate with 
>> new dw8250_check_lcr()")
>> Signed-off-by: Kefeng Wang 
>> ---
>> Keep #ifdef CONFIG_64BIT to ensure it built under arch lacking readq/writeq.
>>
>>  drivers/tty/serial/8250/8250_dw.c | 7 ---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> What changed between all of these versions?  Always document that below
> the --- line otherwise I think they are all the same and I'll just
> delete them all :)

Thanks for your guidance, will add log if with different versions to show what 
changes.
> 
> v4 please.

Ok, thanks again.

> 
> thanks,
> 
> greg k-h
> 
> .
> 



Re: [PATCH 1/2] phy: Group vendor specific phy drivers

2016-04-04 Thread Vivek Gautam
On Fri, Apr 1, 2016 at 8:31 AM, kbuild test robot  wrote:
> Hi Vivek,
>
> [auto build test ERROR on rockchip/for-next]
> [also build test ERROR on v4.6-rc1 next-20160401]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improving the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Vivek-Gautam/phy-Group-vendor-specific-phy-drivers/20160401-192920
> base:   
> https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git 
> for-next
> config: arm-allyesconfig (attached as .config)
> reproduce:
> wget 
> https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
>  -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=arm
>
> All errors (new ones prefixed by >>):
>
>>> make[4]: *** No rule to make target 'drivers/phy/qcom/+=', needed by 
>>> 'drivers/phy/qcom/built-in.o'.
>make[4]: Target '__build' not remade because of errors.

will fix this.

>
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation


-- 
Best Regards
Vivek Gautam
Samsung, India


Re: [PATCH 1/2] phy: Group vendor specific phy drivers

2016-04-04 Thread Vivek Gautam
On Fri, Apr 1, 2016 at 8:31 AM, kbuild test robot  wrote:
> Hi Vivek,
>
> [auto build test ERROR on rockchip/for-next]
> [also build test ERROR on v4.6-rc1 next-20160401]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improving the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Vivek-Gautam/phy-Group-vendor-specific-phy-drivers/20160401-192920
> base:   
> https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git 
> for-next
> config: arm-allyesconfig (attached as .config)
> reproduce:
> wget 
> https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
>  -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=arm
>
> All errors (new ones prefixed by >>):
>
>>> make[4]: *** No rule to make target 'drivers/phy/qcom/+=', needed by 
>>> 'drivers/phy/qcom/built-in.o'.
>make[4]: Target '__build' not remade because of errors.

will fix this.

>
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation


-- 
Best Regards
Vivek Gautam
Samsung, India


[PATCH net-next 0/8] allow bpf attach to tracepoints

2016-04-04 Thread Alexei Starovoitov
Hi Steven, Peter,

last time we discussed bpf+tracepoints it was a year ago [1] and the reason
we didn't proceed with that approach was that bpf would make arguments
arg1, arg2 to trace_xx(arg1, arg2) call to be exposed to bpf program
and that was considered unnecessary extension of abi. Back then I wanted
to avoid the cost of buffer alloc and field assign part in all
of the tracepoints, but looks like when optimized the cost is acceptable.
So this new apporach doesn't expose any new abi to bpf program.
The program is looking at tracepoint fields after they were copied
by perf_trace_xx() and described in /sys/kernel/debug/tracing/events/xxx/format
We made a tool [2] that takes arguments from /sys/.../format and works as:
$ tplist.py -v random:urandom_read
int got_bits;
int pool_left;
int input_left;
Then these fields can be copy-pasted into bpf program like:
struct urandom_read {
__u64 hidden_pad;
int got_bits;
int pool_left;
int input_left;
};
and the program can use it:
SEC("tracepoint/random/urandom_read")
int bpf_prog(struct urandom_read *ctx)
{
return ctx->pool_left > 0 ? 1 : 0;
}
This way the program can access tracepoint fields faster than
equivalent bpf+kprobe program, which is the main goal of these patches.

Patch 1 and 2 are simple changes in perf core side, please review.
I'd like to take the whole set via net-next tree, since the rest of
the patches might conflict with other bpf work going on in net-next
and we want to avoid cross-tree merge conflicts.
Patch 7 is an example of access to tracepoint fields from bpf prog.
Patch 8 is a micro benchmark for bpf+kprobe vs bpf+tracepoint.

Note that for actual tracing tools the user doesn't need to
run tplist.py and copy-paste fields manually. The tools do it
automatically. Like argdist tool [3] can be used as:
$ argdist -H 't:block:block_rq_complete():u32:nr_sector'
where 'nr_sector' is name of tracepoint field taken from
/sys/kernel/debug/tracing/events/block/block_rq_complete/format
and appropriate bpf program is generated on the fly.

[1] http://thread.gmane.org/gmane.linux.kernel.api/8127/focus=8165
[2] https://github.com/iovisor/bcc/blob/master/tools/tplist.py
[3] https://github.com/iovisor/bcc/blob/master/tools/argdist.py

Alexei Starovoitov (8):
  perf: optimize perf_fetch_caller_regs
  perf, bpf: allow bpf programs attach to tracepoints
  bpf: register BPF_PROG_TYPE_TRACEPOINT program type
  bpf: support bpf_get_stackid() and bpf_perf_event_output() in
tracepoint programs
  bpf: sanitize bpf tracepoint access
  samples/bpf: add tracepoint support to bpf loader
  samples/bpf: tracepoint example
  samples/bpf: add tracepoint vs kprobe performance tests

 include/linux/bpf.h |   2 +
 include/linux/perf_event.h  |   2 -
 include/linux/trace_events.h|   1 +
 include/trace/perf.h|  18 +++-
 include/uapi/linux/bpf.h|   1 +
 kernel/bpf/stackmap.c   |   2 +-
 kernel/bpf/verifier.c   |   6 +-
 kernel/events/core.c|  21 -
 kernel/trace/bpf_trace.c|  85 -
 kernel/trace/trace_event_perf.c |   4 +
 kernel/trace/trace_events.c |  18 
 samples/bpf/Makefile|   5 +
 samples/bpf/bpf_load.c  |  26 +-
 samples/bpf/offwaketime_kern.c  |  26 +-
 samples/bpf/test_overhead_kprobe_kern.c |  41 
 samples/bpf/test_overhead_tp_kern.c |  36 +++
 samples/bpf/test_overhead_user.c| 161 
 17 files changed, 432 insertions(+), 23 deletions(-)
 create mode 100644 samples/bpf/test_overhead_kprobe_kern.c
 create mode 100644 samples/bpf/test_overhead_tp_kern.c
 create mode 100644 samples/bpf/test_overhead_user.c

-- 
2.8.0



[PATCH net-next 5/8] bpf: sanitize bpf tracepoint access

2016-04-04 Thread Alexei Starovoitov
during bpf program loading remember the last byte of ctx access
and at the time of attaching the program to tracepoint check that
the program doesn't access bytes beyond defined in tracepoint fields

This also disallows access to __dynamic_array fields, but can be
relaxed in the future.

Signed-off-by: Alexei Starovoitov 
---
 include/linux/bpf.h  |  1 +
 include/linux/trace_events.h |  1 +
 kernel/bpf/verifier.c|  6 +-
 kernel/events/core.c |  8 
 kernel/trace/trace_events.c  | 18 ++
 5 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 198f6ace70ec..b2365a6eba3d 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -131,6 +131,7 @@ struct bpf_prog_type_list {
 struct bpf_prog_aux {
atomic_t refcnt;
u32 used_map_cnt;
+   u32 max_ctx_offset;
const struct bpf_verifier_ops *ops;
struct bpf_map **used_maps;
struct bpf_prog *prog;
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 0810f81b6db2..97bd7da98567 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -569,6 +569,7 @@ extern int trace_define_field(struct trace_event_call 
*call, const char *type,
  int is_signed, int filter_type);
 extern int trace_add_event_call(struct trace_event_call *call);
 extern int trace_remove_event_call(struct trace_event_call *call);
+extern int trace_event_get_offsets(struct trace_event_call *call);
 
 #define is_signed_type(type)   (((type)(-1)) < (type)1)
 
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2e08f8e9b771..58792fed5678 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -652,8 +652,12 @@ static int check_ctx_access(struct verifier_env *env, int 
off, int size,
enum bpf_access_type t)
 {
if (env->prog->aux->ops->is_valid_access &&
-   env->prog->aux->ops->is_valid_access(off, size, t))
+   env->prog->aux->ops->is_valid_access(off, size, t)) {
+   /* remember the offset of last byte accessed in ctx */
+   if (env->prog->aux->max_ctx_offset < off + size)
+   env->prog->aux->max_ctx_offset = off + size;
return 0;
+   }
 
verbose("invalid bpf_context access off=%d size=%d\n", off, size);
return -EACCES;
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 58fc9a7d1562..e7e3c2057582 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7131,6 +7131,14 @@ static int perf_event_set_bpf_prog(struct perf_event 
*event, u32 prog_fd)
return -EINVAL;
}
 
+   if (is_tracepoint) {
+   int off = trace_event_get_offsets(event->tp_event);
+
+   if (prog->aux->max_ctx_offset > off) {
+   bpf_prog_put(prog);
+   return -EACCES;
+   }
+   }
event->tp_event->prog = prog;
 
return 0;
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 05ddc0820771..ced963049e0a 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -204,6 +204,24 @@ static void trace_destroy_fields(struct trace_event_call 
*call)
}
 }
 
+/*
+ * run-time version of trace_event_get_offsets_() that returns the last
+ * accessible offset of trace fields excluding __dynamic_array bytes
+ */
+int trace_event_get_offsets(struct trace_event_call *call)
+{
+   struct ftrace_event_field *tail;
+   struct list_head *head;
+
+   head = trace_get_fields(call);
+   /*
+* head->next points to the last field with the largest offset,
+* since it was added last by trace_define_field()
+*/
+   tail = list_first_entry(head, struct ftrace_event_field, link);
+   return tail->offset + tail->size;
+}
+
 int trace_event_raw_init(struct trace_event_call *call)
 {
int id;
-- 
2.8.0



[PATCH net-next 0/8] allow bpf attach to tracepoints

2016-04-04 Thread Alexei Starovoitov
Hi Steven, Peter,

last time we discussed bpf+tracepoints it was a year ago [1] and the reason
we didn't proceed with that approach was that bpf would make arguments
arg1, arg2 to trace_xx(arg1, arg2) call to be exposed to bpf program
and that was considered unnecessary extension of abi. Back then I wanted
to avoid the cost of buffer alloc and field assign part in all
of the tracepoints, but looks like when optimized the cost is acceptable.
So this new apporach doesn't expose any new abi to bpf program.
The program is looking at tracepoint fields after they were copied
by perf_trace_xx() and described in /sys/kernel/debug/tracing/events/xxx/format
We made a tool [2] that takes arguments from /sys/.../format and works as:
$ tplist.py -v random:urandom_read
int got_bits;
int pool_left;
int input_left;
Then these fields can be copy-pasted into bpf program like:
struct urandom_read {
__u64 hidden_pad;
int got_bits;
int pool_left;
int input_left;
};
and the program can use it:
SEC("tracepoint/random/urandom_read")
int bpf_prog(struct urandom_read *ctx)
{
return ctx->pool_left > 0 ? 1 : 0;
}
This way the program can access tracepoint fields faster than
equivalent bpf+kprobe program, which is the main goal of these patches.

Patch 1 and 2 are simple changes in perf core side, please review.
I'd like to take the whole set via net-next tree, since the rest of
the patches might conflict with other bpf work going on in net-next
and we want to avoid cross-tree merge conflicts.
Patch 7 is an example of access to tracepoint fields from bpf prog.
Patch 8 is a micro benchmark for bpf+kprobe vs bpf+tracepoint.

Note that for actual tracing tools the user doesn't need to
run tplist.py and copy-paste fields manually. The tools do it
automatically. Like argdist tool [3] can be used as:
$ argdist -H 't:block:block_rq_complete():u32:nr_sector'
where 'nr_sector' is name of tracepoint field taken from
/sys/kernel/debug/tracing/events/block/block_rq_complete/format
and appropriate bpf program is generated on the fly.

[1] http://thread.gmane.org/gmane.linux.kernel.api/8127/focus=8165
[2] https://github.com/iovisor/bcc/blob/master/tools/tplist.py
[3] https://github.com/iovisor/bcc/blob/master/tools/argdist.py

Alexei Starovoitov (8):
  perf: optimize perf_fetch_caller_regs
  perf, bpf: allow bpf programs attach to tracepoints
  bpf: register BPF_PROG_TYPE_TRACEPOINT program type
  bpf: support bpf_get_stackid() and bpf_perf_event_output() in
tracepoint programs
  bpf: sanitize bpf tracepoint access
  samples/bpf: add tracepoint support to bpf loader
  samples/bpf: tracepoint example
  samples/bpf: add tracepoint vs kprobe performance tests

 include/linux/bpf.h |   2 +
 include/linux/perf_event.h  |   2 -
 include/linux/trace_events.h|   1 +
 include/trace/perf.h|  18 +++-
 include/uapi/linux/bpf.h|   1 +
 kernel/bpf/stackmap.c   |   2 +-
 kernel/bpf/verifier.c   |   6 +-
 kernel/events/core.c|  21 -
 kernel/trace/bpf_trace.c|  85 -
 kernel/trace/trace_event_perf.c |   4 +
 kernel/trace/trace_events.c |  18 
 samples/bpf/Makefile|   5 +
 samples/bpf/bpf_load.c  |  26 +-
 samples/bpf/offwaketime_kern.c  |  26 +-
 samples/bpf/test_overhead_kprobe_kern.c |  41 
 samples/bpf/test_overhead_tp_kern.c |  36 +++
 samples/bpf/test_overhead_user.c| 161 
 17 files changed, 432 insertions(+), 23 deletions(-)
 create mode 100644 samples/bpf/test_overhead_kprobe_kern.c
 create mode 100644 samples/bpf/test_overhead_tp_kern.c
 create mode 100644 samples/bpf/test_overhead_user.c

-- 
2.8.0



[PATCH net-next 5/8] bpf: sanitize bpf tracepoint access

2016-04-04 Thread Alexei Starovoitov
during bpf program loading remember the last byte of ctx access
and at the time of attaching the program to tracepoint check that
the program doesn't access bytes beyond defined in tracepoint fields

This also disallows access to __dynamic_array fields, but can be
relaxed in the future.

Signed-off-by: Alexei Starovoitov 
---
 include/linux/bpf.h  |  1 +
 include/linux/trace_events.h |  1 +
 kernel/bpf/verifier.c|  6 +-
 kernel/events/core.c |  8 
 kernel/trace/trace_events.c  | 18 ++
 5 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 198f6ace70ec..b2365a6eba3d 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -131,6 +131,7 @@ struct bpf_prog_type_list {
 struct bpf_prog_aux {
atomic_t refcnt;
u32 used_map_cnt;
+   u32 max_ctx_offset;
const struct bpf_verifier_ops *ops;
struct bpf_map **used_maps;
struct bpf_prog *prog;
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 0810f81b6db2..97bd7da98567 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -569,6 +569,7 @@ extern int trace_define_field(struct trace_event_call 
*call, const char *type,
  int is_signed, int filter_type);
 extern int trace_add_event_call(struct trace_event_call *call);
 extern int trace_remove_event_call(struct trace_event_call *call);
+extern int trace_event_get_offsets(struct trace_event_call *call);
 
 #define is_signed_type(type)   (((type)(-1)) < (type)1)
 
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2e08f8e9b771..58792fed5678 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -652,8 +652,12 @@ static int check_ctx_access(struct verifier_env *env, int 
off, int size,
enum bpf_access_type t)
 {
if (env->prog->aux->ops->is_valid_access &&
-   env->prog->aux->ops->is_valid_access(off, size, t))
+   env->prog->aux->ops->is_valid_access(off, size, t)) {
+   /* remember the offset of last byte accessed in ctx */
+   if (env->prog->aux->max_ctx_offset < off + size)
+   env->prog->aux->max_ctx_offset = off + size;
return 0;
+   }
 
verbose("invalid bpf_context access off=%d size=%d\n", off, size);
return -EACCES;
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 58fc9a7d1562..e7e3c2057582 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7131,6 +7131,14 @@ static int perf_event_set_bpf_prog(struct perf_event 
*event, u32 prog_fd)
return -EINVAL;
}
 
+   if (is_tracepoint) {
+   int off = trace_event_get_offsets(event->tp_event);
+
+   if (prog->aux->max_ctx_offset > off) {
+   bpf_prog_put(prog);
+   return -EACCES;
+   }
+   }
event->tp_event->prog = prog;
 
return 0;
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 05ddc0820771..ced963049e0a 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -204,6 +204,24 @@ static void trace_destroy_fields(struct trace_event_call 
*call)
}
 }
 
+/*
+ * run-time version of trace_event_get_offsets_() that returns the last
+ * accessible offset of trace fields excluding __dynamic_array bytes
+ */
+int trace_event_get_offsets(struct trace_event_call *call)
+{
+   struct ftrace_event_field *tail;
+   struct list_head *head;
+
+   head = trace_get_fields(call);
+   /*
+* head->next points to the last field with the largest offset,
+* since it was added last by trace_define_field()
+*/
+   tail = list_first_entry(head, struct ftrace_event_field, link);
+   return tail->offset + tail->size;
+}
+
 int trace_event_raw_init(struct trace_event_call *call)
 {
int id;
-- 
2.8.0



[PATCH net-next 6/8] samples/bpf: add tracepoint support to bpf loader

2016-04-04 Thread Alexei Starovoitov
Recognize "tracepoint/" section name prefix and attach the program
to that tracepoint.

Signed-off-by: Alexei Starovoitov 
---
 samples/bpf/bpf_load.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 58f86bd11b3d..022af71c2bb5 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -49,6 +49,7 @@ static int load_and_attach(const char *event, struct bpf_insn 
*prog, int size)
bool is_socket = strncmp(event, "socket", 6) == 0;
bool is_kprobe = strncmp(event, "kprobe/", 7) == 0;
bool is_kretprobe = strncmp(event, "kretprobe/", 10) == 0;
+   bool is_tracepoint = strncmp(event, "tracepoint/", 11) == 0;
enum bpf_prog_type prog_type;
char buf[256];
int fd, efd, err, id;
@@ -63,6 +64,8 @@ static int load_and_attach(const char *event, struct bpf_insn 
*prog, int size)
prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
} else if (is_kprobe || is_kretprobe) {
prog_type = BPF_PROG_TYPE_KPROBE;
+   } else if (is_tracepoint) {
+   prog_type = BPF_PROG_TYPE_TRACEPOINT;
} else {
printf("Unknown event '%s'\n", event);
return -1;
@@ -111,12 +114,23 @@ static int load_and_attach(const char *event, struct 
bpf_insn *prog, int size)
   event, strerror(errno));
return -1;
}
-   }
 
-   strcpy(buf, DEBUGFS);
-   strcat(buf, "events/kprobes/");
-   strcat(buf, event);
-   strcat(buf, "/id");
+   strcpy(buf, DEBUGFS);
+   strcat(buf, "events/kprobes/");
+   strcat(buf, event);
+   strcat(buf, "/id");
+   } else if (is_tracepoint) {
+   event += 11;
+
+   if (*event == 0) {
+   printf("event name cannot be empty\n");
+   return -1;
+   }
+   strcpy(buf, DEBUGFS);
+   strcat(buf, "events/");
+   strcat(buf, event);
+   strcat(buf, "/id");
+   }
 
efd = open(buf, O_RDONLY, 0);
if (efd < 0) {
@@ -304,6 +318,7 @@ int load_bpf_file(char *path)
 
if (memcmp(shname_prog, "kprobe/", 7) == 0 ||
memcmp(shname_prog, "kretprobe/", 10) == 0 ||
+   memcmp(shname_prog, "tracepoint/", 11) == 0 ||
memcmp(shname_prog, "socket", 6) == 0)
load_and_attach(shname_prog, insns, 
data_prog->d_size);
}
@@ -320,6 +335,7 @@ int load_bpf_file(char *path)
 
if (memcmp(shname, "kprobe/", 7) == 0 ||
memcmp(shname, "kretprobe/", 10) == 0 ||
+   memcmp(shname, "tracepoint/", 11) == 0 ||
memcmp(shname, "socket", 6) == 0)
load_and_attach(shname, data->d_buf, data->d_size);
}
-- 
2.8.0



[PATCH net-next 1/8] perf: optimize perf_fetch_caller_regs

2016-04-04 Thread Alexei Starovoitov
avoid memset in perf_fetch_caller_regs, since it's the critical path of all 
tracepoints.
It's called from perf_sw_event_sched, perf_event_task_sched_in and all of 
perf_trace_##call
with this_cpu_ptr(&__perf_regs[..]) which are zero initialized by perpcu_alloc 
and
subsequent call to perf_arch_fetch_caller_regs initializes the same fields on 
all archs,
so we can safely drop memset from all of the above cases and move it into
perf_ftrace_function_call that calls it with stack allocated pt_regs.

Signed-off-by: Alexei Starovoitov 
---
 include/linux/perf_event.h  | 2 --
 kernel/trace/trace_event_perf.c | 1 +
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index f291275ffd71..e89f7199c223 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -882,8 +882,6 @@ static inline void perf_arch_fetch_caller_regs(struct 
pt_regs *regs, unsigned lo
  */
 static inline void perf_fetch_caller_regs(struct pt_regs *regs)
 {
-   memset(regs, 0, sizeof(*regs));
-
perf_arch_fetch_caller_regs(regs, CALLER_ADDR0);
 }
 
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
index 00df25fd86ef..7a68afca8249 100644
--- a/kernel/trace/trace_event_perf.c
+++ b/kernel/trace/trace_event_perf.c
@@ -316,6 +316,7 @@ perf_ftrace_function_call(unsigned long ip, unsigned long 
parent_ip,
 
BUILD_BUG_ON(ENTRY_SIZE > PERF_MAX_TRACE_SIZE);
 
+   memset(, 0, sizeof(regs));
perf_fetch_caller_regs();
 
entry = perf_trace_buf_prepare(ENTRY_SIZE, TRACE_FN, NULL, );
-- 
2.8.0



[PATCH net-next 6/8] samples/bpf: add tracepoint support to bpf loader

2016-04-04 Thread Alexei Starovoitov
Recognize "tracepoint/" section name prefix and attach the program
to that tracepoint.

Signed-off-by: Alexei Starovoitov 
---
 samples/bpf/bpf_load.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 58f86bd11b3d..022af71c2bb5 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -49,6 +49,7 @@ static int load_and_attach(const char *event, struct bpf_insn 
*prog, int size)
bool is_socket = strncmp(event, "socket", 6) == 0;
bool is_kprobe = strncmp(event, "kprobe/", 7) == 0;
bool is_kretprobe = strncmp(event, "kretprobe/", 10) == 0;
+   bool is_tracepoint = strncmp(event, "tracepoint/", 11) == 0;
enum bpf_prog_type prog_type;
char buf[256];
int fd, efd, err, id;
@@ -63,6 +64,8 @@ static int load_and_attach(const char *event, struct bpf_insn 
*prog, int size)
prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
} else if (is_kprobe || is_kretprobe) {
prog_type = BPF_PROG_TYPE_KPROBE;
+   } else if (is_tracepoint) {
+   prog_type = BPF_PROG_TYPE_TRACEPOINT;
} else {
printf("Unknown event '%s'\n", event);
return -1;
@@ -111,12 +114,23 @@ static int load_and_attach(const char *event, struct 
bpf_insn *prog, int size)
   event, strerror(errno));
return -1;
}
-   }
 
-   strcpy(buf, DEBUGFS);
-   strcat(buf, "events/kprobes/");
-   strcat(buf, event);
-   strcat(buf, "/id");
+   strcpy(buf, DEBUGFS);
+   strcat(buf, "events/kprobes/");
+   strcat(buf, event);
+   strcat(buf, "/id");
+   } else if (is_tracepoint) {
+   event += 11;
+
+   if (*event == 0) {
+   printf("event name cannot be empty\n");
+   return -1;
+   }
+   strcpy(buf, DEBUGFS);
+   strcat(buf, "events/");
+   strcat(buf, event);
+   strcat(buf, "/id");
+   }
 
efd = open(buf, O_RDONLY, 0);
if (efd < 0) {
@@ -304,6 +318,7 @@ int load_bpf_file(char *path)
 
if (memcmp(shname_prog, "kprobe/", 7) == 0 ||
memcmp(shname_prog, "kretprobe/", 10) == 0 ||
+   memcmp(shname_prog, "tracepoint/", 11) == 0 ||
memcmp(shname_prog, "socket", 6) == 0)
load_and_attach(shname_prog, insns, 
data_prog->d_size);
}
@@ -320,6 +335,7 @@ int load_bpf_file(char *path)
 
if (memcmp(shname, "kprobe/", 7) == 0 ||
memcmp(shname, "kretprobe/", 10) == 0 ||
+   memcmp(shname, "tracepoint/", 11) == 0 ||
memcmp(shname, "socket", 6) == 0)
load_and_attach(shname, data->d_buf, data->d_size);
}
-- 
2.8.0



[PATCH net-next 1/8] perf: optimize perf_fetch_caller_regs

2016-04-04 Thread Alexei Starovoitov
avoid memset in perf_fetch_caller_regs, since it's the critical path of all 
tracepoints.
It's called from perf_sw_event_sched, perf_event_task_sched_in and all of 
perf_trace_##call
with this_cpu_ptr(&__perf_regs[..]) which are zero initialized by perpcu_alloc 
and
subsequent call to perf_arch_fetch_caller_regs initializes the same fields on 
all archs,
so we can safely drop memset from all of the above cases and move it into
perf_ftrace_function_call that calls it with stack allocated pt_regs.

Signed-off-by: Alexei Starovoitov 
---
 include/linux/perf_event.h  | 2 --
 kernel/trace/trace_event_perf.c | 1 +
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index f291275ffd71..e89f7199c223 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -882,8 +882,6 @@ static inline void perf_arch_fetch_caller_regs(struct 
pt_regs *regs, unsigned lo
  */
 static inline void perf_fetch_caller_regs(struct pt_regs *regs)
 {
-   memset(regs, 0, sizeof(*regs));
-
perf_arch_fetch_caller_regs(regs, CALLER_ADDR0);
 }
 
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
index 00df25fd86ef..7a68afca8249 100644
--- a/kernel/trace/trace_event_perf.c
+++ b/kernel/trace/trace_event_perf.c
@@ -316,6 +316,7 @@ perf_ftrace_function_call(unsigned long ip, unsigned long 
parent_ip,
 
BUILD_BUG_ON(ENTRY_SIZE > PERF_MAX_TRACE_SIZE);
 
+   memset(, 0, sizeof(regs));
perf_fetch_caller_regs();
 
entry = perf_trace_buf_prepare(ENTRY_SIZE, TRACE_FN, NULL, );
-- 
2.8.0



Re: [PATCH] s390/kexec: Consolidate crash_map/unmap_reserved_pages() and arch_kexec_protect(unprotect)_crashkres()

2016-04-04 Thread Xunlei Pang
On 2016/04/04 at 22:58, Michael Holzheu wrote:
> Hello Xunlei,
>
> On Sat, 2 Apr 2016 09:23:50 +0800
> Xunlei Pang  wrote:
>
>> On 2016/04/02 at 01:41, Michael Holzheu wrote:
>>> Hello Xunlei again,
>>>
>>> Some initial comments below...
>>>
>>> On Wed, 30 Mar 2016 19:47:21 +0800
>>> Xunlei Pang  wrote:
>>>
> [snip]
>
 +  os_info_crashkernel_add(0, 0);
 +  }
 +}
>>> Please do not move these functions in the file. If you leave it at their
>>> old location, the patch will be *much* smaller.
>> In fact, I did this wanting avoiding adding extra declaration.
> IMHO no extra declaration is necessary (see patch below).
>
> [snip]
>
 +/*
   * PM notifier callback for kdump
   */
  static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long 
 action,
 @@ -43,12 +89,12 @@ static int machine_kdump_pm_cb(struct notifier_block 
 *nb, unsigned long action,
switch (action) {
case PM_SUSPEND_PREPARE:
case PM_HIBERNATION_PREPARE:
 -  if (crashk_res.start)
 +  if (kexec_crash_image)
>>> Why this change?
>> arch_kexec_protect_crashkres() will do the unmapping once kdump kernel is 
>> loaded
>> (i.e. kexec_crash_image is non-NULL), so we should check "kexec_crash_image" 
>> here
>> and do the corresponding re-mapping. 
>>
>> NULL crashk_res_image means that kdump kernel is not loaded, in this case 
>> mapping is
>> already setup either initially in reserve_crashkernel() or by 
>> arch_kexec_unprotect_crashkres().
> Sorry, I missed this obvious part. So your change seems to be ok here.
>
> There is another problem with your patch: The vmem_remove_mapping() function
> can only remove mappings which have been added by vmem_add_mapping() before.
> Therefore currently the vmem_remove_mapping() call is a nop and we still have
> a RW mapping after the kexec system call.
>
> If you check "/sys/kernel/debug/kernel_page_tables" you will see that the
> crashkernel memory is still mapped RW after loading kdump.
>
> To fix this we could keep the memblock_remove() and call vmem_add_mapping()
> from a init function (see patch below).

Indeed, thanks for the catching.

>
> [snip]
>
 --- a/arch/s390/kernel/setup.c
 +++ b/arch/s390/kernel/setup.c
 @@ -603,7 +603,7 @@ static void __init reserve_crashkernel(void)
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
insert_resource(_resource, _res);
 -  memblock_remove(crash_base, crash_size);
 +  memblock_reserve(crash_base, crash_size);
>>> I will discuss this next week in our team.
>> This can address the bad page warning when shrinking crashk_res.
> Yes, shrinking crashkernel memory is currently broken on s390. Heiko Carstens
> (on cc) plans to do some general rework that probably will automatically fix
> this issue.

Since this is not critical issue, I'm fine with leaving it to Heiko's rework.

> So I would suggest that you merge the following with your initial patch and
> then resend the merged patch.
>
> What do you think?

That's great, I will send v2 later. Thanks for the review.

Regards,
Xunlei

>
> Michael
> ---8<
> s390/kdump: Consolidate crash_map/unmap_reserved_pages() - update
>
>  - Move functions back to keep the patch small
>  - Consolidate crash_map_reserved_pages/arch_kexec_unprotect_crashkres()
>  - Re-introduce memblock_remove()
>  - Call arch_kexec_unprotect_crashkres() in machine_kdump_pm_init()
>
> Signed-off-by: Michael Holzheu 
> ---
>  arch/s390/kernel/machine_kexec.c |   88 
> +--
>  1 file changed, 40 insertions(+), 48 deletions(-)
>
> --- a/arch/s390/kernel/machine_kexec.c
> +++ b/arch/s390/kernel/machine_kexec.c
> @@ -35,52 +35,6 @@ extern const unsigned long long relocate
>  #ifdef CONFIG_CRASH_DUMP
>  
>  /*
> - * Map or unmap crashkernel memory
> - */
> -static void crash_map_pages(int enable)
> -{
> - unsigned long size = resource_size(_res);
> -
> - BUG_ON(crashk_res.start % KEXEC_CRASH_MEM_ALIGN ||
> -size % KEXEC_CRASH_MEM_ALIGN);
> - if (enable)
> - vmem_add_mapping(crashk_res.start, size);
> - else {
> - vmem_remove_mapping(crashk_res.start, size);
> - if (size)
> - os_info_crashkernel_add(crashk_res.start, size);
> - else
> - os_info_crashkernel_add(0, 0);
> - }
> -}
> -
> -/*
> - * Map crashkernel memory
> - */
> -static void crash_map_reserved_pages(void)
> -{
> - crash_map_pages(1);
> -}
> -
> -/*
> - * Unmap crashkernel memory
> - */
> -static void crash_unmap_reserved_pages(void)
> -{
> - crash_map_pages(0);
> -}
> -
> -void arch_kexec_protect_crashkres(void)
> -{
> - crash_unmap_reserved_pages();
> -}
> -
> -void arch_kexec_unprotect_crashkres(void)
> -{
> - crash_map_reserved_pages();
> -}
> -
> -/*
>   * PM notifier 

Re: [PATCH] s390/kexec: Consolidate crash_map/unmap_reserved_pages() and arch_kexec_protect(unprotect)_crashkres()

2016-04-04 Thread Xunlei Pang
On 2016/04/04 at 22:58, Michael Holzheu wrote:
> Hello Xunlei,
>
> On Sat, 2 Apr 2016 09:23:50 +0800
> Xunlei Pang  wrote:
>
>> On 2016/04/02 at 01:41, Michael Holzheu wrote:
>>> Hello Xunlei again,
>>>
>>> Some initial comments below...
>>>
>>> On Wed, 30 Mar 2016 19:47:21 +0800
>>> Xunlei Pang  wrote:
>>>
> [snip]
>
 +  os_info_crashkernel_add(0, 0);
 +  }
 +}
>>> Please do not move these functions in the file. If you leave it at their
>>> old location, the patch will be *much* smaller.
>> In fact, I did this wanting avoiding adding extra declaration.
> IMHO no extra declaration is necessary (see patch below).
>
> [snip]
>
 +/*
   * PM notifier callback for kdump
   */
  static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long 
 action,
 @@ -43,12 +89,12 @@ static int machine_kdump_pm_cb(struct notifier_block 
 *nb, unsigned long action,
switch (action) {
case PM_SUSPEND_PREPARE:
case PM_HIBERNATION_PREPARE:
 -  if (crashk_res.start)
 +  if (kexec_crash_image)
>>> Why this change?
>> arch_kexec_protect_crashkres() will do the unmapping once kdump kernel is 
>> loaded
>> (i.e. kexec_crash_image is non-NULL), so we should check "kexec_crash_image" 
>> here
>> and do the corresponding re-mapping. 
>>
>> NULL crashk_res_image means that kdump kernel is not loaded, in this case 
>> mapping is
>> already setup either initially in reserve_crashkernel() or by 
>> arch_kexec_unprotect_crashkres().
> Sorry, I missed this obvious part. So your change seems to be ok here.
>
> There is another problem with your patch: The vmem_remove_mapping() function
> can only remove mappings which have been added by vmem_add_mapping() before.
> Therefore currently the vmem_remove_mapping() call is a nop and we still have
> a RW mapping after the kexec system call.
>
> If you check "/sys/kernel/debug/kernel_page_tables" you will see that the
> crashkernel memory is still mapped RW after loading kdump.
>
> To fix this we could keep the memblock_remove() and call vmem_add_mapping()
> from a init function (see patch below).

Indeed, thanks for the catching.

>
> [snip]
>
 --- a/arch/s390/kernel/setup.c
 +++ b/arch/s390/kernel/setup.c
 @@ -603,7 +603,7 @@ static void __init reserve_crashkernel(void)
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
insert_resource(_resource, _res);
 -  memblock_remove(crash_base, crash_size);
 +  memblock_reserve(crash_base, crash_size);
>>> I will discuss this next week in our team.
>> This can address the bad page warning when shrinking crashk_res.
> Yes, shrinking crashkernel memory is currently broken on s390. Heiko Carstens
> (on cc) plans to do some general rework that probably will automatically fix
> this issue.

Since this is not critical issue, I'm fine with leaving it to Heiko's rework.

> So I would suggest that you merge the following with your initial patch and
> then resend the merged patch.
>
> What do you think?

That's great, I will send v2 later. Thanks for the review.

Regards,
Xunlei

>
> Michael
> ---8<
> s390/kdump: Consolidate crash_map/unmap_reserved_pages() - update
>
>  - Move functions back to keep the patch small
>  - Consolidate crash_map_reserved_pages/arch_kexec_unprotect_crashkres()
>  - Re-introduce memblock_remove()
>  - Call arch_kexec_unprotect_crashkres() in machine_kdump_pm_init()
>
> Signed-off-by: Michael Holzheu 
> ---
>  arch/s390/kernel/machine_kexec.c |   88 
> +--
>  1 file changed, 40 insertions(+), 48 deletions(-)
>
> --- a/arch/s390/kernel/machine_kexec.c
> +++ b/arch/s390/kernel/machine_kexec.c
> @@ -35,52 +35,6 @@ extern const unsigned long long relocate
>  #ifdef CONFIG_CRASH_DUMP
>  
>  /*
> - * Map or unmap crashkernel memory
> - */
> -static void crash_map_pages(int enable)
> -{
> - unsigned long size = resource_size(_res);
> -
> - BUG_ON(crashk_res.start % KEXEC_CRASH_MEM_ALIGN ||
> -size % KEXEC_CRASH_MEM_ALIGN);
> - if (enable)
> - vmem_add_mapping(crashk_res.start, size);
> - else {
> - vmem_remove_mapping(crashk_res.start, size);
> - if (size)
> - os_info_crashkernel_add(crashk_res.start, size);
> - else
> - os_info_crashkernel_add(0, 0);
> - }
> -}
> -
> -/*
> - * Map crashkernel memory
> - */
> -static void crash_map_reserved_pages(void)
> -{
> - crash_map_pages(1);
> -}
> -
> -/*
> - * Unmap crashkernel memory
> - */
> -static void crash_unmap_reserved_pages(void)
> -{
> - crash_map_pages(0);
> -}
> -
> -void arch_kexec_protect_crashkres(void)
> -{
> - crash_unmap_reserved_pages();
> -}
> -
> -void arch_kexec_unprotect_crashkres(void)
> -{
> - crash_map_reserved_pages();
> -}
> -
> -/*
>   * PM notifier callback for kdump
>   */
>  static int 

[PATCH net-next 8/8] samples/bpf: add tracepoint vs kprobe performance tests

2016-04-04 Thread Alexei Starovoitov
the first microbenchmark does
fd=open("/proc/self/comm");
for() {
  write(fd, "test");
}
and on 4 cpus in parallel:
  writes per sec
base (no tracepoints, no kprobes) 930k
with kprobe at __set_task_comm()  420k
with tracepoint at task:task_rename   730k

For kprobe + full bpf program manully fetches oldcomm, newcomm via 
bpf_probe_read.
For tracepint bpf program does nothing, since arguments are copied by 
tracepoint.

2nd microbenchmark does:
fd=open("/dev/urandom");
for() {
  read(fd, buf);
}
and on 4 cpus in parallel:
   reads per sec
base (no tracepoints, no kprobes) 300k
with kprobe at urandom_read() 279k
with tracepoint at random:urandom_read290k

bpf progs attached to kprobe and tracepoint are noop.

Signed-off-by: Alexei Starovoitov 
---
 samples/bpf/Makefile|   5 +
 samples/bpf/test_overhead_kprobe_kern.c |  41 
 samples/bpf/test_overhead_tp_kern.c |  36 +++
 samples/bpf/test_overhead_user.c| 161 
 4 files changed, 243 insertions(+)
 create mode 100644 samples/bpf/test_overhead_kprobe_kern.c
 create mode 100644 samples/bpf/test_overhead_tp_kern.c
 create mode 100644 samples/bpf/test_overhead_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 502c9fc8db85..9959771bf808 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -19,6 +19,7 @@ hostprogs-y += lathist
 hostprogs-y += offwaketime
 hostprogs-y += spintest
 hostprogs-y += map_perf_test
+hostprogs-y += test_overhead
 
 test_verifier-objs := test_verifier.o libbpf.o
 test_maps-objs := test_maps.o libbpf.o
@@ -38,6 +39,7 @@ lathist-objs := bpf_load.o libbpf.o lathist_user.o
 offwaketime-objs := bpf_load.o libbpf.o offwaketime_user.o
 spintest-objs := bpf_load.o libbpf.o spintest_user.o
 map_perf_test-objs := bpf_load.o libbpf.o map_perf_test_user.o
+test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -56,6 +58,8 @@ always += lathist_kern.o
 always += offwaketime_kern.o
 always += spintest_kern.o
 always += map_perf_test_kern.o
+always += test_overhead_tp_kern.o
+always += test_overhead_kprobe_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
@@ -75,6 +79,7 @@ HOSTLOADLIBES_lathist += -lelf
 HOSTLOADLIBES_offwaketime += -lelf
 HOSTLOADLIBES_spintest += -lelf
 HOSTLOADLIBES_map_perf_test += -lelf -lrt
+HOSTLOADLIBES_test_overhead += -lelf -lrt
 
 # point this to your LLVM backend with bpf support
 LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc
diff --git a/samples/bpf/test_overhead_kprobe_kern.c 
b/samples/bpf/test_overhead_kprobe_kern.c
new file mode 100644
index ..468a66a92ef9
--- /dev/null
+++ b/samples/bpf/test_overhead_kprobe_kern.c
@@ -0,0 +1,41 @@
+/* Copyright (c) 2016 Facebook
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include 
+#include 
+#include 
+#include "bpf_helpers.h"
+
+#define _(P) ({typeof(P) val = 0; bpf_probe_read(, sizeof(val), ); val;})
+
+SEC("kprobe/__set_task_comm")
+int prog(struct pt_regs *ctx)
+{
+   struct signal_struct *signal;
+   struct task_struct *tsk;
+   char oldcomm[16] = {};
+   char newcomm[16] = {};
+   u16 oom_score_adj;
+   u32 pid;
+
+   tsk = (void *)PT_REGS_PARM1(ctx);
+
+   pid = _(tsk->pid);
+   bpf_probe_read(oldcomm, sizeof(oldcomm), >comm);
+   bpf_probe_read(newcomm, sizeof(newcomm), (void *)PT_REGS_PARM2(ctx));
+   signal = _(tsk->signal);
+   oom_score_adj = _(signal->oom_score_adj);
+   return 0;
+}
+
+SEC("kprobe/urandom_read")
+int prog2(struct pt_regs *ctx)
+{
+   return 0;
+}
+
+char _license[] SEC("license") = "GPL";
+u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/test_overhead_tp_kern.c 
b/samples/bpf/test_overhead_tp_kern.c
new file mode 100644
index ..38f5c0b9da9f
--- /dev/null
+++ b/samples/bpf/test_overhead_tp_kern.c
@@ -0,0 +1,36 @@
+/* Copyright (c) 2016 Facebook
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include 
+#include "bpf_helpers.h"
+
+/* from /sys/kernel/debug/tracing/events/task/task_rename/format */
+struct task_rename {
+   __u64 pad;
+   __u32 pid;
+   char oldcomm[16];
+   char newcomm[16];
+   __u16 oom_score_adj;
+};
+SEC("tracepoint/task/task_rename")
+int prog(struct task_rename *ctx)
+{
+   return 0;
+}
+
+/* from /sys/kernel/debug/tracing/events/random/urandom_read/format */
+struct urandom_read {
+   __u64 pad;
+   int got_bits;
+   int pool_left;
+   int input_left;
+};

[PATCH net-next 2/8] perf, bpf: allow bpf programs attach to tracepoints

2016-04-04 Thread Alexei Starovoitov
introduce BPF_PROG_TYPE_TRACEPOINT program type and allow it to be
attached to tracepoints.
The tracepoint will copy the arguments in the per-cpu buffer and pass
it to the bpf program as its first argument.
The layout of the fields can be discovered by doing
'cat /sys/kernel/debug/tracing/events/sched/sched_switch/format'
prior to the compilation of the program with exception that first 8 bytes
are reserved and not accessible to the program. This area is used to store
the pointer to 'struct pt_regs' which some of the bpf helpers will use:
+-+
| 8 bytes | hidden 'struct pt_regs *' (inaccessible to bpf program)
+-+
| N bytes | static tracepoint fields defined in tracepoint/format (bpf readonly)
+-+
| dynamic | __dynamic_array bytes of tracepoint (inaccessible to bpf yet)
+-+

Not that all of the fields are already dumped to user space via perf ring buffer
and some application access it directly without consulting tracepoint/format.
Same rule applies here: static tracepoint fields should only be accessed
in a format defined in tracepoint/format. The order of fields and
field sizes are not an ABI.

Signed-off-by: Alexei Starovoitov 
---
 include/trace/perf.h| 18 ++
 include/uapi/linux/bpf.h|  1 +
 kernel/events/core.c| 13 +
 kernel/trace/trace_event_perf.c |  3 +++
 4 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/include/trace/perf.h b/include/trace/perf.h
index 26486fcd74ce..55feb69c873f 100644
--- a/include/trace/perf.h
+++ b/include/trace/perf.h
@@ -37,18 +37,19 @@ perf_trace_##call(void *__data, proto)  
\
struct trace_event_call *event_call = __data;   \
struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
struct trace_event_raw_##call *entry;   \
+   struct bpf_prog *prog = event_call->prog;   \
struct pt_regs *__regs; \
u64 __addr = 0, __count = 1;\
struct task_struct *__task = NULL;  \
struct hlist_head *head;\
int __entry_size;   \
int __data_size;\
-   int rctx;   \
+   int rctx, event_type;   \
\
__data_size = trace_event_get_offsets_##call(&__data_offsets, args); \
\
head = this_cpu_ptr(event_call->perf_events);   \
-   if (__builtin_constant_p(!__task) && !__task && \
+   if (!prog && __builtin_constant_p(!__task) && !__task &&\
hlist_empty(head))  \
return; \
\
@@ -56,8 +57,9 @@ perf_trace_##call(void *__data, proto)
\
 sizeof(u64));  \
__entry_size -= sizeof(u32);\
\
-   entry = perf_trace_buf_prepare(__entry_size,\
-   event_call->event.type, &__regs, );\
+   event_type = prog ? TRACE_EVENT_TYPE_MAX : event_call->event.type; \
+   entry = perf_trace_buf_prepare(__entry_size, event_type,\
+  &__regs, ); \
if (!entry) \
return; \
\
@@ -67,6 +69,14 @@ perf_trace_##call(void *__data, proto)   
\
\
{ assign; } \
\
+   if (prog) { \
+   *(struct pt_regs **)entry = __regs; \
+   if (!trace_call_bpf(prog, entry) || hlist_empty(head)) { \
+   perf_swevent_put_recursion_context(rctx);   \
+   return; \
+   }   \
+   memset(>ent, 0, sizeof(entry->ent)); \
+  

[PATCH net-next 8/8] samples/bpf: add tracepoint vs kprobe performance tests

2016-04-04 Thread Alexei Starovoitov
the first microbenchmark does
fd=open("/proc/self/comm");
for() {
  write(fd, "test");
}
and on 4 cpus in parallel:
  writes per sec
base (no tracepoints, no kprobes) 930k
with kprobe at __set_task_comm()  420k
with tracepoint at task:task_rename   730k

For kprobe + full bpf program manully fetches oldcomm, newcomm via 
bpf_probe_read.
For tracepint bpf program does nothing, since arguments are copied by 
tracepoint.

2nd microbenchmark does:
fd=open("/dev/urandom");
for() {
  read(fd, buf);
}
and on 4 cpus in parallel:
   reads per sec
base (no tracepoints, no kprobes) 300k
with kprobe at urandom_read() 279k
with tracepoint at random:urandom_read290k

bpf progs attached to kprobe and tracepoint are noop.

Signed-off-by: Alexei Starovoitov 
---
 samples/bpf/Makefile|   5 +
 samples/bpf/test_overhead_kprobe_kern.c |  41 
 samples/bpf/test_overhead_tp_kern.c |  36 +++
 samples/bpf/test_overhead_user.c| 161 
 4 files changed, 243 insertions(+)
 create mode 100644 samples/bpf/test_overhead_kprobe_kern.c
 create mode 100644 samples/bpf/test_overhead_tp_kern.c
 create mode 100644 samples/bpf/test_overhead_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 502c9fc8db85..9959771bf808 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -19,6 +19,7 @@ hostprogs-y += lathist
 hostprogs-y += offwaketime
 hostprogs-y += spintest
 hostprogs-y += map_perf_test
+hostprogs-y += test_overhead
 
 test_verifier-objs := test_verifier.o libbpf.o
 test_maps-objs := test_maps.o libbpf.o
@@ -38,6 +39,7 @@ lathist-objs := bpf_load.o libbpf.o lathist_user.o
 offwaketime-objs := bpf_load.o libbpf.o offwaketime_user.o
 spintest-objs := bpf_load.o libbpf.o spintest_user.o
 map_perf_test-objs := bpf_load.o libbpf.o map_perf_test_user.o
+test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -56,6 +58,8 @@ always += lathist_kern.o
 always += offwaketime_kern.o
 always += spintest_kern.o
 always += map_perf_test_kern.o
+always += test_overhead_tp_kern.o
+always += test_overhead_kprobe_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
@@ -75,6 +79,7 @@ HOSTLOADLIBES_lathist += -lelf
 HOSTLOADLIBES_offwaketime += -lelf
 HOSTLOADLIBES_spintest += -lelf
 HOSTLOADLIBES_map_perf_test += -lelf -lrt
+HOSTLOADLIBES_test_overhead += -lelf -lrt
 
 # point this to your LLVM backend with bpf support
 LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc
diff --git a/samples/bpf/test_overhead_kprobe_kern.c 
b/samples/bpf/test_overhead_kprobe_kern.c
new file mode 100644
index ..468a66a92ef9
--- /dev/null
+++ b/samples/bpf/test_overhead_kprobe_kern.c
@@ -0,0 +1,41 @@
+/* Copyright (c) 2016 Facebook
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include 
+#include 
+#include 
+#include "bpf_helpers.h"
+
+#define _(P) ({typeof(P) val = 0; bpf_probe_read(, sizeof(val), ); val;})
+
+SEC("kprobe/__set_task_comm")
+int prog(struct pt_regs *ctx)
+{
+   struct signal_struct *signal;
+   struct task_struct *tsk;
+   char oldcomm[16] = {};
+   char newcomm[16] = {};
+   u16 oom_score_adj;
+   u32 pid;
+
+   tsk = (void *)PT_REGS_PARM1(ctx);
+
+   pid = _(tsk->pid);
+   bpf_probe_read(oldcomm, sizeof(oldcomm), >comm);
+   bpf_probe_read(newcomm, sizeof(newcomm), (void *)PT_REGS_PARM2(ctx));
+   signal = _(tsk->signal);
+   oom_score_adj = _(signal->oom_score_adj);
+   return 0;
+}
+
+SEC("kprobe/urandom_read")
+int prog2(struct pt_regs *ctx)
+{
+   return 0;
+}
+
+char _license[] SEC("license") = "GPL";
+u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/test_overhead_tp_kern.c 
b/samples/bpf/test_overhead_tp_kern.c
new file mode 100644
index ..38f5c0b9da9f
--- /dev/null
+++ b/samples/bpf/test_overhead_tp_kern.c
@@ -0,0 +1,36 @@
+/* Copyright (c) 2016 Facebook
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include 
+#include "bpf_helpers.h"
+
+/* from /sys/kernel/debug/tracing/events/task/task_rename/format */
+struct task_rename {
+   __u64 pad;
+   __u32 pid;
+   char oldcomm[16];
+   char newcomm[16];
+   __u16 oom_score_adj;
+};
+SEC("tracepoint/task/task_rename")
+int prog(struct task_rename *ctx)
+{
+   return 0;
+}
+
+/* from /sys/kernel/debug/tracing/events/random/urandom_read/format */
+struct urandom_read {
+   __u64 pad;
+   int got_bits;
+   int pool_left;
+   int input_left;
+};

[PATCH net-next 2/8] perf, bpf: allow bpf programs attach to tracepoints

2016-04-04 Thread Alexei Starovoitov
introduce BPF_PROG_TYPE_TRACEPOINT program type and allow it to be
attached to tracepoints.
The tracepoint will copy the arguments in the per-cpu buffer and pass
it to the bpf program as its first argument.
The layout of the fields can be discovered by doing
'cat /sys/kernel/debug/tracing/events/sched/sched_switch/format'
prior to the compilation of the program with exception that first 8 bytes
are reserved and not accessible to the program. This area is used to store
the pointer to 'struct pt_regs' which some of the bpf helpers will use:
+-+
| 8 bytes | hidden 'struct pt_regs *' (inaccessible to bpf program)
+-+
| N bytes | static tracepoint fields defined in tracepoint/format (bpf readonly)
+-+
| dynamic | __dynamic_array bytes of tracepoint (inaccessible to bpf yet)
+-+

Not that all of the fields are already dumped to user space via perf ring buffer
and some application access it directly without consulting tracepoint/format.
Same rule applies here: static tracepoint fields should only be accessed
in a format defined in tracepoint/format. The order of fields and
field sizes are not an ABI.

Signed-off-by: Alexei Starovoitov 
---
 include/trace/perf.h| 18 ++
 include/uapi/linux/bpf.h|  1 +
 kernel/events/core.c| 13 +
 kernel/trace/trace_event_perf.c |  3 +++
 4 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/include/trace/perf.h b/include/trace/perf.h
index 26486fcd74ce..55feb69c873f 100644
--- a/include/trace/perf.h
+++ b/include/trace/perf.h
@@ -37,18 +37,19 @@ perf_trace_##call(void *__data, proto)  
\
struct trace_event_call *event_call = __data;   \
struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
struct trace_event_raw_##call *entry;   \
+   struct bpf_prog *prog = event_call->prog;   \
struct pt_regs *__regs; \
u64 __addr = 0, __count = 1;\
struct task_struct *__task = NULL;  \
struct hlist_head *head;\
int __entry_size;   \
int __data_size;\
-   int rctx;   \
+   int rctx, event_type;   \
\
__data_size = trace_event_get_offsets_##call(&__data_offsets, args); \
\
head = this_cpu_ptr(event_call->perf_events);   \
-   if (__builtin_constant_p(!__task) && !__task && \
+   if (!prog && __builtin_constant_p(!__task) && !__task &&\
hlist_empty(head))  \
return; \
\
@@ -56,8 +57,9 @@ perf_trace_##call(void *__data, proto)
\
 sizeof(u64));  \
__entry_size -= sizeof(u32);\
\
-   entry = perf_trace_buf_prepare(__entry_size,\
-   event_call->event.type, &__regs, );\
+   event_type = prog ? TRACE_EVENT_TYPE_MAX : event_call->event.type; \
+   entry = perf_trace_buf_prepare(__entry_size, event_type,\
+  &__regs, ); \
if (!entry) \
return; \
\
@@ -67,6 +69,14 @@ perf_trace_##call(void *__data, proto)   
\
\
{ assign; } \
\
+   if (prog) { \
+   *(struct pt_regs **)entry = __regs; \
+   if (!trace_call_bpf(prog, entry) || hlist_empty(head)) { \
+   perf_swevent_put_recursion_context(rctx);   \
+   return; \
+   }   \
+   memset(>ent, 0, sizeof(entry->ent)); \
+   }   

Re: [PATCH 1/2] phy: Group vendor specific phy drivers

2016-04-04 Thread Vivek Gautam
Hi Krzysztof,


On Sat, Apr 2, 2016 at 11:05 PM, Krzysztof Kozlowski
 wrote:
> On Fri, Apr 01, 2016 at 04:59:15PM +0530, Vivek Gautam wrote:
>> Adding vendor specific directories in phy to group
>> phy drivers under their respective vendor umbrella.
>>
>> Signed-off-by: Vivek Gautam 
>> ---
>>
>> With growing number of phy drivers, it makes sense to
>> group these drivers under their respective vendor/platform
>> umbrella directory.
>>
>> Build-tested 'multi_v7_defconfig'.
>
> Please update also the MAINTAINERS file. For many entires the path won't
> match anymore.

Thanks for pointing out. I will update the MAINTAINERS file as well.

>
> Best regards,
> Krzysztof
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 
> in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Best Regards
Vivek Gautam
Samsung, India


Re: [PATCH 1/2] phy: Group vendor specific phy drivers

2016-04-04 Thread Vivek Gautam
Hi Krzysztof,


On Sat, Apr 2, 2016 at 11:05 PM, Krzysztof Kozlowski
 wrote:
> On Fri, Apr 01, 2016 at 04:59:15PM +0530, Vivek Gautam wrote:
>> Adding vendor specific directories in phy to group
>> phy drivers under their respective vendor umbrella.
>>
>> Signed-off-by: Vivek Gautam 
>> ---
>>
>> With growing number of phy drivers, it makes sense to
>> group these drivers under their respective vendor/platform
>> umbrella directory.
>>
>> Build-tested 'multi_v7_defconfig'.
>
> Please update also the MAINTAINERS file. For many entires the path won't
> match anymore.

Thanks for pointing out. I will update the MAINTAINERS file as well.

>
> Best regards,
> Krzysztof
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 
> in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Best Regards
Vivek Gautam
Samsung, India


linux-next: Tree for Apr 5

2016-04-04 Thread Stephen Rothwell
Hi all,

Changes since 20160404:

The btrfs-kdave tree gained conflicts Linus' tree.

The ceph tree gained conflicts Linus' tree.

The staging tree gained conflicts against the staging.current and Linus'
trees.

Non-merge commits (relative to Linus' tree): 2132
 2023 files changed, 82827 insertions(+), 53245 deletions(-)



I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
(patches at http://www.kernel.org/pub/linux/kernel/next/ ).  If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one.  You should use "git fetch" and checkout or reset to the new
master.

You can see which trees have been included by looking in the Next/Trees
file in the source.  There are also quilt-import.log and merge.log
files in the Next directory.  Between each merge, the tree was built
with a ppc64_defconfig for powerpc and an allmodconfig (with
CONFIG_BUILD_DOCSRC=n) for x86_64, a multi_v7_defconfig for arm and a
native build of tools/perf. After the final fixups (if any), I do an
x86_64 modules_install followed by builds for x86_64 allnoconfig,
powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig
(this fails its final link) and pseries_le_defconfig and i386, sparc
and sparc64 defconfig.

Below is a summary of the state of the merge.

I am currently merging 232 trees (counting Linus' and 35 trees of patches
pending for Linus' tree).

Stats about the size of the tree over time can be seen at
http://neuling.org/linux-next-size.html .

Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next .  If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.

Thanks to Randy Dunlap for doing many randconfig builds.  And to Paul
Gortmaker for triage and bug fixes.

-- 
Cheers,
Stephen Rothwell

$ git checkout master
$ git reset --hard stable
Merging origin/master (e865f4965ff6 Merge branch 'for_linus' of 
git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs)
Merging fixes/master (9735a22799b9 Linux 4.6-rc2)
Merging kbuild-current/rc-fixes (3d1450d54a4f Makefile: Force gzip and xz on 
module install)
Merging arc-current/for-curr (f86b8892a1b7 ARC: Don't source 
drivers/pci/pcie/Kconfig ourselves)
Merging arm-current/fixes (0fc03d4c8761 ARM: SMP enable of cache maintanence 
broadcast)
Merging m68k-current/for-linus (efbec135f11d m68k: Fix misspellings in 
comments.)
Merging metag-fixes/fixes (0164a711c97b metag: Fix ioremap_wc/ioremap_cached 
build errors)
Merging powerpc-fixes/fixes (71528d8bd7a8 powerpc: Correct used_vsr comment)
Merging powerpc-merge-mpe/fixes (bc0195aad0da Linux 4.2-rc2)
Merging sparc/master (5ec712934ce1 sparc: Write up preadv2/pwritev2 syscalls.)
Merging net/master (c862cc9b7052 bridge: Fix incorrect variable assignment on 
error path in br_sysfs_addbr)
Merging ipsec/master (d6af1a31cc72 vti: Add pmtu handling to vti_xmit.)
Merging ipvs/master (7617a24f83b5 ipvs: correct initial offset of Call-ID 
header search in SIP persistence engine)
Merging wireless-drivers/master (15da5d11040c Merge tag 
'iwlwifi-for-kalle-2016-03-30' of 
https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes)
Merging mac80211/master (ad8ec957f693 wext: unregister_pernet_subsys() on 
notifier registration failure)
Merging sound-current/for-linus (f03b24a851d3 ALSA: usb-audio: Add a sample 
rate quirk for Phoenix Audio TMX320)
Merging pci-current/for-linus (f55532a0c0b8 Linux 4.6-rc1)
Merging driver-core.current/driver-core-linus (f55532a0c0b8 Linux 4.6-rc1)
Merging tty.current/tty-linus (5e00bbfbc5ec tty: Fix merge of "tty: Refactor 
tty_open()")
Merging usb.current/usb-linus (5a07975ad0a3 USB: digi_acceleport: do sanity 
checking for the number of ports)
Merging usb-gadget-fixes/fixes (7e8ac87a4474 usb: phy: qcom-8x16: fix regulator 
API abuse)
Merging usb-serial-fixes/usb-linus (f55532a0c0b8 Linux 4.6-rc1)
Merging usb-chipidea-fixes/ci-for-usb-stable (d144dfea8af7 usb: chipidea: otg: 
change workqueue ci_otg as freezable)
Merging staging.current/staging-linus (53c43c5ca133 Revert "Staging: olpc_dcon: 
Remove obsolete driver")
Merging char-misc.current/char-misc-linus (f55532a0c0b8 Linux 4.6-rc1)
Merging input-current/for-linus (162f98dea487 Input: gtco - fix crash on 
detecting device without endpoints)
Merging crypto-current/master (ef609c238a8e sunrpc: Fix skcipher/shash 
conversion)
Merging ide/master (1993b176a822 Merge 
git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide)
Merging devicetree-current/devicetree/merge (f76502aa9140 of/dynamic: Fix test 
for PPC_PSERIES)
Merging rr-fixes/fixes (8244062ef1e5 modules: fix longstanding /proc/kallsyms 
vs module insertion race.)
Merging vfio-fixes/for-linus (8160c4e45582 vfio: fix ioctl error

linux-next: Tree for Apr 5

2016-04-04 Thread Stephen Rothwell
Hi all,

Changes since 20160404:

The btrfs-kdave tree gained conflicts Linus' tree.

The ceph tree gained conflicts Linus' tree.

The staging tree gained conflicts against the staging.current and Linus'
trees.

Non-merge commits (relative to Linus' tree): 2132
 2023 files changed, 82827 insertions(+), 53245 deletions(-)



I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
(patches at http://www.kernel.org/pub/linux/kernel/next/ ).  If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one.  You should use "git fetch" and checkout or reset to the new
master.

You can see which trees have been included by looking in the Next/Trees
file in the source.  There are also quilt-import.log and merge.log
files in the Next directory.  Between each merge, the tree was built
with a ppc64_defconfig for powerpc and an allmodconfig (with
CONFIG_BUILD_DOCSRC=n) for x86_64, a multi_v7_defconfig for arm and a
native build of tools/perf. After the final fixups (if any), I do an
x86_64 modules_install followed by builds for x86_64 allnoconfig,
powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig
(this fails its final link) and pseries_le_defconfig and i386, sparc
and sparc64 defconfig.

Below is a summary of the state of the merge.

I am currently merging 232 trees (counting Linus' and 35 trees of patches
pending for Linus' tree).

Stats about the size of the tree over time can be seen at
http://neuling.org/linux-next-size.html .

Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next .  If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.

Thanks to Randy Dunlap for doing many randconfig builds.  And to Paul
Gortmaker for triage and bug fixes.

-- 
Cheers,
Stephen Rothwell

$ git checkout master
$ git reset --hard stable
Merging origin/master (e865f4965ff6 Merge branch 'for_linus' of 
git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs)
Merging fixes/master (9735a22799b9 Linux 4.6-rc2)
Merging kbuild-current/rc-fixes (3d1450d54a4f Makefile: Force gzip and xz on 
module install)
Merging arc-current/for-curr (f86b8892a1b7 ARC: Don't source 
drivers/pci/pcie/Kconfig ourselves)
Merging arm-current/fixes (0fc03d4c8761 ARM: SMP enable of cache maintanence 
broadcast)
Merging m68k-current/for-linus (efbec135f11d m68k: Fix misspellings in 
comments.)
Merging metag-fixes/fixes (0164a711c97b metag: Fix ioremap_wc/ioremap_cached 
build errors)
Merging powerpc-fixes/fixes (71528d8bd7a8 powerpc: Correct used_vsr comment)
Merging powerpc-merge-mpe/fixes (bc0195aad0da Linux 4.2-rc2)
Merging sparc/master (5ec712934ce1 sparc: Write up preadv2/pwritev2 syscalls.)
Merging net/master (c862cc9b7052 bridge: Fix incorrect variable assignment on 
error path in br_sysfs_addbr)
Merging ipsec/master (d6af1a31cc72 vti: Add pmtu handling to vti_xmit.)
Merging ipvs/master (7617a24f83b5 ipvs: correct initial offset of Call-ID 
header search in SIP persistence engine)
Merging wireless-drivers/master (15da5d11040c Merge tag 
'iwlwifi-for-kalle-2016-03-30' of 
https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes)
Merging mac80211/master (ad8ec957f693 wext: unregister_pernet_subsys() on 
notifier registration failure)
Merging sound-current/for-linus (f03b24a851d3 ALSA: usb-audio: Add a sample 
rate quirk for Phoenix Audio TMX320)
Merging pci-current/for-linus (f55532a0c0b8 Linux 4.6-rc1)
Merging driver-core.current/driver-core-linus (f55532a0c0b8 Linux 4.6-rc1)
Merging tty.current/tty-linus (5e00bbfbc5ec tty: Fix merge of "tty: Refactor 
tty_open()")
Merging usb.current/usb-linus (5a07975ad0a3 USB: digi_acceleport: do sanity 
checking for the number of ports)
Merging usb-gadget-fixes/fixes (7e8ac87a4474 usb: phy: qcom-8x16: fix regulator 
API abuse)
Merging usb-serial-fixes/usb-linus (f55532a0c0b8 Linux 4.6-rc1)
Merging usb-chipidea-fixes/ci-for-usb-stable (d144dfea8af7 usb: chipidea: otg: 
change workqueue ci_otg as freezable)
Merging staging.current/staging-linus (53c43c5ca133 Revert "Staging: olpc_dcon: 
Remove obsolete driver")
Merging char-misc.current/char-misc-linus (f55532a0c0b8 Linux 4.6-rc1)
Merging input-current/for-linus (162f98dea487 Input: gtco - fix crash on 
detecting device without endpoints)
Merging crypto-current/master (ef609c238a8e sunrpc: Fix skcipher/shash 
conversion)
Merging ide/master (1993b176a822 Merge 
git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide)
Merging devicetree-current/devicetree/merge (f76502aa9140 of/dynamic: Fix test 
for PPC_PSERIES)
Merging rr-fixes/fixes (8244062ef1e5 modules: fix longstanding /proc/kallsyms 
vs module insertion race.)
Merging vfio-fixes/for-linus (8160c4e45582 vfio: fix ioctl error

Re: linux-next: manual merge of the staging tree with the staging.current tree

2016-04-04 Thread Greg KH
On Tue, Apr 05, 2016 at 01:03:26PM +1000, Stephen Rothwell wrote:
> Hi Greg,
> 
> Today's linux-next merge of the staging tree got a conflict in:
> 
>   drivers/iio/gyro/bmg160_core.c
> 
> between commit:
> 
>   b475c59b113d ("iio: gyro: bmg160: fix buffer read values")
> 
> from the staging.current tree and commit:
> 
>   7e3d1eb123d8 ("iio: accel: bmg160: optimize transfers in trigger handler")
> 
> from the staging tree.
> 
> I fixed it up (I used the version from the staging tree) and can carry the
> fix as necessary. This is now fixed as far as linux-next is concerned,
> but any non trivial conflicts should be mentioned to your upstream
> maintainer when your tree is submitted for merging.  You may also want
> to consider cooperating with the maintainer of the conflicting tree to
> minimise any particularly complex conflicts.

Jonathan warned me about this, thanks for resolving it in your tree.
I'll fix it up in mine once they merge back together in a few weeks.

thanks,

greg k-h


Re: linux-next: manual merge of the staging tree with the staging.current tree

2016-04-04 Thread Greg KH
On Tue, Apr 05, 2016 at 01:03:26PM +1000, Stephen Rothwell wrote:
> Hi Greg,
> 
> Today's linux-next merge of the staging tree got a conflict in:
> 
>   drivers/iio/gyro/bmg160_core.c
> 
> between commit:
> 
>   b475c59b113d ("iio: gyro: bmg160: fix buffer read values")
> 
> from the staging.current tree and commit:
> 
>   7e3d1eb123d8 ("iio: accel: bmg160: optimize transfers in trigger handler")
> 
> from the staging tree.
> 
> I fixed it up (I used the version from the staging tree) and can carry the
> fix as necessary. This is now fixed as far as linux-next is concerned,
> but any non trivial conflicts should be mentioned to your upstream
> maintainer when your tree is submitted for merging.  You may also want
> to consider cooperating with the maintainer of the conflicting tree to
> minimise any particularly complex conflicts.

Jonathan warned me about this, thanks for resolving it in your tree.
I'll fix it up in mine once they merge back together in a few weeks.

thanks,

greg k-h


  1   2   3   4   5   6   7   8   9   10   >