Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/5] Add support for legacy SCPI protocol
From: Sudeep Holla @ 2016-10-19 16:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7h1szc9vnp.fsf@baylibre.com>



On 19/10/16 16:59, Kevin Hilman wrote:
> Sudeep Holla <sudeep.holla@arm.com> writes:
>
>> On 19/10/16 13:51, Neil Armstrong wrote:
>>> This patchset aims to support the legacy SCPI firmware implementation that was
>>> delivered as early technology preview for the JUNO platform.
>>>
>>> Finally a stable, maintained and public implementation for the SCPI protocol
>>> has been upstreamed part of the JUNO support and it is the recommended way
>>> of implementing SCP communication on ARMv8 platforms.
>>>
>>> The Amlogic GXBB platform is using this legacy protocol, as the RK3368 & RK3399
>>> platforms. This patchset will only add support for Amlogic GXBB SoC.
>>>
>>> This patchset add support for the legacy protocol in the arm_scpi.c file,
>>> avoiding code duplication.
>>>
>>> This patchset is rebased against scpi-updates/for-next from [2] and with
>>> already merged patches [3], [4] and [5] and ommited in this patchset.
>>>
>>> Last RFC discution thread can be found at : https://lkml.org/lkml/2016/8/9/210
>>>
>>> Changes since v4 at : http://lkml.kernel.org/r/1475652814-30619-1-git-send-email-narmstrong at baylibre.com
>>>  - Removed legacy locking scheme
>>>  - Removed cmd copy back after token insert
>>>  - Various cleanups
>>>
>>> Changes since v3 at : http://lkml.kernel.org/r/1473262477-18045-1-git-send-email-narmstrong at baylibre.com
>>>  - Changed back author to Sudeep Holla for first patch
>>>  - Merged legacy functions to scpi_send_message, tx_prepare and handle_remote_message
>>>  - Added legacy locking scheme
>>>  - Merged back legacy_scpi_sensor_get_value into scpi_sensor_get_value
>>>  - Rebased on linux-next-20161004 with patchset [1]
>>>
>>> Changes since v2 at : http://lkml.kernel.org/r/1471952816-30877-1-git-send-email-narmstrong at baylibre.com
>>>  - Added command indirection table and use it in each commands
>>>  - Added bitmap for high priority commands
>>>  - Cleaned up legacy tx_prepare/handle_message to align to standard functions
>>>  - Dropped legacy_scpi_ops
>>>
>>> Changes since v1 at : http://lkml.kernel.org/r/1471515066-3626-1-git-send-email-narmstrong at baylibre.com
>>>  - Dropped vendor_send_message and rockchip vendor mechanism patches
>>>  - Merged alternate functions into main functions using is_legacy boolean
>>>  - Added DT match table to set is_legacy to true
>>>  - Kept alternate scpi_ops structure for legacy
>>>
>>> [1] http://lkml.kernel.org/r/1475595430-30075-1-git-send-email-narmstrong at baylibre.com
>>> [2] git.kernel.org/sudeep.holla/linux
>>> [3] scpi: Add cmd indirection table to prepare for legacy commands
>>> [4] scpi: grow MAX_DVFS_OPPS to 16 entries
>>> [5] dt-bindings: Add support for Amlogic GXBB SCPI Interface
>>>
>>> Neil Armstrong (5):
>>>   scpi: Add alternative legacy structures, functions and macros
>>>   scpi: Do not fail if get_capabilities is not implemented
>>>   scpi: Add support for Legacy match table for Amlogic GXBB SoC
>>>   ARM64: dts: meson-gxbb: Add SRAM node
>>>   ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes
>>>
>>>  arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi |  57 ++++++++
>>>  drivers/firmware/arm_scpi.c                 | 206 +++++++++++++++++++++++++---
>>>  2 files changed, 245 insertions(+), 18 deletions(-)
>>>
>>
>> Nice to see this diff stat from a whole new file legacy_scpi.c and 1000+
>> delta. Thanks for working on this. I have applied the first 3 patches in
>> this series with some subject/commit message changes to [1].
>
> Sudeep, will this be an immutable branch? (or could you put a tag at an
> immutable place on this branch?)  I'd like to include this in my amlogic
> integration branch for broader testing.
>

If you plan to test SCPI(which is enabled in defconfig), then you need
all the patches in the branch[1]. I will tag once I get a build success
from kbuild robot and I do some testing. In short, immutable tag = PR
tag IMO. The only thing I can drop from the list is DT bindings patch.

Let me know if you are fine using the same tag ? Or you can propose any
other alternative, I am fine by that too.

-- 
Regards,
Sudeep

[1] git.kernel.org/sudeep.holla/linux/h/scpi-updates/for-next

^ permalink raw reply

* [PATCH v5 1/2] MMC: meson: initial support for GX platforms
From: Kevin Hilman @ 2016-10-19 16:12 UTC (permalink / raw)
  To: linux-arm-kernel

Initial support for the SD/eMMC controller in the Amlogic S905/GX*
family of SoCs.

Signed-off-by: Kevin Hilman <khilman@baylibre.com>
---
Changes since v4: put DT documentation into a separate patch

 MAINTAINERS                 |   1 +
 drivers/mmc/host/Kconfig    |  10 +
 drivers/mmc/host/Makefile   |   1 +
 drivers/mmc/host/meson-gx.c | 853 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 865 insertions(+)
 create mode 100644 drivers/mmc/host/meson-gx.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1cd38a7e0064..73e8d64ec28c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1036,6 +1036,7 @@ F:	arch/arm/mach-meson/
 F:	arch/arm/boot/dts/meson*
 F:	arch/arm64/boot/dts/amlogic/
 F: 	drivers/pinctrl/meson/
+F:	drivers/mmc/host/meson*
 N:	meson
 
 ARM/Annapurna Labs ALPINE ARCHITECTURE
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 5274f503a39a..5cf7ebaf1e8b 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -322,6 +322,16 @@ config MMC_SDHCI_IPROC
 
 	  If unsure, say N.
 
+config MMC_MESON_GX
+	tristate "Amlogic S905/GX* SD/MMC Host Controller support"
+	depends on ARCH_MESON && MMC
+	help
+	  This selects support for the Amlogic SD/MMC Host Controller
+	  found on the S905/GX* family of SoCs.  This controller is
+	  MMC 5.1 compliant and supports SD, eMMC and SDIO interfaces.
+
+	  If you have a controller with this interface, say Y here.
+
 config MMC_MOXART
 	tristate "MOXART SD/MMC Host Controller support"
 	depends on ARCH_MOXART && MMC
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index e2bdaaf43184..1c4852999ae4 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
 obj-$(CONFIG_MMC_VUB300)	+= vub300.o
 obj-$(CONFIG_MMC_USHC)		+= ushc.o
 obj-$(CONFIG_MMC_WMT)		+= wmt-sdmmc.o
+obj-$(CONFIG_MMC_MESON_GX)	+= meson-gx.o
 obj-$(CONFIG_MMC_MOXART)	+= moxart-mmc.o
 obj-$(CONFIG_MMC_SUNXI)		+= sunxi-mmc.o
 obj-$(CONFIG_MMC_USDHI6ROL0)	+= usdhi6rol0.o
