* [PATCH 1/6] mfd: max8997: Initialize max8997 register map
From: Pankaj Dubey @ 2016-11-07 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478513376-14307-1-git-send-email-pankaj.dubey@samsung.com>
This patch add regmap initialization to use register map
in max8997-clk device driver
CC: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
drivers/mfd/max8997.c | 14 ++++++++++++++
include/linux/mfd/max8997-private.h | 3 +++
2 files changed, 17 insertions(+)
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index 2d6e2c3..bda9ec8 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -175,11 +175,17 @@ static inline unsigned long max8997_i2c_get_driver_data(struct i2c_client *i2c,
return id->driver_data;
}
+static const struct regmap_config max8997_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
static int max8997_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max8997_dev *max8997;
struct max8997_platform_data *pdata = dev_get_platdata(&i2c->dev);
+ const struct regmap_config *config = &max8997_regmap_config;
int ret = 0;
max8997 = devm_kzalloc(&i2c->dev, sizeof(struct max8997_dev),
@@ -202,6 +208,14 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
if (!pdata)
return ret;
+ max8997->regmap = devm_regmap_init_i2c(i2c, config);
+ if (IS_ERR(max8997->regmap)) {
+ ret = PTR_ERR(max8997->regmap);
+ dev_err(max8997->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
max8997->pdata = pdata;
max8997->ono = pdata->ono;
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
index 78c76cd..50c7129 100644
--- a/include/linux/mfd/max8997-private.h
+++ b/include/linux/mfd/max8997-private.h
@@ -25,6 +25,7 @@
#include <linux/i2c.h>
#include <linux/export.h>
#include <linux/irqdomain.h>
+#include <linux/regmap.h>
#define MAX8997_REG_INVALID (0xff)
@@ -388,6 +389,8 @@ struct max8997_dev {
struct mutex iolock;
unsigned long type;
+
+ struct regmap *regmap;
struct platform_device *battery; /* battery control (not fuel gauge) */
int irq;
--
2.7.4
^ permalink raw reply related
* [PATCH 2/6] dt-bindings: clk: max8997: Add DT binding documentation
From: Pankaj Dubey @ 2016-11-07 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478513376-14307-1-git-send-email-pankaj.dubey@samsung.com>
Add Device Tree binding documentation for the clocks
outputs in the Maxim-8997 Power Management IC.
CC: Michael Turquette <mturquette@baylibre.com>
CC: Rob Herring <robh+dt@kernel.org>
CC: devicetree at vger.kernel.org
CC: linux-clk at vger.kernel.org
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
.../devicetree/bindings/clock/maxim,max8997.txt | 44 ++++++++++++++++++++++
.../bindings/regulator/max8997-regulator.txt | 3 ++
2 files changed, 47 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/maxim,max8997.txt
diff --git a/Documentation/devicetree/bindings/clock/maxim,max8997.txt b/Documentation/devicetree/bindings/clock/maxim,max8997.txt
new file mode 100644
index 0000000..d2e2a74
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/maxim,max8997.txt
@@ -0,0 +1,44 @@
+Binding for Maxim MAX8997 32k clock generator block
+
+This is a part of device tree bindings of MAX8997 multi-function device.
+More information can be found in bindings/regulator/max8997-regulator.txt file.
+
+The MAX8997 contains two 32.768khz clock outputs that can be controlled
+(gated/ungated) over I2C.
+
+Following properties should be presend in main device node of the MFD chip.
+
+Required properties:
+
+- #clock-cells: from common clock binding; shall be set to 1.
+
+Optional properties:
+- clock-output-names: From common clock binding.
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume. Following indices are allowed:
+ - 0: 32khz_ap clock,
+ - 1: 32khz_cp clock,
+
+Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max8997.h
+header and can be used in device tree sources.
+
+Example: Node of the MFD chip
+
+ max8997: max8997_pmic at 66 {
+ compatible = "maxim,max8997-pmic";
+ reg = <0x66>;
+ interrupt-parent = <&gpx0>;
+ interrupts = <4 0>, <3 0>;
+ #clock-cells = <1>;
+ /* ... */
+ };
+
+Example: Clock consumer node
+
+ foo at 0 {
+ compatible = "bar,foo";
+ /* ... */
+ clocks = <&max8997 MAX8997_CLK_AP>;
+ clock-names = "my-clock";
+ };
diff --git a/Documentation/devicetree/bindings/regulator/max8997-regulator.txt b/Documentation/devicetree/bindings/regulator/max8997-regulator.txt
index 5c186a7..af1f9c0 100644
--- a/Documentation/devicetree/bindings/regulator/max8997-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/max8997-regulator.txt
@@ -6,6 +6,9 @@ interfaced to the host controller using a i2c interface. Each sub-block is
addressed by the host system using different i2c slave address. This document
describes the bindings for 'pmic' sub-block of max8997.
+Binding for the built-in 32k clock generator block is defined separately
+in bindings/clk/maxim,max8997.txt file
+
Required properties:
- compatible: Should be "maxim,max8997-pmic".
- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
--
2.7.4
^ permalink raw reply related
* [PATCH 3/6] clk: Add driver for Maxim-8997 PMIC clocks
From: Pankaj Dubey @ 2016-11-07 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478513376-14307-1-git-send-email-pankaj.dubey@samsung.com>
The MAX8997 PMIC has 32.786kHz crystal oscillator which provides an
accurate low frequency clock for MAX8997 internal circuit as well as
external circuit. This patch adds support for these two clocks.
CC: Michael Turquette <mturquette@baylibre.com>
CC: Rob Herring <robh+dt@kernel.org>
CC: devicetree at vger.kernel.org
CC: linux-clk at vger.kernel.org
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
drivers/clk/Kconfig | 10 ++++
drivers/clk/Makefile | 1 +
drivers/clk/clk-max8997.c | 76 +++++++++++++++++++++++++++++++
include/dt-bindings/clock/maxim,max8997.h | 23 ++++++++++
4 files changed, 110 insertions(+)
create mode 100644 drivers/clk/clk-max8997.c
create mode 100644 include/dt-bindings/clock/maxim,max8997.h
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index e2d9bd7..5339cbe 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -48,6 +48,16 @@ config COMMON_CLK_MAX77802
---help---
This driver supports Maxim 77802 crystal oscillator clock.
+config COMMON_CLK_MAX8997
+ tristate "Clock driver for Maxim 8997 MFD"
+ depends on MFD_MAX8997
+ select COMMON_CLK_MAX_GEN
+ ---help---
+ This driver supports Maxim 8997 crystal oscillator clock.
+ The 32.768kHz crystal oscillator clock provides an accurate
+ low frequency clock for MAX8997 internal circuit as well as
+ external circuit.
+
config COMMON_CLK_RK808
tristate "Clock driver for RK808/RK818"
depends on MFD_RK808
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 3b6f9cf..1cfa9ab 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_MACH_LOONGSON32) += clk-ls1x.o
obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o
+obj-$(CONFIG_COMMON_CLK_MAX8997) += clk-max8997.o
obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o
obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
diff --git a/drivers/clk/clk-max8997.c b/drivers/clk/clk-max8997.c
new file mode 100644
index 0000000..9158354
--- /dev/null
+++ b/drivers/clk/clk-max8997.c
@@ -0,0 +1,76 @@
+/*
+ * clk-max8997.c - Clock driver for Maxim 8997
+ *
+ * Copyright (C) 2016 Samsung Electornics
+ * Pankaj Dubey <pankaj.dubey@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+#include <linux/clk-provider.h>
+#include <linux/mutex.h>
+#include <linux/clkdev.h>
+
+#include <dt-bindings/clock/maxim,max8997.h>
+#include "clk-max-gen.h"
+
+static struct clk_init_data max8997_clks_init[MAX8997_CLKS_NUM] = {
+ [MAX8997_CLK_AP] = {
+ .name = "32khz_ap",
+ .ops = &max_gen_clk_ops,
+ },
+ [MAX8997_CLK_CP] = {
+ .name = "32khz_cp",
+ .ops = &max_gen_clk_ops,
+ },
+};
+
+static int max8997_clk_probe(struct platform_device *pdev)
+{
+ struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+
+ return max_gen_clk_probe(pdev, iodev->regmap, MAX8997_REG_MAINCON1,
+ max8997_clks_init, MAX8997_CLKS_NUM);
+}
+
+static int max8997_clk_remove(struct platform_device *pdev)
+{
+ return max_gen_clk_remove(pdev, MAX8997_CLKS_NUM);
+}
+
+static const struct platform_device_id max8997_clk_id[] = {
+ { "max8997-clk", 0},
+ { },
+};
+MODULE_DEVICE_TABLE(platform, max8997_clk_id);
+
+static struct platform_driver max8997_clk_driver = {
+ .driver = {
+ .name = "max8997-clk",
+ },
+ .probe = max8997_clk_probe,
+ .remove = max8997_clk_remove,
+ .id_table = max8997_clk_id,
+};
+
+module_platform_driver(max8997_clk_driver);
+
+MODULE_DESCRIPTION("MAXIM 8997 Clock Driver");
+MODULE_AUTHOR("Pankaj Dubey <pankaj.dubey@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/include/dt-bindings/clock/maxim,max8997.h b/include/dt-bindings/clock/maxim,max8997.h
new file mode 100644
index 0000000..f2dd972
--- /dev/null
+++ b/include/dt-bindings/clock/maxim,max8997.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Device Tree binding constants clocks for the Maxim 8997 PMIC.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_MAXIM_MAX8997_CLOCK_H
+#define _DT_BINDINGS_CLOCK_MAXIM_MAX8997_CLOCK_H
+
+/* Fixed rate clocks. */
+
+#define MAX8997_CLK_AP 0
+#define MAX8997_CLK_CP 1
+
+/* Total number of clocks. */
+#define MAX8997_CLKS_NUM (MAX8997_CLK_CP + 1)
+
+#endif /* _DT_BINDINGS_CLOCK_MAXIM_MAX8997_CLOCK_H */
--
2.7.4
^ permalink raw reply related
* [PATCH 4/6] ARM: dts: Add clock provider specific properties to max8997 node
From: Pankaj Dubey @ 2016-11-07 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478513376-14307-1-git-send-email-pankaj.dubey@samsung.com>
This patch adds a label and #clock-cells property to device node of
max8997 PMIC to allow using it as a clock provider.
CC: Rob Herring <robh+dt@kernel.org>
CC: devicetree at vger.kernel.org
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
arch/arm/boot/dts/exynos4210-origen.dts | 3 ++-
arch/arm/boot/dts/exynos4210-trats.dts | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index cb3a255..6c7ef4e 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -147,11 +147,12 @@
pinctrl-0 = <&i2c0_bus>;
pinctrl-names = "default";
- max8997_pmic at 66 {
+ max8997: max8997_pmic at 66 {
compatible = "maxim,max8997-pmic";
reg = <0x66>;
interrupt-parent = <&gpx0>;
interrupts = <4 0>, <3 0>;
+ #clock-cells = <1>;
max8997,pmic-buck1-dvs-voltage = <1350000>;
max8997,pmic-buck2-dvs-voltage = <1100000>;
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 0ca1b4d..74a9d39 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -295,12 +295,13 @@
pinctrl-names = "default";
status = "okay";
- max8997_pmic at 66 {
+ max8997: max8997_pmic at 66 {
compatible = "maxim,max8997-pmic";
reg = <0x66>;
interrupt-parent = <&gpx0>;
interrupts = <7 0>;
+ #clock-cells = <1>;
max8997,pmic-buck1-uses-gpio-dvs;
max8997,pmic-buck2-uses-gpio-dvs;
--
2.7.4
^ permalink raw reply related
* [PATCH 5/6] mfd: max8997: Add max8997-clk name in mfd_cell
From: Pankaj Dubey @ 2016-11-07 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478513376-14307-1-git-send-email-pankaj.dubey@samsung.com>
This patch add max8997-clk in mfd_cell max8997_devs in order to probe
max8997-clk device driver.
CC: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
drivers/mfd/max8997.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index bda9ec8..4b809f8 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -48,6 +48,7 @@ static const struct mfd_cell max8997_devs[] = {
{ .name = "max8997-muic", },
{ .name = "max8997-led", .id = 1 },
{ .name = "max8997-led", .id = 2 },
+ { .name = "max8997-clk",},
};
#ifdef CONFIG_OF
--
2.7.4
^ permalink raw reply related
* [PATCH 6/6] ARM: dts: Extend the S3C RTC node with rtc_src clock
From: Pankaj Dubey @ 2016-11-07 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478513376-14307-1-git-send-email-pankaj.dubey@samsung.com>
Extend the S3C RTC node with rtc_src clock so it could be operational.
The rtc_src clock is provided by MAX8997.
CC: Rob Herring <robh+dt@kernel.org>
CC: devicetree at vger.kernel.org
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
arch/arm/boot/dts/exynos4210-origen.dts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index 6c7ef4e..4cac9b6 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -18,6 +18,7 @@
#include "exynos4210.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
+#include <dt-bindings/clock/maxim,max8997.h>
#include "exynos-mfc-reserved-memory.dtsi"
/ {
@@ -324,6 +325,8 @@
&rtc {
status = "okay";
+ clocks = <&clock CLK_RTC>, <&max8997 MAX8997_CLK_AP>;
+ clock-names = "rtc", "rtc_src";
};
&tmu {
--
2.7.4
^ permalink raw reply related
* [BUG] pinctrl: sunxi: sunxi-pinctrl fail to load with CONFIG_DEBUG_TEST_DRIVER_REMOVE
From: Maxime Ripard @ 2016-11-07 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107095953.GB20037@Red>
On Mon, Nov 07, 2016 at 10:59:53AM +0100, Corentin Labbe wrote:
> On Mon, Nov 07, 2016 at 10:56:12AM +0100, Maxime Ripard wrote:
> > On Mon, Nov 07, 2016 at 05:48:43PM +0800, Chen-Yu Tsai wrote:
> > > Hi,
> > >
> > > On Mon, Nov 7, 2016 at 4:18 PM, LABBE Corentin
> > > <clabbe.montjoie@gmail.com> wrote:
> > > > Hello
> > > >
> > > > With CONFIG_DEBUG_TEST_DRIVER_REMOVE=y pinctrl-sunxi fail to load on the second try.
> > > >
> > > > [ 3.900061] sun8i-h3-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver
> > > > [ 3.916251] gpio gpiochip1: GPIO integer space overlap, cannot add chip
> > > > [ 3.923016] gpiochip_add_data: GPIOs 0..223 (1c20800.pinctrl) failed to register
> > > > [ 3.931099] sun8i-h3-pinctrl: probe of 1c20800.pinctrl failed with error -16
> > > > [ 3.944709] sun8i-h3-r-pinctrl 1f02c00.pinctrl: initialized sunXi PIO driver
> > > > [ 3.960796] gpio gpiochip2: GPIO integer space overlap, cannot add chip
> > > > [ 3.967594] gpiochip_add_data: GPIOs 352..383 (1f02c00.pinctrl) failed to register
> > > > [ 3.975633] sun8i-h3-r-pinctrl: probe of 1f02c00.pinctrl failed with error -16
> > > >
> > > > Without it, all subsequent drivers fail to load.
> > > > Tested on Orange PI PC board.
> > >
> > > I don't think the pinctrl drivers were designed to be removed.
> > > And I thought the lack of a .remove callback in the driver blocks
> > > the core from removing the device? Maybe I remember wrong...
> >
> > Using a builtin_platform_driver should be enough to prevent it to be
> > removed.
> >
>
> The problem is that it is already builtin_platform_driver()
Then there's no way it can be removed in the first place.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161107/7d77b907/attachment.sig>
^ permalink raw reply
* [BUG] pinctrl: sunxi: sunxi-pinctrl fail to load with CONFIG_DEBUG_TEST_DRIVER_REMOVE
From: Corentin Labbe @ 2016-11-07 10:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107101500.ostb5auj2fpxcqe6@lukather>
On Mon, Nov 07, 2016 at 11:15:00AM +0100, Maxime Ripard wrote:
> On Mon, Nov 07, 2016 at 10:59:53AM +0100, Corentin Labbe wrote:
> > On Mon, Nov 07, 2016 at 10:56:12AM +0100, Maxime Ripard wrote:
> > > On Mon, Nov 07, 2016 at 05:48:43PM +0800, Chen-Yu Tsai wrote:
> > > > Hi,
> > > >
> > > > On Mon, Nov 7, 2016 at 4:18 PM, LABBE Corentin
> > > > <clabbe.montjoie@gmail.com> wrote:
> > > > > Hello
> > > > >
> > > > > With CONFIG_DEBUG_TEST_DRIVER_REMOVE=y pinctrl-sunxi fail to load on the second try.
> > > > >
> > > > > [ 3.900061] sun8i-h3-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver
> > > > > [ 3.916251] gpio gpiochip1: GPIO integer space overlap, cannot add chip
> > > > > [ 3.923016] gpiochip_add_data: GPIOs 0..223 (1c20800.pinctrl) failed to register
> > > > > [ 3.931099] sun8i-h3-pinctrl: probe of 1c20800.pinctrl failed with error -16
> > > > > [ 3.944709] sun8i-h3-r-pinctrl 1f02c00.pinctrl: initialized sunXi PIO driver
> > > > > [ 3.960796] gpio gpiochip2: GPIO integer space overlap, cannot add chip
> > > > > [ 3.967594] gpiochip_add_data: GPIOs 352..383 (1f02c00.pinctrl) failed to register
> > > > > [ 3.975633] sun8i-h3-r-pinctrl: probe of 1f02c00.pinctrl failed with error -16
> > > > >
> > > > > Without it, all subsequent drivers fail to load.
> > > > > Tested on Orange PI PC board.
> > > >
> > > > I don't think the pinctrl drivers were designed to be removed.
> > > > And I thought the lack of a .remove callback in the driver blocks
> > > > the core from removing the device? Maybe I remember wrong...
> > >
> > > Using a builtin_platform_driver should be enough to prevent it to be
> > > removed.
> > >
> >
> > The problem is that it is already builtin_platform_driver()
>
> Then there's no way it can be removed in the first place.
>
I will send a patch for fixing CONFIG_DEBUG_TEST_DRIVER_REMOVE
^ permalink raw reply
* [PATCH] ARM: avoid cache flushing in flush_dcache_page()
From: Rabin Vincent @ 2016-11-07 10:30 UTC (permalink / raw)
To: linux-arm-kernel
From: Rabin Vincent <rabinv@axis.com>
When the data cache is PIPT or VIPT non-aliasing, and cache operations
are broadcast by the hardware, we can always postpone the flush in
flush_dcache_page(). A similar change was done for ARM64 in commit
b5b6c9e9149d ("arm64: Avoid cache flushing in flush_dcache_page()").
Signed-off-by: Rabin Vincent <rabinv@axis.com>
---
arch/arm/mm/flush.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 3cced84..f1e6190 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -327,6 +327,12 @@ void flush_dcache_page(struct page *page)
if (page == ZERO_PAGE(0))
return;
+ if (!cache_ops_need_broadcast() && cache_is_vipt_nonaliasing()) {
+ if (test_bit(PG_dcache_clean, &page->flags))
+ clear_bit(PG_dcache_clean, &page->flags);
+ return;
+ }
+
mapping = page_mapping(page);
if (!cache_ops_need_broadcast() &&
--
2.1.4
^ permalink raw reply related
* imx6: PCIe imx6_pcie_assert_core_reset() hangs after watchdog reset
From: Lucas Stach @ 2016-11-07 10:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOMZO5ADK9TvQiBs8HrKjNp+avZsO9xujZvG6CO2onZdAcDSGA@mail.gmail.com>
Am Sonntag, den 06.11.2016, 14:59 -0200 schrieb Fabio Estevam:
> On Sun, Nov 6, 2016 at 1:31 PM, Philippe De Muyter <phdm@macq.eu> wrote:
>
> > I use either v3.17 or Freescale's 4.1.15_1.2.0_ga
>
> These kernel versions are not supported by the kernel community.
>
> Do you observe issues with 4.8.6 or 4.9-rc4?
The problem is definitely present in current mainline Linux. I intent to
remove this workaround from the kernel, but we need to make sure that
the bootloader properly disables PCIe before jumping to the kernel
image.
I don't know what the status of this is in U-Boot, but Barebox already
does this correctly.
Fabio, would you mind to port this coed to U-Boot, or at least check if
it does the right thing?
Regards,
Lucas
^ permalink raw reply
* [PATCH 0/3] ARM64: dts: meson-gxl: Enable Ethernet
From: Neil Armstrong @ 2016-11-07 10:43 UTC (permalink / raw)
To: linux-arm-kernel
The Amlogic Meson GXL SoCs have an internal RMII PHY that is muxed with the
external RGMII pins.
The internal PHY is added in the GXL dtsi and support for each
board is added in intermediate board family dtsi or final dts.
This patchset depends on ARM64 dts patch at [1]
Changes since v2 RFC at : [3]
- Change phy Kconfig/Makefile alphabetic order
- GXL dtsi cleanup
- Add P230 External PHY reset
- Add external PHY compatible ID string
Changes since original RFC patchset at : [2]
- Remove meson8b experimental phy switching
- Switch to mdio-mux-mmioreg with extennded size support
- Add internal phy support for S905x and p231
- Add external PHY support for p230
[1] http://lkml.kernel.org/r/1477932286-27482-1-git-send-email-narmstrong at baylibre.com
[2] http://lkml.kernel.org/r/1477060838-14164-1-git-send-email-narmstrong at baylibre.com
[3] http://lkml.kernel.org/r/1477932987-27871-1-git-send-email-narmstrong at baylibre.com
Neil Armstrong (3):
ARM64: dts: meson-gxl: Add ethernet nodes with internal PHY
ARM64: dts: meson-gxl-p23x: Enable ethernet
ARM64: dts: meson-gxl-s905x: Enable internal ethernet PHY
.../boot/dts/amlogic/meson-gxl-s905d-p230.dts | 25 +++++++++++++
.../boot/dts/amlogic/meson-gxl-s905d-p231.dts | 6 +++
.../boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi | 4 ++
arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi | 6 +++
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 43 ++++++++++++++++++++++
5 files changed, 84 insertions(+)
--
2.7.0
^ permalink raw reply
* [PATCH 1/3] ARM64: dts: meson-gxl: Add ethernet nodes with internal PHY
From: Neil Armstrong @ 2016-11-07 10:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107104357.24428-1-narmstrong@baylibre.com>
Add Ethernet node with Internal PHY selection for the Amlogic GXL SoCs
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 43 ++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index d1bf381..3af54dc 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -49,6 +49,22 @@
compatible = "amlogic,meson-gxl";
};
+ðmac {
+ reg = <0x0 0xc9410000 0x0 0x10000
+ 0x0 0xc8834540 0x0 0x4>;
+
+ clocks = <&clkc CLKID_ETH>,
+ <&clkc CLKID_FCLK_DIV2>,
+ <&clkc CLKID_MPLL2>;
+ clock-names = "stmmaceth", "clkin0", "clkin1";
+
+ mdio0: mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ };
+};
+
&aobus {
pinctrl_aobus: pinctrl at 14 {
compatible = "amlogic,meson-gxl-aobus-pinctrl";
@@ -214,6 +230,33 @@
};
};
};
+
+ eth-phy-mux {
+ compatible = "mdio-mux-mmioreg", "mdio-mux";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x55c 0x0 0x4>;
+ mux-mask = <0xffffffff>;
+ mdio-parent-bus = <&mdio0>;
+
+ internal_mdio: mdio at e40908ff {
+ reg = <0xe40908ff>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ internal_phy: ethernet-phy at 8 {
+ compatible = "ethernet-phy-id0181.4400", "ethernet-phy-ieee802.3-c22";
+ reg = <8>;
+ max-speed = <100>;
+ };
+ };
+
+ external_mdio: mdio at 2009087f {
+ reg = <0x2009087f>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
};
&hiubus {
--
2.7.0
^ permalink raw reply related
* [PATCH 2/3] ARM64: dts: meson-gxl-p23x: Enable ethernet
From: Neil Armstrong @ 2016-11-07 10:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107104357.24428-1-narmstrong@baylibre.com>
Enable Ethernet on the p23x board, pinctrl attribute is only added for
the p230 board since the p231 only uses the Internal PHY.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../boot/dts/amlogic/meson-gxl-s905d-p230.dts | 25 ++++++++++++++++++++++
.../boot/dts/amlogic/meson-gxl-s905d-p231.dts | 6 ++++++
.../boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi | 4 ++++
3 files changed, 35 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
index 3dfaa37..4d082a7 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
@@ -49,3 +49,28 @@
compatible = "amlogic,p230", "amlogic,s905d", "amlogic,meson-gxl";
model = "Amlogic Meson GXL (S905D) P230 Development Board";
};
+
+/* P230 has exclusive choice between internal or external PHY */
+ðmac {
+ pinctrl-0 = <ð_pins>;
+ pinctrl-names = "default";
+
+ /* Select external PHY by default */
+ phy-handle = <&external_phy>;
+
+ /* External PHY reset is shared with internal PHY Led signals */
+ snps,reset-gpio = <&gpio GPIOZ_14 0>;
+ snps,reset-delays-us = <0 10000 1000000>;
+ snps,reset-active-low;
+
+ /* External PHY is in RGMII */
+ phy-mode = "rgmii";
+};
+
+&external_mdio {
+ external_phy: ethernet-phy at 0 {
+ compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ max-speed = <1000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
index ade8d29..1cc8d49 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
@@ -49,3 +49,9 @@
compatible = "amlogic,p231", "amlogic,s905d", "amlogic,meson-gxl";
model = "Amlogic Meson GXL (S905D) P231 Development Board";
};
+
+/* P231 has only internal PHY port */
+ðmac {
+ phy-mode = "rmii";
+ phy-handle = <&internal_phy>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi
index bbe46a2..622ffbe 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p23x.dtsi
@@ -182,3 +182,7 @@
clocks = <&clkc CLKID_FCLK_DIV4>;
clock-names = "clkin0";
};
+
+ðmac {
+ status = "okay";
+};
--
2.7.0
^ permalink raw reply related
* [PATCH 3/3] ARM64: dts: meson-gxl-s905x: Enable internal ethernet PHY
From: Neil Armstrong @ 2016-11-07 10:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161107104357.24428-1-narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
index 07f0e0b..08237ee 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x.dtsi
@@ -46,3 +46,9 @@
/ {
compatible = "amlogic,s905x", "amlogic,meson-gxl";
};
+
+/* S905X Only has access to its internal PHY */
+ðmac {
+ phy-mode = "rmii";
+ phy-handle = <&internal_phy>;
+};
--
2.7.0
^ permalink raw reply related
* [PATCH v6 04/16] drivers: iommu: make of_iommu_set/get_ops() DT agnostic
From: Lorenzo Pieralisi @ 2016-11-07 10:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <9e91cb41-3034-c1ca-9275-cce3235cc662@arm.com>
On Tue, Nov 01, 2016 at 04:36:10PM +0000, Robin Murphy wrote:
> Bikeshed alert...
>
> On 18/10/16 17:04, Lorenzo Pieralisi wrote:
> > The of_iommu_{set/get}_ops() API is used to associate a device
> > tree node with a specific set of IOMMU operations. The same
> > kernel interface is required on systems booting with ACPI, where
> > devices are not associated with a device tree node, therefore
> > the interface requires generalization.
> >
> > The struct device fwnode member represents the fwnode token
> > associated with the device and the struct it points at is firmware
> > specific; regardless, it is initialized on both ACPI and DT systems
> > and makes an ideal candidate to use it to associate a set of IOMMU
> > operations to a given device, through its struct device.fwnode member
> > pointer.
> >
> > Convert the DT specific of_iommu_{set/get}_ops() interface to
> > use struct device.fwnode as a look-up token, making the interface
> > usable on ACPI systems.
> >
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > Cc: Will Deacon <will.deacon@arm.com>
> > Cc: Hanjun Guo <hanjun.guo@linaro.org>
> > Cc: Robin Murphy <robin.murphy@arm.com>
> > Cc: Joerg Roedel <joro@8bytes.org>
> > ---
> > drivers/iommu/iommu.c | 43 +++++++++++++++++++++++++++++++++++++++++++
> > drivers/iommu/of_iommu.c | 39 ---------------------------------------
> > include/linux/iommu.h | 14 ++++++++++++++
> > include/linux/of_iommu.h | 12 ++++++++++--
> > 4 files changed, 67 insertions(+), 41 deletions(-)
> >
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 9a2f196..320eb8c 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -1615,6 +1615,49 @@ int iommu_request_dm_for_dev(struct device *dev)
> > return ret;
> > }
> >
> > +struct fwnode_iommu_node {
>
> Having just pulled in this patch in isolation for some hacking, I
> realise that by about the fifth time one reads "fwnode_iommu_node" it
> just looks like meaningless gibberish. Can we just call it
> "iommu_instance" instead, as that's what it's representing here?
Agreed, how about iommu_(fw)entry ? Anyway, I will do, point taken.
> > + struct list_head list;
> > + struct fwnode_handle *fwnode;
> > + const struct iommu_ops *ops;
> > +};
> > +static LIST_HEAD(fwnode_iommu_list);
> > +static DEFINE_SPINLOCK(fwnode_iommu_lock);
> > +
> > +void fwnode_iommu_set_ops(struct fwnode_handle *fwnode,
> > + const struct iommu_ops *ops)
> > +{
> > + struct fwnode_iommu_node *iommu =
> > + kzalloc(sizeof(*iommu), GFP_KERNEL);
>
> (plus it shortens this line so it really doesn't the awkward break)
>
> Apologies, (the original rubbish name was my fault anyway)
No worries, you have a point, will update for next (hopefully last)
posting.
Thanks !
Lorenzo
> Robin.
>
> > +
> > + if (WARN_ON(!iommu))
> > + return;
> > +
> > + if (is_of_node(fwnode))
> > + of_node_get(to_of_node(fwnode));
> > +
> > + INIT_LIST_HEAD(&iommu->list);
> > + iommu->fwnode = fwnode;
> > + iommu->ops = ops;
> > + spin_lock(&fwnode_iommu_lock);
> > + list_add_tail(&iommu->list, &fwnode_iommu_list);
> > + spin_unlock(&fwnode_iommu_lock);
> > +}
> > +
> > +const struct iommu_ops *fwnode_iommu_get_ops(struct fwnode_handle *fwnode)
> > +{
> > + struct fwnode_iommu_node *node;
> > + const struct iommu_ops *ops = NULL;
> > +
> > + spin_lock(&fwnode_iommu_lock);
> > + list_for_each_entry(node, &fwnode_iommu_list, list)
> > + if (node->fwnode == fwnode) {
> > + ops = node->ops;
> > + break;
> > + }
> > + spin_unlock(&fwnode_iommu_lock);
> > + return ops;
> > +}
> > +
> > int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
> > const struct iommu_ops *ops)
> > {
> > diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> > index 5b82862..0f57ddc 100644
> > --- a/drivers/iommu/of_iommu.c
> > +++ b/drivers/iommu/of_iommu.c
> > @@ -96,45 +96,6 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
> > }
> > EXPORT_SYMBOL_GPL(of_get_dma_window);
> >
> > -struct of_iommu_node {
> > - struct list_head list;
> > - struct device_node *np;
> > - const struct iommu_ops *ops;
> > -};
> > -static LIST_HEAD(of_iommu_list);
> > -static DEFINE_SPINLOCK(of_iommu_lock);
> > -
> > -void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops)
> > -{
> > - struct of_iommu_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
> > -
> > - if (WARN_ON(!iommu))
> > - return;
> > -
> > - of_node_get(np);
> > - INIT_LIST_HEAD(&iommu->list);
> > - iommu->np = np;
> > - iommu->ops = ops;
> > - spin_lock(&of_iommu_lock);
> > - list_add_tail(&iommu->list, &of_iommu_list);
> > - spin_unlock(&of_iommu_lock);
> > -}
> > -
> > -const struct iommu_ops *of_iommu_get_ops(struct device_node *np)
> > -{
> > - struct of_iommu_node *node;
> > - const struct iommu_ops *ops = NULL;
> > -
> > - spin_lock(&of_iommu_lock);
> > - list_for_each_entry(node, &of_iommu_list, list)
> > - if (node->np == np) {
> > - ops = node->ops;
> > - break;
> > - }
> > - spin_unlock(&of_iommu_lock);
> > - return ops;
> > -}
> > -
> > static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
> > {
> > struct of_phandle_args *iommu_spec = data;
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index 436dc21..15d5478 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -351,6 +351,9 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
> > const struct iommu_ops *ops);
> > void iommu_fwspec_free(struct device *dev);
> > int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> > +void fwnode_iommu_set_ops(struct fwnode_handle *fwnode,
> > + const struct iommu_ops *ops);
> > +const struct iommu_ops *fwnode_iommu_get_ops(struct fwnode_handle *fwnode);
> >
> > #else /* CONFIG_IOMMU_API */
> >
> > @@ -580,6 +583,17 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
> > return -ENODEV;
> > }
> >
> > +static inline void fwnode_iommu_set_ops(struct fwnode_handle *fwnode,
> > + const struct iommu_ops *ops)
> > +{
> > +}
> > +
> > +static inline
> > +const struct iommu_ops *fwnode_iommu_get_ops(struct fwnode_handle *fwnode)
> > +{
> > + return NULL;
> > +}
> > +
> > #endif /* CONFIG_IOMMU_API */
> >
> > #endif /* __LINUX_IOMMU_H */
> > diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> > index e80b9c7..7681007 100644
> > --- a/include/linux/of_iommu.h
> > +++ b/include/linux/of_iommu.h
> > @@ -31,8 +31,16 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
> >
> > #endif /* CONFIG_OF_IOMMU */
> >
> > -void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
> > -const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> > +static inline void of_iommu_set_ops(struct device_node *np,
> > + const struct iommu_ops *ops)
> > +{
> > + fwnode_iommu_set_ops(&np->fwnode, ops);
> > +}
> > +
> > +static inline const struct iommu_ops *of_iommu_get_ops(struct device_node *np)
> > +{
> > + return fwnode_iommu_get_ops(&np->fwnode);
> > +}
> >
> > extern struct of_device_id __iommu_of_table;
> >
> >
>
^ permalink raw reply
* [PATCH 0/3] Add memremap executable mapping and extend drivers/misc/sram.c
From: Russell King - ARM Linux @ 2016-11-07 11:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161027185612.22362-1-d-gerlach@ti.com>
On Thu, Oct 27, 2016 at 01:56:09PM -0500, Dave Gerlach wrote:
> There are several instances when one would want to execute out of on-chip
> SRAM, such as PM code on ARM platforms, so once again revisiting this
> series to allow that in a generic manner. Seems that having a solution for
> allowing SRAM to be mapped as executable will help clean up PM code on several
> ARM platforms that are using ARM internal __arm_ioremap_exec API
> and also open the door for PM support on new platforms like TI AM335x and
> AM437x. This was last sent as RFC here [1] and based on comments from Russell
> King and Arnd Bergmann has been rewritten to use memremap API rather than
> ioremap API, as executable iomem does not really make sense.
This is better, as it avoids the issue that I pointed out last time
around, but I'm still left wondering about the approach.
Sure, having executable SRAM mappings sounds nice and easy, but we're
creating WX mappings. Folk have spent a while improving the security of
the kernel by ensuring that there are no WX mappings, and this series
reintroduces them. The sad thing is that any WX mapping which appears
at a known address can be exploited.
"A known address" can be something that appears to be random, but ends
up being the same across the same device type... or can be discovered
by some means. Eg, consider if the WX mapping is dynamically allocated,
but occurs at exactly the same point at boot - and if this happens with
android phones, consider how many of those are out there. Or if the
address of the WX mapping is available via some hardware register.
Or...
See Kees Cook's slides at last years kernel summit -
https://outflux.net/slides/2015/ks/security.pdf
So, I think avoiding WX mappings - mappings should be either W or X but
not both simultaneously (see page 19.)
I guess what I'm angling at is that we don't want memremap_exec(), but
we need an API which changes the permissions of a SRAM mapping between
allowing writes and allowing execution.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH V4 6/6] bus: Add support for Tegra Generic Memory Interface
From: Jon Hunter @ 2016-11-07 11:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478507405-13204-7-git-send-email-mirza.krak@gmail.com>
On 07/11/16 08:30, Mirza Krak wrote:
> From: Mirza Krak <mirza.krak@gmail.com>
>
> The Generic Memory Interface bus can be used to connect high-speed
> devices such as NOR flash, FPGAs, DSPs...
>
> Signed-off-by: Mirza Krak <mirza.krak@gmail.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
Thanks for the update.
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Cheers
Jon
--
nvpublic
^ permalink raw reply
* [PATCH] PM / Domains: Fix compatible for domain idle state
From: Ulf Hansson @ 2016-11-07 11:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478210075-92045-2-git-send-email-lina.iyer@linaro.org>
On 3 November 2016 at 22:54, Lina Iyer <lina.iyer@linaro.org> wrote:
> Re-using idle state definition provided by arm,idle-state for domain
> idle states creates a lot of confusion and limits further evolution of
> the domain idle definition. To keep things clear and simple, define a
> idle states for domain using a new compatible "domain-idle-state".
>
> Fix existing PM domains code to look for the newly defined compatible.
>
> Cc: <devicetree@vger.kernel.org>
> Cc: Rob Herring <robh@kernel.org>
> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
> ---
> .../bindings/power/domain-idle-state.txt | 33 ++++++++++++++++++++++
> .../devicetree/bindings/power/power_domain.txt | 8 +++---
> drivers/base/power/domain.c | 2 +-
> 3 files changed, 38 insertions(+), 5 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/power/domain-idle-state.txt
>
> diff --git a/Documentation/devicetree/bindings/power/domain-idle-state.txt b/Documentation/devicetree/bindings/power/domain-idle-state.txt
> new file mode 100644
> index 0000000..eefc7ed
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/domain-idle-state.txt
> @@ -0,0 +1,33 @@
> +PM Domain Idle State Node:
> +
> +A domain idle state node represents the state parameters that will be used to
> +select the state when there are no active components in the domain.
> +
> +The state node has the following parameters -
> +
> +- compatible:
> + Usage: Required
> + Value type: <string>
> + Definition: Must be "domain-idle-state".
> +
> +- entry-latency-us
> + Usage: Required
> + Value type: <prop-encoded-array>
> + Definition: u32 value representing worst case latency in
> + microseconds required to enter the idle state.
> + The exit-latency-us duration may be guaranteed
> + only after entry-latency-us has passed.
As we anyway are going to change this, why not use an u64 and have the
value in ns instead of us?
That should give us better flexibility and I think this would also be
what Rob would recommend, if I remember earlier similar comments from
him.
> +
> +- exit-latency-us
> + Usage: Required
> + Value type: <prop-encoded-array>
> + Definition: u32 value representing worst case latency
> + in microseconds required to exit the idle state.
Ditto.
> +
> +- min-residency-us
> + Usage: Required
> + Value type: <prop-encoded-array>
> + Definition: u32 value representing minimum residency duration
> + in microseconds after which the idle state will yield
> + power benefits after overcoming the overhead in entering
> +i the idle state.
Ditto.
> diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
> index e165036..723e1ad 100644
> --- a/Documentation/devicetree/bindings/power/power_domain.txt
> +++ b/Documentation/devicetree/bindings/power/power_domain.txt
> @@ -31,7 +31,7 @@ Optional properties:
>
> - domain-idle-states : A phandle of an idle-state that shall be soaked into a
> generic domain power state. The idle state definitions are
> - compatible with arm,idle-state specified in [1].
> + compatible with domain-idle-state specified in [1].
> The domain-idle-state property reflects the idle state of this PM domain and
> not the idle states of the devices or sub-domains in the PM domain. Devices
> and sub-domains have their own idle-states independent of the parent
> @@ -85,7 +85,7 @@ Example 3:
> };
>
> DOMAIN_RET: state at 0 {
> - compatible = "arm,idle-state";
> + compatible = "domain-idle-state";
> reg = <0x0>;
> entry-latency-us = <1000>;
> exit-latency-us = <2000>;
> @@ -93,7 +93,7 @@ Example 3:
> };
>
> DOMAIN_PWR_DN: state at 1 {
> - compatible = "arm,idle-state";
> + compatible = "domain-idle-state";
> reg = <0x1>;
> entry-latency-us = <5000>;
> exit-latency-us = <8000>;
> @@ -118,4 +118,4 @@ The node above defines a typical PM domain consumer device, which is located
> inside a PM domain with index 0 of a power controller represented by a node
> with the label "power".
>
> -[1]. Documentation/devicetree/bindings/arm/idle-states.txt
> +[1]. Documentation/devicetree/bindings/power/domain-idle-state.txt
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index 661737c..f0bc672 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -2048,7 +2048,7 @@ int genpd_dev_pm_attach(struct device *dev)
> EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
>
> static const struct of_device_id idle_state_match[] = {
> - { .compatible = "arm,idle-state", },
> + { .compatible = "domain-idle-state", },
> { }
> };
>
> --
> 2.7.4
>
Kind regards
Uffe
^ permalink raw reply
* [PATCH V4 1/6] clk: tegra: add TEGRA20_CLK_NOR to init table
From: Thierry Reding @ 2016-11-07 11:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478507405-13204-2-git-send-email-mirza.krak@gmail.com>
On Mon, Nov 07, 2016 at 09:30:00AM +0100, Mirza Krak wrote:
> From: Mirza Krak <mirza.krak@gmail.com>
>
> Add TEGRA20_CLK_NOR to init table and set default rate to 92 MHz which
> is max rate.
>
> The maximum rate value of 92 MHz is pulled from the downstream L4T
> kernel.
>
> Signed-off-by: Mirza Krak <mirza.krak@gmail.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> Acked-by: Jon Hunter <jonathanh@nvidia.com>
> ---
>
> Changes in v2:
> - no changes
>
> Changes in v3:
> - Added comment in commit message where I got the maximum rates from.
>
> Changes in V4:
> - no changes
Applied, thanks.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161107/14d088fa/attachment.sig>
^ permalink raw reply
* [PATCH V4 2/6] clk: tegra: add TEGRA30_CLK_NOR to init table
From: Thierry Reding @ 2016-11-07 11:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478507405-13204-3-git-send-email-mirza.krak@gmail.com>
On Mon, Nov 07, 2016 at 09:30:01AM +0100, Mirza Krak wrote:
> From: Mirza Krak <mirza.krak@gmail.com>
>
> Add TEGRA30_CLK_NOR to init table and set default rate to 127 MHz which
> is max rate.
>
> The maximum rate value of 127 MHz is pulled from the downstream L4T
> kernel.
>
> Signed-off-by: Mirza Krak <mirza.krak@gmail.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> Acked-by: Jon Hunter <jonathanh@nvidia.com>
> ---
>
> Changes in v2:
> - no changes
>
> Changes in v3:
> - Added comment in commit message where I got the maximum rates from.
>
> Changes in V4:
> - no changes
>
> drivers/clk/tegra/clk-tegra30.c | 1 +
> 1 file changed, 1 insertion(+)
Applied, thanks.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161107/c0620109/attachment-0001.sig>
^ permalink raw reply
* [PATCH/RESEND V4 3/3] ARM64 LPC: LPC driver implementation on Hip06
From: Mark Rutland @ 2016-11-07 11:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478006926-240933-4-git-send-email-yuanzhichang@hisilicon.com>
Hi,
I received an off-list v5 of this for some reason.
I have several concerns with this, but given there's evidently a v5, I
intend to wait until that is posted before I reply with my comments.
Thanks,
Mark.
On Tue, Nov 01, 2016 at 09:28:46PM +0800, zhichang.yuan wrote:
> On Hip06, the accesses to LPC peripherals work in an indirect way. A
> corresponding LPC driver configure some registers in LPC master at first, then
> the real accesses on LPC slave devices are finished by the LPC master, which
> is transparent to LPC driver.
> This patch implement the relevant driver for Hip06 LPC. Cooperating with
> indirect-IO, ipmi messages is in service without any changes on ipmi driver.
>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: zhichang.yuan <yuanzhichang@hisilicon.com>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> ---
> .../arm/hisilicon/hisilicon-low-pin-count.txt | 31 ++
> MAINTAINERS | 8 +
> drivers/bus/Kconfig | 8 +
> drivers/bus/Makefile | 1 +
> drivers/bus/hisi_lpc.c | 501 +++++++++++++++++++++
> 5 files changed, 549 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
> create mode 100644 drivers/bus/hisi_lpc.c
>
> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
> new file mode 100644
> index 0000000..e681419
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
> @@ -0,0 +1,31 @@
> +Hisilicon Hip06 low-pin-count device
> + Usually LPC controller is part of PCI host bridge, so the legacy ISA ports
> + locate on LPC bus can be accessed direclty. But some SoCs have independent
> + LPC controller, and access the legacy ports by triggering LPC I/O cycles.
> + Hisilicon Hip06 implements this LPC device.
> +
> +Required properties:
> +- compatible: should be "hisilicon,low-pin-count"
> +- #address-cells: must be 2 which stick to the ISA/EISA binding doc.
> +- #size-cells: must be 1 which stick to the ISA/EISA binding doc.
> +- reg: base memory range where the register set for this device is mapped.
> +
> +Note:
> + The node name before '@' must be "isa" to represent the binding stick to the
> + ISA/EISA binding specification.
> +
> +Example:
> +
> +isa at a01b0000 {
> + compatible = "hisilicom,low-pin-count";
> + #address-cells = <2>;
> + #size-cells = <1>;
> + reg = <0x0 0xa01b0000 0x0 0x1000>;
> +
> + ipmi0: bt at e4 {
> + compatible = "ipmi-bt";
> + device_type = "ipmi";
> + reg = <0x01 0xe4 0x04>;
> + status = "disabled";
> + };
> +};
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1cd38a7..7c69410 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5716,6 +5716,14 @@ F: include/uapi/linux/if_hippi.h
> F: net/802/hippi.c
> F: drivers/net/hippi/
>
> +HISILICON LPC BUS DRIVER
> +M: Zhichang Yuan <yuanzhichang@hisilicon.com>
> +L: linux-arm-kernel at lists.infradead.org
> +W: http://www.hisilicon.com
> +S: Maintained
> +F: drivers/bus/hisi_lpc.c
> +F: Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
> +
> HISILICON NETWORK SUBSYSTEM DRIVER
> M: Yisen Zhuang <yisen.zhuang@huawei.com>
> M: Salil Mehta <salil.mehta@huawei.com>
> diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
> index 7010dca..a108abc 100644
> --- a/drivers/bus/Kconfig
> +++ b/drivers/bus/Kconfig
> @@ -64,6 +64,14 @@ config BRCMSTB_GISB_ARB
> arbiter. This driver provides timeout and target abort error handling
> and internal bus master decoding.
>
> +config HISILICON_LPC
> + bool "Workaround for nonstandard ISA I/O space on Hisilicon Hip0X"
> + depends on (ARCH_HISI || COMPILE_TEST) && ARM64
> + select ARM64_INDIRECT_PIO
> + help
> + Driver needed for some legacy ISA devices attached to Low-Pin-Count
> + on Hisilicon Hip0X SoC.
> +
> config IMX_WEIM
> bool "Freescale EIM DRIVER"
> depends on ARCH_MXC
> diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
> index c6cfa6b..10b4983 100644
> --- a/drivers/bus/Makefile
> +++ b/drivers/bus/Makefile
> @@ -7,6 +7,7 @@ obj-$(CONFIG_ARM_CCI) += arm-cci.o
> obj-$(CONFIG_ARM_CCN) += arm-ccn.o
>
> obj-$(CONFIG_BRCMSTB_GISB_ARB) += brcmstb_gisb.o
> +obj-$(CONFIG_HISILICON_LPC) += hisi_lpc.o
> obj-$(CONFIG_IMX_WEIM) += imx-weim.o
> obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o
> obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
> diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c
> new file mode 100644
> index 0000000..9f48a1a
> --- /dev/null
> +++ b/drivers/bus/hisi_lpc.c
> @@ -0,0 +1,501 @@
> +/*
> + * Copyright (C) 2016 Hisilicon Limited, All Rights Reserved.
> + * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
> + * Author: Zou Rongrong <zourongrong@huawei.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/console.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/pci.h>
> +#include <linux/serial_8250.h>
> +#include <linux/slab.h>
> +
> +/*
> + * this bit set means each IO operation will target to different port address;
> + * 0 means repeatly IO operations will be sticked on the same port, such as BT;
> + */
> +#define FG_INCRADDR_LPC 0x02
> +
> +struct lpc_cycle_para {
> + unsigned int opflags;
> + unsigned int csize;/* the data length of each operation */
> +};
> +
> +struct hisilpc_dev {
> + spinlock_t cycle_lock;
> + void __iomem *membase;
> + struct extio_ops io_ops;
> +};
> +
> +
> +/* The maximum continous operations*/
> +#define LPC_MAX_OPCNT 16
> +/* only support IO data unit length is four at maximum */
> +#define LPC_MAX_DULEN 4
> +#if LPC_MAX_DULEN > LPC_MAX_OPCNT
> +#error "LPC.. MAX_DULEN must be not bigger than MAX_OPCNT!"
> +#endif
> +
> +#define LPC_REG_START 0x00/* start a new LPC cycle */
> +#define LPC_REG_OP_STATUS 0x04/* the current LPC status */
> +#define LPC_REG_IRQ_ST 0x08/* interrupt enable&status */
> +#define LPC_REG_OP_LEN 0x10/* how many LPC cycles each start */
> +#define LPC_REG_CMD 0x14/* command for the required LPC cycle */
> +#define LPC_REG_ADDR 0x20/* LPC target address */
> +#define LPC_REG_WDATA 0x24/* data to be written */
> +#define LPC_REG_RDATA 0x28/* data coming from peer */
> +
> +
> +/* The command register fields*/
> +#define LPC_CMD_SAMEADDR 0x08
> +#define LPC_CMD_TYPE_IO 0x00
> +#define LPC_CMD_WRITE 0x01
> +#define LPC_CMD_READ 0x00
> +/* the bit attribute is W1C. 1 represents OK. */
> +#define LPC_STAT_BYIRQ 0x02
> +
> +#define LPC_STATUS_IDLE 0x01
> +#define LPC_OP_FINISHED 0x02
> +
> +#define START_WORK 0x01
> +
> +/*
> + * The minimal waiting interval... Suggest it is not less than 10.
> + * Bigger value probably will lower the performance.
> + */
> +#define LPC_NSEC_PERWAIT 100
> +/*
> + * The maximum waiting time is about 128us.
> + * The fastest IO cycle time is about 390ns, but the worst case will wait
> + * for extra 256 lpc clocks, so (256 + 13) * 30ns = 8 us. The maximum
> + * burst cycles is 16. So, the maximum waiting time is about 128us under
> + * worst case.
> + * choose 1300 as the maximum.
> + */
> +#define LPC_MAX_WAITCNT 1300
> +/* About 10us. This is specfic for single IO operation, such as inb. */
> +#define LPC_PEROP_WAITCNT 100
> +
> +
> +static inline int wait_lpc_idle(unsigned char *mbase,
> + unsigned int waitcnt) {
> + u32 opstatus;
> +
> + while (waitcnt--) {
> + ndelay(LPC_NSEC_PERWAIT);
> + opstatus = readl(mbase + LPC_REG_OP_STATUS);
> + if (opstatus & LPC_STATUS_IDLE)
> + return (opstatus & LPC_OP_FINISHED) ? 0 : (-EIO);
> + }
> + return -ETIME;
> +}
> +
> +
> +/**
> + * hisilpc_target_in - trigger a series of lpc cycles to read required data
> + * from target periperal.
> + * @pdev: pointer to hisi lpc device
> + * @para: some paramerters used to control the lpc I/O operations
> + * @ptaddr: the lpc I/O target port address
> + * @buf: where the read back data is stored
> + * @opcnt: how many I/O operations required in this calling
> + *
> + * only one byte data is read each I/O operation.
> + *
> + * Returns 0 on success, non-zero on fail.
> + *
> + */
> +static int hisilpc_target_in(struct hisilpc_dev *pdev,
> + struct lpc_cycle_para *para,
> + unsigned long ptaddr, unsigned char *buf,
> + unsigned long opcnt)
> +{
> + unsigned int cmd_word;
> + unsigned int waitcnt;
> + int retval;
> + unsigned long flags;
> + unsigned long cnt_per_trans;
> +
> + if (!buf || !opcnt || !para || !para->csize || !pdev)
> + return -EINVAL;
> +
> + if (opcnt > LPC_MAX_OPCNT)
> + return -EINVAL;
> +
> + cmd_word = LPC_CMD_TYPE_IO | LPC_CMD_READ;
> + waitcnt = (LPC_PEROP_WAITCNT);
> + if (!(para->opflags & FG_INCRADDR_LPC)) {
> + cmd_word |= LPC_CMD_SAMEADDR;
> + waitcnt = LPC_MAX_WAITCNT;
> + }
> +
> + retval = 0;
> + cnt_per_trans = (para->csize == 1) ? opcnt : para->csize;
> + for (; opcnt && !retval; cnt_per_trans = para->csize) {
> + /* whole operation must be atomic */
> + spin_lock_irqsave(&pdev->cycle_lock, flags);
> +
> + writel(cnt_per_trans, pdev->membase + LPC_REG_OP_LEN);
> +
> + writel(cmd_word, pdev->membase + LPC_REG_CMD);
> +
> + writel(ptaddr, pdev->membase + LPC_REG_ADDR);
> +
> + writel(START_WORK, pdev->membase + LPC_REG_START);
> +
> + /* whether the operation is finished */
> + retval = wait_lpc_idle(pdev->membase, waitcnt);
> + if (!retval) {
> + opcnt -= cnt_per_trans;
> + for (; cnt_per_trans--; buf++)
> + *buf = readl(pdev->membase + LPC_REG_RDATA);
> + }
> +
> + spin_unlock_irqrestore(&pdev->cycle_lock, flags);
> + }
> +
> + return retval;
> +}
> +
> +/**
> + * hisilpc_target_out - trigger a series of lpc cycles to write required data
> + * to target periperal.
> + * @pdev: pointer to hisi lpc device
> + * @para: some paramerters used to control the lpc I/O operations
> + * @ptaddr: the lpc I/O target port address
> + * @buf: where the data to be written is stored
> + * @opcnt: how many I/O operations required
> + *
> + * only one byte data is read each I/O operation.
> + *
> + * Returns 0 on success, non-zero on fail.
> + *
> + */
> +static int hisilpc_target_out(struct hisilpc_dev *pdev,
> + struct lpc_cycle_para *para,
> + unsigned long ptaddr,
> + const unsigned char *buf,
> + unsigned long opcnt)
> +{
> + unsigned int cmd_word;
> + unsigned int waitcnt;
> + int retval;
> + unsigned long flags;
> + unsigned long cnt_per_trans;
> +
> + if (!buf || !opcnt || !para || !pdev)
> + return -EINVAL;
> +
> + if (opcnt > LPC_MAX_OPCNT)
> + return -EINVAL;
> + /* default is increasing address */
> + cmd_word = LPC_CMD_TYPE_IO | LPC_CMD_WRITE;
> + waitcnt = (LPC_PEROP_WAITCNT);
> + if (!(para->opflags & FG_INCRADDR_LPC)) {
> + cmd_word |= LPC_CMD_SAMEADDR;
> + waitcnt = LPC_MAX_WAITCNT;
> + }
> +
> + retval = 0;
> + cnt_per_trans = (para->csize == 1) ? opcnt : para->csize;
> + for (; opcnt && !retval; cnt_per_trans = para->csize) {
> + spin_lock_irqsave(&pdev->cycle_lock, flags);
> +
> + writel(cnt_per_trans, pdev->membase + LPC_REG_OP_LEN);
> + opcnt -= cnt_per_trans;
> + for (; cnt_per_trans--; buf++)
> + writel(*buf, pdev->membase + LPC_REG_WDATA);
> +
> + writel(cmd_word, pdev->membase + LPC_REG_CMD);
> +
> + writel(ptaddr, pdev->membase + LPC_REG_ADDR);
> +
> + writel(START_WORK, pdev->membase + LPC_REG_START);
> +
> + /* whether the operation is finished */
> + retval = wait_lpc_idle(pdev->membase, waitcnt);
> +
> + spin_unlock_irqrestore(&pdev->cycle_lock, flags);
> + }
> +
> + return retval;
> +}
> +
> +
> +/**
> + * hisilpc_comm_in - read/input the data from the I/O peripheral through LPC.
> + * @devobj: pointer to the device information relevant to LPC controller.
> + * @ptaddr: the target I/O port address.
> + * @dlen: the data length required to read from the target I/O port.
> + *
> + * when succeed, the data read back is stored in buffer pointed by inbuf.
> + * For inb, return the data read from I/O or -1 when error occur.
> + */
> +static u64 hisilpc_comm_in(void *devobj, unsigned long ptaddr, size_t dlen)
> +{
> + struct hisilpc_dev *lpcdev;
> + struct lpc_cycle_para iopara;
> + u32 rd_data;
> + unsigned char *newbuf;
> + int ret = 0;
> +
> + if (!devobj || !dlen || dlen > LPC_MAX_DULEN || (dlen & (dlen - 1)))
> + return -1;
> +
> + /* the local buffer must be enough for one data unit */
> + if (sizeof(rd_data) < dlen)
> + return -1;
> +
> + newbuf = (unsigned char *)&rd_data;
> +
> + lpcdev = (struct hisilpc_dev *)devobj;
> +
> + iopara.opflags = FG_INCRADDR_LPC;
> + iopara.csize = dlen;
> +
> + ret = hisilpc_target_in(lpcdev, &iopara, ptaddr, newbuf, dlen);
> + if (ret)
> + return -1;
> +
> + return le32_to_cpu(rd_data);
> +}
> +
> +/**
> + * hisilpc_comm_out - write/output the data whose maximal length is four bytes to
> + * the I/O peripheral through LPC.
> + * @devobj: pointer to the device information relevant to LPC controller.
> + * @outval: a value to be outputed from caller, maximum is four bytes.
> + * @ptaddr: the target I/O port address.
> + * @dlen: the data length required writing to the target I/O port .
> + *
> + * This function is corresponding to out(b,w,l) only
> + *
> + */
> +static void hisilpc_comm_out(void *devobj, unsigned long ptaddr,
> + u32 outval, size_t dlen)
> +{
> + struct hisilpc_dev *lpcdev;
> + struct lpc_cycle_para iopara;
> + const unsigned char *newbuf;
> +
> + if (!devobj || !dlen || dlen > LPC_MAX_DULEN)
> + return;
> +
> + if (sizeof(outval) < dlen)
> + return;
> +
> + outval = cpu_to_le32(outval);
> +
> + newbuf = (const unsigned char *)&outval;
> + lpcdev = (struct hisilpc_dev *)devobj;
> +
> + iopara.opflags = FG_INCRADDR_LPC;
> + iopara.csize = dlen;
> +
> + hisilpc_target_out(lpcdev, &iopara, ptaddr, newbuf, dlen);
> +}
> +
> +
> +/**
> + * hisilpc_comm_ins - read/input the data in buffer to the I/O peripheral
> + * through LPC, it corresponds to ins(b,w,l)
> + * @devobj: pointer to the device information relevant to LPC controller.
> + * @ptaddr: the target I/O port address.
> + * @inbuf: a buffer where read/input data bytes are stored.
> + * @dlen: the data length required writing to the target I/O port .
> + * @count: how many data units whose length is dlen will be read.
> + *
> + */
> +static u64 hisilpc_comm_ins(void *devobj, unsigned long ptaddr,
> + void *inbuf, size_t dlen, unsigned int count)
> +{
> + struct hisilpc_dev *lpcdev;
> + struct lpc_cycle_para iopara;
> + unsigned char *newbuf;
> + unsigned int loopcnt, cntleft;
> + unsigned int max_perburst;
> + int ret = 0;
> +
> + if (!devobj || !inbuf || !count || !dlen ||
> + dlen > LPC_MAX_DULEN || (dlen & (dlen - 1)))
> + return -1;
> +
> + iopara.opflags = 0;
> + if (dlen > 1)
> + iopara.opflags |= FG_INCRADDR_LPC;
> + iopara.csize = dlen;
> +
> + lpcdev = (struct hisilpc_dev *)devobj;
> + newbuf = (unsigned char *)inbuf;
> + /*
> + * ensure data stream whose lenght is multiple of dlen to be processed
> + * each IO input
> + */
> + max_perburst = LPC_MAX_OPCNT & (~(dlen - 1));
> + cntleft = count * dlen;
> + do {
> + loopcnt = (cntleft >= max_perburst) ? max_perburst : cntleft;
> + ret = hisilpc_target_in(lpcdev, &iopara, ptaddr, newbuf,
> + loopcnt);
> + if (ret)
> + break;
> + newbuf += loopcnt;
> + cntleft -= loopcnt;
> + } while (cntleft);
> +
> + return ret;
> +}
> +
> +/**
> + * hisilpc_comm_outs - write/output the data in buffer to the I/O peripheral
> + * through LPC, it corresponds to outs(b,w,l)
> + * @devobj: pointer to the device information relevant to LPC controller.
> + * @ptaddr: the target I/O port address.
> + * @outbuf: a buffer where write/output data bytes are stored.
> + * @dlen: the data length required writing to the target I/O port .
> + * @count: how many data units whose length is dlen will be written.
> + *
> + */
> +static void hisilpc_comm_outs(void *devobj, unsigned long ptaddr,
> + const void *outbuf, size_t dlen, unsigned int count)
> +{
> + struct hisilpc_dev *lpcdev;
> + struct lpc_cycle_para iopara;
> + const unsigned char *newbuf;
> + unsigned int loopcnt, cntleft;
> + unsigned int max_perburst;
> + int ret = 0;
> +
> + if (!devobj || !outbuf || !count || !dlen ||
> + dlen > LPC_MAX_DULEN || (dlen & (dlen - 1)))
> + return;
> +
> + iopara.opflags = 0;
> + if (dlen > 1)
> + iopara.opflags |= FG_INCRADDR_LPC;
> + iopara.csize = dlen;
> +
> + lpcdev = (struct hisilpc_dev *)devobj;
> + newbuf = (unsigned char *)outbuf;
> + /*
> + * ensure data stream whose lenght is multiple of dlen to be processed
> + * each IO input
> + */
> + max_perburst = LPC_MAX_OPCNT & (~(dlen - 1));
> + cntleft = count * dlen;
> + do {
> + loopcnt = (cntleft >= max_perburst) ? max_perburst : cntleft;
> + ret = hisilpc_target_out(lpcdev, &iopara, ptaddr, newbuf,
> + loopcnt);
> + if (ret)
> + break;
> + newbuf += loopcnt;
> + cntleft -= loopcnt;
> + } while (cntleft);
> +}
> +
> +
> +/**
> + * hisilpc_probe - the probe callback function for hisi lpc device,
> + * will finish all the intialization.
> + * @pdev: the platform device corresponding to hisi lpc
> + *
> + * Returns 0 on success, non-zero on fail.
> + *
> + */
> +static int hisilpc_probe(struct platform_device *pdev)
> +{
> + struct resource *iores;
> + struct hisilpc_dev *lpcdev;
> + int ret;
> +
> + dev_info(&pdev->dev, "hslpc start probing...\n");
> +
> + lpcdev = devm_kzalloc(&pdev->dev,
> + sizeof(struct hisilpc_dev), GFP_KERNEL);
> + if (!lpcdev)
> + return -ENOMEM;
> +
> + spin_lock_init(&lpcdev->cycle_lock);
> + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + lpcdev->membase = devm_ioremap_resource(&pdev->dev, iores);
> + if (IS_ERR(lpcdev->membase)) {
> + dev_err(&pdev->dev, "No mem resource for memory mapping!\n");
> + return PTR_ERR(lpcdev->membase);
> + }
> + /*
> + * The first PCIBIOS_MIN_IO is reserved specific for indirectIO.
> + * It will separate indirectIO range from pci host bridge to
> + * avoid the possible PIO conflict.
> + * Set the indirectIO range directly here.
> + */
> + lpcdev->io_ops.start = 0;
> + lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1;
> + lpcdev->io_ops.devpara = lpcdev;
> + lpcdev->io_ops.pfin = hisilpc_comm_in;
> + lpcdev->io_ops.pfout = hisilpc_comm_out;
> + lpcdev->io_ops.pfins = hisilpc_comm_ins;
> + lpcdev->io_ops.pfouts = hisilpc_comm_outs;
> +
> + platform_set_drvdata(pdev, lpcdev);
> +
> + arm64_set_extops(&lpcdev->io_ops);
> +
> + /*
> + * The children scanning is only for dts mode. For ACPI children,
> + * the corresponding devices had be created during acpi scanning.
> + */
> + ret = 0;
> + if (!has_acpi_companion(&pdev->dev))
> + ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
> +
> + if (!ret)
> + dev_info(&pdev->dev, "hslpc end probing. range[0x%lx - %lx]\n",
> + arm64_extio_ops->start, arm64_extio_ops->end);
> + else
> + dev_info(&pdev->dev, "hslpc probing is fail(%d)\n", ret);
> +
> + return ret;
> +}
> +
> +static const struct of_device_id hisilpc_of_match[] = {
> + {
> + .compatible = "hisilicon,low-pin-count",
> + },
> + {},
> +};
> +
> +static const struct acpi_device_id hisilpc_acpi_match[] = {
> + {"HISI0191", },
> + {},
> +};
> +
> +static struct platform_driver hisilpc_driver = {
> + .driver = {
> + .name = "hisi_lpc",
> + .of_match_table = hisilpc_of_match,
> + .acpi_match_table = hisilpc_acpi_match,
> + },
> + .probe = hisilpc_probe,
> +};
> +
> +
> +builtin_platform_driver(hisilpc_driver);
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] ARM: avoid cache flushing in flush_dcache_page()
From: Catalin Marinas @ 2016-11-07 11:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478514624-30910-1-git-send-email-rabin.vincent@axis.com>
On Mon, Nov 07, 2016 at 11:30:24AM +0100, Rabin Vincent wrote:
> diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
> index 3cced84..f1e6190 100644
> --- a/arch/arm/mm/flush.c
> +++ b/arch/arm/mm/flush.c
> @@ -327,6 +327,12 @@ void flush_dcache_page(struct page *page)
> if (page == ZERO_PAGE(0))
> return;
>
> + if (!cache_ops_need_broadcast() && cache_is_vipt_nonaliasing()) {
> + if (test_bit(PG_dcache_clean, &page->flags))
> + clear_bit(PG_dcache_clean, &page->flags);
> + return;
> + }
> +
> mapping = page_mapping(page);
>
> if (!cache_ops_need_broadcast() &&
I'm ok with the logic in this patch but is there a way to combine the
two 'if' blocks together, just to keep the function shorter?
--
Catalin
^ permalink raw reply
* [PATCH V4 3/6] dt/bindings: Add bindings for Tegra GMI controller
From: Thierry Reding @ 2016-11-07 11:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478507405-13204-4-git-send-email-mirza.krak@gmail.com>
On Mon, Nov 07, 2016 at 09:30:02AM +0100, Mirza Krak wrote:
> From: Mirza Krak <mirza.krak@gmail.com>
>
> Document the devicetree bindings for the Generic Memory Interface (GMI)
> bus driver found on Tegra SOCs.
>
> Signed-off-by: Mirza Krak <mirza.krak@gmail.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
> Acked-by: Rob Herring <robh@kernel.org>
> ---
>
> Changes in v2:
> - Updated examples and some information based on comments from Jon Hunter.
>
> Changes in v3:
> - Updates ranges description based on comments from Rob Herring
>
> Changes in v4:
> - renamed snor-*-inv to snor-*-active-high
>
> .../devicetree/bindings/bus/nvidia,tegra20-gmi.txt | 132 +++++++++++++++++++++
> 1 file changed, 132 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt
Applied, thanks.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161107/42611e92/attachment-0001.sig>
^ permalink raw reply
* [PATCH v6 09/16] drivers: acpi: iort: add support for ARM SMMU platform devices creation
From: Lorenzo Pieralisi @ 2016-11-07 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161101223022.GA1234@xora-yoga13>
On Tue, Nov 01, 2016 at 04:30:22PM -0600, Graeme Gregory wrote:
> On Fri, Oct 28, 2016 at 04:50:07PM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Oct 18, 2016 at 05:04:07PM +0100, Lorenzo Pieralisi wrote:
> > > In ARM ACPI systems, IOMMU components are specified through static
> > > IORT table entries. In order to create platform devices for the
> > > corresponding ARM SMMU components, IORT kernel code should be made
> > > able to parse IORT table entries and create platform devices
> > > dynamically.
> > >
> > > This patch adds the generic IORT infrastructure required to create
> > > platform devices for ARM SMMUs.
> > >
> > > ARM SMMU versions have different resources requirement therefore this
> > > patch also introduces an IORT specific structure (ie iort_iommu_config)
> > > that contains hooks (to be defined when the corresponding ARM SMMU
> > > driver support is added to the kernel) to be used to define the
> > > platform devices names, init the IOMMUs, count their resources and
> > > finally initialize them.
> > >
> > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > > Cc: Hanjun Guo <hanjun.guo@linaro.org>
> > > Cc: Tomasz Nowicki <tn@semihalf.com>
> > > Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> > > ---
> > > drivers/acpi/arm64/iort.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++
> > > 1 file changed, 151 insertions(+)
> > >
> > > diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> > > index 1433de3..2eda2f5 100644
> > > --- a/drivers/acpi/arm64/iort.c
> > > +++ b/drivers/acpi/arm64/iort.c
> > > @@ -19,9 +19,11 @@
> > > #define pr_fmt(fmt) "ACPI: IORT: " fmt
> > >
> > > #include <linux/acpi_iort.h>
> > > +#include <linux/iommu.h>
> > > #include <linux/kernel.h>
> > > #include <linux/list.h>
> > > #include <linux/pci.h>
> > > +#include <linux/platform_device.h>
> > > #include <linux/slab.h>
> > >
> > > struct iort_its_msi_chip {
> > > @@ -457,6 +459,153 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
> > > return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
> > > }
> > >
> > > +struct iort_iommu_config {
> > > + const char *name;
> > > + int (*iommu_init)(struct acpi_iort_node *node);
> > > + bool (*iommu_is_coherent)(struct acpi_iort_node *node);
> > > + int (*iommu_count_resources)(struct acpi_iort_node *node);
> > > + void (*iommu_init_resources)(struct resource *res,
> > > + struct acpi_iort_node *node);
> > > +};
> > > +
> > > +static __init
> > > +const struct iort_iommu_config *iort_get_iommu_cfg(struct acpi_iort_node *node)
> > > +{
> > > + return NULL;
> > > +}
> > > +
> > > +/**
> > > + * iort_add_smmu_platform_device() - Allocate a platform device for SMMU
> > > + * @node: Pointer to SMMU ACPI IORT node
> > > + *
> > > + * Returns: 0 on success, <0 failure
> > > + */
> > > +static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node)
> > > +{
> > > + struct fwnode_handle *fwnode;
> > > + struct platform_device *pdev;
> > > + struct resource *r;
> > > + enum dev_dma_attr attr;
> > > + int ret, count;
> > > + const struct iort_iommu_config *ops = iort_get_iommu_cfg(node);
> > > +
> > > + if (!ops)
> > > + return -ENODEV;
> > > +
> > > + pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO);
> > > + if (!pdev)
> > > + return PTR_ERR(pdev);
> > > +
> > > + count = ops->iommu_count_resources(node);
> > > +
> > > + r = kcalloc(count, sizeof(*r), GFP_KERNEL);
> > > + if (!r) {
> > > + ret = -ENOMEM;
> > > + goto dev_put;
> > > + }
> > > +
> > > + ops->iommu_init_resources(r, node);
> > > +
> > > + ret = platform_device_add_resources(pdev, r, count);
> > > + /*
> > > + * Resources are duplicated in platform_device_add_resources,
> > > + * free their allocated memory
> > > + */
> > > + kfree(r);
> > > +
> > > + if (ret)
> > > + goto dev_put;
> > > +
> > > + /*
> > > + * Add a copy of IORT node pointer to platform_data to
> > > + * be used to retrieve IORT data information.
> > > + */
> > > + ret = platform_device_add_data(pdev, &node, sizeof(node));
> > > + if (ret)
> > > + goto dev_put;
> > > +
> > > + /*
> > > + * We expect the dma masks to be equivalent for
> > > + * all SMMUs set-ups
> > > + */
> > > + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
> > > +
> > > + fwnode = iort_get_fwnode(node);
> > > +
> > > + if (!fwnode) {
> > > + ret = -ENODEV;
> > > + goto dev_put;
> > > + }
> > > +
> > > + pdev->dev.fwnode = fwnode;
> > > +
> > > + attr = ops->iommu_is_coherent(node) ?
> > > + DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
> > > +
> > > + /* Configure DMA for the page table walker */
> > > + acpi_dma_configure(&pdev->dev, attr);
> > > +
> > > + ret = platform_device_add(pdev);
> > > + if (ret)
> > > + goto dma_deconfigure;
> > > +
> > > + return 0;
> > > +
> > > +dma_deconfigure:
> > > + acpi_dma_deconfigure(&pdev->dev);
> > > +dev_put:
> > > + platform_device_put(pdev);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static void __init iort_init_platform_devices(void)
> > > +{
> > > + struct acpi_iort_node *iort_node, *iort_end;
> > > + struct acpi_table_iort *iort;
> > > + struct fwnode_handle *fwnode;
> > > + int i, ret;
> > > +
> > > + /*
> > > + * iort_table and iort both point to the start of IORT table, but
> > > + * have different struct types
> > > + */
> > > + iort = (struct acpi_table_iort *)iort_table;
> > > +
> > > + /* Get the first IORT node */
> > > + iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
> > > + iort->node_offset);
> > > + iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
> > > + iort_table->length);
> > > +
> > > + for (i = 0; i < iort->node_count; i++) {
> > > + if (iort_node >= iort_end) {
> > > + pr_err("iort node pointer overflows, bad table\n");
> > > + return;
> > > + }
> > > +
> > > + if ((iort_node->type == ACPI_IORT_NODE_SMMU) ||
> > > + (iort_node->type == ACPI_IORT_NODE_SMMU_V3)) {
> > > +
> > > + fwnode = acpi_alloc_fwnode_static();
> > > + if (!fwnode)
> > > + return;
> > > +
> > > + iort_set_fwnode(iort_node, fwnode);
> > > +
> > > + ret = iort_add_smmu_platform_device(iort_node);
> > > + if (ret) {
> > > + iort_delete_fwnode(iort_node);
> > > + acpi_free_fwnode_static(fwnode);
> > > + return;
> > > + }
> > > + }
> > > +
> > > + iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
> > > + iort_node->length);
> > > + }
> > > +}
> > > +
> > > void __init acpi_iort_init(void)
> > > {
> > > acpi_status status;
> > > @@ -468,5 +617,7 @@ void __init acpi_iort_init(void)
> > > return;
> > > }
> > >
> >
> > Slipped through the cracks while rebasing v6, I should add code that
> > returns if no IORT table found here to prevent calling:
> >
> > iort_init_platform_devices()
> >
> > I will update the next version, it is just a heads-up for testers,
> > I can push an updated/fixed branch if needed.
> >
>
> I could do with the updated branch.
Done, please find it here, I will post a v7 this week with updates.
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git acpi/iort-smmu-v6
Lorenzo
^ permalink raw reply
* [PATCH V3 0/6] ARM64: Uprobe support added
From: Catalin Marinas @ 2016-11-07 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <e1593d0d-b63c-cc7b-fcee-753b5bd8f0de@redhat.com>
On Sat, Nov 05, 2016 at 11:01:31AM +0530, Pratyush Anand wrote:
> On Saturday 05 November 2016 12:16 AM, Catalin Marinas wrote:
> > On Fri, Nov 04, 2016 at 11:49:51AM -0600, Catalin Marinas wrote:
> > > On Wed, Nov 02, 2016 at 02:40:40PM +0530, Pratyush Anand wrote:
> > > > Pratyush Anand (6):
> > > > arm64: kprobe: protect/rename few definitions to be reused by uprobe
> > > > arm64: kgdb_step_brk_fn: ignore other's exception
> > > > arm64: Handle TRAP_TRACE for user mode as well
> > > > arm64: Handle TRAP_BRKPT for user mode as well
> > > > arm64: introduce mm context flag to keep 32 bit task information
> > > > arm64: Add uprobe support
> > >
> > > I queued the patches for 4.10. I will push them into -next sometime next
> > > week once I do some testing (I'm currently at the LPC).
> >
> > I spoke too soon. With these patches on top of 4.9-rc3, defconfig
> > together with FTRACE and UPROBE_EVENT enabled I get:
> >
> > In file included from /work/Linux/linux-2.6-aarch64/arch/arm64/kernel/probes/decode-insn.c:20:0:
> > /work/Linux/linux-2.6-aarch64/arch/arm64/include/asm/kprobes.h:52:5: error: conflicting types for 'kprobe_fault_handler'
> > int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
> > ^~~~~~~~~~~~~~~~~~~~
> > In file included from /work/Linux/linux-2.6-aarch64/arch/arm64/kernel/probes/decode-insn.c:17:0:
> > /work/Linux/linux-2.6-aarch64/include/linux/kprobes.h:398:90: note: previous definition of 'kprobe_fault_handler' was here
> > static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
> > ^
> > /work/Linux/linux-2.6-aarch64/scripts/Makefile.build:290: recipe for target 'arch/arm64/kernel/probes/decode-insn.o' failed
>
> Hummmm...CONFIG_KPROBE was defined in my setup and did not notice it :( . We
> need to remove #include <asm/kprobes.h> from
> /arch/arm64/kernel/probes/decode-insn.c.
> <asm/kprobes.h> is already included from <linux/kprobes.h> under #ifdef
> CONFIG_KPROBE.
>
> diff --git a/arch/arm64/kernel/probes/decode-insn.c
> b/arch/arm64/kernel/probes/decode-insn.c
> index 8a29d29..6bf6657 100644
> --- a/arch/arm64/kernel/probes/decode-insn.c
> +++ b/arch/arm64/kernel/probes/decode-insn.c
> @@ -17,7 +17,6 @@
> #include <linux/kprobes.h>
> #include <linux/module.h>
> #include <linux/kallsyms.h>
> -#include <asm/kprobes.h>
> #include <asm/insn.h>
> #include <asm/sections.h>
>
> So, do you want me to send V4 or a separate topup fixup patch. Please let me
> know, will do accordingly.
Just a separate patch on top of your series would do. Also please test
your series with CONFIG_KPROBE disabled and I assume this wasn't done
(just in case there is an interaction we were not aware of).
Thanks.
--
Catalin
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox