Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [v4 06/11] drivers/peci: Add a PECI adapter driver for Aspeed AST24xx/AST25xx
From: Jae Hyun Yoo @ 2018-05-21 19:58 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds PECI adapter driver implementation for Aspeed
AST24xx/AST25xx SoCs.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
Reviewed-by: Haiyue Wang <haiyue.wang@linux.intel.com>
Reviewed-by: James Feist <james.feist@linux.intel.com>
Reviewed-by: Vernon Mauery <vernon.mauery@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Ryan Chen <ryan_chen@aspeedtech.com>
---
 drivers/peci/Kconfig       |  27 ++
 drivers/peci/Makefile      |   3 +
 drivers/peci/peci-aspeed.c | 496 +++++++++++++++++++++++++++++++++++++
 3 files changed, 526 insertions(+)
 create mode 100644 drivers/peci/peci-aspeed.c

diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
index 1fbc13f9e6c2..7285c53b0ca2 100644
--- a/drivers/peci/Kconfig
+++ b/drivers/peci/Kconfig
@@ -14,4 +14,31 @@ config PECI
 	  processors and chipset components to external monitoring or control
 	  devices.
 
+	  If you want PECI support, you should say Y here and also to the
+	  specific driver for your bus adapter(s) below.
+
+if PECI
+
+#
+# PECI hardware bus configuration
+#
+
+menu "PECI Hardware Bus support"
+
+config PECI_ASPEED
+	tristate "ASPEED PECI support"
+	select REGMAP_MMIO
+	depends on OF
+	depends on ARCH_ASPEED || COMPILE_TEST
+	help
+	  Say Y here if you want support for the Platform Environment Control
+	  Interface (PECI) bus adapter driver on the ASPEED SoCs.
+
+	  This support is also available as a module.  If so, the module
+	  will be called peci-aspeed.
+
+endmenu
+
+endif # PECI
+
 endmenu
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index 9e8615e0d3ff..886285e69765 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -4,3 +4,6 @@
 
 # Core functionality
 obj-$(CONFIG_PECI)		+= peci-core.o