diff --git a/drivers/mmc/host/meson-gx.c b/drivers/mmc/host/meson-gx.c
new file mode 100644
index 000000000000..fd3c40322b2d
--- /dev/null
+++ b/drivers/mmc/host/meson-gx.c
@@ -0,0 +1,853 @@
+/*
+ * Amlogic SD/eMMC driver for the GX/S905 family SoCs
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Kevin Hilman <khilman@baylibre.com>
+ *
+ * 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.
+ *
+ * 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/>.
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/regulator/consumer.h>
+
+#define DRIVER_NAME "meson-gxbb-mmc"
+
+#define SD_EMMC_CLOCK 0x0
+#define   CLK_DIV_SHIFT 0
+#define   CLK_DIV_WIDTH 6
+#define   CLK_DIV_MASK 0x3f
+#define   CLK_DIV_MAX 63
+#define   CLK_SRC_SHIFT 6
+#define   CLK_SRC_WIDTH 2
+#define   CLK_SRC_MASK 0x3
+#define   CLK_SRC_XTAL 0   /* external crystal */
+#define   CLK_SRC_XTAL_RATE 24000000
+#define   CLK_SRC_PLL 1    /* FCLK_DIV2 */
+#define   CLK_SRC_PLL_RATE 1000000000
+#define   CLK_PHASE_SHIFT 8
+#define   CLK_PHASE_MASK 0x3
+#define   CLK_PHASE_0 0
+#define   CLK_PHASE_90 1
+#define   CLK_PHASE_180 2
+#define   CLK_PHASE_270 3
+#define   CLK_ALWAYS_ON BIT(24)
+
+#define SD_EMMC_DElAY 0x4
+#define SD_EMMC_ADJUST 0x8
+#define SD_EMMC_CALOUT 0x10
+#define SD_EMMC_START 0x40
+#define   START_DESC_INIT BIT(0)
+#define   START_DESC_BUSY BIT(1)
+#define   START_DESC_ADDR_SHIFT 2
+#define   START_DESC_ADDR_MASK (~0x3)
+
+#define SD_EMMC_CFG 0x44
+#define   CFG_BUS_WIDTH_SHIFT 0
+#define   CFG_BUS_WIDTH_MASK 0x3
+#define   CFG_BUS_WIDTH_1 0x0
+#define   CFG_BUS_WIDTH_4 0x1
+#define   CFG_BUS_WIDTH_8 0x2
+#define   CFG_DDR BIT(2)
+#define   CFG_BLK_LEN_SHIFT 4
+#define   CFG_BLK_LEN_MASK 0xf
+#define   CFG_RESP_TIMEOUT_SHIFT 8
+#define   CFG_RESP_TIMEOUT_MASK 0xf
+#define   CFG_RC_CC_SHIFT 12
+#define   CFG_RC_CC_MASK 0xf
+#define   CFG_STOP_CLOCK BIT(22)
+#define   CFG_CLK_ALWAYS_ON BIT(18)
+#define   CFG_AUTO_CLK BIT(23)
+
+#define SD_EMMC_STATUS 0x48
+#define   STATUS_BUSY BIT(31)
+
+#define SD_EMMC_IRQ_EN 0x4c
+#define   IRQ_EN_MASK 0x3fff
+#define   IRQ_RXD_ERR_SHIFT 0
+#define   IRQ_RXD_ERR_MASK 0xff
+#define   IRQ_TXD_ERR BIT(8)
+#define   IRQ_DESC_ERR BIT(9)
+#define   IRQ_RESP_ERR BIT(10)
+#define   IRQ_RESP_TIMEOUT BIT(11)
+#define   IRQ_DESC_TIMEOUT BIT(12)
+#define   IRQ_END_OF_CHAIN BIT(13)
+#define   IRQ_RESP_STATUS BIT(14)
+#define   IRQ_SDIO BIT(15)
+
+#define SD_EMMC_CMD_CFG 0x50
+#define SD_EMMC_CMD_ARG 0x54
+#define SD_EMMC_CMD_DAT 0x58
+#define SD_EMMC_CMD_RSP 0x5c
+#define SD_EMMC_CMD_RSP1 0x60
+#define SD_EMMC_CMD_RSP2 0x64
+#define SD_EMMC_CMD_RSP3 0x68
+
+#define SD_EMMC_RXD 0x94
+#define SD_EMMC_TXD 0x94
+#define SD_EMMC_LAST_REG SD_EMMC_TXD
+
+#define SD_EMMC_CFG_BLK_SIZE 512 /* internal buffer max: 512 bytes */
+#define SD_EMMC_CFG_RESP_TIMEOUT 256 /* in clock cycles */
+#define SD_EMMC_CFG_CMD_GAP 16 /* in clock cycles */
+#define MUX_CLK_NUM_PARENTS 2
+
+struct meson_host {
+	struct	device		*dev;
+	struct	mmc_host	*mmc;
+	struct	mmc_request	*mrq;
+	struct	mmc_command	*cmd;
+
+	spinlock_t lock;
+	void __iomem *regs;
+	int irq;
+	u32 ocr_mask;
+	struct clk *core_clk;
+	struct clk_mux mux;
+	struct clk *mux_clk;
+	struct clk *mux_parent[MUX_CLK_NUM_PARENTS];
+	unsigned long mux_parent_rate[MUX_CLK_NUM_PARENTS];
+
+	struct clk_divider cfg_div;
+	struct clk *cfg_div_clk;
+
+	unsigned int bounce_buf_size;
+	void *bounce_buf;
+	dma_addr_t bounce_dma_addr;
+
+	bool vqmmc_enabled;
+};
+
+struct sd_emmc_desc {
+	u32 cmd_cfg;
+	u32 cmd_arg;
+	u32 cmd_data;
+	u32 cmd_resp;
+};
+#define CMD_CFG_LENGTH_SHIFT 0
+#define CMD_CFG_LENGTH_MASK 0x1ff
+#define CMD_CFG_BLOCK_MODE BIT(9)
+#define CMD_CFG_R1B BIT(10)
+#define CMD_CFG_END_OF_CHAIN BIT(11)
+#define CMD_CFG_TIMEOUT_SHIFT 12
+#define CMD_CFG_TIMEOUT_MASK 0xf
+#define CMD_CFG_NO_RESP BIT(16)
+#define CMD_CFG_NO_CMD BIT(17)
+#define CMD_CFG_DATA_IO BIT(18)
+#define CMD_CFG_DATA_WR BIT(19)
+#define CMD_CFG_RESP_NOCRC BIT(20)
+#define CMD_CFG_RESP_128 BIT(21)
+#define CMD_CFG_RESP_NUM BIT(22)
+#define CMD_CFG_DATA_NUM BIT(23)
+#define CMD_CFG_CMD_INDEX_SHIFT 24
+#define CMD_CFG_CMD_INDEX_MASK 0x3f
+#define CMD_CFG_ERROR BIT(30)
+#define CMD_CFG_OWNER BIT(31)
+
+#define CMD_DATA_MASK (~0x3)
+#define CMD_DATA_BIG_ENDIAN BIT(1)
+#define CMD_DATA_SRAM BIT(0)
+#define CMD_RESP_MASK (~0x1)
+#define CMD_RESP_SRAM BIT(0)
+
+static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate)
+{
+	struct mmc_host *mmc = host->mmc;
+	int ret = 0;
+	u32 cfg;
+
+	if (clk_rate) {
+		if (WARN_ON(clk_rate > mmc->f_max))
+			clk_rate = mmc->f_max;
+		else if (WARN_ON(clk_rate < mmc->f_min))
+			clk_rate = mmc->f_min;
+	}
+
+	if (clk_rate == mmc->actual_clock)
+		return 0;
+
+	/* stop clock */
+	cfg = readl(host->regs + SD_EMMC_CFG);
+	if (!(cfg & CFG_STOP_CLOCK)) {
+		cfg |= CFG_STOP_CLOCK;
+		writel(cfg, host->regs + SD_EMMC_CFG);
+	}
+
+	dev_dbg(host->dev, "change clock rate %u -> %lu\n",
+		mmc->actual_clock, clk_rate);
+
+	if (clk_rate == 0) {
+		mmc->actual_clock = 0;
+		return 0;
+	}
+
+	ret = clk_set_rate(host->cfg_div_clk, clk_rate);
+	if (ret)
+		dev_warn(host->dev, "Unable to set cfg_div_clk to %lu. ret=%d\n",
+			 clk_rate, ret);
+	else if (clk_rate && clk_rate != clk_get_rate(host->cfg_div_clk))
+		dev_warn(host->dev, "divider requested rate %lu != actual rate %lu: ret=%d\n",
+			 clk_rate, clk_get_rate(host->cfg_div_clk), ret);
+	else
+		mmc->actual_clock = clk_rate;
+
+	/* (re)start clock, if non-zero */
+	if (!ret && clk_rate) {
+		cfg = readl(host->regs + SD_EMMC_CFG);
+		cfg &= ~CFG_STOP_CLOCK;
+		writel(cfg, host->regs + SD_EMMC_CFG);
+	}
+
+	return ret;
+}
+
+/*
+ * The SD/eMMC IP block has an internal mux and divider used for
+ * generating the MMC clock.  Use the clock framework to create and
+ * manage these clocks.
+ */
+static int meson_mmc_clk_init(struct meson_host *host)
+{
+	struct clk_init_data init;
+	char clk_name[32];
+	int i, ret = 0;
+	const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
+	unsigned int mux_parent_count = 0;
+	const char *clk_div_parents[1];
+	unsigned int f_min = UINT_MAX;
+	u32 clk_reg, cfg;
+
+	/* get the mux parents */
+	for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
+		char name[16];
+
+		snprintf(name, sizeof(name), "clkin%d", i);
+		host->mux_parent[i] = devm_clk_get(host->dev, name);
+		if (IS_ERR(host->mux_parent[i])) {
+			ret = PTR_ERR(host->mux_parent[i]);
+			if (PTR_ERR(host->mux_parent[i]) != -EPROBE_DEFER)
+				dev_err(host->dev, "Missing clock %s\n", name);
+			host->mux_parent[i] = NULL;
+			return ret;
+		}
+
+		host->mux_parent_rate[i] = clk_get_rate(host->mux_parent[i]);
+		mux_parent_names[i] = __clk_get_name(host->mux_parent[i]);
+		mux_parent_count++;
+		if (host->mux_parent_rate[i] < f_min)
+			f_min = host->mux_parent_rate[i];
+	}
+
+	/* cacluate f_min based on input clocks, and max divider value */
+	if (f_min != UINT_MAX)
+		f_min = DIV_ROUND_UP(CLK_SRC_XTAL_RATE, CLK_DIV_MAX);
+	else
+		f_min = 4000000;  /* default min: 400 MHz */
+	host->mmc->f_min = f_min;
+
+	/* create the mux */
+	snprintf(clk_name, sizeof(clk_name), "%s#mux", dev_name(host->dev));
+	init.name = clk_name;
+	init.ops = &clk_mux_ops;
+	init.flags = 0;
+	init.parent_names = mux_parent_names;
+	init.num_parents = mux_parent_count;
+
+	host->mux.reg = host->regs + SD_EMMC_CLOCK;
+	host->mux.shift = CLK_SRC_SHIFT;
+	host->mux.mask = CLK_SRC_MASK;
+	host->mux.flags = 0;
+	host->mux.table = NULL;
+	host->mux.hw.init = &init;
+
+	host->mux_clk = devm_clk_register(host->dev, &host->mux.hw);
+	if (WARN_ON(IS_ERR(host->mux_clk)))
+		return PTR_ERR(host->mux_clk);
+
+	/* create the divider */
+	snprintf(clk_name, sizeof(clk_name), "%s#div", dev_name(host->dev));
+	init.name = devm_kstrdup(host->dev, clk_name, GFP_KERNEL);
+	init.ops = &clk_divider_ops;
+	init.flags = CLK_SET_RATE_PARENT;
+	clk_div_parents[0] = __clk_get_name(host->mux_clk);
+	init.parent_names = clk_div_parents;
+	init.num_parents = ARRAY_SIZE(clk_div_parents);
+
+	host->cfg_div.reg = host->regs + SD_EMMC_CLOCK;
+	host->cfg_div.shift = CLK_DIV_SHIFT;
+	host->cfg_div.width = CLK_DIV_WIDTH;
+	host->cfg_div.hw.init = &init;
+	host->cfg_div.flags = CLK_DIVIDER_ONE_BASED |
+		CLK_DIVIDER_ROUND_CLOSEST | CLK_DIVIDER_ALLOW_ZERO;
+
+	host->cfg_div_clk = devm_clk_register(host->dev, &host->cfg_div.hw);
+	if (WARN_ON(PTR_ERR_OR_ZERO(host->cfg_div_clk)))
+		return PTR_ERR(host->cfg_div_clk);
+
+	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
+	clk_reg = 0;
+	clk_reg |= CLK_PHASE_180 << CLK_PHASE_SHIFT;
+	clk_reg |= CLK_SRC_XTAL << CLK_SRC_SHIFT;
+	clk_reg |= CLK_DIV_MAX << CLK_DIV_SHIFT;
+	clk_reg &= ~CLK_ALWAYS_ON;
+	writel(clk_reg, host->regs + SD_EMMC_CLOCK);
+
+	/* Ensure clock starts in "auto" mode, not "always on" */
+	cfg = readl(host->regs + SD_EMMC_CFG);
+	cfg &= ~CFG_CLK_ALWAYS_ON;
+	cfg |= CFG_AUTO_CLK;
+	writel(cfg, host->regs + SD_EMMC_CFG);
+
+	ret = clk_prepare_enable(host->cfg_div_clk);
+	if (!ret)
+		ret = meson_mmc_clk_set(host, f_min);
+
+	if (!ret)
+		clk_disable_unprepare(host->cfg_div_clk);
+
+	return ret;
+}
+
+static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct meson_host *host = mmc_priv(mmc);
+	u32 bus_width;
+	u32 val, orig;
+
+	/*
+	 * GPIO regulator, only controls switching between 1v8 and
+	 * 3v3, doesn't support MMC_POWER_OFF, MMC_POWER_ON.
+	 */
+	switch (ios->power_mode) {
+	case MMC_POWER_OFF:
+		if (!IS_ERR(mmc->supply.vmmc))
+			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
+
+		if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) {
+			regulator_disable(mmc->supply.vqmmc);
+			host->vqmmc_enabled = false;
+		}
+
+		break;
+
+	case MMC_POWER_UP:
+		if (!IS_ERR(mmc->supply.vmmc))
+			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
+		break;
+
+	case MMC_POWER_ON:
+		if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) {
+			int ret = regulator_enable(mmc->supply.vqmmc);
+
+			if (ret < 0)
+				dev_err(mmc_dev(mmc),
+					"failed to enable vqmmc regulator\n");
+			else
+				host->vqmmc_enabled = true;
+		}
+
+		break;
+	}
+
+
+	meson_mmc_clk_set(host, ios->clock);
+
+	/* Bus width */
+	val = readl(host->regs + SD_EMMC_CFG);
+	switch (ios->bus_width) {
+	case MMC_BUS_WIDTH_1:
+		bus_width = CFG_BUS_WIDTH_1;
+		break;
+	case MMC_BUS_WIDTH_4:
+		bus_width = CFG_BUS_WIDTH_4;
+		break;
+	case MMC_BUS_WIDTH_8:
+		bus_width = CFG_BUS_WIDTH_8;
+		break;
+	default:
+		dev_err(host->dev, "Invalid ios->bus_width: %u.  Setting to 4.\n",
+			ios->bus_width);
+		bus_width = CFG_BUS_WIDTH_4;
+		return;
+	}
+
+	val = readl(host->regs + SD_EMMC_CFG);
+	orig = val;
+
+	val &= ~(CFG_BUS_WIDTH_MASK << CFG_BUS_WIDTH_SHIFT);
+	val |= bus_width << CFG_BUS_WIDTH_SHIFT;
+
+	val &= ~(CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT);
+	val |= ilog2(SD_EMMC_CFG_BLK_SIZE) << CFG_BLK_LEN_SHIFT;
+
+	val &= ~(CFG_RESP_TIMEOUT_MASK << CFG_RESP_TIMEOUT_SHIFT);
+	val |= ilog2(SD_EMMC_CFG_RESP_TIMEOUT) << CFG_RESP_TIMEOUT_SHIFT;
+
+	val &= ~(CFG_RC_CC_MASK << CFG_RC_CC_SHIFT);
+	val |= ilog2(SD_EMMC_CFG_CMD_GAP) << CFG_RC_CC_SHIFT;
+
+	writel(val, host->regs + SD_EMMC_CFG);
+
+	if (val != orig)
+		dev_dbg(host->dev, "%s: SD_EMMC_CFG: 0x%08x -> 0x%08x\n",
+			__func__, orig, val);
+}
+
+static int meson_mmc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct meson_host *host = mmc_priv(mmc);
+
+	WARN_ON(host->mrq != mrq);
+
+	host->mrq = NULL;
+	host->cmd = NULL;
+	mmc_request_done(host->mmc, mrq);
+
+	return 0;
+}
+
+static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
+{
+	struct meson_host *host = mmc_priv(mmc);
+	struct sd_emmc_desc *desc, desc_tmp;
+	u32 cfg;
+	u8 blk_len, cmd_cfg_timeout;
+	unsigned int xfer_bytes = 0;
+
+	/* Setup descriptors */
+	dma_rmb();
+	desc = &desc_tmp;
+	memset(desc, 0, sizeof(struct sd_emmc_desc));
+
+	desc->cmd_cfg |= (cmd->opcode & CMD_CFG_CMD_INDEX_MASK)	<<
+		CMD_CFG_CMD_INDEX_SHIFT;
+	desc->cmd_cfg |= CMD_CFG_OWNER;  /* owned by CPU */
+	desc->cmd_arg = cmd->arg;
+
+	/* Response */
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		desc->cmd_cfg &= ~CMD_CFG_NO_RESP;
+		if (cmd->flags & MMC_RSP_136)
+			desc->cmd_cfg |= CMD_CFG_RESP_128;
+		desc->cmd_cfg |= CMD_CFG_RESP_NUM;
+		desc->cmd_resp = 0;
+
+		if (!(cmd->flags & MMC_RSP_CRC))
+			desc->cmd_cfg |= CMD_CFG_RESP_NOCRC;
+
+		if (cmd->flags & MMC_RSP_BUSY)
+			desc->cmd_cfg |= CMD_CFG_R1B;
+	} else {
+		desc->cmd_cfg |= CMD_CFG_NO_RESP;
+	}
+
+	/* data? */
+	if (cmd->data) {
+		desc->cmd_cfg |= CMD_CFG_DATA_IO;
+		if (cmd->data->blocks > 1) {
+			desc->cmd_cfg |= CMD_CFG_BLOCK_MODE;
+			desc->cmd_cfg |=
+				(cmd->data->blocks & CMD_CFG_LENGTH_MASK) <<
+				CMD_CFG_LENGTH_SHIFT;
+
+			/* check if block-size matches, if not update */
+			cfg = readl(host->regs + SD_EMMC_CFG);
+			blk_len = cfg & (CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT);
+			blk_len >>= CFG_BLK_LEN_SHIFT;
+			if (blk_len != ilog2(cmd->data->blksz)) {
+				dev_warn(host->dev, "%s: update blk_len %d -> %d\n",
+					__func__, blk_len,
+					 ilog2(cmd->data->blksz));
+				blk_len = ilog2(cmd->data->blksz);
+				cfg &= ~(CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT);
+				cfg |= blk_len << CFG_BLK_LEN_SHIFT;
+				writel(cfg, host->regs + SD_EMMC_CFG);
+			}
+		} else {
+			desc->cmd_cfg &= ~CMD_CFG_BLOCK_MODE;
+			desc->cmd_cfg |=
+				(cmd->data->blksz & CMD_CFG_LENGTH_MASK) <<
+				CMD_CFG_LENGTH_SHIFT;
+		}
+
+		cmd->data->bytes_xfered = 0;
+		xfer_bytes = cmd->data->blksz * cmd->data->blocks;
+		if (cmd->data->flags & MMC_DATA_WRITE) {
+			desc->cmd_cfg |= CMD_CFG_DATA_WR;
+			WARN_ON(xfer_bytes > host->bounce_buf_size);
+			sg_copy_to_buffer(cmd->data->sg, cmd->data->sg_len,
+					  host->bounce_buf, xfer_bytes);
+			cmd->data->bytes_xfered = xfer_bytes;
+			dma_wmb();
+		} else {
+			desc->cmd_cfg &= ~CMD_CFG_DATA_WR;
+		}
+
+		if (xfer_bytes > 0) {
+			desc->cmd_cfg &= ~CMD_CFG_DATA_NUM;
+			desc->cmd_data = host->bounce_dma_addr & CMD_DATA_MASK;
+		} else {
+			/* write data to data_addr */
+			desc->cmd_cfg |= CMD_CFG_DATA_NUM;
+			desc->cmd_data = 0;
+		}
+
+		cmd_cfg_timeout = 12;
+	} else {
+		desc->cmd_cfg &= ~CMD_CFG_DATA_IO;
+		cmd_cfg_timeout = 10;
+	}
+	desc->cmd_cfg |= (cmd_cfg_timeout & CMD_CFG_TIMEOUT_MASK) <<
+		CMD_CFG_TIMEOUT_SHIFT;
+
+	host->cmd = cmd;
+
+	/* Last descriptor */
+	desc->cmd_cfg |= CMD_CFG_END_OF_CHAIN;
+	writel(desc->cmd_cfg, host->regs + SD_EMMC_CMD_CFG);
+	writel(desc->cmd_data, host->regs + SD_EMMC_CMD_DAT);
+	writel(desc->cmd_resp, host->regs + SD_EMMC_CMD_RSP);
+	wmb(); /* ensure descriptor is written before kicked */
+	writel(desc->cmd_arg, host->regs + SD_EMMC_CMD_ARG);
+}
+
+static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct meson_host *host = mmc_priv(mmc);
+
+	WARN_ON(host->mrq != NULL);
+
+	/* Stop execution */
+	writel(0, host->regs + SD_EMMC_START);
+
+	/* clear, ack, enable all interrupts */
+	writel(0, host->regs + SD_EMMC_IRQ_EN);
+	writel(IRQ_EN_MASK, host->regs + SD_EMMC_STATUS);
+	writel(IRQ_EN_MASK, host->regs + SD_EMMC_IRQ_EN);
+
+	host->mrq = mrq;
+
+	if (mrq->sbc)
+		meson_mmc_start_cmd(mmc, mrq->sbc);
+	else
+		meson_mmc_start_cmd(mmc, mrq->cmd);
+}
+
+static int meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
+{
+	struct meson_host *host = mmc_priv(mmc);
+
+	if (cmd->flags & MMC_RSP_136) {
+		cmd->resp[0] = readl(host->regs + SD_EMMC_CMD_RSP3);
+		cmd->resp[1] = readl(host->regs + SD_EMMC_CMD_RSP2);
+		cmd->resp[2] = readl(host->regs + SD_EMMC_CMD_RSP1);
+		cmd->resp[3] = readl(host->regs + SD_EMMC_CMD_RSP);
+	} else if (cmd->flags & MMC_RSP_PRESENT) {
+		cmd->resp[0] = readl(host->regs + SD_EMMC_CMD_RSP);
+	}
+
+	return 0;
+}
+
+static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
+{
+	struct meson_host *host = dev_id;
+	struct mmc_request *mrq;
+	struct mmc_command *cmd = host->cmd;
+	u32 irq_en, status, raw_status;
+	irqreturn_t ret = IRQ_HANDLED;
+
+	if (WARN_ON(!host))
+		return IRQ_NONE;
+
+	mrq = host->mrq;
+
+	if (WARN_ON(!mrq))
+		return IRQ_NONE;
+
+	if (WARN_ON(!cmd))
+		return IRQ_NONE;
+
+	spin_lock(&host->lock);
+	irq_en = readl(host->regs + SD_EMMC_IRQ_EN);
+	raw_status = readl(host->regs + SD_EMMC_STATUS);
+	status = raw_status & irq_en;
+
+	if (!status) {
+		dev_warn(host->dev, "Spurious IRQ! status=0x%08x, irq_en=0x%08x\n",
+			 raw_status, irq_en);
+		ret = IRQ_NONE;
+		goto out;
+	}
+
+	cmd->error = 0;
+	if (status & IRQ_RXD_ERR_MASK) {
+		dev_dbg(host->dev, "Unhandled IRQ: RXD error\n");
+		cmd->error = -EILSEQ;
+	}
+	if (status & IRQ_TXD_ERR) {
+		dev_dbg(host->dev, "Unhandled IRQ: TXD error\n");
+		cmd->error = -EILSEQ;
+	}
+	if (status & IRQ_DESC_ERR)
+		dev_dbg(host->dev, "Unhandled IRQ: Descriptor error\n");
+	if (status & IRQ_RESP_ERR) {
+		dev_dbg(host->dev, "Unhandled IRQ: Response error\n");
+		cmd->error = -EILSEQ;
+	}
+	if (status & IRQ_RESP_TIMEOUT) {
+		dev_dbg(host->dev, "Unhandled IRQ: Response timeout\n");
+		cmd->error = -ETIMEDOUT;
+	}
+	if (status & IRQ_DESC_TIMEOUT) {
+		dev_dbg(host->dev, "Unhandled IRQ: Descriptor timeout\n");
+		cmd->error = -ETIMEDOUT;
+	}
+	if (status & IRQ_SDIO)
+		dev_dbg(host->dev, "Unhandled IRQ: SDIO.\n");
+
+	if (status & (IRQ_END_OF_CHAIN | IRQ_RESP_STATUS))
+		ret = IRQ_WAKE_THREAD;
+	else  {
+		dev_warn(host->dev, "Unknown IRQ! status=0x%04x: MMC CMD%u arg=0x%08x flags=0x%08x stop=%d\n",
+			 status, cmd->opcode, cmd->arg,
+			 cmd->flags, mrq->stop ? 1 : 0);
+		if (cmd->data) {
+			struct mmc_data *data = cmd->data;
+
+			dev_warn(host->dev, "\tblksz %u blocks %u flags 0x%08x (%s%s)",
+				 data->blksz, data->blocks, data->flags,
+				 data->flags & MMC_DATA_WRITE ? "write" : "",
+				 data->flags & MMC_DATA_READ ? "read" : "");
+		}
+	}
+
+out:
+	/* ack all (enabled) interrupts */
+	writel(status, host->regs + SD_EMMC_STATUS);
+
+	if (ret == IRQ_HANDLED) {
+		meson_mmc_read_resp(host->mmc, cmd);
+		meson_mmc_request_done(host->mmc, cmd->mrq);
+	}
+
+	spin_unlock(&host->lock);
+	return ret;
+}
+
+static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
+{
+	struct meson_host *host = dev_id;
+	struct mmc_request *mrq = host->mrq;
+	struct mmc_command *cmd = host->cmd;
+	struct mmc_data *data;
+	unsigned int xfer_bytes;
+	int ret = IRQ_HANDLED;
+
+	if (WARN_ON(!mrq))
+		ret = IRQ_NONE;
+
+	if (WARN_ON(!cmd))
+		ret = IRQ_NONE;
+
+	data = cmd->data;
+	if (data) {
+		xfer_bytes = data->blksz * data->blocks;
+		if (data->flags & MMC_DATA_READ) {
+			WARN_ON(xfer_bytes > host->bounce_buf_size);
+			sg_copy_from_buffer(data->sg, data->sg_len,
+					    host->bounce_buf, xfer_bytes);
+			data->bytes_xfered = xfer_bytes;
+		}
+	}
+
+	meson_mmc_read_resp(host->mmc, cmd);
+	if (!data || !data->stop || mrq->sbc)
+		meson_mmc_request_done(host->mmc, mrq);
+	else
+		meson_mmc_start_cmd(host->mmc, data->stop);
+
+	return ret;
+}
+
+/*
+ * NOTE: we only need this until the GPIO/pinctrl driver can handle
+ * interrupts.  For now, the MMC core will use this for polling.
+ */
+static int meson_mmc_get_cd(struct mmc_host *mmc)
+{
+	int status = mmc_gpio_get_cd(mmc);
+
+	if (status == -ENOSYS)
+		return 1; /* assume present */
+
+	return status;
+}
+
+static const struct mmc_host_ops meson_mmc_ops = {
+	.request	= meson_mmc_request,
+	.set_ios	= meson_mmc_set_ios,
+	.get_cd         = meson_mmc_get_cd,
+};
+
+static int meson_mmc_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct meson_host *host;
+	struct mmc_host *mmc;
+	int ret;
+
+	mmc = mmc_alloc_host(sizeof(struct meson_host), &pdev->dev);
+	if (!mmc)
+		return -ENOMEM;
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+	host->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, host);
+
+	spin_lock_init(&host->lock);
+
+	/* Get regulators and the supported OCR mask */
+	host->vqmmc_enabled = false;
+	ret = mmc_regulator_get_supply(mmc);
+	if (ret == -EPROBE_DEFER)
+		goto free_host;
+
+	ret = mmc_of_parse(mmc);
+	if (ret) {
+		dev_warn(&pdev->dev, "error parsing DT: %d\n", ret);
+		goto free_host;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	host->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(host->regs)) {
+		ret = PTR_ERR(host->regs);
+		goto free_host;
+	}
+
+	host->irq = platform_get_irq(pdev, 0);
+	if (host->irq == 0) {
+		dev_err(&pdev->dev, "failed to get interrupt resource.\n");
+		ret = -EINVAL;
+		goto free_host;
+	}
+
+	host->core_clk = devm_clk_get(&pdev->dev, "core");
+	if (IS_ERR(host->core_clk)) {
+		ret = PTR_ERR(host->core_clk);
+		goto free_host;
+	}
+
+	ret = clk_prepare_enable(host->core_clk);
+	if (ret)
+		goto free_host;
+
+	ret = meson_mmc_clk_init(host);
+	if (ret)
+		goto free_host;
+
+	/* Stop execution */
+	writel(0, host->regs + SD_EMMC_START);
+
+	/* clear, ack, enable all interrupts */
+	writel(0, host->regs + SD_EMMC_IRQ_EN);
+	writel(IRQ_EN_MASK, host->regs + SD_EMMC_STATUS);
+
+	ret = devm_request_threaded_irq(&pdev->dev, host->irq,
+					meson_mmc_irq, meson_mmc_irq_thread,
+					IRQF_SHARED, DRIVER_NAME, host);
+	if (ret)
+		goto free_host;
+
+	/* data bounce buffer */
+	host->bounce_buf_size = SZ_512K;
+	host->bounce_buf =
+		dma_alloc_coherent(host->dev, host->bounce_buf_size,
+				   &host->bounce_dma_addr, GFP_KERNEL);
+	if (host->bounce_buf == NULL) {
+		dev_err(host->dev, "Unable to map allocate DMA bounce buffer.\n");
+		ret = -ENOMEM;
+		goto free_host;
+	}
+
+	mmc->ops = &meson_mmc_ops;
+	mmc_add_host(mmc);
+
+	return 0;
+
+free_host:
+	clk_disable_unprepare(host->cfg_div_clk);
+	clk_disable_unprepare(host->core_clk);
+	mmc_free_host(mmc);
+	return ret;
+}
+
+static int meson_mmc_remove(struct platform_device *pdev)
+{
+	struct meson_host *host = dev_get_drvdata(&pdev->dev);
+
+	if (WARN_ON(!host))
+		return 0;
+
+	if (host->bounce_buf)
+		dma_free_coherent(host->dev, host->bounce_buf_size,
+				  host->bounce_buf, host->bounce_dma_addr);
+
+	clk_disable_unprepare(host->cfg_div_clk);
+	clk_disable_unprepare(host->core_clk);
+
+	mmc_free_host(host->mmc);
+	return 0;
+}
+
+static const struct of_device_id meson_mmc_of_match[] = {
+	{ .compatible = "amlogic,meson-gx-mmc", },
+	{ .compatible = "amlogic,meson-gxbb-mmc", },
+	{ .compatible = "amlogic,meson-gxl-mmc", },
+	{ .compatible = "amlogic,meson-gxm-mmc", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, meson_mmc_of_match);
+
+static struct platform_driver meson_mmc_driver = {
+	.probe		= meson_mmc_probe,
+	.remove		= meson_mmc_remove,
+	.driver		= {
+		.name = DRIVER_NAME,
+		.of_match_table = of_match_ptr(meson_mmc_of_match),
+	},
+};
+
+module_platform_driver(meson_mmc_driver);
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_DESCRIPTION("Amlogic S905/GXBB SD/eMMC driver");
+MODULE_AUTHOR("Kevin Hilman <khilman@baylibre.com>");
+MODULE_LICENSE("GPL v2");
+
-- 
2.9.3

^ permalink raw reply related

* [PATCH v5 2/2] Documentation: DT: MMC: meson-gx: new bindings doc
From: Kevin Hilman @ 2016-10-19 16:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019161205.28565-1-khilman@baylibre.com>

Signed-off-by: Kevin Hilman <khilman@baylibre.com>
---
 .../devicetree/bindings/mmc/amlogic,meson-gx.txt   | 33 ++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt

diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt
new file mode 100644
index 000000000000..a2fa9a1c26ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt
@@ -0,0 +1,33 @@
+Amlogic SD / eMMC controller for S905/GXBB family SoCs
+
+The MMC 5.1 compliant host controller on Amlogic provides the
+interface for SD, eMMC and SDIO devices.
+
+This file documents the properties in addition to those available in
+the MMC core bindings, documented by mmc.txt.
+
+Required properties:
+- compatible : contains one of:
+  - "amlogic,meson-gx-mmc"
+  - "amlogic,meson-gxbb-mmc"
+  - "amlogic,meson-gxl-mmc"
+  - "amlogic,meson-gxm-mmc"
+- clocks     : A list of phandle + clock-specifier pairs for the clocks listed in clock-names.
+- clock-names: Should contain the following:
+	"core" - Main peripheral bus clock
+	"clkin0" - Parent clock of internal mux
+	"clkin1" - Other parent clock of internal mux
+  The driver has an interal mux clock which switches between clkin0 and clkin1 depending on the
+  clock rate requested by the MMC core.
+
+Example:
+
+	sd_emmc_a: mmc at 70000 {
+        	compatible = "amlogic,meson-gxbb-mmc";
+		reg = <0x0 0x70000 0x0 0x2000>;
+                interrupts = < GIC_SPI 216 IRQ_TYPE_EDGE_RISING>;
+		clocks = <&clkc CLKID_SD_EMMC_A>, <&xtal>, <&clkc CLKID_FCLK_DIV2>;
+		clock-names = "core", "clkin0", "clkin1";
+		pinctrl-0 = <&emmc_pins>;
+	};
+
-- 
2.9.3

^ permalink raw reply related

* [PATCH v4] MMC: meson: initial support for GX platforms
From: Kevin Hilman @ 2016-10-19 16:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPDyKFps2QYq9N1erqDdCnmXJyUT60HLQDe8+gR7A571-F8NLg@mail.gmail.com>

Ulf Hansson <ulf.hansson@linaro.org> writes:

> On 18 October 2016 at 21:56, Kevin Hilman <khilman@baylibre.com> wrote:
>> Initial support for the SD/eMMC controller in the Amlogic S905/GX*
>> family of SoCs.
>>
>> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
>> ---
>> Changes from v3:
>> - better handling of clock error paths
>> - rename to meson-gx to reflect support for newer SoCs
>> - has now been tested with SDIO
>>
>>  .../devicetree/bindings/mmc/amlogic,meson-gxbb.txt |  33 +
>
> Just realize this. You should split the DT doc into a separate patch,
> such the DT maintainers can ack it.

OK, I separated out the binding and sent a v5.

> Otherwise this looks good to me!

Thanks for the review!

Kevin

^ permalink raw reply

* [PATCH v4] MMC: meson: initial support for GX platforms
From: Javier Martinez Canillas @ 2016-10-19 16:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018195605.21145-1-khilman@baylibre.com>

Hello Kevin,

On Tue, Oct 18, 2016 at 4:56 PM, Kevin Hilman <khilman@baylibre.com> wrote:
> Initial support for the SD/eMMC controller in the Amlogic S905/GX*
> family of SoCs.
>
> Signed-off-by: Kevin Hilman <khilman@baylibre.com>

[snip]

> +
> +MODULE_ALIAS("platform:" DRIVER_NAME);

Why is this module alias needed? I thought that the Amlogic was a
DT-only platform and so devices will always be registered from OF (and
the OF modalias used).

I've seen platform module aliases in other Meson drivers too (i.e:
meson-rng and meson-pwm), so the same question applies to those.

Best regards,
Javier

^ permalink raw reply

* [PATCH] mtd: nand: Add OX820 NAND Support
From: Boris Brezillon @ 2016-10-19 16:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019145523.6763-1-narmstrong@baylibre.com>

On Wed, 19 Oct 2016 16:55:23 +0200
Neil Armstrong <narmstrong@baylibre.com> wrote:

> Add NAND driver to support the Oxford Semiconductor OX820 NAND Controller.
> This is a simple memory mapped NAND controller with single chip select and
> software ECC.
> 
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  .../devicetree/bindings/mtd/oxnas-nand.txt         |  24 +++
>  drivers/mtd/nand/Kconfig                           |   5 +
>  drivers/mtd/nand/Makefile                          |   1 +
>  drivers/mtd/nand/oxnas_nand.c                      | 204 +++++++++++++++++++++
>  4 files changed, 234 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mtd/oxnas-nand.txt
>  create mode 100644 drivers/mtd/nand/oxnas_nand.c
> 
> Changes since RFC http://lkml.kernel.org/r/20161018090927.1990-1-narmstrong at baylibre.com :
>  - Avoid using chip->IO_ADDR*
>  - Use new DT structure
>  - Assign a chip for the subnode
>  - Use the nand_hw_control structure
>  - Cleanup probe
>  - Cleanup cmd_ctrl by using a context ctrl offset used in write_bytes
> 
> diff --git a/Documentation/devicetree/bindings/mtd/oxnas-nand.txt b/Documentation/devicetree/bindings/mtd/oxnas-nand.txt
> new file mode 100644
> index 0000000..83b684d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/oxnas-nand.txt
> @@ -0,0 +1,24 @@
> +* Oxford Semiconductor OXNAS NAND Controller
> +
> +Please refer to nand.txt for generic information regarding MTD NAND bindings.
> +
> +Required properties:
> + - compatible: "oxsemi,ox820-nand"
> + - reg: Base address and length for NAND mapped memory.
> +
> +Optional Properties:
> + - clocks: phandle to the NAND gate clock if needed.
> + - resets: phandle to the NAND reset control if needed.
> +
> +Example:
> +
> +nand: nand at 41000000 {
> +	compatible = "oxsemi,ox820-nand";
> +	reg = <0x41000000 0x100000>;
> +	nand-ecc-mode = "soft";
> +	clocks = <&stdclk CLK_820_NAND>;
> +	resets = <&reset RESET_NAND>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	status = "disabled";
> +};
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index 7b7a887..c023125 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -426,6 +426,11 @@ config MTD_NAND_ORION
>  	  No board specific support is done by this driver, each board
>  	  must advertise a platform_device for the driver to attach.
>  
> +config MTD_NAND_OXNAS
> +	tristate "NAND Flash support for Oxford Semiconductor SoC"
> +	help
> +	  This enables the NAND flash controller on Oxford Semiconductor SoCs.
> +
>  config MTD_NAND_FSL_ELBC
>  	tristate "NAND support for Freescale eLBC controllers"
>  	depends on FSL_SOC
> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> index cafde6f..05fc054 100644
> --- a/drivers/mtd/nand/Makefile
> +++ b/drivers/mtd/nand/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_MTD_NAND_TMIO)		+= tmio_nand.o
>  obj-$(CONFIG_MTD_NAND_PLATFORM)		+= plat_nand.o
>  obj-$(CONFIG_MTD_NAND_PASEMI)		+= pasemi_nand.o
>  obj-$(CONFIG_MTD_NAND_ORION)		+= orion_nand.o
> +obj-$(CONFIG_MTD_NAND_OXNAS)		+= oxnas_nand.o
>  obj-$(CONFIG_MTD_NAND_FSL_ELBC)		+= fsl_elbc_nand.o
>  obj-$(CONFIG_MTD_NAND_FSL_IFC)		+= fsl_ifc_nand.o
>  obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
> diff --git a/drivers/mtd/nand/oxnas_nand.c b/drivers/mtd/nand/oxnas_nand.c
> new file mode 100644
> index 0000000..a9fe1ac
> --- /dev/null
> +++ b/drivers/mtd/nand/oxnas_nand.c
> @@ -0,0 +1,204 @@
> +/*
> + * Oxford Semiconductor OXNAS NAND driver
> +
> + * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
> + * Heavily based on plat_nand.c :
> + * Author: Vitaly Wool <vitalywool@gmail.com>
> + * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
> + * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
> + *
> + * 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.
> + *
> + */
> +
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/nand.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/of.h>
> +
> +/* Nand commands */
> +#define OXNAS_NAND_CMD_ALE		BIT(18)
> +#define OXNAS_NAND_CMD_CLE		BIT(19)
> +
> +#define OXNAS_NAND_MAX_CHIPS	1
> +
> +struct oxnas_nand {

One last thing, please rename the struct: oxnas_nandc, oxnas_nand_ctrl
or oxnas_nand_controller. Pick the one you prefer or choose another
one, I don't care, as long as the name clearly shows that this is a NAND
controller and not the NAND chip.

> +	struct nand_hw_control base;
> +	void __iomem *io_base;
> +	struct clk *clk;
> +	struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS];
> +	unsigned long ctrl;
> +};