+
+# Hardware specific bus drivers
+obj-$(CONFIG_PECI_ASPEED)	+= peci-aspeed.o
diff --git a/drivers/peci/peci-aspeed.c b/drivers/peci/peci-aspeed.c
new file mode 100644
index 000000000000..2cd737a74839
--- /dev/null
+++ b/drivers/peci/peci-aspeed.c
@@ -0,0 +1,496 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2012-2017 ASPEED Technology Inc.
+// Copyright (c) 2018 Intel Corporation
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/peci.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+/* ASPEED PECI Registers */
+#define ASPEED_PECI_CTRL     0x00
+#define ASPEED_PECI_TIMING   0x04
+#define ASPEED_PECI_CMD      0x08
+#define ASPEED_PECI_CMD_CTRL 0x0c
+#define ASPEED_PECI_EXP_FCS  0x10
+#define ASPEED_PECI_CAP_FCS  0x14
+#define ASPEED_PECI_INT_CTRL 0x18
+#define ASPEED_PECI_INT_STS  0x1c
+#define ASPEED_PECI_W_DATA0  0x20
+#define ASPEED_PECI_W_DATA1  0x24
+#define ASPEED_PECI_W_DATA2  0x28
+#define ASPEED_PECI_W_DATA3  0x2c
+#define ASPEED_PECI_R_DATA0  0x30
+#define ASPEED_PECI_R_DATA1  0x34
+#define ASPEED_PECI_R_DATA2  0x38
+#define ASPEED_PECI_R_DATA3  0x3c
+#define ASPEED_PECI_W_DATA4  0x40
+#define ASPEED_PECI_W_DATA5  0x44
+#define ASPEED_PECI_W_DATA6  0x48
+#define ASPEED_PECI_W_DATA7  0x4c
+#define ASPEED_PECI_R_DATA4  0x50
+#define ASPEED_PECI_R_DATA5  0x54
+#define ASPEED_PECI_R_DATA6  0x58
+#define ASPEED_PECI_R_DATA7  0x5c
+
+/* ASPEED_PECI_CTRL - 0x00 : Control Register */
+#define PECI_CTRL_SAMPLING_MASK      GENMASK(19, 16)
+#define PECI_CTRL_READ_MODE_MASK     GENMASK(13, 12)
+#define PECI_CTRL_READ_MODE_COUNT    BIT(12)
+#define PECI_CTRL_READ_MODE_DBG      BIT(13)
+#define PECI_CTRL_CLK_SOURCE_MASK    BIT(11)
+#define PECI_CTRL_CLK_DIV_MASK       GENMASK(10, 8)
+#define PECI_CTRL_INVERT_OUT         BIT(7)
+#define PECI_CTRL_INVERT_IN          BIT(6)
+#define PECI_CTRL_BUS_CONTENT_EN     BIT(5)
+#define PECI_CTRL_PECI_EN            BIT(4)
+#define PECI_CTRL_PECI_CLK_EN        BIT(0)
+
+/* ASPEED_PECI_TIMING - 0x04 : Timing Negotiation Register */
+#define PECI_TIMING_MESSAGE_MASK     GENMASK(15, 8)
+#define PECI_TIMING_ADDRESS_MASK     GENMASK(7, 0)
+
+/* ASPEED_PECI_CMD - 0x08 : Command Register */
+#define PECI_CMD_PIN_MON             BIT(31)
+#define PECI_CMD_STS_MASK            GENMASK(27, 24)
+#define PECI_CMD_FIRE                BIT(0)
+
+/* ASPEED_PECI_LEN - 0x0C : Read/Write Length Register */
+#define PECI_AW_FCS_EN               BIT(31)
+#define PECI_READ_LEN_MASK           GENMASK(23, 16)
+#define PECI_WRITE_LEN_MASK          GENMASK(15, 8)
+#define PECI_TAGET_ADDR_MASK         GENMASK(7, 0)
+
+/* ASPEED_PECI_EXP_FCS - 0x10 : Expected FCS Data Register */
+#define PECI_EXPECT_READ_FCS_MASK    GENMASK(23, 16)
+#define PECI_EXPECT_AW_FCS_AUTO_MASK GENMASK(15, 8)
+#define PECI_EXPECT_WRITE_FCS_MASK   GENMASK(7, 0)
+
+/* ASPEED_PECI_CAP_FCS - 0x14 : Captured FCS Data Register */
+#define PECI_CAPTURE_READ_FCS_MASK   GENMASK(23, 16)
+#define PECI_CAPTURE_WRITE_FCS_MASK  GENMASK(7, 0)
+
+/* ASPEED_PECI_INT_CTRL/STS - 0x18/0x1c : Interrupt Register */
+#define PECI_INT_TIMING_RESULT_MASK  GENMASK(31, 30)
+#define PECI_INT_TIMEOUT             BIT(4)
+#define PECI_INT_CONNECT             BIT(3)
+#define PECI_INT_W_FCS_BAD           BIT(2)
+#define PECI_INT_W_FCS_ABORT         BIT(1)
+#define PECI_INT_CMD_DONE            BIT(0)
+
+#define PECI_INT_MASK  (PECI_INT_TIMEOUT | PECI_INT_CONNECT | \
+			PECI_INT_W_FCS_BAD | PECI_INT_W_FCS_ABORT | \
+			PECI_INT_CMD_DONE)
+
+#define PECI_IDLE_CHECK_TIMEOUT_USEC    50000
+#define PECI_IDLE_CHECK_INTERVAL_USEC   10000
+
+#define PECI_RD_SAMPLING_POINT_DEFAULT  8
+#define PECI_RD_SAMPLING_POINT_MAX      15
+#define PECI_CLK_DIV_DEFAULT            0
+#define PECI_CLK_DIV_MAX                7
+#define PECI_MSG_TIMING_DEFAULT         1
+#define PECI_MSG_TIMING_MAX             255
+#define PECI_ADDR_TIMING_DEFAULT        1
+#define PECI_ADDR_TIMING_MAX            255
+#define PECI_CMD_TIMEOUT_MS_DEFAULT     1000
+#define PECI_CMD_TIMEOUT_MS_MAX         60000
+
+struct aspeed_peci {
+	struct peci_adapter	*adapter;
+	struct device		*dev;
+	struct regmap		*regmap;
+	struct reset_control	*rst;
+	int			irq;
+	spinlock_t		lock; /* to sync completion status handling */
+	struct completion	xfer_complete;
+	u32			status;
+	u32			cmd_timeout_ms;
+};
+
+static int aspeed_peci_xfer_native(struct aspeed_peci *priv,
+				   struct peci_xfer_msg *msg)
+{
+	long err, timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
+	u32 peci_head, peci_state, rx_data, cmd_sts;
+	unsigned long flags;
+	int i, rc;
+	uint reg;
+
+	/* Check command sts and bus idle state */
+	rc = regmap_read_poll_timeout(priv->regmap, ASPEED_PECI_CMD, cmd_sts,
+		!(cmd_sts & (PECI_CMD_STS_MASK | PECI_CMD_PIN_MON)),
+		PECI_IDLE_CHECK_INTERVAL_USEC, PECI_IDLE_CHECK_TIMEOUT_USEC);
+	if (rc)
+		return rc; /* -ETIMEDOUT */
+
+	spin_lock_irqsave(&priv->lock, flags);
+	reinit_completion(&priv->xfer_complete);
+
+	peci_head = FIELD_PREP(PECI_TAGET_ADDR_MASK, msg->addr) |
+		    FIELD_PREP(PECI_WRITE_LEN_MASK, msg->tx_len) |
+		    FIELD_PREP(PECI_READ_LEN_MASK, msg->rx_len);
+
+	regmap_write(priv->regmap, ASPEED_PECI_CMD_CTRL, peci_head);
+
+	for (i = 0; i < msg->tx_len; i += 4) {
+		reg = i < 16 ? ASPEED_PECI_W_DATA0 + i % 16 :
+			       ASPEED_PECI_W_DATA4 + i % 16;
+		regmap_write(priv->regmap, reg,
+			     cpu_to_le32p((u32 *)&msg->tx_buf[i]));
+	}
+
+	dev_dbg(priv->dev, "HEAD : 0x%08x\n", peci_head);
+	print_hex_dump_debug("TX : ", DUMP_PREFIX_NONE, 16, 1,
+			     msg->tx_buf, msg->tx_len, true);
+
+	priv->status = 0;
+	regmap_write(priv->regmap, ASPEED_PECI_CMD, PECI_CMD_FIRE);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	err = wait_for_completion_interruptible_timeout(&priv->xfer_complete,
+							timeout);
+
+	spin_lock_irqsave(&priv->lock, flags);
+	dev_dbg(priv->dev, "INT_STS : 0x%08x\n", priv->status);
+	regmap_read(priv->regmap, ASPEED_PECI_CMD, &peci_state);
+	dev_dbg(priv->dev, "PECI_STATE : 0x%lx\n",
+		FIELD_GET(PECI_CMD_STS_MASK, peci_state));
+
+	regmap_write(priv->regmap, ASPEED_PECI_CMD, 0);
+
+	if (err <= 0 || priv->status != PECI_INT_CMD_DONE) {
+		if (err < 0) { /* -ERESTARTSYS */
+			rc = (int)err;
+			goto err_irqrestore;
+		} else if (err == 0) {
+			dev_dbg(priv->dev, "Timeout waiting for a response!\n");
+			rc = -ETIMEDOUT;
+			goto err_irqrestore;
+		}
+
+		dev_dbg(priv->dev, "No valid response!\n");
+		rc = -EIO;
+		goto err_irqrestore;
+	}
+
+	/**
+	 * Note that rx_len and rx_buf size can be an odd number.
+	 * Byte handling is more efficient.
+	 */
+	for (i = 0; i < msg->rx_len; i++) {
+		u8 byte_offset = i % 4;
+
+		if (byte_offset == 0) {
+			reg = i < 16 ? ASPEED_PECI_R_DATA0 + i % 16 :
+				       ASPEED_PECI_R_DATA4 + i % 16;
+			regmap_read(priv->regmap, reg, &rx_data);
+		}
+
+		msg->rx_buf[i] = (u8)(rx_data >> (byte_offset << 3));
+	}
+
+	print_hex_dump_debug("RX : ", DUMP_PREFIX_NONE, 16, 1,
+			     msg->rx_buf, msg->rx_len, true);
+
+	regmap_read(priv->regmap, ASPEED_PECI_CMD, &peci_state);
+	dev_dbg(priv->dev, "PECI_STATE : 0x%lx\n",
+		FIELD_GET(PECI_CMD_STS_MASK, peci_state));
+	dev_dbg(priv->dev, "------------------------\n");
+
+err_irqrestore:
+	spin_unlock_irqrestore(&priv->lock, flags);
+	return rc;
+}
+
+static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
+{
+	struct aspeed_peci *priv = arg;
+	u32 status_ack = 0;
+	u32 status;
+
+	spin_lock(&priv->lock);
+	regmap_read(priv->regmap, ASPEED_PECI_INT_STS, &status);
+	priv->status |= (status & PECI_INT_MASK);
+
+	/**
+	 * In most cases, interrupt bits will be set one by one but also note
+	 * that multiple interrupt bits could be set at the same time.
+	 */
+	if (status & PECI_INT_TIMEOUT) {
+		dev_dbg(priv->dev, "PECI_INT_TIMEOUT\n");
+		status_ack |= PECI_INT_TIMEOUT;
+	}
+
+	if (status & PECI_INT_CONNECT) {
+		dev_dbg(priv->dev, "PECI_INT_CONNECT\n");
+		status_ack |= PECI_INT_CONNECT;
+	}
+
+	if (status & PECI_INT_W_FCS_BAD) {
+		dev_dbg(priv->dev, "PECI_INT_W_FCS_BAD\n");
+		status_ack |= PECI_INT_W_FCS_BAD;
+	}
+
+	if (status & PECI_INT_W_FCS_ABORT) {
+		dev_dbg(priv->dev, "PECI_INT_W_FCS_ABORT\n");
+		status_ack |= PECI_INT_W_FCS_ABORT;
+	}
+
+	/**
+	 * All commands should be ended up with a PECI_INT_CMD_DONE bit set
+	 * even in an error case.
+	 */
+	if (status & PECI_INT_CMD_DONE) {
+		dev_dbg(priv->dev, "PECI_INT_CMD_DONE\n");
+		status_ack |= PECI_INT_CMD_DONE;
+		complete(&priv->xfer_complete);
+	}
+
+	regmap_write(priv->regmap, ASPEED_PECI_INT_STS, status_ack);
+	spin_unlock(&priv->lock);
+	return IRQ_HANDLED;
+}
+
+static int aspeed_peci_init_ctrl(struct aspeed_peci *priv)
+{
+	u32 msg_timing, addr_timing, rd_sampling_point;
+	u32 clk_freq, clk_divisor, clk_div_val = 0;
+	struct clk *clkin;
+	int ret;
+
+	clkin = devm_clk_get(priv->dev, NULL);
+	if (IS_ERR(clkin)) {
+		dev_err(priv->dev, "Failed to get clk source.\n");
+		return PTR_ERR(clkin);
+	}
+
+	ret = of_property_read_u32(priv->dev->of_node, "clock-frequency",
+				   &clk_freq);
+	if (ret) {
+		dev_err(priv->dev,
+			"Could not read clock-frequency property.\n");
+		return ret;
+	}
+
+	clk_divisor = clk_get_rate(clkin) / clk_freq;
+	devm_clk_put(priv->dev, clkin);
+
+	while ((clk_divisor >> 1) && (clk_div_val < PECI_CLK_DIV_MAX))
+		clk_div_val++;
+
+	ret = of_property_read_u32(priv->dev->of_node, "msg-timing",
+				   &msg_timing);
+	if (ret || msg_timing > PECI_MSG_TIMING_MAX) {
+		if (!ret)
+			dev_warn(priv->dev,
+				 "Invalid msg-timing : %u, Use default : %u\n",
+				 msg_timing, PECI_MSG_TIMING_DEFAULT);
+		msg_timing = PECI_MSG_TIMING_DEFAULT;
+	}
+
+	ret = of_property_read_u32(priv->dev->of_node, "addr-timing",
+				   &addr_timing);
+	if (ret || addr_timing > PECI_ADDR_TIMING_MAX) {
+		if (!ret)
+			dev_warn(priv->dev,
+				 "Invalid addr-timing : %u, Use default : %u\n",
+				 addr_timing, PECI_ADDR_TIMING_DEFAULT);
+		addr_timing = PECI_ADDR_TIMING_DEFAULT;
+	}
+
+	ret = of_property_read_u32(priv->dev->of_node, "rd-sampling-point",
+				   &rd_sampling_point);
+	if (ret || rd_sampling_point > PECI_RD_SAMPLING_POINT_MAX) {
+		if (!ret)
+			dev_warn(priv->dev,
+				 "Invalid rd-sampling-point : %u. Use default : %u\n",
+				 rd_sampling_point,
+				 PECI_RD_SAMPLING_POINT_DEFAULT);
+		rd_sampling_point = PECI_RD_SAMPLING_POINT_DEFAULT;
+	}
+
+	ret = of_property_read_u32(priv->dev->of_node, "cmd-timeout-ms",
+				   &priv->cmd_timeout_ms);
+	if (ret || priv->cmd_timeout_ms > PECI_CMD_TIMEOUT_MS_MAX ||
+	    priv->cmd_timeout_ms == 0) {
+		if (!ret)
+			dev_warn(priv->dev,
+				 "Invalid cmd-timeout-ms : %u. Use default : %u\n",
+				 priv->cmd_timeout_ms,
+				 PECI_CMD_TIMEOUT_MS_DEFAULT);
+		priv->cmd_timeout_ms = PECI_CMD_TIMEOUT_MS_DEFAULT;
+	}
+
+	regmap_write(priv->regmap, ASPEED_PECI_CTRL,
+		     FIELD_PREP(PECI_CTRL_CLK_DIV_MASK, PECI_CLK_DIV_DEFAULT) |
+		     PECI_CTRL_PECI_CLK_EN);
+
+	/**
+	 * Timing negotiation period setting.
+	 * The unit of the programmed value is 4 times of PECI clock period.
+	 */
+	regmap_write(priv->regmap, ASPEED_PECI_TIMING,
+		     FIELD_PREP(PECI_TIMING_MESSAGE_MASK, msg_timing) |
+		     FIELD_PREP(PECI_TIMING_ADDRESS_MASK, addr_timing));
+
+	/* Clear interrupts */
+	regmap_write(priv->regmap, ASPEED_PECI_INT_STS, PECI_INT_MASK);
+
+	/* Enable interrupts */
+	regmap_write(priv->regmap, ASPEED_PECI_INT_CTRL, PECI_INT_MASK);
+
+	/* Read sampling point and clock speed setting */
+	regmap_write(priv->regmap, ASPEED_PECI_CTRL,
+		     FIELD_PREP(PECI_CTRL_SAMPLING_MASK, rd_sampling_point) |
+		     FIELD_PREP(PECI_CTRL_CLK_DIV_MASK, clk_div_val) |
+		     PECI_CTRL_PECI_EN | PECI_CTRL_PECI_CLK_EN);
+
+	return 0;
+}
+
+static const struct regmap_config aspeed_peci_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = ASPEED_PECI_R_DATA7,
+	.val_format_endian = REGMAP_ENDIAN_LITTLE,
+	.fast_io = true,
+};
+
+static int aspeed_peci_xfer(struct peci_adapter *adapter,
+			    struct peci_xfer_msg *msg)
+{
+	struct aspeed_peci *priv = peci_get_adapdata(adapter);
+
+	return aspeed_peci_xfer_native(priv, msg);
+}
+
+static int aspeed_peci_probe(struct platform_device *pdev)
+{
+	struct peci_adapter *adapter;
+	struct aspeed_peci *priv;
+	struct resource *res;
+	void __iomem *base;
+	u32 cmd_sts;
+	int ret;
+
+	adapter = peci_alloc_adapter(&pdev->dev, sizeof(*priv));
+	if (!adapter)
+		return -ENOMEM;
+
+	priv = peci_get_adapdata(adapter);
+	priv->adapter = adapter;
+	priv->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, priv);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		ret = PTR_ERR(base);
+		goto err_put_adapter_dev;
+	}
+
+	priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					     &aspeed_peci_regmap_config);
+	if (IS_ERR(priv->regmap)) {
+		ret = PTR_ERR(priv->regmap);
+		goto err_put_adapter_dev;
+	}
+
+	/**
+	 * We check that the regmap works on this very first access,
+	 * but as this is an MMIO-backed regmap, subsequent regmap
+	 * access is not going to fail and we skip error checks from
+	 * this point.
+	 */
+	ret = regmap_read(priv->regmap, ASPEED_PECI_CMD, &cmd_sts);
+	if (ret) {
+		ret = -EIO;
+		goto err_put_adapter_dev;
+	}
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (!priv->irq) {
+		ret = -ENODEV;
+		goto err_put_adapter_dev;
+	}
+
+	ret = devm_request_irq(&pdev->dev, priv->irq, aspeed_peci_irq_handler,
+			       0, "peci-aspeed-irq", priv);
+	if (ret)
+		goto err_put_adapter_dev;
+
+	init_completion(&priv->xfer_complete);
+	spin_lock_init(&priv->lock);
+
+	priv->adapter->owner = THIS_MODULE;
+	priv->adapter->dev.of_node = of_node_get(dev_of_node(priv->dev));
+	strlcpy(priv->adapter->name, pdev->name, sizeof(priv->adapter->name));
+	priv->adapter->xfer = aspeed_peci_xfer;
+
+	priv->rst = devm_reset_control_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->rst)) {
+		dev_err(&pdev->dev,
+			"missing or invalid reset controller entry");
+		ret = PTR_ERR(priv->rst);
+		goto err_put_adapter_dev;
+	}
+	reset_control_deassert(priv->rst);
+
+	ret = aspeed_peci_init_ctrl(priv);
+	if (ret)
+		goto err_put_adapter_dev;
+
+	ret = peci_add_adapter(priv->adapter);
+	if (ret)
+		goto err_put_adapter_dev;
+
+	dev_info(&pdev->dev, "peci bus %d registered, irq %d\n",
+		 priv->adapter->nr, priv->irq);
+
+	return 0;
+
+err_put_adapter_dev:
+	put_device(&adapter->dev);
+	return ret;
+}
+
+static int aspeed_peci_remove(struct platform_device *pdev)
+{
+	struct aspeed_peci *priv = dev_get_drvdata(&pdev->dev);
+
+	reset_control_assert(priv->rst);
+	peci_del_adapter(priv->adapter);
+	of_node_put(priv->adapter->dev.of_node);
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_peci_of_table[] = {
+	{ .compatible = "aspeed,ast2400-peci", },
+	{ .compatible = "aspeed,ast2500-peci", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, aspeed_peci_of_table);
+
+static struct platform_driver aspeed_peci_driver = {
+	.probe  = aspeed_peci_probe,
+	.remove = aspeed_peci_remove,
+	.driver = {
+		.name           = "peci-aspeed",
+		.of_match_table = of_match_ptr(aspeed_peci_of_table),
+	},
+};
+module_platform_driver(aspeed_peci_driver);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>");
+MODULE_DESCRIPTION("ASPEED PECI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.17.0

^ permalink raw reply related

* [v4 05/11] ARM: dts: aspeed: peci: Add PECI node
From: Jae Hyun Yoo @ 2018-05-21 19:58 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds PECI bus/adapter node of AST24xx/AST25xx into
aspeed-g4 and aspeed-g5.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
Reviewed-by: Haiyue Wang <haiyue.wang@linux.intel.com>
Reviewed-by: James Feist <james.feist@linux.intel.com>
Reviewed-by: Vernon Mauery <vernon.mauery@linux.intel.com>
Cc: Jason M Biils <jason.m.bills@linux.intel.com>
Cc: Ryan Chen <ryan_chen@aspeedtech.com>
---
 arch/arm/boot/dts/aspeed-g4.dtsi | 26 ++++++++++++++++++++++++++
 arch/arm/boot/dts/aspeed-g5.dtsi | 26 ++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index 518d2bc7c7fc..c101601429b4 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -29,6 +29,7 @@
 		serial3 = &uart4;
 		serial4 = &uart5;
 		serial5 = &vuart;
+		peci0 = &peci0;
 	};
 
 	cpus {
@@ -270,6 +271,13 @@
 				};
 			};
 
+			peci: peci at 1e78b000 {
+				compatible = "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1e78b000 0x60>;
+			};
+
 			uart2: serial at 1e78d000 {
 				compatible = "ns16550a";
 				reg = <0x1e78d000 0x20>;
@@ -313,6 +321,24 @@
 	};
 };
 
+&peci {
+	peci0: peci-bus at 0 {
+		compatible = "aspeed,ast2400-peci";
+		reg = <0x0 0x60>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interrupts = <15>;
+		clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
+		resets = <&syscon ASPEED_RESET_PECI>;
+		clock-frequency = <24000000>;
+		msg-timing = <1>;
+		addr-timing = <1>;
+		rd-sampling-point = <8>;
+		cmd-timeout-ms = <1000>;
+		status = "disabled";
+	};
+};
+
 &i2c {
 	i2c_ic: interrupt-controller at 0 {
 		#interrupt-cells = <1>;
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index f9917717dd08..0c4850c3f456 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -29,6 +29,7 @@
 		serial3 = &uart4;
 		serial4 = &uart5;
 		serial5 = &vuart;
+		peci0 = &peci0;
 	};
 
 	cpus {
@@ -320,6 +321,13 @@
 				};
 			};
 