^ permalink raw reply

* Build failure with v4.9-rc1 and GCC trunk -- compiler weirdness
From: Will Deacon @ 2016-10-19 16:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CA+55aFx=ZX=7u07R6zJ7fSw=zSQNaYqVX7R3LQs4riiEf+uA=A@mail.gmail.com>

On Wed, Oct 19, 2016 at 09:01:33AM -0700, Linus Torvalds wrote:
> On Wed, Oct 19, 2016 at 8:56 AM, Markus Trippelsdorf
> <markus@trippelsdorf.de> wrote:
> > On 2016.10.19 at 08:55 -0700, Linus Torvalds wrote:
> >>
> >> Well, in the meantime we apparently have to live with it. Unless Will
> >> is using some unreleased gcc version that nobody else is using and we
> >> can just ignore it?
> >
> > Yes, he is using gcc-7 that is unreleased. (It will be released April
> > next year.)
> 
> Ahh, self-built? So it's not part of some experimental ARM distro
> setup and this will be annoying lots of people?

Our friendly compiler guys built it, but it's just a snapshot of trunk,
so it's all heading towards GCC 7.0. AFAIU, the problematic optimisation
is also a mid-end pass, so it would affect other architectures too.

> If so, still think that we could just get rid of the ____ilog2_NaN()
> thing as it's not _that_ important, but it's certainly not very
> high-priority. Will can do it in his tree too for testing, and it can
> remind people to get the gcc problem fixed.

I'm carrying the diff below, which fixes arm64 defconfig, but I'm worried
that we might be relying on this trick elsewhere. The arm __bad_cmpxchg
function, for example.

Will

--->8

diff --git a/include/linux/log2.h b/include/linux/log2.h
index fd7ff3d91e6a..9cf5ad69065d 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -16,12 +16,6 @@
 #include <linux/bitops.h>
 
 /*
- * deal with unrepresentable constant logarithms
- */
-extern __attribute__((const, noreturn))
-int ____ilog2_NaN(void);
-
-/*
  * non-constant log of base 2 calculators
  * - the arch may override these in asm/bitops.h if they can be implemented
  *   more efficiently than using fls() and fls64()
@@ -85,7 +79,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 #define ilog2(n)				\
 (						\
 	__builtin_constant_p(n) ? (		\
-		(n) < 1 ? ____ilog2_NaN() :	\
+		(n) < 1 ? 0 :			\
 		(n) & (1ULL << 63) ? 63 :	\
 		(n) & (1ULL << 62) ? 62 :	\
 		(n) & (1ULL << 61) ? 61 :	\
@@ -149,9 +143,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 		(n) & (1ULL <<  3) ?  3 :	\
 		(n) & (1ULL <<  2) ?  2 :	\
 		(n) & (1ULL <<  1) ?  1 :	\
-		(n) & (1ULL <<  0) ?  0 :	\
-		____ilog2_NaN()			\
-				   ) :		\
+		0) :				\
 	(sizeof(n) <= 4) ?			\
 	__ilog2_u32(n) :			\
 	__ilog2_u64(n)				\
@@ -194,7 +186,6 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
  * @n: parameter
  *
  * The first few values calculated by this routine:
- *  ob2(0) = 0
  *  ob2(1) = 0
  *  ob2(2) = 1
  *  ob2(3) = 2

^ permalink raw reply related

* exynos-drm: display manager fails to start without IOMMU problem
From: Tobias Jakobi @ 2016-10-19 16:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2173cc13-7c77-1a38-501d-2c0f522ff5d5@osg.samsung.com>

Hello Shuah,

just a short note that more misleading comments about default allocation
flags can be found in libdrm.

https://cgit.freedesktop.org/mesa/drm/tree/exynos/exynos_drm.c

See e.g. the comment for exynos_bo_create().

In my opinion, the whole approach to _set_ a bit to get non-contigious
memory is messed up. It would make more sense to me to set a bit to
request an additional property (here "being contiguous") of the memory.

Anyway, clearing up this situation is highly appreciated!

More comments below.

With best wishes,
Tobias



Shuah Khan wrote:
> Restarting the thread with a different subject line:
> 
> I haven't given up on this yet. I am still seeing the following failure:
> 
> Additional debug messages I added:
> [   15.287403] exynos_drm_gem_create_ioctl() 1
> [   15.287419] exynos_drm_gem_create() flags 1
> 
> [   15.311511] [drm:exynos_drm_framebuffer_init] *ERROR* Non-contiguous GEM memory is not supported.
> 
> Additional debug message I added:
> [   15.318981] [drm:exynos_user_fb_create] *ERROR* failed to initialize framebuffer
> 
> This is what happens:
> 
> 1. exynos_drm_gem_create_ioctl() gets called with EXYNOS_BO_NONCONTIG request
> 2. exynos_drm_gem_create(0 goes ahead and creates the GEM buffers
> 3. exynos_user_fb_create() tries to associate GEM to fb and fails during
>    check_fb_gem_memory_type()
> 
> At this point, there is no recovery and lightdm fails
> 
> xf86-video-armsoc/src/drmmode_exynos/drmmode_exynos.c assumes contiguous
> allocations are not supported in some exynos drm versions: The following
> commit introduced this change:
> 
> https://git.linaro.org/arm/xorg/driver/xf86-video-armsoc.git/commitdiff/3be1f6273441fe95dd442f44064387322e16b7e9
> 
> excerpts from the diff:-       if (create_gem->buf_type == ARMSOC_BO_SCANOUT)
> -               create_exynos.flags = EXYNOS_BO_CONTIG;
> -       else
> -               create_exynos.flags = EXYNOS_BO_NONCONTIG;
> +
> +       /* Contiguous allocations are not supported in some exynos drm versions.
> +        * When they are supported all allocations are effectively contiguous
> +        * anyway, so for simplicity we always request non contiguous buffers.
> +        */
> +       create_exynos.flags = EXYNOS_BO_NONCONTIG;
> 
> There might have been logic on exynos_drm that forced Contig when it coudn't
> support NONCONTIG. At least, that is what this comment suggests. This assumption
> doesn't appear to be a good one and not sure if this change was made to fix a bug.
> 
> After the IOMMU support, this assumption is no longer true. Hence, with IOMMU
> support, latest kernels have a mismatch with the installed xf86-video-armsoc
> 
> This is what I am running into. This leads to the following question:
> 
> 1. How do we ensure exynos_drm kernel changes don't break user-space
>    specifically xf86-video-armsoc
> 2. This seems to have gone undetected for a while. I see a change in
>    exynos_drm_gem_dumb_create() that is probably addressing this type
>    of breakage. Commit 122beea84bb90236b1ae545f08267af58591c21b adds
>    handling for IOMMU NONCONTIG case.
I don't think that this commit is related to the issue, since it is only
used for the generic dumb buffer ioctl, while armsoc is using an Exynos
specific ioctl.

So in particular you shouldn't see the issue with
xf86-video-modesetting. Might be worth trying that one out?


> 
> Anyway, I am interested in getting the exynos_drm kernel side code
> and xf86-video-armsoc in sync to resolve the issue.
> 
> Could you recommend a going forward plan?
> 
> I can submit a patch to xf86-video-armsoc. I am also looking ahead to
> see if we can avoid such breaks in the future by keeping kernel and
> xf86-video-armsoc in sync.
> 
> thanks,
> -- Shuah
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 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

* [arm:for-next 7/8] warning: (ARM && ..) selects GENERIC_CLOCKEVENTS_BROADCAST which has unmet direct dependencies (GENERIC_CLOCKEVENTS)
From: kbuild test robot @ 2016-10-19 16:35 UTC (permalink / raw)
  To: linux-arm-kernel

tree:   git://git.armlinux.org.uk/~rmk/linux-arm.git for-next
head:   4f3ebefbc0ed334491f0b7f1f0154b14c47c0774
commit: e085002c23dfb35705c630b975827a69ff9aceb6 [7/8] ARM: 8620/1: Kconfig: select GENERIC_CLOCKEVENTS_BROADCAST also on UP
config: arm-ebsa110_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
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
        git checkout e085002c23dfb35705c630b975827a69ff9aceb6
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All error/warnings (new ones prefixed by >>):

warning: (ARM && SOC_AM43XX && MIPS_CPS_CPUIDLE) selects GENERIC_CLOCKEVENTS_BROADCAST which has unmet direct dependencies (GENERIC_CLOCKEVENTS)
   kernel/time/tick-broadcast.c: In function 'tick_broadcast_start_periodic':
>> kernel/time/tick-broadcast.c:65:3: error: implicit declaration of function 'tick_setup_periodic' [-Werror=implicit-function-declaration]
      tick_setup_periodic(bc, 1);
      ^~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_check_broadcast_device':
>> kernel/time/tick-broadcast.c:74:13: error: dereferencing pointer to incomplete type 'struct clock_event_device'
     if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) ||
                ^~
>> kernel/time/tick-broadcast.c:74:26: error: 'CLOCK_EVT_FEAT_DUMMY' undeclared (first use in this function)
     if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) ||
                             ^~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c:74:26: note: each undeclared identifier is reported only once for each function it appears in
>> kernel/time/tick-broadcast.c:75:26: error: 'CLOCK_EVT_FEAT_PERCPU' undeclared (first use in this function)
         (newdev->features & CLOCK_EVT_FEAT_PERCPU) ||
                             ^~~~~~~~~~~~~~~~~~~~~
>> kernel/time/tick-broadcast.c:76:26: error: 'CLOCK_EVT_FEAT_C3STOP' undeclared (first use in this function)
         (newdev->features & CLOCK_EVT_FEAT_C3STOP))
                             ^~~~~~~~~~~~~~~~~~~~~
>> kernel/time/tick-broadcast.c:80:27: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
         !(newdev->features & CLOCK_EVT_FEAT_ONESHOT))
                              ^~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_install_broadcast_device':
>> kernel/time/tick-broadcast.c:99:2: error: implicit declaration of function 'clockevents_exchange_device' [-Werror=implicit-function-declaration]
     clockevents_exchange_device(cur, dev);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> kernel/time/tick-broadcast.c:101:24: error: 'clockevents_handle_noop' undeclared (first use in this function)
      cur->event_handler = clockevents_handle_noop;
                           ^~~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c:113:22: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
     if (dev->features & CLOCK_EVT_FEAT_ONESHOT)
                         ^~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_broadcast_update_freq':
>> kernel/time/tick-broadcast.c:131:9: error: implicit declaration of function '__clockevents_update_freq' [-Werror=implicit-function-declaration]
      ret = __clockevents_update_freq(dev, freq);
            ^~~~~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_device_setup_broadcast_func':
>> kernel/time/tick-broadcast.c:146:20: error: 'tick_broadcast' undeclared (first use in this function)
      dev->broadcast = tick_broadcast;
                       ^~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_device_uses_broadcast':
>> kernel/time/tick-broadcast.c:172:7: error: implicit declaration of function 'tick_device_is_functional' [-Werror=implicit-function-declaration]
     if (!tick_device_is_functional(dev)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~
>> kernel/time/tick-broadcast.c:173:24: error: 'tick_handle_periodic' undeclared (first use in this function)
      dev->event_handler = tick_handle_periodic;
                           ^~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c:186:25: error: 'CLOCK_EVT_FEAT_C3STOP' undeclared (first use in this function)
      if (!(dev->features & CLOCK_EVT_FEAT_C3STOP))
                            ^~~~~~~~~~~~~~~~~~~~~
>> kernel/time/tick-broadcast.c:219:5: error: implicit declaration of function 'clockevents_shutdown' [-Werror=implicit-function-declaration]
        clockevents_shutdown(bc);
        ^~~~~~~~~~~~~~~~~~~~
>> kernel/time/tick-broadcast.c:228:31: error: 'CLOCK_EVT_FEAT_HRTIMER' undeclared (first use in this function)
       if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER))
                                  ^~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_do_broadcast':
   kernel/time/tick-broadcast.c:284:28: error: 'CLOCK_EVT_FEAT_HRTIMER' undeclared (first use in this function)
      local = !(bc->features & CLOCK_EVT_FEAT_HRTIMER);
                               ^~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_handle_periodic_broadcast':