+			peci: peci at 1e78b000 {
+				compatible = "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1e78b000 0x60>;
+			};
+
 			uart2: serial at 1e78d000 {
 				compatible = "ns16550a";
 				reg = <0x1e78d000 0x20>;
@@ -363,6 +371,24 @@
 	};
 };
 
+&peci {
+	peci0: peci-bus at 0 {
+		compatible = "aspeed,ast2500-peci";
+		reg = <0x0 0x60>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interrupts = <15>;
+		clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
+		resets = <&syscon ASPEED_RESET_PECI>;
+		clock-frequency = <24000000>;
+		msg-timing = <1>;
+		addr-timing = <1>;
+		rd-sampling-point = <8>;
+		cmd-timeout-ms = <1000>;
+		status = "disabled";
+	};
+};
+
 &i2c {
 	i2c_ic: interrupt-controller at 0 {
 		#interrupt-cells = <1>;
-- 
2.17.0

^ permalink raw reply related

* [v4 04/11] dt-bindings: Add a document of PECI adapter driver for ASPEED AST24xx/25xx SoCs
From: Jae Hyun Yoo @ 2018-05-21 19:58 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds a dt-bindings document of PECI adapter driver for ASPEED
AST24xx/25xx SoCs.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
Reviewed-by: Haiyue Wang <haiyue.wang@linux.intel.com>
Reviewed-by: James Feist <james.feist@linux.intel.com>
Reviewed-by: Vernon Mauery <vernon.mauery@linux.intel.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Jason M Biils <jason.m.bills@linux.intel.com>
Cc: Milton Miller II <miltonm@us.ibm.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Ryan Chen <ryan_chen@aspeedtech.com>
---
 .../devicetree/bindings/peci/peci-aspeed.txt  | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.txt

diff --git a/Documentation/devicetree/bindings/peci/peci-aspeed.txt b/Documentation/devicetree/bindings/peci/peci-aspeed.txt
new file mode 100644
index 000000000000..8c35f905589d
--- /dev/null
+++ b/Documentation/devicetree/bindings/peci/peci-aspeed.txt
@@ -0,0 +1,57 @@
+Device tree configuration for PECI buses on the AST24XX and AST25XX SoCs.
+
+Required properties:
+- compatible        : Should be "aspeed,ast2400-peci" or "aspeed,ast2500-peci"
+		      - aspeed,ast2400-peci: ASPEED AST2400 family PECI
+					     controller
+		      - aspeed,ast2500-peci: ASPEED AST2500 family PECI
+					     controller
+- reg               : Should contain PECI controller registers location and
+		      length.
+- #address-cells    : Should be <1> required to define a client address.
+- #size-cells       : Should be <0> required to define a client address.
+- interrupts        : Should contain PECI controller interrupt.
+- clocks            : Should contain clock source for PECI controller. Should
+		      reference the external oscillator clock in the second
+		      cell.
+- resets            : Should contain phandle to reset controller with the reset
+		      number in the second cell.
+- clock-frequency   : Should contain the operation frequency of PECI controller
+		      in units of Hz.
+		      187500 ~ 24000000
+
+Optional properties:
+- msg-timing        : Message timing negotiation period. This value will
+		      determine the period of message timing negotiation to be
+		      issued by PECI controller. The unit of the programmed
+		      value is four times of PECI clock period.
+		      0 ~ 255 (default: 1)
+- addr-timing       : Address timing negotiation period. This value will
+		      determine the period of address timing negotiation to be
+		      issued by PECI controller. The unit of the programmed
+		      value is four times of PECI clock period.
+		      0 ~ 255 (default: 1)
+- rd-sampling-point : Read sampling point selection. The whole period of a bit
+		      time will be divided into 16 time frames. This value will
+		      determine the time frame in which the controller will
+		      sample PECI signal for data read back. Usually in the
+		      middle of a bit time is the best.
+		      0 ~ 15 (default: 8)
+- cmd-timeout-ms    : Command timeout in units of ms.
+		      1 ~ 60000 (default: 1000)
+
+Example:
+	peci0: peci-bus at 0 {
+		compatible = "aspeed,ast2500-peci";
+		reg = <0x0 0x60>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interrupts = <15>;
+		clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
+		resets = <&syscon ASPEED_RESET_PECI>;
+		clock-frequency = <24000000>;
+		msg-timing = <1>;
+		addr-timing = <1>;
+		rd-sampling-point = <8>;
+		cmd-timeout-ms = <1000>;
+	};
-- 
2.17.0

^ permalink raw reply related

* [PATCH v4 00/10] PECI device driver introduction
From: Jae Hyun Yoo @ 2018-05-21 19:56 UTC (permalink / raw)
  To: linux-arm-kernel

Introduction of the Platform Environment Control Interface (PECI) bus
device driver. PECI is a one-wire bus interface that provides a
communication channel between an Intel processor and chipset components to
external monitoring or control devices. PECI is designed to support the
following sideband functions:

* Processor and DRAM thermal management
  - Processor fan speed control is managed by comparing Digital Thermal
    Sensor (DTS) thermal readings acquired via PECI against the
    processor-specific fan speed control reference point, or TCONTROL. Both
    TCONTROL and DTS thermal readings are accessible via the processor PECI
    client. These variables are referenced to a common temperature, the TCC
    activation point, and are both defined as negative offsets from that
    reference.
  - PECI based access to the processor package configuration space provides
    a means for Baseboard Management Controllers (BMC) or other platform
    management devices to actively manage the processor and memory power
    and thermal features.

* Platform Manageability
  - Platform manageability functions including thermal, power, and error
    monitoring. Note that platform 'power' management includes monitoring
    and control for both the processor and DRAM subsystem to assist with
    data center power limiting.
  - PECI allows read access to certain error registers in the processor MSR
    space and status monitoring registers in the PCI configuration space
    within the processor and downstream devices.
  - PECI permits writes to certain registers in the processor PCI
    configuration space.

* Processor Interface Tuning and Diagnostics
  - Processor interface tuning and diagnostics capabilities
    (Intel Interconnect BIST). The processors Intel Interconnect Built In
    Self Test (Intel IBIST) allows for infield diagnostic capabilities in
    the Intel UPI and memory controller interfaces. PECI provides a port to
    execute these diagnostics via its PCI Configuration read and write
    capabilities.

* Failure Analysis
  - Output the state of the processor after a failure for analysis via
    Crashdump.

PECI uses a single wire for self-clocking and data transfer. The bus
requires no additional control lines. The physical layer is a self-clocked
one-wire bus that begins each bit with a driven, rising edge from an idle
level near zero volts. The duration of the signal driven high depends on
whether the bit value is a logic '0' or logic '1'. PECI also includes
variable data transfer rate established with every message. In this way, it
is highly flexible even though underlying logic is simple.

The interface design was optimized for interfacing between an Intel
processor and chipset components in both single processor and multiple
processor environments. The single wire interface provides low board
routing overhead for the multiple load connections in the congested routing
area near the processor and chipset components. Bus speed, error checking,
and low protocol overhead provides adequate link bandwidth and reliability
to transfer critical device operating conditions and configuration
information.

This implementation provides the basic framework to add PECI extensions to
the Linux bus and device models. A hardware specific 'Adapter' driver can
be attached to the PECI bus to provide sideband functions described above.
It is also possible to access all devices on an adapter from userspace
through the /dev interface. A device specific 'Client' driver also can be
attached to the PECI bus so each processor client's features can be
supported by the 'Client' driver through an adapter connection in the bus.
This patch set includes Aspeed 24xx/25xx PECI driver and PECI
cputemp/dimmtemp drivers as the first implementation for both adapter and
client drivers on the PECI bus framework.

Please review.

Thanks,

-Jae

Changes from v3:
* Made code more simple and compact.
* Removed unused header file inclusion.
* Fixed incorrect error return values and messages.
* Removed DTS margin temperature from the peci-cputemp.
* Made some magic numbers use defines.
* Moved peci_get_cpu_id() into peci-core as a common function.
* Replaced the cancel_delayed_work() call with a cancel_delayed_work_sync().
* Replaced AST and Aspeed uses with ASPEED.
* Simplified peci command timeout checking logic using
  regmap_read_poll_timeout().
* Simplified endian swap codes using endian handling macros.
* Dropped regmap read/write error checking except for the first access.
* Added a PECI reset setting in the device tree node.
* Removed unnecessary sleep from the probe context.
* Removed IRQF_SHARED flag from irq request code in the ASPEED PECI driver.
* Fixed typos in documents.
* Combined peci-bus.txt, peci-adapter.txt and peci-client.txt into peci.txt.
* Fixed and swept documents to drop some incorrect or unnecessary
  descriptions.
* Fixed device tree to make unit-address format use reg contents.
* Simplified bit manipulations using <linux/bitfield.h>.
* Made client CPU model checking use <asm/intel-family.h> if available.
* Modified adapter heap allocation method to use kobject reference count
  based.
* Added the low-level PECI xfer IOCTL again to support the Redfish
  requirement.
* Added PM domain attach/detach code.
* Added logic for device instantiation through sysfs.
* Fix a bug of interrupt status checking code in peci-aspeed driver.

Changes from v2:
* Divided peci-hwmon driver into two drivers, peci-cputemp and
  peci-dimmtemp.
* Added generic dt binding documents for PECI bus, adapter and client.
* Removed in_atomic() call from the PECI core driver.
* Improved PECI commands masking logic.
* Added permission check logic for PECI ioctls.
* Removed unnecessary type casts.
* Fixed some invalid error return codes.
* Added the mark_updated() function to improve update interval checking
  logic.
* Fixed a bug in populated DIMM checking function.
* Fixed some typo, grammar and style issues in documents.
* Rewrote hwmon drivers to use devm_hwmon_device_register_with_info API.
* Made peci_match_id() function as a static.
* Replaced a deprecated create_singlethread_workqueue() call with an
  alloc_ordered_workqueue() call.
* Reordered local variable definitions in reversed xmas tree notation.
* Listed up client CPUs that can be supported by peci-cputemp and
  peci-dimmtemp hwmon drivers.
* Added CPU generation detection logic which checks CPUID signature through
  PECI connection.
* Improved interrupt handling logic in the Aspeed PECI adapter driver.
* Fixed SPDX license identifier style in header files.
* Changed some macros in peci.h to static inline functions.
* Dropped sleepable context checking code in peci-core.
* Adjusted rt_mutex protection scope in peci-core.
* Moved adapter->xfer() checking code into peci_register_adapter().
* Improved PECI command retry checking logic.
* Changed ioctl base from 'P' to 0xb6 to avoid confiliction and updated
  ioctl-number.txt to reflect the ioctl number of PECI subsystem.
* Added a comment to describe PECI retry action.
* Simplified return code handling of peci_ioctl_ping().
* Changed type of peci_ioctl_fn[] to static const.
* Fixed range checking code for valid PECI commands.
* Fixed the error return code on invalid PECI commands.
* Fixed incorrect definitions of PECI ioctl and its handling logic.

Changes from v1:
* Additionally implemented a core driver to support PECI linux bus driver
  model.
* Modified Aspeed PECI driver to make that to be an adapter driver in PECI
  bus.
* Modified PECI hwmon driver to make that to be a client driver in PECI
  bus.
* Simplified hwmon driver attribute labels and removed redundant strings.
* Removed core_nums from device tree setting of hwmon driver and modified
  core number detection logic to check the resolved_core register in client
  CPU's local PCI configuration area.
* Removed dimm_nums from device tree setting of hwmon driver and added
  populated DIMM detection logic to support dynamic creation.
* Removed indexing gap on core temperature and DIMM temperature attributes.
* Improved hwmon registration and dynamic attribute creation logic.
* Fixed structure definitions in PECI uapi header to make that use __u8,
  __u16 and etc.
* Modified wait_for_completion_interruptible_timeout error handling logic
  in Aspeed PECI driver to deliver errors correctly.
* Removed low-level xfer command from ioctl and kept only high-level PECI
  command suite as ioctls.
* Fixed I/O timeout logic in Aspeed PECI driver using ktime.
* Added a function into hwmon driver to simplify update delay checking.
* Added a function into hwmon driver to convert 10.6 to millidegree.
* Dropped non-standard attributes in hwmon driver.
* Fixed OF table for hwmon to make it indicate as a PECI client of Intel
  CPU target.
* Added a maintainer of PECI subsystem into MAINTAINERS document.

Jae Hyun Yoo (11):
  dt-bindings: Add a document of PECI subsystem
  Documentation: ioctl: Add ioctl numbers for PECI subsystem
  drivers/peci: Add support for PECI bus driver core
  dt-bindings: Add a document of PECI adapter driver for ASPEED
    AST24xx/25xx SoCs
  ARM: dts: aspeed: peci: Add PECI node
  drivers/peci: Add a PECI adapter driver for Aspeed AST24xx/AST25xx
  dt-bindings: hwmon: Add documents for PECI hwmon client drivers
  Documentation: hwmon: Add documents for PECI hwmon client drivers
  drivers/hwmon: Add PECI cputemp driver
  drivers/hwmon: Add PECI dimmtemp driver
  Add maintainers for the PECI subsystem

 .../bindings/hwmon/peci-cputemp.txt           |   23 +
 .../bindings/hwmon/peci-dimmtemp.txt          |   24 +
 .../devicetree/bindings/peci/peci-aspeed.txt  |   57 +
 .../devicetree/bindings/peci/peci.txt         |   59 +
 Documentation/hwmon/peci-cputemp              |   78 +
 Documentation/hwmon/peci-dimmtemp             |   50 +
 Documentation/ioctl/ioctl-number.txt          |    2 +
 MAINTAINERS                                   |   10 +
 arch/arm/boot/dts/aspeed-g4.dtsi              |   26 +
 arch/arm/boot/dts/aspeed-g5.dtsi              |   26 +
 drivers/Kconfig                               |    2 +
 drivers/Makefile                              |    1 +
 drivers/hwmon/Kconfig                         |   28 +
 drivers/hwmon/Makefile                        |    2 +
 drivers/hwmon/peci-cputemp.c                  |  407 +++++
 drivers/hwmon/peci-dimmtemp.c                 |  300 ++++
 drivers/hwmon/peci-hwmon.c                    |  124 ++
 drivers/hwmon/peci-hwmon.h                    |   51 +
 drivers/peci/Kconfig                          |   44 +
 drivers/peci/Makefile                         |    9 +
 drivers/peci/peci-aspeed.c                    |  496 ++++++
 drivers/peci/peci-core.c                      | 1451 +++++++++++++++++
 include/linux/peci.h                          |  105 ++
 include/uapi/linux/peci-ioctl.h               |  265 +++
 24 files changed, 3640 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/peci-cputemp.txt
 create mode 100644 Documentation/devicetree/bindings/hwmon/peci-dimmtemp.txt
 create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.txt
 create mode 100644 Documentation/devicetree/bindings/peci/peci.txt
 create mode 100644 Documentation/hwmon/peci-cputemp
 create mode 100644 Documentation/hwmon/peci-dimmtemp
 create mode 100644 drivers/hwmon/peci-cputemp.c
 create mode 100644 drivers/hwmon/peci-dimmtemp.c
 create mode 100644 drivers/hwmon/peci-hwmon.c
 create mode 100644 drivers/hwmon/peci-hwmon.h
 create mode 100644 drivers/peci/Kconfig
 create mode 100644 drivers/peci/Makefile
 create mode 100644 drivers/peci/peci-aspeed.c
 create mode 100644 drivers/peci/peci-core.c
 create mode 100644 include/linux/peci.h
 create mode 100644 include/uapi/linux/peci-ioctl.h

-- 
2.17.0

^ permalink raw reply

* [GIT PULL 3/3] more omap dts changes for v4.18 merge window
From: Tony Lindgren @ 2018-05-21 19:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <pull-1526925630-789198@atomide.com>

From: "Tony Lindgren" <tony@atomide.com>

The following changes since commit 8dfa75524a0e0e2b4eaf2a3dc178f6b4d8db85d9:

  ARM: dts: correct invalid I/O definition for MMC/SD card detect on T410 (2018-05-03 10:03:01 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.18/dt-part2-signed

for you to fetch changes up to 0dbf99542caf8a767ea0ac286ca8077cc5e8bd32:

  ARM: dts: am3517-evm: Add User LEDs and Pushbutton (2018-05-18 14:07:38 -0700)

----------------------------------------------------------------
Second set of dts changes for omap variants for v4.18 merge window

This series of changes contains fixes for already queued tps65218
IRQ_TYPE, and fixes for omap3 and am335x use of IRQ_TYPE. There are
also addition of oscillator clock for logicpd omap3 boards and a series
of changes to improve support for am3517-evm board. And there is also
a change to configure WLAN for am437x-sk-evm.

----------------------------------------------------------------
Adam Ford (11):
      ARM: dts: logicpd-torpedo: Add fixed 26MHz clock as fck for twl
      ARM: dts: logicpd-som-lv: Add fixed 26MHz clock as fck for twl
      ARM: dts: am3517: Add pinmuxing, CD and WP for MMC1
      ARM: dts: am3517-evm: Split off SOM features from baseboard
      ARM: dts: am3517-som: Add TI TPS65023 regulators
      ARM: dts: am3517-som: Associate cpu to regulator supply
      ARM: dts: am3517-evm: Add LCD panel type 15 support
      ARM: dts: am3517-som: Add Seiko Instruments RTC s35390a
      ARM: dts: logicpd-som-lv: Fix Touchscreen controller
      ARM: dts: am3517-evm: Add I/O expander for User DIP switches and LEDS
      ARM: dts: am3517-evm: Add User LEDs and Pushbutton

Eyal Reizer (1):
      ARM: dts: am437x-sk-evm: add wilink8 support

Hern?n Gonzalez (5):
      ARM: dts: am335x-baltos-ir3220: Use IRQ_TYPE specifier
      ARM: dts: am335x-baltos-ir5221: Use IRQ_TYPE specifier
      ARM: dts: am335x-baltos.dtsi: Use IRQ_TYPE specifier
      ARM: dts: am335x-boneblue: Use IRQ_TYPE specifier
      ARM: dts: omap3-pandora-common: Use IRQ_TYPE specifier

Peter Ujfalusi (5):
      ARM: dts: am335x-evmsk: Add phandle for the backlight for the panel
      ARM: dts: am437x-gp-evm: Fixup (again) tps65218 irq type
      ARM: dts: am437x-cm-t43: Fixup (again) tps65218 irq type
      ARM: dts: am437x-epos-evm: Fixup (again) tps65218 irq type
      Revert "ARM: dts: am437x-sk-evm: Correct tps65218 irq type"

Rob Herring (2):
      ARM: dts: omap: fix OF graph in omap3-devkit8000
      ARM: dts: omap: fix OMAP3 CM-T3x OF graph video connectors

Tony Lindgren (1):
      Merge branch 'omap-for-v4.18/dt-fixes' into omap-for-v4.18/dt

 arch/arm/boot/dts/am335x-baltos-ir3220.dts         |   2 +-
 arch/arm/boot/dts/am335x-baltos-ir5221.dts         |   2 +-
 arch/arm/boot/dts/am335x-baltos.dtsi               |   2 +-
 arch/arm/boot/dts/am335x-boneblue.dts              |   2 +-
 arch/arm/boot/dts/am335x-evmsk.dts                 |   3 +-
 arch/arm/boot/dts/am3517-evm.dts                   | 233 ++++++++++++++++++++-
 arch/arm/boot/dts/am3517-som.dtsi                  | 142 +++++++++++++
 arch/arm/boot/dts/am437x-cm-t43.dts                |   2 +-
 arch/arm/boot/dts/am437x-gp-evm.dts                |   2 +-
 arch/arm/boot/dts/am437x-sk-evm.dts                | 117 ++++++++++-
 arch/arm/boot/dts/am43x-epos-evm.dts               |   2 +-
 arch/arm/boot/dts/logicpd-som-lv.dtsi              |  21 +-
 arch/arm/boot/dts/logicpd-torpedo-som.dtsi         |  10 +
 arch/arm/boot/dts/omap3-cm-t3x.dtsi                |   2 +-
 arch/arm/boot/dts/omap3-devkit8000-common.dtsi     |   9 +-
 arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi |   5 +-
 arch/arm/boot/dts/omap3-pandora-common.dtsi        |   2 +-
 arch/arm/boot/dts/omap3-sb-t35.dtsi                |   2 +-
 18 files changed, 538 insertions(+), 22 deletions(-)
 create mode 100644 arch/arm/boot/dts/am3517-som.dtsi

^ permalink raw reply

* [GIT PULL 2/3] omap soc chages for v4.18 merge window
From: Tony Lindgren @ 2018-05-21 19:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <pull-1526925630-789198@atomide.com>

From: "Tony Lindgren" <tony@atomide.com>

The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.18/soc-signed

for you to fetch changes up to 3bb3799cd4233b7c24622ae8c41455fb27a55c0f:

  Merge branch 'omap-for-v4.18/soc-fixes' into omap-for-v4.18/soc (2018-05-21 10:34:17 -0700)

----------------------------------------------------------------
SoC changes for omap variants for v4.18 merge window

This series mostly adds saving of power and clock domain registers for
am335x/am437x suspend to RTC only mode. There is also a non-urgent fix
for omap4 PM where we could end up losing GPIO interrupts if bootloader
has LOGICRETSTATE cleared for domains. And there is a clean-up patch for
omap1 to use device properties for at24 eeprom.

----------------------------------------------------------------
Bartosz Golaszewski (1):
      ARM: omap1: osk: use device properties for at24 eeprom

Dave Gerlach (1):
      ARM: OMAP2+: prm44xx: Introduce context save/restore for am43 PRCM IO

Keerthy (3):
      ARM: OMAP2+: clockdomain: Inroduce cpu_pm notifiers for context save/restore
      ARM: OMAP2+: powerdomain: Introduce cpu_pm notifiers for context save/restore
      ARM: OMAP2+: prm44xx: Inroduce cpu_pm notifiers for context save/restore

Russ Dill (2):
      ARM: OMAP2+: Add functions to save and restore clockdomain context en-masse.
      ARM: OMAP2+: Add functions to save and restore powerdomain context

Tony Lindgren (2):
      ARM: OMAP2+: Make sure LOGICRETSTATE bits are not cleared
      Merge branch 'omap-for-v4.18/soc-fixes' into omap-for-v4.18/soc

 arch/arm/mach-omap1/board-osk.c   |  10 ++--
 arch/arm/mach-omap2/clockdomain.c |  73 ++++++++++++++++++++++++++
 arch/arm/mach-omap2/clockdomain.h |   8 +++
 arch/arm/mach-omap2/cm33xx.c      |  53 +++++++++++++++++++
 arch/arm/mach-omap2/cminst44xx.c  |  43 ++++++++++++++++
 arch/arm/mach-omap2/pm44xx.c      |  13 +++++
 arch/arm/mach-omap2/powerdomain.c |  87 +++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/powerdomain.h |   7 +++
 arch/arm/mach-omap2/prm33xx.c     |  31 ++++++++++++
 arch/arm/mach-omap2/prm44xx.c     | 104 ++++++++++++++++++++++++++++++++++++++
 10 files changed, 424 insertions(+), 5 deletions(-)

^ permalink raw reply

* [GIT PULL 1/3] ti-sysc array access fix for v4.18 merge window
From: Tony Lindgren @ 2018-05-21 19:41 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Tony Lindgren" <tony@atomide.com>

The following changes since commit dc4c85eac6bc8cfe25144936c5636aa1415bbc12:

  bus: ti-sysc: Show module information for suspend if DEBUG is enabled (2018-05-01 06:54:17 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.18/ti-sysc-fix-signed

for you to fetch changes up to c97c8620833e4a55ddb7a43961d3205184a487f0:

  bus: ti-sysc: Fix optional clocks array access (2018-05-18 07:54:44 -0700)

----------------------------------------------------------------
One ti-sysc fix for v4.18 merge window

This fixes an array access errors if there are more optional clocks
than one.

----------------------------------------------------------------
Tony Lindgren (1):
      bus: ti-sysc: Fix optional clocks array access

 drivers/bus/ti-sysc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

^ permalink raw reply

* [PATCH RFC] ARM: dts: add Raspberry Pi Compute Module and IO board
From: Stefan Wahren @ 2018-05-21 19:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87d0xouapx.fsf@anholt.net>

> Eric Anholt <eric@anholt.net> hat am 21. Mai 2018 um 20:26 geschrieben:
> 
> 
> Stefan Wahren <stefan.wahren@i2se.com> writes:
> 
> > The Raspberry Pi Compute Module (CM1) is a SoM which contains a
> > BCM2835 processor, 512 MB RAM and a 4 GB eMMC. There is also a carrier
> > board which is called Compute Module IO Board.
> >
> > Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> > ---
> >  arch/arm/boot/dts/Makefile                |  1 +
> >  arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts | 92 +++++++++++++++++++++++++++++++
> >  arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi    | 34 ++++++++++++
> >  3 files changed, 127 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
> >  create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
> >
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index ec2024e..a9883e8 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -73,6 +73,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
> >  	bcm2835-rpi-b-rev2.dtb \
> >  	bcm2835-rpi-b-plus.dtb \
> >  	bcm2835-rpi-a-plus.dtb \
> > +	bcm2835-rpi-cm1-io1.dtb \
> >  	bcm2836-rpi-2-b.dtb \
> >  	bcm2837-rpi-3-b.dtb \
> >  	bcm2837-rpi-3-b-plus.dtb \
> > diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts b/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
> > new file mode 100644
> > index 0000000..4d9aa22
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
> > @@ -0,0 +1,92 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/dts-v1/;
> > +#include "bcm2835-rpi-cm1.dtsi"
> > +#include "bcm283x-rpi-usb-host.dtsi"
> > +
> > +/ {
> > +	compatible = "raspberrypi,compute-module", "brcm,bcm2835";
> > +	model = "Raspberry Pi Compute Module IO board rev1";
> > +};
> > +
> > +&dsi1 {
> > +	status = "okay";
> > +};
> > +
> > +&gpio {
> > +	/*
> > +	 * This is based on the official GPU firmware DT blob.
> > +	 *
> > +	 * Legend:
> > +	 * "NC" = not connected (no rail from the SoC)
> > +	 * "FOO" = GPIO line named "FOO" on the schematic
> > +	 * "FOO_N" = GPIO line named "FOO" on schematic, active low
> > +	 */
> > +	gpio-line-names = "GPIO0",
> > +			  "GPIO1",
> > +			  "GPIO2",
> > +			  "GPIO3",
> > +			  "GPIO4",
> > +			  "GPIO5",
> > +			  "GPIO6",
> > +			  "GPIO7",
> > +			  "GPIO8",
> > +			  "GPIO9",
> > +			  "GPIO10",
> > +			  "GPIO11",
> > +			  "GPIO12",
> > +			  "GPIO13",
> > +			  "GPIO14",
> > +			  "GPIO15",
> > +			  "GPIO16",
> > +			  "GPIO17",
> > +			  "GPIO18",
> > +			  "GPIO19",
> > +			  "GPIO20",
> > +			  "GPIO21",
> > +			  "GPIO22",
> > +			  "GPIO23",
> > +			  "GPIO24",
> > +			  "GPIO25",
> > +			  "GPIO26",
> > +			  "GPIO27",
> > +			  "GPIO28",
> > +			  "GPIO29",
> > +			  "GPIO30",
> > +			  "GPIO31",
> > +			  "GPIO32",
> > +			  "GPIO33",
> > +			  "GPIO34",
> > +			  "GPIO35",
> > +			  "GPIO36",
> > +			  "GPIO37",
> > +			  "GPIO38",
> > +			  "GPIO39",
> > +			  "GPIO40",
> > +			  "GPIO41",
> > +			  "GPIO42",
> > +			  "GPIO43",
> > +			  "GPIO44",
> > +			  "GPIO45",
> > +			  "HDMI_HPD_N",
> > +			  /* Also used as ACT LED */
> > +			  "EMMC_EN_N",
> > +			  /* Used by eMMC */
> > +			  "SD_CLK_R",
> > +			  "SD_CMD_R",
> > +			  "SD_DATA0_R",
> > +			  "SD_DATA1_R",
> > +			  "SD_DATA2_R",
> > +			  "SD_DATA3_R";
> > +
> > +	pinctrl-0 = <&gpioout &alt0>;
> > +};
> > +
> > +&hdmi {
> > +	hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
> > +};
> 
> I think this should be ACTIVE_LOW, since it's "HDMI_HPD_N_1V8", right?

I just copy & paste from the rpi-4.14/bcm2708-rpi-cm.dts. I thought the HDMI interface on my IO board is broken, but maybe this is a downstream issue.

> 
> > +
> > +&uart0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&uart0_gpio14>;
> > +	status = "okay";
> > +};
> > diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
> > new file mode 100644
> > index 0000000..ef22c2d
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
> > @@ -0,0 +1,34 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/dts-v1/;
> > +#include "bcm2835.dtsi"
> > +#include "bcm2835-rpi.dtsi"
> > +
> > +/ {
> > +	leds {
> > +		act {
> > +			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
> > +		};
> > +	};
> > +
> > +	reg_3v3: fixed-regulator {
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "3V3";
> > +		regulator-min-microvolt = <3300000>;
> > +		regulator-max-microvolt = <3300000>;
> > +		regulator-always-on;
> > +	};
> > +
> > +	reg_1v8: fixed-regulator {
> > +		compatible = "regulator-fixed";
> > +		regulator-name = "1V8";
> > +		regulator-min-microvolt = <1800000>;
> > +		regulator-max-microvolt = <1800000>;
> > +		regulator-always-on;
> > +	};
> > +};
> > +
> > +&sdhost {
> > +	non-removable;
> > +	vmmc-supply = <&reg_3v3>;
> > +	vqmmc-supply = <&reg_1v8>;
> > +};
> 
> Also, looking at some datasheets I have laying around, it says "eMMC I/O
> Voltage fixed at 1V8" -- is this regulator setup right, in that case?

Usually an eMMC has 2 different voltage sources:
vqmmc-supply -> supply node for IO line power (usually switchable, but fixed on Compute Module)
vmmc-supply -> supply node for card's power (usually fixed)

Do you have a specific concern (voltage, naming)?

Does this conversation help [1]?

Please also look at the CM schematics page 1 and 3.

[1] - https://www.raspberrypi.org/forums/viewtopic.php?f=107&t=213772

> 
> With answers for these two issues, it will be:
> 
> Reviewed-by: Eric Anholt <eric@anholt.net>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH 2/2] rtc: brcmstb-waketimer: add range
From: Florian Fainelli @ 2018-05-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520202730.28172-2-alexandre.belloni@bootlin.com>

On 05/20/2018 01:27 PM, Alexandre Belloni wrote:
> Let the core handle the range.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
-- 
Florian

^ permalink raw reply

* [PATCH 1/2] rtc: brcmstb-waketimer: switch to rtc_register_device
From: Florian Fainelli @ 2018-05-21 19:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180520202730.28172-1-alexandre.belloni@bootlin.com>

On 05/20/2018 01:27 PM, Alexandre Belloni wrote:
> Switch to devm_rtc_allocate_device/rtc_register_device.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* [PATCH v2] arm: bcm2835: Add the PMU to the devicetree.
From: Stefan Wahren @ 2018-05-21 18:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180521183907.27563-1-eric@anholt.net>


> Eric Anholt <eric@anholt.net> hat am 21. Mai 2018 um 20:39 geschrieben:
> 
> 
> This only probes on arm64 so far, but hopefully that driver will be
> generalized soon.
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>

Acked-by: Stefan Wahren <stefan.wahren@i2se.com>

^ permalink raw reply

* [PATCHv2] drivers/perf: arm-ccn: don't log to dmesg in event_init
From: Kim Phillips @ 2018-05-21 18:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180521171949.31412-1-mark.rutland@arm.com>

[adding LKML, linux-perf-users.  Please do so from now on]

On Mon, 21 May 2018 18:19:49 +0100
Mark Rutland <mark.rutland@arm.com> wrote:

> The ARM CCN PMU driver uses dev_warn() to complain about parameters in
> the user-provided perf_event_attr. This means that under normal
> operation (e.g. a single invocation of the perf tool), a number of
> messages warnings may be logged to dmesg.
> 
> Tools may issue multiple syscalls to probe for feature support, and
> multiple applications (from multiple users) can attempt to open events
> simultaneously, so this is not very helpful, even if a user happens to
> have access to dmesg. Worse, this can push important information out of
> the dmesg ring buffer, and can significantly slow down syscall fuzzers,
> vastly increasing the time it takes to find critical bugs.
> 
> Demote the dev_warn() instances to dev_dbg(), as is the case for all
> other PMU drivers under drivers/perf/. Users who wish to debug PMU event
> initialisation can enable dynamic debug to receive these messages.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---

Care to address my comments to the rationale?:

https://marc.info/?l=linux-arm-kernel&m=152582291919277&w=2

Thanks,

Kim

^ permalink raw reply

* Delivery Status Notification (Failure)
From: Pintu Kumar @ 2018-05-21 18:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOuPNLiaAc16BoMQ=EiqWiyMs14MP4YPOTUf42XbUs2xNYzUUg@mail.gmail.com>

Dear Lucas,

Can you give me some pointers on how to set affinity for entire GPIO Bank.
Currently I am exploring drivers/gpio/gpio-mxc.c to find out how the
GPIO banks are set up.

I also found that affinity can be set using: desc->irq_data.affinity,
may be by using cpumask_copy(...).
But still I am not familiar with this.

So, I need your help.


Thank You!

Regards,
Pintu



On Thu, May 17, 2018 at 6:58 PM, Pintu Kumar <pintu.ping@gmail.com> wrote:
> On Mon, May 14, 2018 at 7:58 PM, Pintu Kumar <pintu.ping@gmail.com> wrote:
>>
>> On Mon, May 14, 2018 at 6:41 PM, Lucas Stach <l.stach@pengutronix.de> wrote:
>> > Am Montag, den 14.05.2018, 17:42 +0530 schrieb Pintu Kumar:
>> >> Hi,
>> >>
>> >> Is there any work around possible to set IRQ affinity for some GPIO
>> >> interrupt ?
>> >> How to avoid CPU0 to receive the current GPIO interrupt ?
>> >> How do we assign GPIO interrupts to any CPU other than CPU0 ?
>> >> Is it possible to isolate CPU0 for a sometime, from my GPIO driver so
>> >> that GPIO interrupt can be served by another CPU ?
>> >>
>> >> Need your inputs to decide whether it is still possible to set
>> >> affinity for GPIO interrupt, or its impossible ?
>> >
>> > This is not possible. The GPIO IRQs are aggregated into one GPC/GIC IRQ
>> > line per GPIO bank, so it is not possible to change affinity of a
>> > single GPIO interrupt to another CPU.
>>
>> OK. Thanks for your confirmation.
>>
>> > Best we could do is change the
>> > affinity of the whole bank,
>>
>
> Hi,
>
> I found that the driver is responsible for setting GPIO bank in i.MX7:
> https://elixir.bootlin.com/linux/v4.2/source/drivers/gpio/gpio-mxc.c
>
> However I still dont know how to set the cpumask for one of the GPIO Bank.
>
> From this link, it seems it is possible to set affinity for a GPIO IRQ.
> https://community.nxp.com/thread/303144
>
> But when I try it form my GPIO138 (GPIO5_IO10) it did not help.
>
> So, as you said, I wanted to change affinity for the whole GPIO bank and try it.
> Please give me some pointers.
>
> Thanks
>
>
>> OK. How can we do this on the fly from my driver code.
>> If you have any reference please let me know.
>> This is required only for experimental purpose to prove the point to be mgmt.
>> My idea is, from the driver, change the affinity of the whole bank.
>> So, the GPIO interrupt can be delivered on to this specific CPU bank.
>> Once I am done, I will revert back to the old bank.
>> Please give me some hint on how to do this from my kernel module....
>>
>>
>> > but given the limited usefulness of
>> > something like that, nobody bothered to implement such a thing.
>> >
>> > Regards,
>> > Lucas
>> >
>> >>
>> >>
>> >> On Fri, May 11, 2018 at 8:07 PM, Pintu Kumar <pintu.ping@gmail.com>
>> >> wrote:
>> >> > On Fri, May 11, 2018 at 6:34 PM, Lucas Stach <l.stach@pengutronix.d
>> >> > e> wrote:
>> >> > > Am Freitag, den 11.05.2018, 13:39 +0100 schrieb Russell King -
>> >> > > ARM Linux:
>> >> > > > On Fri, May 11, 2018 at 05:07:37PM +0530, Pintu Kumar wrote:
>> >> > > > > Hi,
>> >> > > > >
>> >> > > > > I need one help.
>> >> > > > > I am using i.MX7 Sabre board with kernel version 4.1.15
>> >> > > > >
>> >> > > > > Let's say I am interested in GPIO number: 21
>> >> > > > > I wanted to set CPU affinity for particular GPIO->IRQ number,
>> >> > > > > so I
>> >> > > > > tried the below steps:
>> >> > > > > root at 10:~# echo 21 > /sys/class/gpio/export
>> >> > > > > root at 10:~# echo "rising" > /sys/class/gpio/gpio21/edge
>> >> > > > > root at 10:~# cat /proc/interrupts | grep 21
>> >> > > > >   47: 0 0 gpio-mxc 21 Edge gpiolib
>> >> > > > > root at 10:~# cat /sys/class/gpio/gpio21/direction
>> >> > > > > in
>> >> > > > > root at 10:~# cat /proc/irq/47/smp_affinity
>> >> > > > > 3
>> >> > > > > root at 10:~# echo 2 > /proc/irq/47/smp_affinity
>> >> > > > > -bash: echo: write error: Input/output error
>> >> > > > >
>> >> > > > > But I get input/output error.
>> >> > > > > When I debug further, found that irq_can_set_affinity is
>> >> > > > > returning 0:
>> >> > > > > [    0.000000] genirq: irq_can_set_affinity (0): balance: 1,
>> >> > > > > irq_data.chip: a81b7e48, irq_set_affinity:   (null)
>> >> > > > > [    0.000000] write_irq_affinity: FAIL
>> >> > > > >
>> >> > > > > I also tried first setting /proc/irq/default_smp_affinity to
>> >> > > > > 2 (from 3).
>> >> > > > > This change is working, but the smp_affinity setting for the
>> >> > > > > new IRQ
>> >> > > > > is not working.
>> >> > > > >
>> >> > > > > When I try to set smp_affinity for mmc0, then it works.
>> >> > > > > # cat /proc/interrupts | grep mmc
>> >> > > > > 295:         55          0     GPCV2  22 Edge      mmc0
>> >> > > > > 296:          0          0     GPCV2  23 Edge      mmc1
>> >> > > > > 297:         52          0     GPCV2  24 Edge      mmc2
>> >> > > > >
>> >> > > > > root at 10:~# echo 2 > /proc/irq/295/smp_affinity
>> >> > > > > root at 10:~#
>> >> > > > >
>> >> > > > >
>> >> > > > > So, I wanted to know what are the conditions for which
>> >> > > > > setting
>> >> > > > > smp_affinity for an IRQ will work ?
>> >> > > > >
>> >> > > > > Is there any way by which I can set CPU affinity to a GPIO ->
>> >> > > > > IRQ ?
>> >> > > > > Whether, irq_set_affinity_hint() will work in this case ?
>> >> > > >
>> >> > > > IRQ affinity is only supported where interrupts are _directly_
>> >> > > > wired to
>> >> > > > the GIC.  It's the GIC which does the interrupt steering to the
>> >> > > > CPU
>> >> > > > cores.
>> >> > > >
>> >> > > > Interrupts on downstream interrupt controllers (such as GPCV2)
>> >> > > > have no
>> >> > > > ability to be directed independently to other CPUs - the only
>> >> > > > possible
>> >> > > > way to change the mapping is to move _all_ interrupts on that
>> >> > > > controller,
>> >> > > > and any downstream chained interrupts at GIC level.
>> >> > > >
>> >> > > > Hence why Interrupt 295 has no irq_set_affinity function: there
>> >> > > > is no way
>> >> > > > for the interrupt controller itself to change the affinity of
>> >> > > > the input
>> >> > > > interrupt.
>> >> > >
>> >> > > The GPCv2 though is a secondary IRQ controller which has a 1:1
>> >> > > mapping
>> >> > > of its input IRQs to the upstream GIC IRQ lines. Affinity can
>> >> > > thus be
>> >> > > handled by forwarding the request to the GIC by
>> >> > > irq_chip_set_affinity_parent().
>> >> > >
>> >> > > As this is handled correctly in the upstream kernel since the
>> >> > > first
>> >> > > commit introducing support for the GPCv2, it seems the issue is
>> >> > > only
>> >> > > present in some downstream kernel.
>> >> > >
>> >> >
>> >> > OK. Thanks so much for your reply.
>> >> >
>> >> > I saw some of the drivers using irq_set_affinity_hint() to force
>> >> > the
>> >> > IRQ affinity to a particular CPU.
>> >> > This is the sample:
>> >> > {
>> >> > cpumask_clear(mask);
>> >> > cpumask_set_cpu(cpu, mask);
>> >> > irq_set_affinity_hint(irq, mask);
>> >> > }
>> >> >
>> >> > Whether this logic will work for a particular GPIO pin ?
>> >> >
>
>
>>
>> >> >
>> >> > > Regards,
>> >> > > Lucas

^ permalink raw reply

* [PATCH] iommu/io-pgtable-arm: Make allocations NUMA-aware
From: Will Deacon @ 2018-05-21 18:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <b745ecc2acd6aad20b5c3776ecd58022a9019c91.1526926225.git.robin.murphy@arm.com>

On Mon, May 21, 2018 at 07:12:40PM +0100, Robin Murphy wrote:
> We would generally expect pagetables to be read by the IOMMU more than
> written by the CPU, so in NUMA systems it would be preferable to avoid
> the IOMMU making cross-node pagetable walks if possible. We already have
> a handle on the IOMMU device for the sake of coherency management, so
> it's trivial to grab the appropriate NUMA node when allocating new
> pagetable pages.
> 
> Note that we drop the semantics of alloc_pages_exact(), but that's fine
> since they have never been necessary: the only time we're allocating
> more than one page is for stage 2 top-level concatenation, but since
> that is based on the number of IPA bits, the size is always some exact
> power of two anyway.
> 
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  drivers/iommu/io-pgtable-arm.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 39c2a056da21..e80ca386c5b4 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -231,12 +231,16 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
>  				    struct io_pgtable_cfg *cfg)
>  {
>  	struct device *dev = cfg->iommu_dev;
> +	int order = get_order(size);
> +	struct page *p;
>  	dma_addr_t dma;
> -	void *pages = alloc_pages_exact(size, gfp | __GFP_ZERO);
> +	void *pages;
>  
> -	if (!pages)
> +	p = alloc_pages_node(dev_to_node(dev), gfp | __GFP_ZERO, order);
> +	if (!p)
>  		return NULL;
>  
> +	pages = page_address(p);

Might be worth checking/masking out __GFP_HIGHMEM if we see it, since we
could theoretically run into trouble if we got back a highmem mapping here
and we're losing the check in __get_free_pages afaict.

Other than than, looks good:

Acked-by: Will Deacon <will.deacon@arm.com>

Will

^ permalink raw reply

* [PATCH v2] arm: bcm2835: Add the PMU to the devicetree.
From: Eric Anholt @ 2018-05-21 18:39 UTC (permalink / raw)
  To: linux-arm-kernel

This only probes on arm64 so far, but hopefully that driver will be
generalized soon.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/boot/dts/bcm2837.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi
index 7704bb029605..beb6c502dadc 100644
--- a/arch/arm/boot/dts/bcm2837.dtsi
+++ b/arch/arm/boot/dts/bcm2837.dtsi
@@ -17,6 +17,12 @@
 		};
 	};
 