>> kernel/time/tick-broadcast.c:321:6: error: implicit declaration of function 'clockevent_state_shutdown' [-Werror=implicit-function-declaration]
     if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) {
         ^~~~~~~~~~~~~~~~~~~~~~~~~
>> kernel/time/tick-broadcast.c:328:6: error: implicit declaration of function 'clockevent_state_oneshot' [-Werror=implicit-function-declaration]
     if (clockevent_state_oneshot(dev)) {
         ^~~~~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/rcupdate.h:47:0,
                    from include/linux/idr.h:18,
                    from include/linux/kernfs.h:14,
                    from include/linux/sysfs.h:15,
                    from include/linux/kobject.h:21,
                    from include/linux/device.h:17,
                    from include/linux/node.h:17,
                    from include/linux/cpu.h:16,
                    from kernel/time/tick-broadcast.c:14:
>> kernel/time/tick-broadcast.c:329:45: error: 'tick_period' undeclared (first use in this function)
      ktime_t next = ktime_add(dev->next_event, tick_period);
                                                ^
   include/linux/ktime.h:64:39: note: in definition of macro 'ktime_add'
      ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
                                          ^~~
>> kernel/time/tick-broadcast.c:331:3: error: implicit declaration of function 'clockevents_program_event' [-Werror=implicit-function-declaration]
      clockevents_program_event(dev, next, true);
      ^~~~~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_broadcast_control':
   kernel/time/tick-broadcast.c:367:32: error: 'CLOCK_EVT_FEAT_C3STOP' undeclared (first use in this function)
     if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
                                   ^~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c:392:31: error: 'CLOCK_EVT_FEAT_HRTIMER' undeclared (first use in this function)
       if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER) &&
                                  ^~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_set_periodic_handler':
   kernel/time/tick-broadcast.c:433:24: error: 'tick_handle_periodic' undeclared (first use in this function)
      dev->event_handler = tick_handle_periodic;
                           ^~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_resume_broadcast':
>> kernel/time/tick-broadcast.c:502:3: error: implicit declaration of function 'clockevents_tick_resume' [-Werror=implicit-function-declaration]
      clockevents_tick_resume(bc);
      ^~~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function '__tick_broadcast_oneshot_control':
   kernel/time/tick-broadcast.c:988:29: error: 'CLOCK_EVT_FEAT_HRTIMER' undeclared (first use in this function)
     if (!bc || (bc->features & CLOCK_EVT_FEAT_HRTIMER))
                                ^~~~~~~~~~~~~~~~~~~~~~
   kernel/time/tick-broadcast.c: In function 'tick_check_broadcast_device':
>> kernel/time/tick-broadcast.c:84:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^
   cc1: some warnings being treated as errors

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 10679 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161020/f747e3dc/attachment.gz>

^ permalink raw reply

* [arm:for-next 7/8] warning: (ARM && ..) selects GENERIC_CLOCKEVENTS_BROADCAST which has unmet direct dependencies (GENERIC_CLOCKEVENTS)
From: Russell King - ARM Linux @ 2016-10-19 16:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201610200017.9XQc5RQ5%fengguang.wu@intel.com>

Patch dropped.

On Thu, Oct 20, 2016 at 12:35:22AM +0800, kbuild test robot wrote:
> tree:   git://git.armlinux.org.uk/~rmk/linux-arm.git for-next
> head:   4f3ebefbc0ed334491f0b7f1f0154b14c47c0774
> commit: e085002c23dfb35705c630b975827a69ff9aceb6 [7/8] ARM: 8620/1: Kconfig: select GENERIC_CLOCKEVENTS_BROADCAST also on UP
> config: arm-ebsa110_defconfig (attached as .config)
> compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
> 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
>         git checkout e085002c23dfb35705c630b975827a69ff9aceb6
>         # save the attached .config to linux build tree
>         make.cross ARCH=arm 
> 
> All error/warnings (new ones prefixed by >>):
> 
> warning: (ARM && SOC_AM43XX && MIPS_CPS_CPUIDLE) selects GENERIC_CLOCKEVENTS_BROADCAST which has unmet direct dependencies (GENERIC_CLOCKEVENTS)
>    kernel/time/tick-broadcast.c: In function 'tick_broadcast_start_periodic':
> >> kernel/time/tick-broadcast.c:65:3: error: implicit declaration of function 'tick_setup_periodic' [-Werror=implicit-function-declaration]
>       tick_setup_periodic(bc, 1);
>       ^~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_check_broadcast_device':
> >> kernel/time/tick-broadcast.c:74:13: error: dereferencing pointer to incomplete type 'struct clock_event_device'
>      if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) ||
>                 ^~
> >> kernel/time/tick-broadcast.c:74:26: error: 'CLOCK_EVT_FEAT_DUMMY' undeclared (first use in this function)
>      if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) ||
>                              ^~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c:74:26: note: each undeclared identifier is reported only once for each function it appears in
> >> kernel/time/tick-broadcast.c:75:26: error: 'CLOCK_EVT_FEAT_PERCPU' undeclared (first use in this function)
>          (newdev->features & CLOCK_EVT_FEAT_PERCPU) ||
>                              ^~~~~~~~~~~~~~~~~~~~~
> >> kernel/time/tick-broadcast.c:76:26: error: 'CLOCK_EVT_FEAT_C3STOP' undeclared (first use in this function)
>          (newdev->features & CLOCK_EVT_FEAT_C3STOP))
>                              ^~~~~~~~~~~~~~~~~~~~~
> >> kernel/time/tick-broadcast.c:80:27: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
>          !(newdev->features & CLOCK_EVT_FEAT_ONESHOT))
>                               ^~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_install_broadcast_device':
> >> kernel/time/tick-broadcast.c:99:2: error: implicit declaration of function 'clockevents_exchange_device' [-Werror=implicit-function-declaration]
>      clockevents_exchange_device(cur, dev);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
> >> kernel/time/tick-broadcast.c:101:24: error: 'clockevents_handle_noop' undeclared (first use in this function)
>       cur->event_handler = clockevents_handle_noop;
>                            ^~~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c:113:22: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
>      if (dev->features & CLOCK_EVT_FEAT_ONESHOT)
>                          ^~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_broadcast_update_freq':
> >> kernel/time/tick-broadcast.c:131:9: error: implicit declaration of function '__clockevents_update_freq' [-Werror=implicit-function-declaration]
>       ret = __clockevents_update_freq(dev, freq);
>             ^~~~~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_device_setup_broadcast_func':
> >> kernel/time/tick-broadcast.c:146:20: error: 'tick_broadcast' undeclared (first use in this function)
>       dev->broadcast = tick_broadcast;
>                        ^~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_device_uses_broadcast':
> >> kernel/time/tick-broadcast.c:172:7: error: implicit declaration of function 'tick_device_is_functional' [-Werror=implicit-function-declaration]
>      if (!tick_device_is_functional(dev)) {
>           ^~~~~~~~~~~~~~~~~~~~~~~~~
> >> kernel/time/tick-broadcast.c:173:24: error: 'tick_handle_periodic' undeclared (first use in this function)
>       dev->event_handler = tick_handle_periodic;
>                            ^~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c:186:25: error: 'CLOCK_EVT_FEAT_C3STOP' undeclared (first use in this function)
>       if (!(dev->features & CLOCK_EVT_FEAT_C3STOP))
>                             ^~~~~~~~~~~~~~~~~~~~~
> >> kernel/time/tick-broadcast.c:219:5: error: implicit declaration of function 'clockevents_shutdown' [-Werror=implicit-function-declaration]
>         clockevents_shutdown(bc);
>         ^~~~~~~~~~~~~~~~~~~~
> >> kernel/time/tick-broadcast.c:228:31: error: 'CLOCK_EVT_FEAT_HRTIMER' undeclared (first use in this function)
>        if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER))
>                                   ^~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_do_broadcast':
>    kernel/time/tick-broadcast.c:284:28: error: 'CLOCK_EVT_FEAT_HRTIMER' undeclared (first use in this function)
>       local = !(bc->features & CLOCK_EVT_FEAT_HRTIMER);
>                                ^~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_handle_periodic_broadcast':
> >> kernel/time/tick-broadcast.c:321:6: error: implicit declaration of function 'clockevent_state_shutdown' [-Werror=implicit-function-declaration]
>      if (clockevent_state_shutdown(tick_broadcast_device.evtdev)) {
>          ^~~~~~~~~~~~~~~~~~~~~~~~~
> >> kernel/time/tick-broadcast.c:328:6: error: implicit declaration of function 'clockevent_state_oneshot' [-Werror=implicit-function-declaration]
>      if (clockevent_state_oneshot(dev)) {
>          ^~~~~~~~~~~~~~~~~~~~~~~~
>    In file included from include/linux/rcupdate.h:47:0,
>                     from include/linux/idr.h:18,
>                     from include/linux/kernfs.h:14,
>                     from include/linux/sysfs.h:15,
>                     from include/linux/kobject.h:21,
>                     from include/linux/device.h:17,
>                     from include/linux/node.h:17,
>                     from include/linux/cpu.h:16,
>                     from kernel/time/tick-broadcast.c:14:
> >> kernel/time/tick-broadcast.c:329:45: error: 'tick_period' undeclared (first use in this function)
>       ktime_t next = ktime_add(dev->next_event, tick_period);
>                                                 ^
>    include/linux/ktime.h:64:39: note: in definition of macro 'ktime_add'
>       ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
>                                           ^~~
> >> kernel/time/tick-broadcast.c:331:3: error: implicit declaration of function 'clockevents_program_event' [-Werror=implicit-function-declaration]
>       clockevents_program_event(dev, next, true);
>       ^~~~~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_broadcast_control':
>    kernel/time/tick-broadcast.c:367:32: error: 'CLOCK_EVT_FEAT_C3STOP' undeclared (first use in this function)
>      if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
>                                    ^~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c:392:31: error: 'CLOCK_EVT_FEAT_HRTIMER' undeclared (first use in this function)
>        if (bc && !(bc->features & CLOCK_EVT_FEAT_HRTIMER) &&
>                                   ^~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_set_periodic_handler':
>    kernel/time/tick-broadcast.c:433:24: error: 'tick_handle_periodic' undeclared (first use in this function)
>       dev->event_handler = tick_handle_periodic;
>                            ^~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_resume_broadcast':
> >> kernel/time/tick-broadcast.c:502:3: error: implicit declaration of function 'clockevents_tick_resume' [-Werror=implicit-function-declaration]
>       clockevents_tick_resume(bc);
>       ^~~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function '__tick_broadcast_oneshot_control':
>    kernel/time/tick-broadcast.c:988:29: error: 'CLOCK_EVT_FEAT_HRTIMER' undeclared (first use in this function)
>      if (!bc || (bc->features & CLOCK_EVT_FEAT_HRTIMER))
>                                 ^~~~~~~~~~~~~~~~~~~~~~
>    kernel/time/tick-broadcast.c: In function 'tick_check_broadcast_device':
> >> kernel/time/tick-broadcast.c:84:1: warning: control reaches end of non-void function [-Wreturn-type]
>     }
>     ^
>    cc1: some warnings being treated as errors
> 
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation



-- 
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 v5 0/5] Add support for legacy SCPI protocol
From: Kevin Hilman @ 2016-10-19 16:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4aa21ebe-446e-6343-238c-515718cbb162@arm.com>

Sudeep Holla <sudeep.holla@arm.com> writes:

> On 19/10/16 16:59, Kevin Hilman wrote:

[...]

>>
>> Sudeep, will this be an immutable branch? (or could you put a tag at an
>> immutable place on this branch?)  I'd like to include this in my amlogic
>> integration branch for broader testing.
>>
>
> If you plan to test SCPI(which is enabled in defconfig), then you need
> all the patches in the branch[1]. I will tag once I get a build success
> from kbuild robot and I do some testing. In short, immutable tag = PR
> tag IMO. The only thing I can drop from the list is DT bindings patch.
>
> Let me know if you are fine using the same tag ? Or you can propose any
> other alternative, I am fine by that too.

I'm currently using your scpi-updates/for-next branch, so a tag at (or
near) there should be fine after you've validated it.

Thanks,

Kevin

^ permalink raw reply

* [PATCH 1/2] host: ehci-exynos: Convert to use the SET_SYSTEM_SLEEP_PM_OPS
From: Anand Moon @ 2016-10-19 16:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161009183933.GA15270@kozik-lap>

Hi Krzysztof,

On 10 October 2016 at 00:09, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> On Sun, Oct 09, 2016 at 11:57:59PM +0530, Anand Moon wrote:
>> hi Krzysztof,
>>
>> On 9 October 2016 at 22:57, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>> > On Sun, Oct 09, 2016 at 10:45:40PM +0530, Anand Moon wrote:
>> >> Hi Krzysztof,
>> >>
>> >> On 9 October 2016 at 22:04, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>> >> > On Sun, Oct 09, 2016 at 02:34:14PM +0000, Anand Moon wrote:
>> >> >> Move the ehci-exynos system PM callbacks within #ifdef CONFIG_PM_SLEEP
>> >> >> as to avoid them being build when not used. This also allows us to use the
>> >> >> SET_SYSTEM_SLEEP_PM_OPS macro which simplifies the code.
>> >> >>
>> >> >> Signed-off-by: Anand Moon <linux.amoon@gmail.com>
>> >> >> ---
>> >> >>  drivers/usb/host/ehci-exynos.c | 14 ++++++--------
>> >> >>  1 file changed, 6 insertions(+), 8 deletions(-)
>> >> >>
>> >> >> diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
>> >> >> index 42e5b66..1899900 100644
>> >> >> --- a/drivers/usb/host/ehci-exynos.c
>> >> >> +++ b/drivers/usb/host/ehci-exynos.c
>> >> >> @@ -251,7 +251,7 @@ static int exynos_ehci_remove(struct platform_device *pdev)
>> >> >>       return 0;
>> >> >>  }
>> >> >>
>> >> >> -#ifdef CONFIG_PM
>> >> >> +#ifdef CONFIG_PM_SLEEP
>> >> >
>> >> > Does not look like an equivalent change. How will it behave in a config
>> >> > with !SUSPEND && !HIBERNATE && PM?
>> >> >
>> >>
>> >> [snip]
>> >>
>> >> I just wanted to update suspend and resume callback to use
>> >> SET_SYSTEM_SLEEP_PM_OPS
>> >> as they are define under CONFIG_PM_SLEEP so I update above to avoid
>> >> compilation warning/error.
>> >
>> Apologize: for not understanding your question.
>>
>> > First of all you did not answer to my question, so let me rephrase into
>> > two:
>> > 1. Is the code equivalent?
>>
>> No CONFIG_PM and CONFIG_PM_SLEEP are different options.
>> But I could not disable CONFIG_PM_SLEEP option with either in exynos_defconfig
>
> So the code is not equivalent...

I might be wrong, below is the kconfig option for PM_SLEEP

 Symbol: PM_SLEEP [=y]
 Type  : boolean
    Defined at kernel/power/Kconfig
     Depends on: SUSPEND [=y] || HIBERNATE_CALLBACKS [=n]
     Selects: PM [=y]

So we cannot set CONFIG_PM_SLEEP=n and CONFIG_PM=y

I observed at many places were either CONFIG_PM or CONFIG_PM_SLEEP are used.

So I would like to use SIMPLE_DEV_PM_OPS macro to set struct
dev_pm_ops exynos_ohci_pm_ops to correct the code.

Best Regards
-Anand Moon

>
>>
>> CONFIG_PM_SLEEP=n or
>> # CONFIG_PM_SLEEP is not set
>>
>> > 2. What will be the output with !SUSPEND && !HIBERNATE && PM?
>>
>> #
>> # Power management options
>> #
>> # CONFIG_SUSPEND is not set
>> # CONFIG_HIBERNATION is not set
>> # CONFIG_PM is not set
>>
>> When CONFIG_SUSPEND and CONFIG_HIBERNATION are not set
>> CONFIG_PM is disabled and so is CONFIG_PM_SLEEP.
>
> In my config, the CONFIG_PM was enabled thus the code changes the
> functionality... Maybe this was intented but I really don't get it from
> the commit message or from your explanations here.
>
> Krzysztof

^ permalink raw reply

* [PATCH 00/10] mm: adjust get_user_pages* functions to explicitly pass FOLL_* flags
From: Dave Hansen @ 2016-10-19 16:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019090727.GE7517@dhcp22.suse.cz>