+	arm-pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupt-parent = <&local_intc>;
+		interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	timer {
 		compatible = "arm,armv7-timer";
 		interrupt-parent = <&local_intc>;
-- 
2.17.0

^ permalink raw reply related

* [PATCH RFC] ARM: dts: add Raspberry Pi Compute Module and IO board
From: Eric Anholt @ 2018-05-21 18:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526589872-13459-1-git-send-email-stefan.wahren@i2se.com>

Stefan Wahren <stefan.wahren@i2se.com> writes:

> The Raspberry Pi Compute Module (CM1) is a SoM which contains a
> BCM2835 processor, 512 MB RAM and a 4 GB eMMC. There is also a carrier
> board which is called Compute Module IO Board.
>
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> ---
>  arch/arm/boot/dts/Makefile                |  1 +
>  arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts | 92 +++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi    | 34 ++++++++++++
>  3 files changed, 127 insertions(+)
>  create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
>  create mode 100644 arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index ec2024e..a9883e8 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -73,6 +73,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
>  	bcm2835-rpi-b-rev2.dtb \
>  	bcm2835-rpi-b-plus.dtb \
>  	bcm2835-rpi-a-plus.dtb \
> +	bcm2835-rpi-cm1-io1.dtb \
>  	bcm2836-rpi-2-b.dtb \
>  	bcm2837-rpi-3-b.dtb \
>  	bcm2837-rpi-3-b-plus.dtb \
> diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts b/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
> new file mode 100644
> index 0000000..4d9aa22
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
> @@ -0,0 +1,92 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/dts-v1/;
> +#include "bcm2835-rpi-cm1.dtsi"
> +#include "bcm283x-rpi-usb-host.dtsi"
> +
> +/ {
> +	compatible = "raspberrypi,compute-module", "brcm,bcm2835";
> +	model = "Raspberry Pi Compute Module IO board rev1";
> +};
> +
> +&dsi1 {
> +	status = "okay";
> +};
> +
> +&gpio {
> +	/*
> +	 * This is based on the official GPU firmware DT blob.
> +	 *
> +	 * Legend:
> +	 * "NC" = not connected (no rail from the SoC)
> +	 * "FOO" = GPIO line named "FOO" on the schematic
> +	 * "FOO_N" = GPIO line named "FOO" on schematic, active low
> +	 */
> +	gpio-line-names = "GPIO0",
> +			  "GPIO1",
> +			  "GPIO2",
> +			  "GPIO3",
> +			  "GPIO4",
> +			  "GPIO5",
> +			  "GPIO6",
> +			  "GPIO7",
> +			  "GPIO8",
> +			  "GPIO9",
> +			  "GPIO10",
> +			  "GPIO11",
> +			  "GPIO12",
> +			  "GPIO13",
> +			  "GPIO14",
> +			  "GPIO15",
> +			  "GPIO16",
> +			  "GPIO17",
> +			  "GPIO18",
> +			  "GPIO19",
> +			  "GPIO20",
> +			  "GPIO21",
> +			  "GPIO22",
> +			  "GPIO23",
> +			  "GPIO24",
> +			  "GPIO25",
> +			  "GPIO26",
> +			  "GPIO27",
> +			  "GPIO28",
> +			  "GPIO29",
> +			  "GPIO30",
> +			  "GPIO31",
> +			  "GPIO32",
> +			  "GPIO33",
> +			  "GPIO34",
> +			  "GPIO35",
> +			  "GPIO36",
> +			  "GPIO37",
> +			  "GPIO38",
> +			  "GPIO39",
> +			  "GPIO40",
> +			  "GPIO41",
> +			  "GPIO42",
> +			  "GPIO43",
> +			  "GPIO44",
> +			  "GPIO45",
> +			  "HDMI_HPD_N",
> +			  /* Also used as ACT LED */
> +			  "EMMC_EN_N",
> +			  /* Used by eMMC */
> +			  "SD_CLK_R",
> +			  "SD_CMD_R",
> +			  "SD_DATA0_R",
> +			  "SD_DATA1_R",
> +			  "SD_DATA2_R",
> +			  "SD_DATA3_R";
> +
> +	pinctrl-0 = <&gpioout &alt0>;
> +};
> +
> +&hdmi {
> +	hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
> +};

I think this should be ACTIVE_LOW, since it's "HDMI_HPD_N_1V8", right?

> +
> +&uart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart0_gpio14>;
> +	status = "okay";
> +};
> diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
> new file mode 100644
> index 0000000..ef22c2d
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/dts-v1/;
> +#include "bcm2835.dtsi"
> +#include "bcm2835-rpi.dtsi"
> +
> +/ {
> +	leds {
> +		act {
> +			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +
> +	reg_3v3: fixed-regulator {
> +		compatible = "regulator-fixed";
> +		regulator-name = "3V3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		regulator-always-on;
> +	};
> +
> +	reg_1v8: fixed-regulator {
> +		compatible = "regulator-fixed";
> +		regulator-name = "1V8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		regulator-always-on;
> +	};
> +};
> +
> +&sdhost {
> +	non-removable;
> +	vmmc-supply = <&reg_3v3>;
> +	vqmmc-supply = <&reg_1v8>;
> +};

Also, looking at some datasheets I have laying around, it says "eMMC I/O
Voltage fixed at 1V8" -- is this regulator setup right, in that case?

With answers for these two issues, it will be:

Reviewed-by: Eric Anholt <eric@anholt.net>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180521/aced93f8/attachment.sig>

^ permalink raw reply

* [PATCH v3 0/5]
From: Will Deacon @ 2018-05-21 18:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518143913.26306-1-marc.zyngier@arm.com>

Hi Marc,

Thanks for this.

On Fri, May 18, 2018 at 03:39:08PM +0100, Marc Zyngier wrote:
> PMUv3 has been introduced with ARMv8 and, while it has only been used
> on 64bit systems so far, it would definitely be useful for 32bit
> guests running under KVM/arm64, for example.
> 
> There is also the case of people natively running 32bit kernels on
> 64bit HW and trying to upstream unspeakable hacks, hoping that the
> stars will align and that they'll win the lottery (see [1]).
> 
> So let's try again, and make the PMUv3 driver usable for everyone.
> 
> This is done in three steps:
> (1) Move the driver from arch/arm64 to drivers/perf
> (2) Add a handful of system register accessors so that we can reuse
>     the driver on 32bit
> (3) Provide the same accessors on 32bit, enable compilation, and
>     make it the default selection for mach-virt.
> 
> Tested on a Seattle box with 32bit guests.

I think we should go ahead with something like this, but I don't think
we're quite there with these patches. If we're going to move the arch code
out into drivers, let's do that for the perf_event* files under arch/arm/
as well. Then we could have a structure along the lines of:


  drivers/perf/arm_pmu.c			- As it is today
  drivers/perf/arm_cpu/xscale_pmu.c		- Only builds for 32-bit
  drivers/perf/arm_cpu/armv6_pmu.c		- Only builds for 32-bit
  drivers/perf/arm_cpu/arch_pmu.c		- Works for v7/v8 on
                                                  both 32-bit and 64-bit

The latter can then pull in whatever accessors it needs from the arch
code headers.

I know it's more of an invasive change, but this way we always end up
running the same code on the two architectures and it will be much easier
to maintain.

Will

^ permalink raw reply

* [PATCH] arm64: Kconfig: Enable LSE atomics by default
From: Will Deacon @ 2018-05-21 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we're seeing CPUs shipping with LSE atomics, default them to
'on' in Kconfig. CPUs without the instructions will continue to use
LDXR/STXR-based sequences, but they will be placed out-of-line by the
compiler.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4d98774cf3c7..3aed13626fd7 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1051,6 +1051,7 @@ config ARM64_PAN
 
 config ARM64_LSE_ATOMICS
 	bool "Atomic instructions"
+	default y
 	help
 	  As part of the Large System Extensions, ARMv8.1 introduces new
 	  atomic instructions that are designed specifically to scale in
@@ -1059,7 +1060,8 @@ config ARM64_LSE_ATOMICS
 	  Say Y here to make use of these instructions for the in-kernel
 	  atomic routines. This incurs a small overhead on CPUs that do
 	  not support these instructions and requires the kernel to be
-	  built with binutils >= 2.25.
+	  built with binutils >= 2.25 in order for the new instructions
+	  to be used.
 
 config ARM64_VHE
 	bool "Enable support for Virtualization Host Extensions (VHE)"
-- 
2.1.4

^ permalink raw reply related

* [PATCH] iommu/io-pgtable-arm: Make allocations NUMA-aware
From: Robin Murphy @ 2018-05-21 18:12 UTC (permalink / raw)
  To: linux-arm-kernel

We would generally expect pagetables to be read by the IOMMU more than
written by the CPU, so in NUMA systems it would be preferable to avoid
the IOMMU making cross-node pagetable walks if possible. We already have
a handle on the IOMMU device for the sake of coherency management, so
it's trivial to grab the appropriate NUMA node when allocating new
pagetable pages.

Note that we drop the semantics of alloc_pages_exact(), but that's fine
since they have never been necessary: the only time we're allocating
more than one page is for stage 2 top-level concatenation, but since
that is based on the number of IPA bits, the size is always some exact
power of two anyway.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
 drivers/iommu/io-pgtable-arm.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 39c2a056da21..e80ca386c5b4 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -231,12 +231,16 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
 				    struct io_pgtable_cfg *cfg)
 {
 	struct device *dev = cfg->iommu_dev;
+	int order = get_order(size);
+	struct page *p;
 	dma_addr_t dma;
-	void *pages = alloc_pages_exact(size, gfp | __GFP_ZERO);
+	void *pages;
 
-	if (!pages)
+	p = alloc_pages_node(dev_to_node(dev), gfp | __GFP_ZERO, order);
+	if (!p)
 		return NULL;
 
+	pages = page_address(p);
 	if (!(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)) {
 		dma = dma_map_single(dev, pages, size, DMA_TO_DEVICE);
 		if (dma_mapping_error(dev, dma))
@@ -256,7 +260,7 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
 	dev_err(dev, "Cannot accommodate DMA translation for IOMMU page tables\n");
 	dma_unmap_single(dev, dma, size, DMA_TO_DEVICE);
 out_free:
-	free_pages_exact(pages, size);
+	__free_pages(p, order);
 	return NULL;
 }
 
@@ -266,7 +270,7 @@ static void __arm_lpae_free_pages(void *pages, size_t size,
 	if (!(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA))
 		dma_unmap_single(cfg->iommu_dev, __arm_lpae_dma_addr(pages),
 				 size, DMA_TO_DEVICE);
-	free_pages_exact(pages, size);
+	free_pages((unsigned long)pages, get_order(size));
 }
 
 static void __arm_lpae_sync_pte(arm_lpae_iopte *ptep,
-- 
2.17.0.dirty

^ permalink raw reply related

* [PATCH 1/6] ARM: OMAP1: ams-delta: add GPIO lookup tables
From: Janusz Krzysztofik @ 2018-05-21 18:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180521173519.GA98604@atomide.com>

On Monday, May 21, 2018 7:35:19 PM CEST Tony Lindgren wrote:
> Hi,
> 
> * Janusz Krzysztofik <jmkrzyszt@gmail.com> [180518 14:12]:
> > Scope of the change is limited to GPIO pins used by board specific
> > device drivers which will be updated by follow-up patches of the
> > series. Those are some OMAP GPIO (gpio-0-15) and most of Amstrad Delta
> > latch2 GPIO bank pins. Remaining pins of those banks, as well as
> > Amstrad Delta latch1 pins, will be addressed later.
> > 
> > Assign a label ("latch2") to the bank, enumerate its pins and put that
> > information, together with OMAP GPIO bank pins, in GPIO lookup tables.
> > Assign lookup tables to devices as soon as those devices are registered
> > and their names can be obtained.
> > 
> > A step froward in:
> > - removal of hard-coded GPIO numbers from drivers,
> > - removal of board mach includes from drivers,
> > - switching to dynamically assigned GPIO numbers.
> 
> Is this first patch safe for me to apply separately?

Absolutely, it is.

Thanks,
Janusz

^ permalink raw reply

* [PATCH v3 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: Doug Anderson @ 2018-05-21 18:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <dc1fbe9c-8973-1c4d-0fbd-809c1ec0a6be@codeaurora.org>

Hi,

On Fri, May 18, 2018 at 5:46 PM, David Collins <collinsd@codeaurora.org> wrote:
> On 05/17/2018 06:01 PM, Doug Anderson wrote:
>> On Thu, May 17, 2018 at 5:16 PM, David Collins <collinsd@codeaurora.org> wrote:
>>> On 05/17/2018 02:22 PM, Doug Anderson wrote:
>>>> On Fri, May 11, 2018 at 7:28 PM, David Collins <collinsd@codeaurora.org> wrote:
>>>>> +- qcom,regulator-initial-microvolt
>>>>> +       Usage:      optional; VRM regulators only
>>>>> +       Value type: <u32>
>>>>> +       Definition: Specifies the initial voltage in microvolts to request for a
>>>>> +                   VRM regulator.
>>>>
>>>> Now that Mark has landed the patch adding support for the
>>>> -ENOTRECOVERABLE error code from get_voltage() / get_voltage_sel(), do
>>>> we still need the qcom,regulator-initial-microvolt property?
>>>
>>> Yes, this is still needed.  The -ENOTRECOVERABLE patch ensures that
>>> qcom-rpmh-regulator devices can be registered even if
>>> qcom,regulator-initial-microvolt is not specified.  However, that will
>>> result in the regulators being configured for the minimum voltage
>>> supported in the DT specified min/max range.  The
>>> qcom,regulator-initial-microvolt property allows us to set a specific
>>> voltage that is larger than the min constraint.
>>
>> Ah, OK.  In the device tree fragment I saw the initial was always
>> equal to the min, so I wasn't sure if this was really needed in
>> practice.  I presume it would only be important if a voltage was left
>> high by the bootloader for some peripheral that needs to continue to
>> function (and use the existing higher voltage) until a real device
>> claims it.  For all other voltages, it should be fine if it's set to
>> the min until a real device claims it.  Do you have real examples of
>> devices like this in boards using sdm845?
>
> Something to keep in mind about the downstream rpmh-regulator driver is
> that it caches the initial voltages specified in device tree and only
> sends them after a consumer driver makes a regulator framework call. This
> saves time during boot and ensures that requests are not made for
> regulators that no Linux consumer cares about.

You're saying that in the downstream driver you'd specify
"initial-voltage" in the device tree and:

* This voltage would be reported by any subsequent get_voltage() calls

* This voltage would _not_ be communicated to RPMh.

That seems really strange because you're essentially going to be
returning something from get_voltage() that could be a lie.  You don't
know if the BIOS actually set the value or not but you'll claim that
it did.  It also doesn't seem to match what I see in the downstream
driver.  There I see it read "qcom,init-voltage" and then do a
"rpmh_regulator_set_reg()".  Thus my reading of the downstream driver
is that it should do the same requests that you're doing.


> It is generally not safe to request all regulators to be set to the
> minimum allowed voltage.  Special care will be needed with the upstream
> qcom-rpmh-regulator driver to avoid disrupting the boot up state of
> regulators that are needed by other subsystems.  Therefore, I would like
> to keep the initial voltage feature supported.

I was asking for specific examples.  Do you have any?


BTW: have I already said how terrible of a design it is that you can't
read back the voltages that the BIOS set?  If we could just read back
what the BIOS set then everything would work great and we could stop
talking about this.


>>>>> +- qcom,allowed-drms-modes
>>>>> +       Usage:      required if regulator-allow-set-load is specified;
>>>>> +                   VRM regulators only
>>>>> +       Value type: <prop-encoded-array>
>>>>> +       Definition: A list of integers specifying the PMIC regulator modes which
>>>>> +                   can be configured at runtime based upon consumer load needs.
>>>>> +                   Supported values are RPMH_REGULATOR_MODE_* which are defined
>>>>> +                   in [1] (i.e. 0 to 3).
>>>>
>>>> Why is this still here?  You moved it to the core regulator framework,
>>>> right?  It's still in your examples too.  Shouldn't this be removed?
>>>> It looks like the driver still needs this and it needs to be an exact
>>>> duplicate of the common binding.  That doesn't seem right...
>>>
>>> The qcom,allowed-drms-modes property supports a different feature than the
>>> regulator-allowed-modes property accepted in [2].  The latter specifies
>>> the modes that may be used at all (e.g. in regulator_set_mode() calls) and
>>> it lists the mode values in an unordered fashion.
>>>
>>> qcom,allowed-drms-modes defines a specific subset of the possible allowed
>>> modes that should be set based on DRMS (e.g. in regulator_set_load()
>>> calls).  Its values are listed in a specific order and must match 1-to-1
>>> with qcom,drms-mode-max-microamps entries.
>>>
>>> It would probably be good to change the name of the property from
>>> qcom,allowed-drms-modes to qcom,regulator-drms-modes.
>>
>> Ah, I see.  It's unfortunate that now we need to effectively list all
>> modes twice.  Have you seen real-life examples where these sets of
>> modes need to be different, or is this just theoretical?  If not can
>> we start with one property (that controls both things) and if we
>> really see that we need to specify different sets of modes for the two
>> cases we can add a separate property?  ...actually, even if you do
>> have real-life examples of where these need to be different, if 90% of
>> the time they are the same it would still be nice to just have one
>> property apply to both cases.
>
> I plan to keep qcom,regulator-drms-modes (and
> qcom,drms-mode-max-microamps) around as a property specifically handled
> for qcom-rpmh-regulator.  It serves a purpose that is distinct from that
> of the generic regulator-allowed-modes.  Without it, there will not be a
> way to utilize regulator_set_load() to configure the regulator modes.

I guess we'll have to wait for Mark's opinion here.  If it were up to
me I wouldn't accept things with two properties, but if Mark is happy
with it then I won't yell.  To make it really clear what we're talking
about, currently the bindings want you to specify both:

regulator-allowed-modes =
  <RPMH_REGULATOR_MODE_LPM
   RPMH_REGULATOR_MODE_HPM>;
qcom,allowed-drms-modes =
  <RPMH_REGULATOR_MODE_LPM
   RPMH_REGULATOR_MODE_HPM>;
qcom,drms-mode-max-microamps = <1 500000>;

...with the argument that "regulator-allowed-modes" is unordered and
"qcom,allowed-drms-modes" is ordered and needs to match with
"qcom,drms-mode-max-microamps".  ...and also (in theory) you could
come up with an example where the set of allowed modes could be
different sometimes.


>>>>> +- qcom,drms-mode-max-microamps
>>>>> +       Usage:      required if regulator-allow-set-load is specified;
>>>>> +                   VRM regulators only
>>>>> +       Value type: <prop-encoded-array>
>>>>> +       Definition: A list of integers specifying the maximum allowed load
>>>>> +                   current in microamps for each of the modes listed in
>>>>> +                   qcom,allowed-drms-modes (matched 1-to-1 in order).  Elements
>>>>> +                   must be specified in order from lowest to highest value.
>>>>
>>>> Any reason this can't go into the regulator core?  You'd basically
>>>> just take the existing concept of rpmh_regulator_vrm_set_load() and
>>>> put it in the core.
>>>
>>> This could be implemented in the core via new constraint elements parsed
>>> in of_regulator and a helper function to specify in regulator_ops.
>>> However, I'm not sure about the wide-spread applicability of this feature.
>>>  I'd prefer to leave it in the driver unless Mark would like me to add it
>>> into the core.
>>
>> You're already using pre-existing APIs around specifying the current
>> and having the regulator core call you to map the total current into a
>> mode.  That implies that this is applicable to others.  Adding this
>> tiny amount of code to the core makes the pre-existing APIs generally
>> useful.
>
> I don't see the benefit of making struct regulation_constraints more
> complicated with DRMS mode and current arrays that would only every be
> used by the qcom-rpmh-regulator driver.  Other regulator drivers are able
> to hard code this information in the driver code using get_optimum_mode()
> callbacks.

IMO this belongs in the core since it's a generic mechanism and if
drivers want to implement their own custom thing they can, but again
whatever Mark says goes so I guess we'll leave it to him.


> As a side note, changing qcom-rpmh-regulator to use a get_optimum_mode()
> callback instead of a set_load() callback would probably be a good idea too.

Yeah, I remember wondering this earlier and it seemed like it was 6 of
one half dozen of the other.  ...the downside of using
get_optimum_mode() is that it requires a valid input voltage to be
supplied.  It also makes a handful of other calls that you probably
don't need in your case.


-Doug

^ permalink raw reply

* [PATCH 12/33] clk: bcm2835: use match_string() helper
From: Eric Anholt @ 2018-05-21 17:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526903890-35761-13-git-send-email-xieyisheng1@huawei.com>

Yisheng Xie <xieyisheng1@huawei.com> writes:

> match_string() returns the index of an array for a matching string,
> which can be used intead of open coded variant.
>
> Cc: Michael Turquette <mturquette@baylibre.com>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Cc: Eric Anholt <eric@anholt.net>
> Cc: Stefan Wahren <stefan.wahren@i2se.com>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-rpi-kernel at lists.infradead.org
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Yisheng Xie <xieyisheng1@huawei.com>
> ---
>  drivers/clk/bcm/clk-bcm2835.c | 14 ++++++--------
>  1 file changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
> index fa0d5c8..a27c0d2 100644
> --- a/drivers/clk/bcm/clk-bcm2835.c
> +++ b/drivers/clk/bcm/clk-bcm2835.c
> @@ -1395,8 +1395,7 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
>  	struct bcm2835_clock *clock;
>  	struct clk_init_data init;
>  	const char *parents[1 << CM_SRC_BITS];
> -	size_t i, j;
> -	int ret;
> +	int i, ret;
>  
>  	/*
>  	 * Replace our strings referencing parent clocks with the
> @@ -1405,12 +1404,11 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
>  	for (i = 0; i < data->num_mux_parents; i++) {
>  		parents[i] = data->parents[i];
>  
> -		for (j = 0; j < ARRAY_SIZE(cprman_parent_names); j++) {
> -			if (strcmp(parents[i], cprman_parent_names[j]) == 0) {
> -				parents[i] = cprman->real_parent_names[j];
> -				break;
> -			}
> -		}
> +		ret = match_string(cprman_parent_names,
> +				   ARRAY_SIZE(cprman_parent_names),
> +				   parents[i]);
> +		if (ret >= 0)
> +			parents[i] = cprman->real_parent_names[ret];

Reviewed-by: Eric Anholt <eric@anholt.net>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180521/d011e272/attachment.sig>

^ permalink raw reply

* [PATCH 1/6] ARM: OMAP1: ams-delta: add GPIO lookup tables
From: Tony Lindgren @ 2018-05-21 17:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180518210954.29044-1-jmkrzyszt@gmail.com>

Hi,

* Janusz Krzysztofik <jmkrzyszt@gmail.com> [180518 14:12]:
> Scope of the change is limited to GPIO pins used by board specific
> device drivers which will be updated by follow-up patches of the
> series. Those are some OMAP GPIO (gpio-0-15) and most of Amstrad Delta
> latch2 GPIO bank pins. Remaining pins of those banks, as well as
> Amstrad Delta latch1 pins, will be addressed later.
> 
> Assign a label ("latch2") to the bank, enumerate its pins and put that
> information, together with OMAP GPIO bank pins, in GPIO lookup tables.
> Assign lookup tables to devices as soon as those devices are registered
> and their names can be obtained.
> 
> A step froward in:
> - removal of hard-coded GPIO numbers from drivers,
> - removal of board mach includes from drivers,
> - switching to dynamically assigned GPIO numbers.

Is this first patch safe for me to apply separately?

Regards,

Tony

^ permalink raw reply

* [PATCH 06/15] drm/sun4i: tcon: Add support for tcon-top
From: Jernej Škrabec @ 2018-05-21 17:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180521080759.rgviuva65ijcfm2e@flea>

Hi,

Dne ponedeljek, 21. maj 2018 ob 10:07:59 CEST je Maxime Ripard napisal(a):
> On Sat, May 19, 2018 at 08:31:18PM +0200, Jernej Skrabec wrote:
> > If SoC has TCON TOP unit, it has to be configured from TCON, since it
> > has all information needed. Additionally, if it is TCON TV, it must also
> > enable bus gate inside TCON TOP unit.
> 
> Why?

I'll explain my design decision below.

> 
> > Add support for such TCONs.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/gpu/drm/sun4i/sun4i_tcon.c | 28 ++++++++++++++++++++++++++++
> >  drivers/gpu/drm/sun4i/sun4i_tcon.h |  8 ++++++++
> >  2 files changed, 36 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 08747fc3ee71..e0c562ce1c22
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > @@ -688,6 +688,16 @@ static int sun4i_tcon_init_clocks(struct device *dev,
> > 
> >  		dev_err(dev, "Couldn't get the TCON bus clock\n");
> >  		return PTR_ERR(tcon->clk);
> >  	
> >  	}
> > 
> > +
> > +	if (tcon->quirks->needs_tcon_top && tcon->quirks->has_channel_1) {
> > +		tcon->top_clk = devm_clk_get(dev, "tcon-top");
> > +		if (IS_ERR(tcon->top_clk)) {
> > +			dev_err(dev, "Couldn't get the TCON TOP bus clock\n");
> > +			return PTR_ERR(tcon->top_clk);
> > +		}
> > +		clk_prepare_enable(tcon->top_clk);
> > +	}
> > +
> > 
> >  	clk_prepare_enable(tcon->clk);
> >  	
> >  	if (tcon->quirks->has_channel_0) {
> > 
> > @@ -712,6 +722,7 @@ static int sun4i_tcon_init_clocks(struct device *dev,
> > 
> >  static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon)
> >  {
> >  
> >  	clk_disable_unprepare(tcon->clk);
> > 
> > +	clk_disable_unprepare(tcon->top_clk);
> > 
> >  }
> >  
> >  static int sun4i_tcon_init_irq(struct device *dev,
> > 
> > @@ -980,6 +991,23 @@ static int sun4i_tcon_bind(struct device *dev, struct
> > device *master,> 
> >  	tcon->id = engine->id;
> >  	tcon->quirks = of_device_get_match_data(dev);
> > 
> > +	if (tcon->quirks->needs_tcon_top) {
> > +		struct device_node *np;
> > +
> > +		np = of_parse_phandle(dev->of_node, "allwinner,tcon-top", 0);
> > +		if (np) {
> > +			struct platform_device *pdev;
> > +
> > +			pdev = of_find_device_by_node(np);
> > +			if (pdev)
> > +				tcon->tcon_top = platform_get_drvdata(pdev);
> > +			of_node_put(np);
> > +
> > +			if (!tcon->tcon_top)
> > +				return -EPROBE_DEFER;
> > +		}
> > +	}
> > +
> 
> I might have missed it, but I've not seen the bindings additions for
> that property. This shouldn't really be done that way anyway, instead
> of using a direct phandle, you should be using the of-graph, with the
> TCON-top sitting where it belongs in the flow of data.

Just to answer to the first question, it did describe it in "[PATCH 07/15] dt-
bindings: display: sun4i-drm: Add R40 HDMI pipeline".

As why I designed it that way - HW representation could be described that way 
(ASCII art makes sense when fixed width font is used to view it):

                            / LCD0/LVDS0
                / TCON-LCD0
                |           \ MIPI DSI
mixer0          |
       \        / TCON-LCD1 - LCD1/LVDS1
        TCON-TOP
       /        \ TCON-TV0 - TVE0/RGB
mixer1          |          \
                |           TCON-TOP - HDMI
                |          /
                \ TCON-TV1 - TVE1/RGB

This is a bit simplified, since there is also TVE-TOP, which is responsible 
for sharing 4 DACs between both TVE encoders. You can have two TV outs (PAL/
NTSC) or TVE0 as TV out and TVE1 as RGB or vice versa. It even seems that you 
can arbitrarly choose which DAC is responsible for which signal, so there is a 
ton of possible end combinations, but I'm not 100% sure.

Even though I wrote TCON-TOP twice, this is same unit in HW. R40 manual 
suggest more possibilities, although some of them seem wrong, like RGB feeding 
from LCD TCON. That is confirmed to be wrong when checking BSP code. 

Additionally, TCON-TOP comes in the middle of TVE0 and LCD0, TVE1 and LCD1 for 
pin muxing, although I'm not sure why is that needed at all, since according 
to R40 datasheet, TVE0 and TVE1 pins are dedicated and not on PORT D and PORT 
H, respectively, as TCON-TOP documentation suggest. However, HSYNC and PSYNC 
lines might be shared between TVE (when it works in RGB mode) and LCD. But 
that is just my guess since I'm not really familiar with RGB and LCD 
interfaces.

I'm really not sure what would be the best representation in OF-graph. Can you 
suggest one?

On the other hand, mux callback in TCON driver has all available informations 
at hand. It knows mixer ID, TCON ID and most importantly, encoder type. Based 
on all that informations, it's easy to configure TCON TOP.

I hope you understand. If you have better idea, I'm all ears, since phandle 
seems a bit weird to me too, but I think it's the only future proof, when 
adding LVDS, RGB, TVE or LCD support.

Best regards,
Jernej

^ permalink raw reply

* arm64: add missing early clobber in atomic64_dec_if_positive()
From: Will Deacon @ 2018-05-21 17:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c540dd519065316c859e5cb1290de7f5041cb816.camel@redhat.com>

On Mon, May 21, 2018 at 01:18:39PM -0400, Mark Salter wrote:
> On Mon, 2018-05-21 at 18:00 +0100, Will Deacon wrote:
> > Hi Mark,
> > 
> > Thanks for reporting this.
> > 
> > On Sat, May 19, 2018 at 08:17:26PM -0400, Mark Salter wrote:
> > > When running a kernel compiled with gcc8 on a machine using LSE, I
> > > get:
> > > 
> > >  Unable to handle kernel paging request at virtual address 11111122222221
> > 
> > [...]
> > 
> > > The fault happens at the casal insn of inlined atomic64_dec_if_positive().
> > > The inline asm code in that function has:
> > > 
> > > 	"1:	ldr	x30, %[v]\n"
> > > 	"	subs	%[ret], x30, #1\n"
> > > 	"	b.lt	2f\n"
> > > 	"	casal	x30, %[ret], %[v]\n"
> > > 	"	sub	x30, x30, #1\n"
> > > 	"	sub	x30, x30, %[ret]\n"
> > > 	"	cbnz	x30, 1b\n"
> > > 	"2:")
> > > 	: [ret] "+r" (x0), [v] "+Q" (v->counter)
> > > 
> > > gcc8 used register x0 for both [ret] and [v] and the subs was
> > > clobbering [v] before it was used for casal. Gcc is free to do
> > > this because [ret] lacks an early clobber modifier. So add one
> > > to tell gcc a separate register is needed for [v].
> > 
> > Oh blimey, it looks like GCC is realising that counter is at offset 0
> > of atomic_t and therefore assigns the same register for [ret] and [v],
> > which is actually forced to be x0 by the 'register' local variable in
> > C code. The "+Q" constraint only says that the memory is read/write, so
> > the pointer is fair game.
> > 
> > I agree with your fix, but we also need to fix up the other places relying
> > on this. Patch below -- please yell if you think I missed any.
> 
> I looked at the other places but figured they were okay because we're
> explicitly using separate registers. But I suppose the early clobber
> is the right thing to do in any case.

I was worried about silly things like a caller doing:

  atomic64_and((long)v, v);

and then GCC figuring out that the two values were equal and allocating
the same register..

Will

^ 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