On 10/19/2016 02:07 AM, Michal Hocko wrote:
> On Wed 19-10-16 09:58:15, Lorenzo Stoakes wrote:
>> On Tue, Oct 18, 2016 at 05:30:50PM +0200, Michal Hocko wrote:
>>> I am wondering whether we can go further. E.g. it is not really clear to
>>> me whether we need an explicit FOLL_REMOTE when we can in fact check
>>> mm != current->mm and imply that. Maybe there are some contexts which
>>> wouldn't work, I haven't checked.
>>
>> This flag is set even when /proc/self/mem is used. I've not looked deeply into
>> this flag but perhaps accessing your own memory this way can be considered
>> 'remote' since you're not accessing it directly. On the other hand, perhaps this
>> is just mistaken in this case?
> 
> My understanding of the flag is quite limited as well. All I know it is
> related to protection keys and it is needed to bypass protection check.
> See arch_vma_access_permitted. See also 1b2ee1266ea6 ("mm/core: Do not
> enforce PKEY permissions on remote mm access").

Yeah, we need the flag to tell us when PKEYs should be applied or not.
The current task's PKRU (pkey rights register) should really only be
used to impact access to the task's memory, but has no bearing on how a
given task should access remote memory.

^ permalink raw reply

* [PATCH v2] arm64: defconfig: enable EEPROM_AT25 config option
From: Olof Johansson @ 2016-10-19 16:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5740014.mZjAIri61F@wuerfel>

On Wed, Oct 19, 2016 at 1:04 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday, October 18, 2016 3:23:26 PM CEST Scott Branden wrote:
>> I have be.config and le.config that allow you to switch the defconfig
>> between big and little endian.  Does this make sense to upstream to
>> arm/configs if you have accepted dram_0x00000000.config?
>
> Yes, they clearly fall into the same category, let's merge those as well.
>
>> Would you also accept this to arm64/configs?  We actually use
>> big and little endian on the same SoC more on arm64 platforms.  But, in
>> order to boot big endian we need to maintain this outside the kernel
>> right now.
>
> I'm in favor of that, but let's see what the arm64 maintainers think.

Single-line fragments aren't really all that valuable, IMHO. Flipping
just one option is trivial to do without fragments, or when they're
not simple Y/N flips (i.e. like the ram base).

Fragments are mostly useful when you need to flip several options
together to enable some set of functionality.


-Olof

^ permalink raw reply

* [PATCH 2/3] arm64: mm: Set PSTATE.PAN from the cpu_enable_pan() call
From: Will Deacon @ 2016-10-19 16:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476786468-2173-3-git-send-email-james.morse@arm.com>

On Tue, Oct 18, 2016 at 11:27:47AM +0100, James Morse wrote:
> Commit 338d4f49d6f7 ("arm64: kernel: Add support for Privileged Access
> Never") enabled PAN by enabling the 'SPAN' feature-bit in SCTLR_EL1.
> This means the PSTATE.PAN bit won't be set until the next return to the
> kernel from userspace. On a preemptible kernel we may schedule work that
> accesses userspace on a CPU before it has done this.
> 
> Now that cpufeature enable() calls are scheduled via stop_machine(), we
> can set PSTATE.PAN from the cpu_enable_pan() call.
> 
> Add WARN_ON_ONCE(in_interrupt()) to check the PSTATE value we updated
> is not immediately discarded.
> 
> Reported-by: Tony Thompson <anthony.thompson@arm.com>
> Reported-by: Vladimir Murzin <vladimir.murzin@arm.com>
> Signed-off-by: James Morse <james.morse@arm.com>
> 
> ---
> This patch depends on 'arm64: cpufeature: Schedule enable() calls instead
> of calling them via IPI', which doesn't apply to linux-stable versions
> before v4.8.
> 
>  arch/arm64/mm/fault.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 3e9ff9b0c78d..f942ab6cc206 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -29,7 +29,9 @@
>  #include <linux/sched.h>
>  #include <linux/highmem.h>
>  #include <linux/perf_event.h>
> +#include <linux/preempt.h>
>  
> +#include <asm/bug.h>
>  #include <asm/cpufeature.h>
>  #include <asm/exception.h>
>  #include <asm/debug-monitors.h>
> @@ -672,7 +674,14 @@ NOKPROBE_SYMBOL(do_debug_exception);
>  #ifdef CONFIG_ARM64_PAN
>  int cpu_enable_pan(void *__unused)
>  {
> +	/*
> +	 * We modify PSTATE. This won't work from irq context as the PSTATE
> +	 * is discared once we return from the exception.
> +	 */

I fixed the typo in the comment and queued these as fixes. Please take
care of stable once these are in mainline.

Will

^ permalink raw reply

* [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8
From: Abdulhamid, Harb @ 2016-10-19 16:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <496ddac3-a220-fd42-5ca1-3d0fb0238907@linaro.org>

On 10/18/2016 8:44 AM, Hanjun Guo wrote:
> Hi Tyler,
> 
> On 2016/10/8 5:31, Tyler Baicar wrote:
>> ARM APEI extension proposal added SEA (Synchrounous External
>> Abort) notification type for ARMv8.
>> Add a new GHES error source handling function for SEA. If an error
>> source's notification type is SEA, then this function can be registered
>> into the SEA exception handler. That way GHES will parse and report
>> SEA exceptions when they occur.
> 
> Does this SEA is replayed by the firmware (firmware first handling)
> or directly triggered by the hardware when error is happened?

Architecturally, an SEA must be synchronous and *precise*, so if you
take an SEA on a particular load instruction, firmware/hardware should
not be corrupting the context/state of the PE to allow software to
determine which thread/process encountered the abort.  GHES error status
block will be expose to software with information about the type,
severity, physical address impacted.

Generally the error status block is populated by firmware.  However, as
long as the above requirement is met, I don't think the spec precludes
error status block being populated by hardware.  Those details must be
completely transparent to software.

Finally, to answer your more specific question:  If the implementation
of firmware-first involves trapping the SEA in EL3 to do some firmware
first handling, firmware must maintain the context of the offending ELx,
generate an error record, and then "replay" the exception to normal
(non-secure) software at the appropriate vector base address.

Thanks,
Harb
-- 
-- 
Qualcomm Datacenter Technologies, Inc.
as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH] arm64: Enable HIBERNATION in defconfig
From: Catalin Marinas @ 2016-10-19 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds CONFIG_HIBERNATION to the arm64 defconfig.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---

Re-sent post 4.9-rc1 as it was missed during the merging window.

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index dab2cb0c1f1c..4fc5ae07b035 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -82,6 +82,7 @@ CONFIG_KEXEC=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_COMPAT=y
 CONFIG_CPU_IDLE=y
+CONFIG_HIBERNATION=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPUFREQ_DT=y

^ permalink raw reply related

* [PATCH -next] dmaengine: st_fdma: Fix the error return code in st_fdma_probe()
From: Vinod Koul @ 2016-10-19 17:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476883430-11970-1-git-send-email-weiyj.lk@gmail.com>

On Wed, Oct 19, 2016 at 01:23:50PM +0000, Wei Yongjun wrote:
> From: Wei Yongjun <weiyongjun1@huawei.com>
> 
> In case of error, the function st_slim_rproc_alloc() returns ERR_PTR()
> and never returns NULL. The NULL test in the return value check should
> be replaced with IS_ERR().
> 

Applied, thanks

-- 
~Vinod

^ permalink raw reply

* [PATCH 00/10] mm: adjust get_user_pages* functions to explicitly pass FOLL_* flags
From: Michal Hocko @ 2016-10-19 17:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5807A427.7010200@linux.intel.com>

On Wed 19-10-16 09:49:43, Dave Hansen wrote:
> On 10/19/2016 02:07 AM, Michal Hocko wrote:
> > On Wed 19-10-16 09:58:15, Lorenzo Stoakes wrote:
> >> On Tue, Oct 18, 2016 at 05:30:50PM +0200, Michal Hocko wrote:
> >>> I am wondering whether we can go further. E.g. it is not really clear to
> >>> me whether we need an explicit FOLL_REMOTE when we can in fact check
> >>> mm != current->mm and imply that. Maybe there are some contexts which
> >>> wouldn't work, I haven't checked.
> >>
> >> This flag is set even when /proc/self/mem is used. I've not looked deeply into
> >> this flag but perhaps accessing your own memory this way can be considered
> >> 'remote' since you're not accessing it directly. On the other hand, perhaps this
> >> is just mistaken in this case?
> > 
> > My understanding of the flag is quite limited as well. All I know it is
> > related to protection keys and it is needed to bypass protection check.
> > See arch_vma_access_permitted. See also 1b2ee1266ea6 ("mm/core: Do not
> > enforce PKEY permissions on remote mm access").
> 
> Yeah, we need the flag to tell us when PKEYs should be applied or not.
> The current task's PKRU (pkey rights register) should really only be
> used to impact access to the task's memory, but has no bearing on how a
> given task should access remote memory.

The question I had earlier was whether this has to be an explicit FOLL
flag used by g-u-p users or we can just use it internally when mm !=
current->mm

-- 
Michal Hocko
SUSE Labs

^ permalink raw reply

* [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8
From: Abdulhamid, Harb @ 2016-10-19 17:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <57c81498-78f1-8aac-01b1-b5445415d822@linaro.org>

On 10/18/2016 9:04 AM, Hanjun Guo wrote:
> On 2016/10/8 5:31, Tyler Baicar wrote:
>> ARM APEI extension proposal added SEA (Synchrounous External
>> Abort) notification type for ARMv8.
>> Add a new GHES error source handling function for SEA. If an error
>> source's notification type is SEA, then this function can be registered
>> into the SEA exception handler. That way GHES will parse and report
>> SEA exceptions when they occur.
>>
>> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
>> ---
>>  arch/arm64/Kconfig        |  1 +
>>  drivers/acpi/apei/Kconfig | 15 +++++++++
>>  drivers/acpi/apei/ghes.c  | 83
>> +++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 99 insertions(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b380c87..ae34349 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -53,6 +53,7 @@ config ARM64
>>      select HANDLE_DOMAIN_IRQ
>>      select HARDIRQS_SW_RESEND
>>      select HAVE_ACPI_APEI if (ACPI && EFI)
>> +    select HAVE_ACPI_APEI_SEA if (ACPI && EFI)
>>      select HAVE_ALIGNED_STRUCT_PAGE if SLUB
>>      select HAVE_ARCH_AUDITSYSCALL
>>      select HAVE_ARCH_BITREVERSE
>> diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
>> index b0140c8..fb99c1c 100644
>> --- a/drivers/acpi/apei/Kconfig
>> +++ b/drivers/acpi/apei/Kconfig
>> @@ -4,6 +4,21 @@ config HAVE_ACPI_APEI
>>  config HAVE_ACPI_APEI_NMI
>>      bool
>>
>> +config HAVE_ACPI_APEI_SEA
>> +    bool "APEI Synchronous External Abort logging/recovering support"
>> +    depends on ARM64
>> +    help
>> +      This option should be enabled if the system supports
>> +      firmware first handling of SEA (Synchronous External Abort).
>> +      SEA happens with certain faults of data abort or instruction
>> +      abort synchronous exceptions on ARMv8 systems. If a system
>> +      supports firmware first handling of SEA, the platform analyzes
>> +      and handles hardware error notifications with SEA, and it may then
>> +      form a HW error record for the OS to parse and handle. This
>> +      option allows the OS to look for such HW error record, and
>> +      take appropriate action.
> 
> OK, I can see that it's firmware first handling, so it's triggered
> by firmware to me, correct me if I'm wrong.

Not exactly... the exception itself is *initially* triggered by the
processor itself (e.g. ECC error on a particular load causes a data
abort), but then may be intercepted by firmware (e.g. EL3) to generate
the error record and then be *replayed* back to software (e.g. jump to
appropriate EL and vector that originally caused the exception).

The reason we use the term "platform" here is because platform can be
hardware/firmware, and this can be implemented in different ways
depending on the preference of the platform vendor.  This is consistent
with the language in the UEFI/ACPI spec when describing the "thing" that
is not normal software (i.e. OS/Hypervisor).

> 
> [...]
>>  #ifdef CONFIG_HAVE_ACPI_APEI_NMI
>>  /*
>>   * printk is not safe in NMI context.  So in NMI handler, we allocate
>> @@ -1023,6 +1083,14 @@ static int ghes_probe(struct platform_device
>> *ghes_dev)
>>      case ACPI_HEST_NOTIFY_EXTERNAL:
>>      case ACPI_HEST_NOTIFY_SCI:
>>          break;
>> +    case ACPI_HEST_NOTIFY_SEA:
>> +        if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_SEA)) {
>> +            pr_warn(GHES_PFX "Generic hardware error source: %d
>> notified via SEA is not supported\n",
>> +                generic->header.source_id);
>> +            rc = -ENOTSUPP;
>> +            goto err;
>> +        }
>> +        break;
>>      case ACPI_HEST_NOTIFY_NMI:
>>          if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_NMI)) {
>>              pr_warn(GHES_PFX "Generic hardware error source: %d
>> notified via NMI interrupt is not supported!\n",
>> @@ -1034,6 +1102,13 @@ static int ghes_probe(struct platform_device
>> *ghes_dev)
>>          pr_warning(GHES_PFX "Generic hardware error source: %d
>> notified via local interrupt is not supported!\n",
>>                 generic->header.source_id);
>>          goto err;
>> +    case ACPI_HEST_NOTIFY_GPIO:
>> +    case ACPI_HEST_NOTIFY_SEI:
>> +    case ACPI_HEST_NOTIFY_GSIV:
>> +        pr_warn(GHES_PFX "Generic hardware error source: %d notified
>> via notification type %u is not supported\n",
>> +            generic->header.source_id, generic->header.source_id);
> 
> Hmm, some platform may trigger a interrupt to OS for firmware handling
> and it's in the ACPI 6.1 spec, is it a limitation now, or we need to
> add code later to support it?

On the current platforms we know of, we only leverage "emulated SCI",
which essentially maps to a GPIO interrupt (via ACPI event - mapped to
particular GPIO).  We will need to add support for other options
available in the spec (e.g. GSIV and SEI) later as platforms that use
those notification types become available.

Thanks,
--Harb
-- 
Qualcomm Datacenter Technologies, Inc.
as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH 00/10] mm: adjust get_user_pages* functions to explicitly pass FOLL_* flags
From: Dave Hansen @ 2016-10-19 17:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019170127.GN24393@dhcp22.suse.cz>

On 10/19/2016 10:01 AM, Michal Hocko wrote:
> The question I had earlier was whether this has to be an explicit FOLL
> flag used by g-u-p users or we can just use it internally when mm !=
> current->mm

The reason I chose not to do that was that deferred work gets run under
a basically random 'current'.  If we just use 'mm != current->mm', then
the deferred work will sometimes have pkeys enforced and sometimes not,
basically randomly.

We want to be consistent with whether they are enforced or not, so we
explicitly indicate that by calling the remote variant vs. plain.

^ permalink raw reply

* [PATCH 1/2] host: ehci-exynos: Convert to use the SET_SYSTEM_SLEEP_PM_OPS
From: Alan Stern @ 2016-10-19 17:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CANAwSgTXo_=buNVnD+UjxYXo=bHbptGj+ZXivBiQA6LK+ZjNLg@mail.gmail.com>

On Wed, 19 Oct 2016, Anand Moon wrote:

> I might be wrong, below is the kconfig option for PM_SLEEP
> 
>  Symbol: PM_SLEEP [=y]
>  Type  : boolean
>     Defined at kernel/power/Kconfig
>      Depends on: SUSPEND [=y] || HIBERNATE_CALLBACKS [=n]
>      Selects: PM [=y]
> 
> So we cannot set CONFIG_PM_SLEEP=n and CONFIG_PM=y

You have it backward.  We cannot set CONFIG_PM_SLEEP=y and CONFIG_PM=n.
But you can have CONFIG_PM_SLEEP=n and CONFIG_PM=y.

Alan Stern

> I observed at many places were either CONFIG_PM or CONFIG_PM_SLEEP are used.
> 
> So I would like to use SIMPLE_DEV_PM_OPS macro to set struct
> dev_pm_ops exynos_ohci_pm_ops to correct the code.
> 
> Best Regards
> -Anand Moon
> 
> >
> >>
> >> CONFIG_PM_SLEEP=n or
> >> # CONFIG_PM_SLEEP is not set
> >>
> >> > 2. What will be the output with !SUSPEND && !HIBERNATE && PM?
> >>
> >> #
> >> # Power management options
> >> #
> >> # CONFIG_SUSPEND is not set
> >> # CONFIG_HIBERNATION is not set
> >> # CONFIG_PM is not set
> >>
> >> When CONFIG_SUSPEND and CONFIG_HIBERNATION are not set
> >> CONFIG_PM is disabled and so is CONFIG_PM_SLEEP.
> >
> > In my config, the CONFIG_PM was enabled thus the code changes the
> > functionality... Maybe this was intented but I really don't get it from
> > the commit message or from your explanations here.
> >
> > Krzysztof
> 
> 

^ permalink raw reply

* [PATCH/RESEND] clocksource/arm_arch_timer: Map frame with of_io_request_and_map()
From: Stephen Boyd @ 2016-10-19 17:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5807255A.8060906@arm.com>

On 10/19, Marc Zyngier wrote:
> On 19/10/16 00:45, Stephen Boyd wrote:
> > Let's use the of_io_request_and_map() API so that the frame
> > region is protected and shows up in /proc/iomem.
> > 
> > Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> > ---
> >  drivers/clocksource/arm_arch_timer.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> > index 73c487da6d2a..cbfa3bc5be75 100644
> > --- a/drivers/clocksource/arm_arch_timer.c
> > +++ b/drivers/clocksource/arm_arch_timer.c
> > @@ -964,7 +964,8 @@ static int __init arch_timer_mem_init(struct device_node *np)
> >  	}
> >  
> >  	ret= -ENXIO;
> > -	base = arch_counter_base = of_iomap(best_frame, 0);
> > +	base = arch_counter_base = of_io_request_and_map(best_frame, 0,
> > +							 "arch_mem_timer");
> >  	if (!base) {
> >  		pr_err("arch_timer: Can't map frame's registers\n");
> >  		goto out;
> > 
> 
> Careful here: of_io_request_and_map() returns an ERR_PTR() on failure,
> while of_iomap just returns NULL. You want to change the error handling
> if you're going down that road.
> 

Eek! I was clearing out my pending queue and this one is
especially old so perhaps that function signature changed. Or I
just fail at life. Anyway, thanks!

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH V5 00/10] dmaengine: qcom_hidma: add MSI interrupt support
From: Sinan Kaya @ 2016-10-19 17:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019133406.GO2467@localhost>

Hi Vinod,

On 10/19/2016 6:34 AM, Vinod Koul wrote:
> On Fri, Oct 07, 2016 at 01:25:05AM -0400, Sinan Kaya wrote:
>> The new version of the HW supports MSI interrupts instead of wired
>> interrupts. The MSI interrupts are especially useful for the guest machine
>> execution. The wired interrupts usually trap to the hypervisor and then are
>> relayed to the actual interrupt.
>>
>> The MSI interrupts can be directly fed into the interrupt controller.
>>
>> Adding a new OF compat string (qcom,hidma-1.1) and ACPI string (QCOM8062)
>> to distinguish newer HW from the older ones.
> 
> I was only able to apply 6 patches in this series. Which tree were these
> generated against?
> 
> Please rebase rest..
> 

I'll post V6 now with the remaining 4 patches. My tree is as follows. 
I'll also repost V2 of the "dmaengine: qcom_hidma: cleanup sysfs entries during remove"
patch with your suggestion.

b8faa2a dmaengine: qcom_hidma: add MSI support for interrupts
54043eb dmaengine: qcom_hidma: break completion processing on error
31c9e2c dmaengine: qcom_hidma: protect common data structures
252ef1f dmaengine: qcom_hidma: add a common API to setup the interrupt
4e6c5ce dmaengine: qcom_hidma: bring out interrupt cause
784851a dmaengine: qcom_hidma: make pending_tre_count atomic
098685b dmaengine: qcom_hidma: configure DMA and MSI for OF
79f97f0 of: irq: make of_msi_configure accessible from modules
81e9b3a Documentation: DT: qcom_hidma: correct spelling mistakes
c55ceac Documentation: DT: qcom_hidma: update binding for MSI
7f3470c dmaengine: qcom_hidma: cleanup sysfs entries during remove
78e5299 dmaengine: qcom_hidma: remove useless debugfs file removal
96633c0 ACPI: platform: setup MSI domain for ACPI based platform device
851aadc irqchip: gicv3-its: platform-msi: scan MADT to create platform msi domain
5a8622e irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare for ACPI
ca80550 ACPI: platform-msi: retrieve dev id from IORT
b631797 irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
1001354 Linux 4.9-rc1

Sinan


-- 
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH V6 00/10] dmaengine: qcom_hidma: add MSI interrupt support
From: Sinan Kaya @ 2016-10-19 17:51 UTC (permalink / raw)
  To: linux-arm-kernel

The new version of the HW supports MSI interrupts instead of wired
interrupts. The MSI interrupts are especially useful for the guest machine
execution. The wired interrupts usually trap to the hypervisor and then are
relayed to the actual interrupt.

The MSI interrupts can be directly fed into the interrupt controller.

Adding a new OF compat string (qcom,hidma-1.1) and ACPI string (QCOM8062)
to distinguish newer HW from the older ones.

v6:
* rebase 4.9 kernel

v5:
http://www.spinics.net/lists/arm-kernel/msg537014.html
* dmaengine: qcom_hidma: add MSI support for interrupts
** Return MSI interrupts before calling platform_msi_domain_free_irqs.
Also cleanup MSI interrupts on the error path.
** Free the legacy IRQ only if MSI is disabled
* add dmaengine: qcom_hidma: break completion processing on error
in order to break the completions if an error is observed while servicing
completed work.
* drop dmaengine: qcom_hidma: make error and success path common
as the success path assumes that we'll get the number of notifications for
the
jobs queued. This is not true under error conditions.
* simplify dmaengine: qcom_hidma: protect common data structures. We just
need to protect the TRE processed offset. It is the variable that keeps
track
of outstanding requests.

v4:
http://www.spinics.net/lists/devicetree/msg144563.html
* device tree binding update to refer to msi.txt

v3:
* day 0 fix for when ACPI is not compiled in
* https://www.spinics.net/lists/arm-kernel/msg532179.html

v2:
https://patchwork.kernel.org/patch/9326399/
* Documentation update for DT bindings
* Rebased to slave-next
* Dropped dmaengine: qcom_hidma: eliminate processed variables. Replaced it
  with dmaengine: qcom_hidma: protect common data structures

v1:
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/444167.html
* initial implementation

Sinan Kaya (10):
  Documentation: DT: qcom_hidma: update binding for MSI
  Documentation: DT: qcom_hidma: correct spelling mistakes
  of: irq: make of_msi_configure accessible from modules
  dmaengine: qcom_hidma: configure DMA and MSI for OF
  dmaengine: qcom_hidma: make pending_tre_count atomic
  dmaengine: qcom_hidma: bring out interrupt cause
  dmaengine: qcom_hidma: add a common API to setup the interrupt
  dmaengine: qcom_hidma: protect common data structures
  dmaengine: qcom_hidma: break completion processing on error
  dmaengine: qcom_hidma: add MSI support for interrupts

 .../devicetree/bindings/dma/qcom_hidma_mgmt.txt    |  12 +-
 drivers/dma/qcom/hidma.c                           | 143 +++++++++++++++++-
 drivers/dma/qcom/hidma.h                           |   6 +-
 drivers/dma/qcom/hidma_dbg.c                       |   3 +-
 drivers/dma/qcom/hidma_ll.c                        | 161 +++++++++++----------
 drivers/dma/qcom/hidma_mgmt.c                      |   9 +-
 drivers/of/irq.c                                   |   1 +
 7 files changed, 250 insertions(+), 85 deletions(-)

-- 
1.9.1

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox