* [PATCH] ARM64: dts: meson-gx: fix ATF reserved memory region
From: Kevin Hilman @ 2018-06-08 23:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607205514.36631-1-khilman@baylibre.com>
Kevin Hilman <khilman@baylibre.com> writes:
> Vendor firmware/uboot has different reserved regions depending on
> firmware version, but current codebase reserves the same regions on
> GXL and GXBB, so move the additional reserved memory region to common
> .dtsi.
>
> Found when putting a recent vendor u-boot on meson-gxbb-p200.
>
> Recommended-by: Neil Armstrong <narmstrong@baylibre.com>
oops, this should've been the more common "Suggested-by". Fixed, and
then...
> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
...added a Cc:stable and applied to v4.18/fixes.
Kevin
> ---
> arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
> arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 8 --------
> 2 files changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> index b003f324ca31..b8dc4dbb391b 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> @@ -35,6 +35,12 @@
> no-map;
> };
>
> + /* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
> + secmon_reserved_alt: secmon at 5000000 {
> + reg = <0x0 0x05000000 0x0 0x300000>;
> + no-map;
> + };
> +
> linux,cma {
> compatible = "shared-dma-pool";
> reusable;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
> index 27538eea547b..c87a80e9bcc6 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
> @@ -13,14 +13,6 @@
> / {
> compatible = "amlogic,meson-gxl";
>
> - reserved-memory {
> - /* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
> - secmon_reserved_alt: secmon at 5000000 {
> - reg = <0x0 0x05000000 0x0 0x300000>;
> - no-map;
> - };
> - };
> -
> soc {
> usb0: usb at c9000000 {
> status = "disabled";
^ permalink raw reply
* [PATCH v2] ARM64: dts: meson: fix register ranges for SD/eMMC
From: Kevin Hilman @ 2018-06-08 23:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180605215937.16634-1-khilman@baylibre.com>
Kevin Hilman <khilman@baylibre.com> writes:
> Based on updated information from Amlogic, correct the register range
> for the SD/eMMC blocks to the right size.
>
> Reported-by: Yixun Lan <yixun.lan@amlogic.com>
> Tested-by: Yixun Lan <yixun.lan@amlogic.com>
> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
Applied to v4.18/fixes,
Kevin
^ permalink raw reply
* [PATCH] ARM64: dts: meson-gxl-s905x-p212: Add phy-supply for usb0
From: Kevin Hilman @ 2018-06-08 23:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAFBinCCF7v40PrtL3HVf9X-fEVx7P2uOVePa5wQ_y6s7uLKmnw@mail.gmail.com>
Martin Blumenstingl <martin.blumenstingl@googlemail.com> writes:
> On Tue, Jun 5, 2018 at 10:52 AM, Neil Armstrong <narmstrong@baylibre.com> wrote:
>> Like LibreTech-CC, the USB0 needs the 5V regulator to be enabled to power the
>> devices on the P212 Reference Design based boards.
>>
>> Fixes: b9f07cb4f41f ("ARM64: dts: meson-gxl-s905x-p212: enable the USB controller")
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>
> Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Applied to v4.18/fixes (will queue for v4.18-rc).
Kevin
^ permalink raw reply
* [PATCH v7 2/2] regulator: add QCOM RPMh regulator driver
From: David Collins @ 2018-06-08 23:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1528498807.git.collinsd@codeaurora.org>
Add the QCOM RPMh regulator driver to manage PMIC regulators
which are controlled via RPMh on some Qualcomm Technologies, Inc.
SoCs. RPMh is a hardware block which contains several
accelerators which are used to manage various hardware resources
that are shared between the processors of the SoC. The final
hardware state of a regulator is determined within RPMh by
performing max aggregation of the requests made by all of the
processors.
Add support for PMIC regulator control via the voltage regulator
manager (VRM) and oscillator buffer (XOB) RPMh accelerators.
VRM supports manipulation of enable state, voltage, and mode.
XOB supports manipulation of enable state.
Signed-off-by: David Collins <collinsd@codeaurora.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
---
drivers/regulator/Kconfig | 9 +
drivers/regulator/Makefile | 1 +
drivers/regulator/qcom-rpmh-regulator.c | 753 ++++++++++++++++++++++++++++++++
3 files changed, 763 insertions(+)
create mode 100644 drivers/regulator/qcom-rpmh-regulator.c
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 5dbccf5..96b701f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -682,6 +682,15 @@ config REGULATOR_QCOM_RPM
Qualcomm RPM as a module. The module will be named
"qcom_rpm-regulator".
+config REGULATOR_QCOM_RPMH
+ tristate "Qualcomm Technologies, Inc. RPMh regulator driver"
+ depends on QCOM_RPMH || COMPILE_TEST
+ help
+ This driver supports control of PMIC regulators via the RPMh hardware
+ block found on Qualcomm Technologies Inc. SoCs. RPMh regulator
+ control allows for voting on regulator state between multiple
+ processors within the SoC.
+
config REGULATOR_QCOM_SMD_RPM
tristate "Qualcomm SMD based RPM regulator driver"
depends on QCOM_SMD_RPM
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index bd818ce..06e76a6 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
+obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
new file mode 100644
index 0000000..6f61625
--- /dev/null
+++ b/drivers/regulator/qcom-rpmh-regulator.c
@@ -0,0 +1,753 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+#include <soc/qcom/cmd-db.h>
+#include <soc/qcom/rpmh.h>
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+/**
+ * enum rpmh_regulator_type - supported RPMh accelerator types
+ * %VRM: RPMh VRM accelerator which supports voting on enable, voltage,
+ * and mode of LDO, SMPS, and BOB type PMIC regulators.
+ * %XOB: RPMh XOB accelerator which supports voting on the enable state
+ * of PMIC regulators.
+ */
+enum rpmh_regulator_type {
+ VRM,
+ XOB,
+};
+
+#define RPMH_REGULATOR_REG_VRM_VOLTAGE 0x0
+#define RPMH_REGULATOR_REG_ENABLE 0x4
+#define RPMH_REGULATOR_REG_VRM_MODE 0x8
+
+#define RPMH_REGULATOR_MODE_COUNT 4
+
+#define PMIC4_LDO_MODE_RETENTION 4
+#define PMIC4_LDO_MODE_LPM 5
+#define PMIC4_LDO_MODE_HPM 7
+
+#define PMIC4_SMPS_MODE_RETENTION 4
+#define PMIC4_SMPS_MODE_PFM 5
+#define PMIC4_SMPS_MODE_AUTO 6
+#define PMIC4_SMPS_MODE_PWM 7
+
+#define PMIC4_BOB_MODE_PASS 0
+#define PMIC4_BOB_MODE_PFM 1
+#define PMIC4_BOB_MODE_AUTO 2
+#define PMIC4_BOB_MODE_PWM 3
+
+/**
+ * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations
+ * @regulator_type: RPMh accelerator type used to manage this
+ * regulator
+ * @ops: Pointer to regulator ops callback structure
+ * @voltage_range: The single range of voltages supported by this
+ * PMIC regulator type
+ * @n_voltages: The number of unique voltage set points defined
+ * by voltage_range
+ * @hpm_min_load_uA: Minimum load current in microamps that requires
+ * high power mode (HPM) operation. This is used
+ * for LDO hardware type regulators only.
+ * @pmic_mode_map: Array indexed by regulator framework mode
+ * containing PMIC hardware modes. Must be large
+ * enough to index all framework modes supported
+ * by this regulator hardware type.
+ * @of_map_mode: Maps an RPMH_REGULATOR_MODE_* mode value defined
+ * in device tree to a regulator framework mode
+ */
+struct rpmh_vreg_hw_data {
+ enum rpmh_regulator_type regulator_type;
+ const struct regulator_ops *ops;
+ const struct regulator_linear_range voltage_range;
+ int n_voltages;
+ int hpm_min_load_uA;
+ const int *pmic_mode_map;
+ unsigned int (*of_map_mode)(unsigned int mode);
+};
+
+/**
+ * struct rpmh_vreg - individual RPMh regulator data structure encapsulating a
+ * single regulator device
+ * @dev: Device pointer for the top-level PMIC RPMh
+ * regulator parent device. This is used as a
+ * handle in RPMh write requests.
+ * @addr: Base address of the regulator resource within
+ * an RPMh accelerator
+ * @rdesc: Regulator descriptor
+ * @hw_data: PMIC regulator configuration data for this RPMh
+ * regulator
+ * @always_wait_for_ack: Boolean flag indicating if a request must always
+ * wait for an ACK from RPMh before continuing even
+ * if it corresponds to a strictly lower power
+ * state (e.g. enabled --> disabled).
+ * @enabled: Flag indicating if the regulator is enabled or
+ * not
+ * @bypassed: Boolean indicating if the regulator is in
+ * bypass (pass-through) mode or not. This is
+ * only used by BOB rpmh-regulator resources.
+ * @voltage_selector: Selector used for get_voltage_sel() and
+ * set_voltage_sel() callbacks
+ * @mode: RPMh VRM regulator current framework mode
+ */
+struct rpmh_vreg {
+ struct device *dev;
+ u32 addr;
+ struct regulator_desc rdesc;
+ const struct rpmh_vreg_hw_data *hw_data;
+ bool always_wait_for_ack;
+
+ int enabled;
+ bool bypassed;
+ int voltage_selector;
+ unsigned int mode;
+};
+
+/**
+ * struct rpmh_vreg_init_data - initialization data for an RPMh regulator
+ * @name: Name for the regulator which also corresponds
+ * to the device tree subnode name of the regulator
+ * @resource_name: RPMh regulator resource name format string.
+ * This must include exactly one field: '%s' which
+ * is filled at run-time with the PMIC ID provided
+ * by device tree property qcom,pmic-id. Example:
+ * "ldo%s1" for RPMh resource "ldoa1".
+ * @supply_name: Parent supply regulator name
+ * @hw_data: Configuration data for this PMIC regulator type
+ */
+struct rpmh_vreg_init_data {
+ const char *name;
+ const char *resource_name;
+ const char *supply_name;
+ const struct rpmh_vreg_hw_data *hw_data;
+};
+
+/**
+ * rpmh_regulator_send_request() - send the request to RPMh
+ * @vreg: Pointer to the RPMh regulator
+ * @cmd: Pointer to the RPMh command to send
+ * @wait_for_ack: Boolean indicating if execution must wait until the
+ * request has been acknowledged as complete
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_send_request(struct rpmh_vreg *vreg,
+ struct tcs_cmd *cmd, bool wait_for_ack)
+{
+ int ret;
+
+ if (wait_for_ack || vreg->always_wait_for_ack)
+ ret = rpmh_write(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd, 1);
+ else
+ ret = rpmh_write_async(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd,
+ 1);
+
+ return ret;
+}
+
+static int _rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned int selector, bool wait_for_ack)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
+ };
+ int ret;
+
+ /* VRM voltage control register is set with voltage in millivolts. */
+ cmd.data = DIV_ROUND_UP(regulator_list_voltage_linear_range(rdev,
+ selector), 1000);
+
+ ret = rpmh_regulator_send_request(vreg, &cmd, wait_for_ack);
+ if (!ret)
+ vreg->voltage_selector = selector;
+
+ return ret;
+}
+
+static int rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+ if (vreg->enabled == -EINVAL) {
+ /*
+ * Cache the voltage and send it later when the regulator is
+ * enabled or disabled.
+ */
+ vreg->voltage_selector = selector;
+ return 0;
+ }
+
+ return _rpmh_regulator_vrm_set_voltage_sel(rdev, selector,
+ selector > vreg->voltage_selector);
+}
+
+static int rpmh_regulator_vrm_get_voltage_sel(struct regulator_dev *rdev)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+ return vreg->voltage_selector;
+}
+
+static int rpmh_regulator_is_enabled(struct regulator_dev *rdev)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+ return vreg->enabled;
+}
+
+static int rpmh_regulator_set_enable_state(struct regulator_dev *rdev,
+ bool enable)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
+ .data = enable,
+ };
+ int ret;
+
+ if (vreg->enabled == -EINVAL &&
+ vreg->voltage_selector != -ENOTRECOVERABLE) {
+ ret = _rpmh_regulator_vrm_set_voltage_sel(rdev,
+ vreg->voltage_selector, true);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = rpmh_regulator_send_request(vreg, &cmd, enable);
+ if (!ret)
+ vreg->enabled = enable;
+
+ return ret;
+}
+
+static int rpmh_regulator_enable(struct regulator_dev *rdev)
+{
+ return rpmh_regulator_set_enable_state(rdev, true);
+}
+
+static int rpmh_regulator_disable(struct regulator_dev *rdev)
+{
+ return rpmh_regulator_set_enable_state(rdev, false);
+}
+
+static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
+ unsigned int mode, bool bypassed)
+{
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
+ };
+ int pmic_mode;
+
+ if (mode > REGULATOR_MODE_STANDBY)
+ return -EINVAL;
+
+ pmic_mode = vreg->hw_data->pmic_mode_map[mode];
+ if (pmic_mode < 0)
+ return pmic_mode;
+
+ cmd.data = bypassed ? PMIC4_BOB_MODE_PASS : pmic_mode;
+
+ return rpmh_regulator_send_request(vreg, &cmd, true);
+}
+
+static int rpmh_regulator_vrm_set_mode(struct regulator_dev *rdev,
+ unsigned int mode)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+ int ret;
+
+ if (mode == vreg->mode)
+ return 0;
+
+ ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
+ if (!ret)
+ vreg->mode = mode;
+
+ return ret;
+}
+
+static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+ return vreg->mode;
+}
+
+/**
+ * rpmh_regulator_vrm_set_load() - set the regulator mode based upon the load
+ * current requested
+ * @rdev: Regulator device pointer for the rpmh-regulator
+ * @load_uA: Aggregated load current in microamps
+ *
+ * This function is used in the regulator_ops for VRM type RPMh regulator
+ * devices.
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_vrm_set_load(struct regulator_dev *rdev, int load_uA)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+ unsigned int mode;
+
+ if (load_uA >= vreg->hw_data->hpm_min_load_uA)
+ mode = REGULATOR_MODE_FAST;
+ else
+ mode = REGULATOR_MODE_IDLE;
+
+ return rpmh_regulator_vrm_set_mode(rdev, mode);
+}
+
+static int rpmh_regulator_vrm_set_bypass(struct regulator_dev *rdev,
+ bool enable)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+ int ret;
+
+ if (vreg->bypassed == enable)
+ return 0;
+
+ ret = rpmh_regulator_vrm_set_mode_bypass(vreg, vreg->mode, enable);
+ if (!ret)
+ vreg->bypassed = enable;
+
+ return ret;
+}
+
+static int rpmh_regulator_vrm_get_bypass(struct regulator_dev *rdev,
+ bool *enable)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+ *enable = vreg->bypassed;
+
+ return 0;
+}
+
+static const struct regulator_ops rpmh_regulator_vrm_ops = {
+ .enable = rpmh_regulator_enable,
+ .disable = rpmh_regulator_disable,
+ .is_enabled = rpmh_regulator_is_enabled,
+ .set_voltage_sel = rpmh_regulator_vrm_set_voltage_sel,
+ .get_voltage_sel = rpmh_regulator_vrm_get_voltage_sel,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .set_mode = rpmh_regulator_vrm_set_mode,
+ .get_mode = rpmh_regulator_vrm_get_mode,
+};
+
+static const struct regulator_ops rpmh_regulator_vrm_drms_ops = {
+ .enable = rpmh_regulator_enable,
+ .disable = rpmh_regulator_disable,
+ .is_enabled = rpmh_regulator_is_enabled,
+ .set_voltage_sel = rpmh_regulator_vrm_set_voltage_sel,
+ .get_voltage_sel = rpmh_regulator_vrm_get_voltage_sel,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .set_mode = rpmh_regulator_vrm_set_mode,
+ .get_mode = rpmh_regulator_vrm_get_mode,
+ .set_load = rpmh_regulator_vrm_set_load,
+};
+
+static const struct regulator_ops rpmh_regulator_vrm_bypass_ops = {
+ .enable = rpmh_regulator_enable,
+ .disable = rpmh_regulator_disable,
+ .is_enabled = rpmh_regulator_is_enabled,
+ .set_voltage_sel = rpmh_regulator_vrm_set_voltage_sel,
+ .get_voltage_sel = rpmh_regulator_vrm_get_voltage_sel,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .set_mode = rpmh_regulator_vrm_set_mode,
+ .get_mode = rpmh_regulator_vrm_get_mode,
+ .set_bypass = rpmh_regulator_vrm_set_bypass,
+ .get_bypass = rpmh_regulator_vrm_get_bypass,
+};
+
+static const struct regulator_ops rpmh_regulator_xob_ops = {
+ .enable = rpmh_regulator_enable,
+ .disable = rpmh_regulator_disable,
+ .is_enabled = rpmh_regulator_is_enabled,
+};
+
+/**
+ * rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator
+ * vreg: Pointer to the individual rpmh-regulator resource
+ * dev: Pointer to the top level rpmh-regulator PMIC device
+ * node: Pointer to the individual rpmh-regulator resource
+ * device node
+ * pmic_id: String used to identify the top level rpmh-regulator
+ * PMIC device on the board
+ * pmic_rpmh_data: Pointer to a null-terminated array of rpmh-regulator
+ * resources defined for the top level PMIC device
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
+ struct device_node *node, const char *pmic_id,
+ const struct rpmh_vreg_init_data *pmic_rpmh_data)
+{
+ struct regulator_config reg_config = {};
+ char rpmh_resource_name[20] = "";
+ const struct rpmh_vreg_init_data *rpmh_data;
+ struct regulator_init_data *init_data;
+ struct regulator_dev *rdev;
+ int ret;
+
+ vreg->dev = dev;
+
+ for (rpmh_data = pmic_rpmh_data; rpmh_data->name; rpmh_data++)
+ if (!strcmp(rpmh_data->name, node->name))
+ break;
+
+ if (!rpmh_data->name) {
+ dev_err(dev, "Unknown regulator %s\n", node->name);
+ return -EINVAL;
+ }
+
+ scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name),
+ rpmh_data->resource_name, pmic_id);
+
+ vreg->addr = cmd_db_read_addr(rpmh_resource_name);
+ if (!vreg->addr) {
+ dev_err(dev, "%s: could not find RPMh address for resource %s\n",
+ node->name, rpmh_resource_name);
+ return -ENODEV;
+ }
+
+ vreg->rdesc.name = rpmh_data->name;
+ vreg->rdesc.supply_name = rpmh_data->supply_name;
+ vreg->hw_data = rpmh_data->hw_data;
+
+ vreg->enabled = -EINVAL;
+ vreg->voltage_selector = -ENOTRECOVERABLE;
+ vreg->mode = REGULATOR_MODE_INVALID;
+
+ if (rpmh_data->hw_data->n_voltages) {
+ vreg->rdesc.linear_ranges = &rpmh_data->hw_data->voltage_range;
+ vreg->rdesc.n_linear_ranges = 1;
+ vreg->rdesc.n_voltages = rpmh_data->hw_data->n_voltages;
+ }
+
+ vreg->always_wait_for_ack = of_property_read_bool(node,
+ "qcom,always-wait-for-ack");
+
+ vreg->rdesc.owner = THIS_MODULE;
+ vreg->rdesc.type = REGULATOR_VOLTAGE;
+ vreg->rdesc.ops = vreg->hw_data->ops;
+ vreg->rdesc.of_map_mode = vreg->hw_data->of_map_mode;
+
+ init_data = of_get_regulator_init_data(dev, node, &vreg->rdesc);
+ if (!init_data)
+ return -ENOMEM;
+
+ if (rpmh_data->hw_data->regulator_type == XOB &&
+ init_data->constraints.min_uV &&
+ init_data->constraints.min_uV == init_data->constraints.max_uV) {
+ vreg->rdesc.fixed_uV = init_data->constraints.min_uV;
+ vreg->rdesc.n_voltages = 1;
+ }
+
+ reg_config.dev = dev;
+ reg_config.init_data = init_data;
+ reg_config.of_node = node;
+ reg_config.driver_data = vreg;
+
+ rdev = devm_regulator_register(dev, &vreg->rdesc, ®_config);
+ if (IS_ERR(rdev)) {
+ ret = PTR_ERR(rdev);
+ dev_err(dev, "%s: devm_regulator_register() failed, ret=%d\n",
+ node->name, ret);
+ return ret;
+ }
+
+ dev_dbg(dev, "%s regulator registered for RPMh resource %s @ 0x%05X\n",
+ node->name, rpmh_resource_name, vreg->addr);
+
+ return 0;
+}
+
+static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
+ [REGULATOR_MODE_INVALID] = -EINVAL,
+ [REGULATOR_MODE_STANDBY] = PMIC4_LDO_MODE_RETENTION,
+ [REGULATOR_MODE_IDLE] = PMIC4_LDO_MODE_LPM,
+ [REGULATOR_MODE_NORMAL] = -EINVAL,
+ [REGULATOR_MODE_FAST] = PMIC4_LDO_MODE_HPM,
+};
+
+static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int mode)
+{
+ static const unsigned int of_mode_map[RPMH_REGULATOR_MODE_COUNT] = {
+ [RPMH_REGULATOR_MODE_RET] = REGULATOR_MODE_STANDBY,
+ [RPMH_REGULATOR_MODE_LPM] = REGULATOR_MODE_IDLE,
+ [RPMH_REGULATOR_MODE_AUTO] = REGULATOR_MODE_INVALID,
+ [RPMH_REGULATOR_MODE_HPM] = REGULATOR_MODE_FAST,
+ };
+
+ if (mode >= RPMH_REGULATOR_MODE_COUNT)
+ return -EINVAL;
+
+ return of_mode_map[mode];
+}
+
+static const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = {
+ [REGULATOR_MODE_INVALID] = -EINVAL,
+ [REGULATOR_MODE_STANDBY] = PMIC4_SMPS_MODE_RETENTION,
+ [REGULATOR_MODE_IDLE] = PMIC4_SMPS_MODE_PFM,
+ [REGULATOR_MODE_NORMAL] = PMIC4_SMPS_MODE_AUTO,
+ [REGULATOR_MODE_FAST] = PMIC4_SMPS_MODE_PWM,
+};
+
+static unsigned int rpmh_regulator_pmic4_smps_of_map_mode(unsigned int mode)
+{
+ static const unsigned int of_mode_map[RPMH_REGULATOR_MODE_COUNT] = {
+ [RPMH_REGULATOR_MODE_RET] = REGULATOR_MODE_STANDBY,
+ [RPMH_REGULATOR_MODE_LPM] = REGULATOR_MODE_IDLE,
+ [RPMH_REGULATOR_MODE_AUTO] = REGULATOR_MODE_NORMAL,
+ [RPMH_REGULATOR_MODE_HPM] = REGULATOR_MODE_FAST,
+ };
+
+ if (mode >= RPMH_REGULATOR_MODE_COUNT)
+ return -EINVAL;
+
+ return of_mode_map[mode];
+}
+
+static const int pmic_mode_map_pmic4_bob[REGULATOR_MODE_STANDBY + 1] = {
+ [REGULATOR_MODE_INVALID] = -EINVAL,
+ [REGULATOR_MODE_STANDBY] = -EINVAL,
+ [REGULATOR_MODE_IDLE] = PMIC4_BOB_MODE_PFM,
+ [REGULATOR_MODE_NORMAL] = PMIC4_BOB_MODE_AUTO,
+ [REGULATOR_MODE_FAST] = PMIC4_BOB_MODE_PWM,
+};
+
+static unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int mode)
+{
+ static const unsigned int of_mode_map[RPMH_REGULATOR_MODE_COUNT] = {
+ [RPMH_REGULATOR_MODE_RET] = REGULATOR_MODE_INVALID,
+ [RPMH_REGULATOR_MODE_LPM] = REGULATOR_MODE_IDLE,
+ [RPMH_REGULATOR_MODE_AUTO] = REGULATOR_MODE_NORMAL,
+ [RPMH_REGULATOR_MODE_HPM] = REGULATOR_MODE_FAST,
+ };
+
+ if (mode >= RPMH_REGULATOR_MODE_COUNT)
+ return -EINVAL;
+
+ return of_mode_map[mode];
+}
+
+static const struct rpmh_vreg_hw_data pmic4_pldo = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_drms_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
+ .n_voltages = 256,
+ .hpm_min_load_uA = 10000,
+ .pmic_mode_map = pmic_mode_map_pmic4_ldo,
+ .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_pldo_lv = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_drms_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
+ .n_voltages = 128,
+ .hpm_min_load_uA = 10000,
+ .pmic_mode_map = pmic_mode_map_pmic4_ldo,
+ .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_nldo = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_drms_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
+ .n_voltages = 128,
+ .hpm_min_load_uA = 30000,
+ .pmic_mode_map = pmic_mode_map_pmic4_ldo,
+ .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_hfsmps3 = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
+ .n_voltages = 216,
+ .pmic_mode_map = pmic_mode_map_pmic4_smps,
+ .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_ftsmps426 = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
+ .n_voltages = 259,
+ .pmic_mode_map = pmic_mode_map_pmic4_smps,
+ .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_bob = {
+ .regulator_type = VRM,
+ .ops = &rpmh_regulator_vrm_bypass_ops,
+ .voltage_range = REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
+ .n_voltages = 84,
+ .pmic_mode_map = pmic_mode_map_pmic4_bob,
+ .of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_lvs = {
+ .regulator_type = XOB,
+ .ops = &rpmh_regulator_xob_ops,
+ /* LVS hardware does not support voltage or mode configuration. */
+};
+
+#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
+{ \
+ .name = _name, \
+ .resource_name = _resource_name, \
+ .hw_data = _hw_data, \
+ .supply_name = _supply_name, \
+}
+
+static const struct rpmh_vreg_init_data pm8998_vreg_data[] = {
+ RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"),
+ RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"),
+ RPMH_VREG("smps3", "smp%s3", &pmic4_hfsmps3, "vdd-s3"),
+ RPMH_VREG("smps4", "smp%s4", &pmic4_hfsmps3, "vdd-s4"),
+ RPMH_VREG("smps5", "smp%s5", &pmic4_hfsmps3, "vdd-s5"),
+ RPMH_VREG("smps6", "smp%s6", &pmic4_ftsmps426, "vdd-s6"),
+ RPMH_VREG("smps7", "smp%s7", &pmic4_ftsmps426, "vdd-s7"),
+ RPMH_VREG("smps8", "smp%s8", &pmic4_ftsmps426, "vdd-s8"),
+ RPMH_VREG("smps9", "smp%s9", &pmic4_ftsmps426, "vdd-s9"),
+ RPMH_VREG("smps10", "smp%s10", &pmic4_ftsmps426, "vdd-s10"),
+ RPMH_VREG("smps11", "smp%s11", &pmic4_ftsmps426, "vdd-s11"),
+ RPMH_VREG("smps12", "smp%s12", &pmic4_ftsmps426, "vdd-s12"),
+ RPMH_VREG("smps13", "smp%s13", &pmic4_ftsmps426, "vdd-s13"),
+ RPMH_VREG("ldo1", "ldo%s1", &pmic4_nldo, "vdd-l1-l27"),
+ RPMH_VREG("ldo2", "ldo%s2", &pmic4_nldo, "vdd-l2-l8-l17"),
+ RPMH_VREG("ldo3", "ldo%s3", &pmic4_nldo, "vdd-l3-l11"),
+ RPMH_VREG("ldo4", "ldo%s4", &pmic4_nldo, "vdd-l4-l5"),
+ RPMH_VREG("ldo5", "ldo%s5", &pmic4_nldo, "vdd-l4-l5"),
+ RPMH_VREG("ldo6", "ldo%s6", &pmic4_pldo, "vdd-l6"),
+ RPMH_VREG("ldo7", "ldo%s7", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
+ RPMH_VREG("ldo8", "ldo%s8", &pmic4_nldo, "vdd-l2-l8-l17"),
+ RPMH_VREG("ldo9", "ldo%s9", &pmic4_pldo, "vdd-l9"),
+ RPMH_VREG("ldo10", "ldo%s10", &pmic4_pldo, "vdd-l10-l23-l25"),
+ RPMH_VREG("ldo11", "ldo%s11", &pmic4_nldo, "vdd-l3-l11"),
+ RPMH_VREG("ldo12", "ldo%s12", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
+ RPMH_VREG("ldo13", "ldo%s13", &pmic4_pldo, "vdd-l13-l19-l21"),
+ RPMH_VREG("ldo14", "ldo%s14", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
+ RPMH_VREG("ldo15", "ldo%s15", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
+ RPMH_VREG("ldo16", "ldo%s16", &pmic4_pldo, "vdd-l16-l28"),
+ RPMH_VREG("ldo17", "ldo%s17", &pmic4_nldo, "vdd-l2-l8-l17"),
+ RPMH_VREG("ldo18", "ldo%s18", &pmic4_pldo, "vdd-l18-l22"),
+ RPMH_VREG("ldo19", "ldo%s19", &pmic4_pldo, "vdd-l13-l19-l21"),
+ RPMH_VREG("ldo20", "ldo%s20", &pmic4_pldo, "vdd-l20-l24"),
+ RPMH_VREG("ldo21", "ldo%s21", &pmic4_pldo, "vdd-l13-l19-l21"),
+ RPMH_VREG("ldo22", "ldo%s22", &pmic4_pldo, "vdd-l18-l22"),
+ RPMH_VREG("ldo23", "ldo%s23", &pmic4_pldo, "vdd-l10-l23-l25"),
+ RPMH_VREG("ldo24", "ldo%s24", &pmic4_pldo, "vdd-l20-l24"),
+ RPMH_VREG("ldo25", "ldo%s25", &pmic4_pldo, "vdd-l10-l23-l25"),
+ RPMH_VREG("ldo26", "ldo%s26", &pmic4_nldo, "vdd-l26"),
+ RPMH_VREG("ldo27", "ldo%s27", &pmic4_nldo, "vdd-l1-l27"),
+ RPMH_VREG("ldo28", "ldo%s28", &pmic4_pldo, "vdd-l16-l28"),
+ RPMH_VREG("lvs1", "vs%s1", &pmic4_lvs, "vin-lvs-1-2"),
+ RPMH_VREG("lvs2", "vs%s2", &pmic4_lvs, "vin-lvs-1-2"),
+ {},
+};
+
+static const struct rpmh_vreg_init_data pmi8998_vreg_data[] = {
+ RPMH_VREG("bob", "bob%s1", &pmic4_bob, "vdd-bob"),
+ {},
+};
+
+static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
+ RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"),
+ RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"),
+ RPMH_VREG("smps3", "smp%s3", &pmic4_ftsmps426, "vdd-s3"),
+ RPMH_VREG("smps4", "smp%s4", &pmic4_ftsmps426, "vdd-s4"),
+ {},
+};
+
+static int rpmh_regulator_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct rpmh_vreg_init_data *vreg_data;
+ struct device_node *node;
+ struct rpmh_vreg *vreg;
+ const char *pmic_id;
+ int ret;
+
+ ret = cmd_db_ready();
+ if (ret < 0) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Command DB not available, ret=%d\n", ret);
+ return ret;
+ }
+
+ vreg_data = of_device_get_match_data(dev);
+ if (!vreg_data)
+ return -ENODEV;
+
+ ret = of_property_read_string(dev->of_node, "qcom,pmic-id", &pmic_id);
+ if (ret < 0) {
+ dev_err(dev, "qcom,pmic-id missing in DT node\n");
+ return ret;
+ }
+
+ for_each_available_child_of_node(dev->of_node, node) {
+ vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
+ if (!vreg) {
+ of_node_put(node);
+ return -ENOMEM;
+ }
+
+ ret = rpmh_regulator_init_vreg(vreg, dev, node, pmic_id,
+ vreg_data);
+ if (ret < 0) {
+ of_node_put(node);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct of_device_id rpmh_regulator_match_table[] = {
+ {
+ .compatible = "qcom,pm8998-rpmh-regulators",
+ .data = pm8998_vreg_data,
+ },
+ {
+ .compatible = "qcom,pmi8998-rpmh-regulators",
+ .data = pmi8998_vreg_data,
+ },
+ {
+ .compatible = "qcom,pm8005-rpmh-regulators",
+ .data = pm8005_vreg_data,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
+
+static struct platform_driver rpmh_regulator_driver = {
+ .driver = {
+ .name = "qcom-rpmh-regulator",
+ .of_match_table = of_match_ptr(rpmh_regulator_match_table),
+ },
+ .probe = rpmh_regulator_probe,
+};
+module_platform_driver(rpmh_regulator_driver);
+
+MODULE_DESCRIPTION("Qualcomm RPMh regulator driver");
+MODULE_LICENSE("GPL v2");
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH v7 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: David Collins @ 2018-06-08 23:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1528498807.git.collinsd@codeaurora.org>
Introduce bindings for RPMh regulator devices found on some
Qualcomm Technlogies, Inc. SoCs. These devices allow a given
processor within the SoC to make PMIC regulator requests which
are aggregated within the RPMh hardware block along with requests
from other processors in the SoC to determine the final PMIC
regulator hardware state.
Signed-off-by: David Collins <collinsd@codeaurora.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
---
.../bindings/regulator/qcom,rpmh-regulator.txt | 160 +++++++++++++++++++++
.../dt-bindings/regulator/qcom,rpmh-regulator.h | 36 +++++
2 files changed, 196 insertions(+)
create mode 100644 Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
create mode 100644 include/dt-bindings/regulator/qcom,rpmh-regulator.h
diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
new file mode 100644
index 0000000..7ef2dbe
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
@@ -0,0 +1,160 @@
+Qualcomm Technologies, Inc. RPMh Regulators
+
+rpmh-regulator devices support PMIC regulator management via the Voltage
+Regulator Manager (VRM) and Oscillator Buffer (XOB) RPMh accelerators. The APPS
+processor communicates with these hardware blocks via a Resource State
+Coordinator (RSC) using command packets. The VRM allows changing three
+parameters for a given regulator: enable state, output voltage, and operating
+mode. The XOB allows changing only a single parameter for a given regulator:
+its enable state. Despite its name, the XOB is capable of controlling the
+enable state of any PMIC peripheral. It is used for clock buffers, low-voltage
+switches, and LDO/SMPS regulators which have a fixed voltage and mode.
+
+=======================
+Required Node Structure
+=======================
+
+RPMh regulators must be described in two levels of device nodes. The first
+level describes the PMIC containing the regulators and must reside within an
+RPMh device node. The second level describes each regulator within the PMIC
+which is to be used on the board. Each of these regulators maps to a single
+RPMh resource.
+
+The names used for regulator nodes must match those supported by a given PMIC.
+Supported regulator node names:
+ PM8998: smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
+ PMI8998: bob
+ PM8005: smps1 - smps4
+
+========================
+First Level Nodes - PMIC
+========================
+
+- compatible
+ Usage: required
+ Value type: <string>
+ Definition: Must be one of: "qcom,pm8998-rpmh-regulators",
+ "qcom,pmi8998-rpmh-regulators" or
+ "qcom,pm8005-rpmh-regulators".
+
+- qcom,pmic-id
+ Usage: required
+ Value type: <string>
+ Definition: RPMh resource name suffix used for the regulators found on
+ this PMIC. Typical values: "a", "b", "c", "d", "e", "f".
+
+- vdd-s1-supply
+- vdd-s2-supply
+- vdd-s3-supply
+- vdd-s4-supply
+ Usage: optional (PM8998 and PM8005 only)
+ Value type: <phandle>
+ Definition: phandle of the parent supply regulator of one or more of the
+ regulators for this PMIC.
+
+- vdd-s5-supply
+- vdd-s6-supply
+- vdd-s7-supply
+- vdd-s8-supply
+- vdd-s9-supply
+- vdd-s10-supply
+- vdd-s11-supply
+- vdd-s12-supply
+- vdd-s13-supply
+- vdd-l1-l27-supply
+- vdd-l2-l8-l17-supply
+- vdd-l3-l11-supply
+- vdd-l4-l5-supply
+- vdd-l6-supply
+- vdd-l7-l12-l14-l15-supply
+- vdd-l9-supply
+- vdd-l10-l23-l25-supply
+- vdd-l13-l19-l21-supply
+- vdd-l16-l28-supply
+- vdd-l18-l22-supply
+- vdd-l20-l24-supply
+- vdd-l26-supply
+- vin-lvs-1-2-supply
+ Usage: optional (PM8998 only)
+ Value type: <phandle>
+ Definition: phandle of the parent supply regulator of one or more of the
+ regulators for this PMIC.
+
+- vdd-bob-supply
+ Usage: optional (PMI8998 only)
+ Value type: <phandle>
+ Definition: BOB regulator parent supply phandle
+
+===============================
+Second Level Nodes - Regulators
+===============================
+
+- qcom,always-wait-for-ack
+ Usage: optional
+ Value type: <empty>
+ Definition: Boolean flag which indicates that the application processor
+ must wait for an ACK or a NACK from RPMh for every request
+ sent for this regulator including those which are for a
+ strictly lower power state.
+
+Other properties defined in Documentation/devicetree/bindings/regulator.txt
+may also be used. regulator-initial-mode and regulator-allowed-modes may be
+specified for VRM regulators using mode values from
+include/dt-bindings/regulator/qcom,rpmh-regulator.h. regulator-allow-bypass
+may be specified for BOB type regulators managed via VRM.
+regulator-allow-set-load may be specified for LDO type regulators managed via
+VRM.
+
+========
+Examples
+========
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+&apps_rsc {
+ pm8998-rpmh-regulators {
+ compatible = "qcom,pm8998-rpmh-regulators";
+ qcom,pmic-id = "a";
+
+ vdd-l7-l12-l14-l15-supply = <&pm8998_s5>;
+
+ smps2 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ pm8998_s5: smps5 {
+ regulator-min-microvolt = <1904000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ ldo7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allowed-modes =
+ <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ };
+
+ lvs1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+
+ pmi8998-rpmh-regulators {
+ compatible = "qcom,pmi8998-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ bob {
+ regulator-min-microvolt = <3312000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-allowed-modes =
+ <RPMH_REGULATOR_MODE_AUTO
+ RPMH_REGULATOR_MODE_HPM>;
+ regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+ };
+ };
+};
diff --git a/include/dt-bindings/regulator/qcom,rpmh-regulator.h b/include/dt-bindings/regulator/qcom,rpmh-regulator.h
new file mode 100644
index 0000000..86713dc
--- /dev/null
+++ b/include/dt-bindings/regulator/qcom,rpmh-regulator.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
+
+#ifndef __QCOM_RPMH_REGULATOR_H
+#define __QCOM_RPMH_REGULATOR_H
+
+/*
+ * These mode constants may be used to specify modes for various RPMh regulator
+ * device tree properties (e.g. regulator-initial-mode). Each type of regulator
+ * supports a subset of the possible modes.
+ *
+ * %RPMH_REGULATOR_MODE_RET: Retention mode in which only an extremely small
+ * load current is allowed. This mode is supported
+ * by LDO and SMPS type regulators.
+ * %RPMH_REGULATOR_MODE_LPM: Low power mode in which a small load current is
+ * allowed. This mode corresponds to PFM for SMPS
+ * and BOB type regulators. This mode is supported
+ * by LDO, HFSMPS, BOB, and PMIC4 FTSMPS type
+ * regulators.
+ * %RPMH_REGULATOR_MODE_AUTO: Auto mode in which the regulator hardware
+ * automatically switches between LPM and HPM based
+ * upon the real-time load current. This mode is
+ * supported by HFSMPS, BOB, and PMIC4 FTSMPS type
+ * regulators.
+ * %RPMH_REGULATOR_MODE_HPM: High power mode in which the full rated current
+ * of the regulator is allowed. This mode
+ * corresponds to PWM for SMPS and BOB type
+ * regulators. This mode is supported by all types
+ * of regulators.
+ */
+#define RPMH_REGULATOR_MODE_RET 0
+#define RPMH_REGULATOR_MODE_LPM 1
+#define RPMH_REGULATOR_MODE_AUTO 2
+#define RPMH_REGULATOR_MODE_HPM 3
+
+#endif
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH v7 0/2] regulator: add QCOM RPMh regulator driver
From: David Collins @ 2018-06-08 23:44 UTC (permalink / raw)
To: linux-arm-kernel
This patch series adds a driver and device tree binding documentation for
PMIC regulator control via Resource Power Manager-hardened (RPMh) on some
Qualcomm Technologies, Inc. SoCs such as SDM845. RPMh is a hardware block
which contains several accelerators which are used to manage various
hardware resources that are shared between the processors of the SoC. The
final hardware state of a regulator is determined within RPMh by performing
max aggregation of the requests made by all of the processors.
The RPMh regulator driver depends upon the RPMh driver [1] and command DB
driver [2] which are both still undergoing review. It also depends upon
three recent regulator changes: [3], [4], and [5].
Changes since v6 [6]:
- Removed 'count' parameter from rpmh_regulator_send_request() since
it is always 1
- Fixed _rpmh_regulator_vrm_set_voltage_sel() return value
- Added a helper function to capture common code between
rpmh_regulator_enable() and rpmh_regulator_disable()
- Added an iterator for pmic_rpmh_data in rpmh_regulator_init_vreg()
- Added Reviewed-by tag for both patches
Changes since v5 [7]:
- Removed unused constants
- Added Reviewed-by tag for DT patch 1/2
Changes since v4 [8]:
- Removed support for DT properties qcom,regulator-drms-modes and
qcom,drms-mode-max-microamps
- Specified fixed DRMS high power mode minimum limits for LDO type
regulators
- Removed DRMS support for SMPS and BOB type regulators
- Simplified voltage caching logic
Changes since v3 [9]:
- Removed support for DT properties qcom,regulator-initial-microvolt
and qcom,headroom-microvolt
- Renamed DT property qcom,allowed-drms-modes to be
qcom,regulator-drms-modes
- Updated DT binding documentation to mention which common regulator
bindings can be used for qcom-rpmh-regulator devices
- Added voltage caching so that voltage requests are only sent to RPMh
after the regulator has been enabled at least once
- Changed 'voltage_selector' default value to be -ENOTRECOVERABLE to
interact with [5]
- Initialized 'enabled' to -EINVAL so that unused regulators are
disabled by regulator_late_cleanup()
- Removed rpmh_regulator_load_default_parameters() as it is no longer
needed
- Updated the mode usage description in qcom,rpmh-regulator.h
Changes since v2 [10]:
- Replaced '_' with '-' in device tree supply property names
- Renamed qcom_rpmh-regulator.c to be qcom-rpmh-regulator.c
- Updated various DT property names to use "microvolt" and "microamp"
- Moved allowed modes constraint specification out of the driver [4]
- Replaced rpmh_client with device pointer to match new RPMh API [1]
- Corrected drms mode threshold checking
- Initialized voltage_selector to -EINVAL when not specified in DT
- Added constants for PMIC regulator hardware modes
- Corrected type sign of mode mapping tables
- Made variable names for mode arrays plural
- Simplified Kconfig depends on
- Removed unnecessary constants and struct fields
- Added some descriptive comments
Changes since v1 [11]:
- Addressed review feedback from Doug, Mark, and Stephen
- Replaced set_voltage()/get_voltage() callbacks with set_voltage_sel()/
get_voltage_sel()
- Added set_bypass()/get_bypass() callbacks for BOB pass-through mode
control
- Removed top-level PMIC data structures
- Removed initialization variables from structs and passed them as
function parameters
- Removed various comments and error messages
- Simplified mode handling
- Refactored per-PMIC rpmh-regulator data specification
- Simplified probe function
- Moved header into DT patch
- Removed redundant property listings from DT binding documentation
[1]: https://lkml.org/lkml/2018/5/9/729
[2]: https://lkml.org/lkml/2018/4/10/714
[3]: https://lkml.org/lkml/2018/4/18/556
[4]: https://lkml.org/lkml/2018/5/11/696
[5]: https://lkml.org/lkml/2018/5/15/1005
[6]: https://lkml.org/lkml/2018/6/4/879
[7]: https://lkml.org/lkml/2018/6/1/895
[8]: https://lkml.org/lkml/2018/5/22/1168
[9]: https://lkml.org/lkml/2018/5/11/701
[10]: https://lkml.org/lkml/2018/4/13/687
[11]: https://lkml.org/lkml/2018/3/16/1431
David Collins (2):
regulator: dt-bindings: add QCOM RPMh regulator bindings
regulator: add QCOM RPMh regulator driver
.../bindings/regulator/qcom,rpmh-regulator.txt | 160 +++++
drivers/regulator/Kconfig | 9 +
drivers/regulator/Makefile | 1 +
drivers/regulator/qcom-rpmh-regulator.c | 753 +++++++++++++++++++++
.../dt-bindings/regulator/qcom,rpmh-regulator.h | 36 +
5 files changed, 959 insertions(+)
create mode 100644 Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
create mode 100644 drivers/regulator/qcom-rpmh-regulator.c
create mode 100644 include/dt-bindings/regulator/qcom,rpmh-regulator.h
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH 04/24] 32-bit userspace ABI: introduce ARCH_32BIT_OFF_T config option
From: Palmer Dabbelt @ 2018-06-08 22:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180608173207.nwoi25jee52gpdwy@armageddon.cambridge.arm.com>
On Fri, 08 Jun 2018 10:32:07 PDT (-0700), catalin.marinas at arm.com wrote:
> On Wed, May 16, 2018 at 11:18:49AM +0300, Yury Norov wrote:
>> diff --git a/arch/Kconfig b/arch/Kconfig
>> index 76c0b54443b1..ee079244dc3c 100644
>> --- a/arch/Kconfig
>> +++ b/arch/Kconfig
>> @@ -264,6 +264,21 @@ config ARCH_THREAD_STACK_ALLOCATOR
>> config ARCH_WANTS_DYNAMIC_TASK_STRUCT
>> bool
>>
>> +config ARCH_32BIT_OFF_T
>> + bool
>> + depends on !64BIT
>> + help
>> + All new 32-bit architectures should have 64-bit off_t type on
>> + userspace side which corresponds to the loff_t kernel type. This
>> + is the requirement for modern ABIs. Some existing architectures
>> + already have 32-bit off_t. This option is enabled for all such
>> + architectures explicitly. Namely: arc, arm, blackfin, cris, frv,
>> + h8300, hexagon, m32r, m68k, metag, microblaze, mips32, mn10300,
>> + nios2, openrisc, parisc32, powerpc32, score, sh, sparc, tile32,
>> + unicore32, x86_32 and xtensa. This is the complete list. Any
>> + new 32-bit architecture should declare 64-bit off_t type on user
>> + side and so should not enable this option.
>
> Do you know if this is the case for riscv and nds32, merged in the
> meantime? If not, I suggest you drop this patch altogether and just
> define force_o_largefile() for arm64/ilp32 as we don't seem to stick to
> "all new 32-bit architectures should have 64-bit off_t".
We (RISC-V) don't have support for rv32i in glibc yet, so there really isn't a
fixed ABI there yet. From my understanding the rv32i port as it currently
stands has a 32-bit off_t (via __kernel_off_t being defined as long), so this
change would technically be a kernel ABI break.
Since we don't have rv32i glibc yet I'm not fundamentally opposed to an ABI
break. Is there a concrete advantage to this?
^ permalink raw reply
* [PATCH 10/20] dts: juno: Update coresight bindings for hw port
From: Mathieu Poirier @ 2018-06-08 21:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180608214946.GI30587@xps15>
On 8 June 2018 at 15:49, Mathieu Poirier <mathieu.poirier@linaro.org> wrote:
> On Tue, Jun 05, 2018 at 10:43:21PM +0100, Suzuki K Poulose wrote:
>> Switch to updated coresight bindings for hw ports.
>>
>> Cc: Sudeep Holla <sudeep.holla@arm.com>
>> Cc: Liviu Dudau <liviu.dudau@arm.com>
>> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> ---
>> Changes since V1:
>> - Add support Juno for r1 & r2.
>> ---
>
> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Sudeep please hold on before applying this as there is more work to be
done on this set.
>
>> arch/arm64/boot/dts/arm/juno-base.dtsi | 82 ++++++++++++++++++++++---------
>> arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi | 26 +++++++---
>> arch/arm64/boot/dts/arm/juno.dts | 5 +-
>> 3 files changed, 81 insertions(+), 32 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
>> index eb749c5..33b41ba 100644
>> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
>> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
>> @@ -122,15 +122,18 @@
>> port at 0 {
>> reg = <0>;
>> etf0_in_port: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&main_funnel_out_port>;
>> + coresight,hwid = <0>;
>> };
>> };
>>
>> /* output port */
>> port at 1 {
>> - reg = <0>;
>> + reg = <1>;
>> etf0_out_port: endpoint {
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>> };
>> @@ -145,8 +148,9 @@
>> power-domains = <&scpi_devpd 0>;
>> port {
>> tpiu_in_port: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&replicator_out_port0>;
>> + coresight,hwid = <0>;
>> };
>> };
>> };
>> @@ -168,23 +172,27 @@
>> reg = <0>;
>> main_funnel_out_port: endpoint {
>> remote-endpoint = <&etf0_in_port>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>>
>> /* input ports */
>> port at 1 {
>> - reg = <0>;
>> + reg = <1>;
>> main_funnel_in_port0: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&cluster0_funnel_out_port>;
>> + coresight,hwid = <0>;
>> };
>> };
>>
>> port at 2 {
>> - reg = <1>;
>> + reg = <2>;
>> main_funnel_in_port1: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&cluster1_funnel_out_port>;
>> + coresight,hwid = <1>;
>> };
>> };
>> };
>> @@ -200,8 +208,9 @@
>> power-domains = <&scpi_devpd 0>;
>> port {
>> etr_in_port: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&replicator_out_port1>;
>> + coresight,hwid = <0>;
>> };
>> };
>> };
>> @@ -217,6 +226,8 @@
>> power-domains = <&scpi_devpd 0>;
>> port {
>> stm_out_port: endpoint {
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>> };
>> @@ -240,6 +251,8 @@
>> port {
>> cluster0_etm0_out_port: endpoint {
>> remote-endpoint = <&cluster0_funnel_in_port0>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>> };
>> @@ -259,22 +272,26 @@
>> reg = <0>;
>> cluster0_funnel_out_port: endpoint {
>> remote-endpoint = <&main_funnel_in_port0>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>>
>> port at 1 {
>> - reg = <0>;
>> + reg = <1>;
>> cluster0_funnel_in_port0: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&cluster0_etm0_out_port>;
>> + coresight,hwid = <0>;
>> };
>> };
>>
>> port at 2 {
>> - reg = <1>;
>> + reg = <2>;
>> cluster0_funnel_in_port1: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&cluster0_etm1_out_port>;
>> + coresight,hwid = <1>;
>> };
>> };
>> };
>> @@ -299,6 +316,8 @@
>> port {
>> cluster0_etm1_out_port: endpoint {
>> remote-endpoint = <&cluster0_funnel_in_port1>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>> };
>> @@ -322,6 +341,8 @@
>> port {
>> cluster1_etm0_out_port: endpoint {
>> remote-endpoint = <&cluster1_funnel_in_port0>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>> };
>> @@ -341,36 +362,42 @@
>> reg = <0>;
>> cluster1_funnel_out_port: endpoint {
>> remote-endpoint = <&main_funnel_in_port1>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>>
>> port at 1 {
>> - reg = <0>;
>> + reg = <1>;
>> cluster1_funnel_in_port0: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&cluster1_etm0_out_port>;
>> + coresight,hwid = <0>;
>> };
>> };
>>
>> port at 2 {
>> - reg = <1>;
>> + reg = <2>;
>> cluster1_funnel_in_port1: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&cluster1_etm1_out_port>;
>> + coresight,hwid = <1>;
>> };
>> };
>> port at 3 {
>> - reg = <2>;
>> + reg = <3>;
>> cluster1_funnel_in_port2: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&cluster1_etm2_out_port>;
>> + coresight,hwid = <2>;
>> };
>> };
>> port at 4 {
>> - reg = <3>;
>> + reg = <4>;
>> cluster1_funnel_in_port3: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&cluster1_etm3_out_port>;
>> + coresight,hwid = <3>;
>> };
>> };
>> };
>> @@ -395,6 +422,8 @@
>> port {
>> cluster1_etm1_out_port: endpoint {
>> remote-endpoint = <&cluster1_funnel_in_port1>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>> };
>> @@ -418,6 +447,8 @@
>> port {
>> cluster1_etm2_out_port: endpoint {
>> remote-endpoint = <&cluster1_funnel_in_port2>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>> };
>> @@ -441,6 +472,8 @@
>> port {
>> cluster1_etm3_out_port: endpoint {
>> remote-endpoint = <&cluster1_funnel_in_port3>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>> };
>> @@ -462,6 +495,8 @@
>> reg = <0>;
>> replicator_out_port0: endpoint {
>> remote-endpoint = <&tpiu_in_port>;
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> };
>> };
>>
>> @@ -469,14 +504,17 @@
>> reg = <1>;
>> replicator_out_port1: endpoint {
>> remote-endpoint = <&etr_in_port>;
>> + coresight,hwid = <1>;
>> + direction = <1>;
>> };
>> };
>>
>> /* replicator input port */
>> port at 2 {
>> - reg = <0>;
>> + reg = <2>;
>> replicator_in_port0: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> + coresight,hwid = <0>;
>> };
>> };
>> };
>> diff --git a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
>> index 0c43fb3..146a5d9 100644
>> --- a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
>> +++ b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
>> @@ -15,15 +15,18 @@
>> port at 0 {
>> reg = <0>;
>> csys1_funnel_out_port: endpoint {
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> remote-endpoint = <&etf1_in_port>;
>> };
>> };
>>
>> /* input port */
>> port at 1 {
>> - reg = <0>;
>> + reg = <1>;
>> csys1_funnel_in_port0: endpoint {
>> - slave-mode;
>> + coresight,hwid = <0>;
>> + direction = <0>;
>> };
>> };
>>
>> @@ -45,15 +48,18 @@
>> port at 0 {
>> reg = <0>;
>> etf1_in_port: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> + coresight,hwid = <0>;
>> remote-endpoint = <&csys1_funnel_out_port>;
>> };
>> };
>>
>> /* output port */
>> port at 1 {
>> - reg = <0>;
>> + reg = <1>;
>> etf1_out_port: endpoint {
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> remote-endpoint = <&csys2_funnel_in_port1>;
>> };
>> };
>> @@ -75,23 +81,27 @@
>> port at 0 {
>> reg = <0>;
>> csys2_funnel_out_port: endpoint {
>> + coresight,hwid = <0>;
>> + direction = <1>;
>> remote-endpoint = <&replicator_in_port0>;
>> };
>> };
>>
>> /* input ports */
>> port at 1 {
>> - reg = <0>;
>> + reg = <1>;
>> csys2_funnel_in_port0: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> + coresight,hwid = <0>;
>> remote-endpoint = <&etf0_out_port>;
>> };
>> };
>>
>> port at 2 {
>> - reg = <1>;
>> + reg = <2>;
>> csys2_funnel_in_port1: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> + coresight,hwid = <1>;
>> remote-endpoint = <&etf1_out_port>;
>> };
>> };
>> diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
>> index c9236c4..27b8036 100644
>> --- a/arch/arm64/boot/dts/arm/juno.dts
>> +++ b/arch/arm64/boot/dts/arm/juno.dts
>> @@ -260,10 +260,11 @@
>> &main_funnel {
>> ports {
>> port at 3 {
>> - reg = <2>;
>> + reg = <3>;
>> main_funnel_in_port2: endpoint {
>> - slave-mode;
>> + direction = <0>;
>> remote-endpoint = <&stm_out_port>;
>> + coresight,hwid = <2>;
>> };
>> };
>> };
>> --
>> 2.7.4
>>
^ permalink raw reply
* [PATCH 10/20] dts: juno: Update coresight bindings for hw port
From: Mathieu Poirier @ 2018-06-08 21:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528235011-30691-11-git-send-email-suzuki.poulose@arm.com>
On Tue, Jun 05, 2018 at 10:43:21PM +0100, Suzuki K Poulose wrote:
> Switch to updated coresight bindings for hw ports.
>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Liviu Dudau <liviu.dudau@arm.com>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> Changes since V1:
> - Add support Juno for r1 & r2.
> ---
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> arch/arm64/boot/dts/arm/juno-base.dtsi | 82 ++++++++++++++++++++++---------
> arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi | 26 +++++++---
> arch/arm64/boot/dts/arm/juno.dts | 5 +-
> 3 files changed, 81 insertions(+), 32 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
> index eb749c5..33b41ba 100644
> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
> @@ -122,15 +122,18 @@
> port at 0 {
> reg = <0>;
> etf0_in_port: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&main_funnel_out_port>;
> + coresight,hwid = <0>;
> };
> };
>
> /* output port */
> port at 1 {
> - reg = <0>;
> + reg = <1>;
> etf0_out_port: endpoint {
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
> };
> @@ -145,8 +148,9 @@
> power-domains = <&scpi_devpd 0>;
> port {
> tpiu_in_port: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&replicator_out_port0>;
> + coresight,hwid = <0>;
> };
> };
> };
> @@ -168,23 +172,27 @@
> reg = <0>;
> main_funnel_out_port: endpoint {
> remote-endpoint = <&etf0_in_port>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
>
> /* input ports */
> port at 1 {
> - reg = <0>;
> + reg = <1>;
> main_funnel_in_port0: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&cluster0_funnel_out_port>;
> + coresight,hwid = <0>;
> };
> };
>
> port at 2 {
> - reg = <1>;
> + reg = <2>;
> main_funnel_in_port1: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&cluster1_funnel_out_port>;
> + coresight,hwid = <1>;
> };
> };
> };
> @@ -200,8 +208,9 @@
> power-domains = <&scpi_devpd 0>;
> port {
> etr_in_port: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&replicator_out_port1>;
> + coresight,hwid = <0>;
> };
> };
> };
> @@ -217,6 +226,8 @@
> power-domains = <&scpi_devpd 0>;
> port {
> stm_out_port: endpoint {
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
> };
> @@ -240,6 +251,8 @@
> port {
> cluster0_etm0_out_port: endpoint {
> remote-endpoint = <&cluster0_funnel_in_port0>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
> };
> @@ -259,22 +272,26 @@
> reg = <0>;
> cluster0_funnel_out_port: endpoint {
> remote-endpoint = <&main_funnel_in_port0>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
>
> port at 1 {
> - reg = <0>;
> + reg = <1>;
> cluster0_funnel_in_port0: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&cluster0_etm0_out_port>;
> + coresight,hwid = <0>;
> };
> };
>
> port at 2 {
> - reg = <1>;
> + reg = <2>;
> cluster0_funnel_in_port1: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&cluster0_etm1_out_port>;
> + coresight,hwid = <1>;
> };
> };
> };
> @@ -299,6 +316,8 @@
> port {
> cluster0_etm1_out_port: endpoint {
> remote-endpoint = <&cluster0_funnel_in_port1>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
> };
> @@ -322,6 +341,8 @@
> port {
> cluster1_etm0_out_port: endpoint {
> remote-endpoint = <&cluster1_funnel_in_port0>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
> };
> @@ -341,36 +362,42 @@
> reg = <0>;
> cluster1_funnel_out_port: endpoint {
> remote-endpoint = <&main_funnel_in_port1>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
>
> port at 1 {
> - reg = <0>;
> + reg = <1>;
> cluster1_funnel_in_port0: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&cluster1_etm0_out_port>;
> + coresight,hwid = <0>;
> };
> };
>
> port at 2 {
> - reg = <1>;
> + reg = <2>;
> cluster1_funnel_in_port1: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&cluster1_etm1_out_port>;
> + coresight,hwid = <1>;
> };
> };
> port at 3 {
> - reg = <2>;
> + reg = <3>;
> cluster1_funnel_in_port2: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&cluster1_etm2_out_port>;
> + coresight,hwid = <2>;
> };
> };
> port at 4 {
> - reg = <3>;
> + reg = <4>;
> cluster1_funnel_in_port3: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&cluster1_etm3_out_port>;
> + coresight,hwid = <3>;
> };
> };
> };
> @@ -395,6 +422,8 @@
> port {
> cluster1_etm1_out_port: endpoint {
> remote-endpoint = <&cluster1_funnel_in_port1>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
> };
> @@ -418,6 +447,8 @@
> port {
> cluster1_etm2_out_port: endpoint {
> remote-endpoint = <&cluster1_funnel_in_port2>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
> };
> @@ -441,6 +472,8 @@
> port {
> cluster1_etm3_out_port: endpoint {
> remote-endpoint = <&cluster1_funnel_in_port3>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
> };
> @@ -462,6 +495,8 @@
> reg = <0>;
> replicator_out_port0: endpoint {
> remote-endpoint = <&tpiu_in_port>;
> + coresight,hwid = <0>;
> + direction = <1>;
> };
> };
>
> @@ -469,14 +504,17 @@
> reg = <1>;
> replicator_out_port1: endpoint {
> remote-endpoint = <&etr_in_port>;
> + coresight,hwid = <1>;
> + direction = <1>;
> };
> };
>
> /* replicator input port */
> port at 2 {
> - reg = <0>;
> + reg = <2>;
> replicator_in_port0: endpoint {
> - slave-mode;
> + direction = <0>;
> + coresight,hwid = <0>;
> };
> };
> };
> diff --git a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
> index 0c43fb3..146a5d9 100644
> --- a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
> +++ b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
> @@ -15,15 +15,18 @@
> port at 0 {
> reg = <0>;
> csys1_funnel_out_port: endpoint {
> + coresight,hwid = <0>;
> + direction = <1>;
> remote-endpoint = <&etf1_in_port>;
> };
> };
>
> /* input port */
> port at 1 {
> - reg = <0>;
> + reg = <1>;
> csys1_funnel_in_port0: endpoint {
> - slave-mode;
> + coresight,hwid = <0>;
> + direction = <0>;
> };
> };
>
> @@ -45,15 +48,18 @@
> port at 0 {
> reg = <0>;
> etf1_in_port: endpoint {
> - slave-mode;
> + direction = <0>;
> + coresight,hwid = <0>;
> remote-endpoint = <&csys1_funnel_out_port>;
> };
> };
>
> /* output port */
> port at 1 {
> - reg = <0>;
> + reg = <1>;
> etf1_out_port: endpoint {
> + coresight,hwid = <0>;
> + direction = <1>;
> remote-endpoint = <&csys2_funnel_in_port1>;
> };
> };
> @@ -75,23 +81,27 @@
> port at 0 {
> reg = <0>;
> csys2_funnel_out_port: endpoint {
> + coresight,hwid = <0>;
> + direction = <1>;
> remote-endpoint = <&replicator_in_port0>;
> };
> };
>
> /* input ports */
> port at 1 {
> - reg = <0>;
> + reg = <1>;
> csys2_funnel_in_port0: endpoint {
> - slave-mode;
> + direction = <0>;
> + coresight,hwid = <0>;
> remote-endpoint = <&etf0_out_port>;
> };
> };
>
> port at 2 {
> - reg = <1>;
> + reg = <2>;
> csys2_funnel_in_port1: endpoint {
> - slave-mode;
> + direction = <0>;
> + coresight,hwid = <1>;
> remote-endpoint = <&etf1_out_port>;
> };
> };
> diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
> index c9236c4..27b8036 100644
> --- a/arch/arm64/boot/dts/arm/juno.dts
> +++ b/arch/arm64/boot/dts/arm/juno.dts
> @@ -260,10 +260,11 @@
> &main_funnel {
> ports {
> port at 3 {
> - reg = <2>;
> + reg = <3>;
> main_funnel_in_port2: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&stm_out_port>;
> + coresight,hwid = <2>;
> };
> };
> };
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH 09/20] coresight: dts: Define new bindings for direction of data flow
From: Mathieu Poirier @ 2018-06-08 21:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528235011-30691-10-git-send-email-suzuki.poulose@arm.com>
On Tue, Jun 05, 2018 at 10:43:20PM +0100, Suzuki K Poulose wrote:
> So far we have relied on an undocumented property "slave-mode",
> to indicate if the given port is input or not. Since we are
> redefining the coresight bindings, define new property for the
> "direction" of data flow for a given connection endpoint in the
> device.
>
> Each endpoint must define the following property.
>
> - "direction" : 0 => Port is input
> 1 => Port is output
>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> .../devicetree/bindings/arm/coresight.txt | 24 ++++++++++++++--------
> drivers/hwtracing/coresight/of_coresight.c | 22 ++++++++++++++++----
> 2 files changed, 34 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> index bf75ab3..ff382bc 100644
> --- a/Documentation/devicetree/bindings/arm/coresight.txt
> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> @@ -103,9 +103,11 @@ with a specific direction of data flow, each connection must define the
> following properties to uniquely identify the connection details.
>
> * Direction of the data flow w.r.t the component :
> - Each input port must have the following property defined at the "endpoint"
> + Each hardware port must have the following property defined at the "endpoint"
> for the port.
> - "slave-mode"
> + "direction" - 32bit integer, whose values are defined as follows :
> + 0 => the endpoint is an Input port
> + 1 => the endpoint is an Output port.
>
> * Hardware Port number at the component:
> - Each "endpoint" must define the hardware port of the local end of the
> @@ -129,7 +131,7 @@ Example:
> clock-names = "apb_pclk";
> port {
> etb_in_port: endpoint at 0 {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&replicator_out_port0>;
> coresight,hwid = <0>;
> };
> @@ -144,7 +146,7 @@ Example:
> clock-names = "apb_pclk";
> port {
> tpiu_in_port: endpoint at 0 {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&replicator_out_port1>;
> coresight,hwid = <0>;
> };
> @@ -166,6 +168,7 @@ Example:
> port at 0 {
> reg = <0>;
> replicator_out_port0: endpoint {
> + direction = <1>;
> remote-endpoint = <&etb_in_port>;
> coresight,hwid = <0>;
> };
> @@ -174,6 +177,7 @@ Example:
> port at 1 {
> reg = <1>;
> replicator_out_port1: endpoint {
> + direction = <1>;
> remote-endpoint = <&tpiu_in_port>;
> coresight,hwid = <1>;
> };
> @@ -183,7 +187,7 @@ Example:
> port at 2 {
> reg = <1>;
> replicator_in_port0: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&funnel_out_port0>;
> coresight,hwid = <0>;
> };
> @@ -205,6 +209,7 @@ Example:
> port at 0 {
> reg = <0>;
> funnel_out_port0: endpoint {
> + direction = <1>;
> remote-endpoint =
> <&replicator_in_port0>;
> coresight,hwid = <0>;
> @@ -215,7 +220,7 @@ Example:
> port at 1 {
> reg = <1>;
> funnel_in_port0: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&ptm0_out_port>;
> coresight,hwid = <0>;
> };
> @@ -224,7 +229,7 @@ Example:
> port at 2 {
> reg = <2>;
> funnel_in_port1: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&ptm1_out_port>;
> coresight,hwid = <1>;
> };
> @@ -233,7 +238,7 @@ Example:
> port at 3 {
> reg = <3>;
> funnel_in_port2: endpoint {
> - slave-mode;
> + direction = <0>;
> remote-endpoint = <&etm0_out_port>;
> coresight,hwid = <2>;
> };
> @@ -252,6 +257,7 @@ Example:
> clock-names = "apb_pclk";
> port {
> ptm0_out_port: endpoint {
> + direction = <1>;
> remote-endpoint = <&funnel_in_port0>;
> coresight,hwid = <0>;
> };
> @@ -267,6 +273,7 @@ Example:
> clock-names = "apb_pclk";
> port {
> ptm1_out_port: endpoint {
> + direction = <1>;
> remote-endpoint = <&funnel_in_port1>;
> coresight,hwid = <0>;
> };
> @@ -284,6 +291,7 @@ Example:
> clock-names = "apb_pclk";
> port {
> stm_out_port: endpoint {
> + direction = <1>;
> remote-endpoint = <&main_funnel_in_port2>;
> coresight,hwid = <0>;
> };
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index d23d7dd..0d6e6a9 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -45,7 +45,20 @@ of_coresight_get_endpoint_device(struct device_node *endpoint)
> endpoint, of_dev_node_match);
> }
>
> -static void of_coresight_get_ports(const struct device_node *node,
> +static bool of_coresight_endpoint_is_input(struct device *dev,
> + struct device_node *ep_node)
> +{
> + u32 dir;
> +
> + if (!of_property_read_u32(ep_node, "direction", &dir))
> + return dir == 0;
> +
> + dev_warn_once(dev, "Missing mandatory \"direction\" property!\n");
> + return of_property_read_bool(ep_node, "slave-mode");
> +}
> +
> +static void of_coresight_get_ports(struct device *dev,
> + const struct device_node *node,
> int *nr_inport, int *nr_outport)
> {
> struct device_node *ep = NULL;
> @@ -56,7 +69,7 @@ static void of_coresight_get_ports(const struct device_node *node,
> if (!ep)
> break;
>
> - if (of_property_read_bool(ep, "slave-mode"))
> + if (of_coresight_endpoint_is_input(dev, ep))
> in++;
> else
> out++;
> @@ -149,7 +162,7 @@ static int of_coresight_parse_endpoint(struct device *dev,
> * No need to deal with input ports, processing for as
> * processing for output ports will deal with them.
> */
> - if (of_find_property(ep, "slave-mode", NULL))
> + if (of_coresight_endpoint_is_input(dev, ep))
> break;
>
> /* Parse the local port details */
> @@ -212,7 +225,8 @@ of_get_coresight_platform_data(struct device *dev,
> pdata->cpu = of_coresight_get_cpu(node);
>
> /* Get the number of input and output port for this component */
> - of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
> + of_coresight_get_ports(dev, node,
> + &pdata->nr_inport, &pdata->nr_outport);
>
> /* If there are not output connections, we are done */
> if (!pdata->nr_outport)
For both the binding and the code:
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH 08/20] coresight: dts: Cleanup device tree graph bindings
From: Mathieu Poirier @ 2018-06-08 21:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528235011-30691-9-git-send-email-suzuki.poulose@arm.com>
On Tue, Jun 05, 2018 at 10:43:19PM +0100, Suzuki K Poulose wrote:
> The coresight drivers relied on default bindings for graph
> in DT, while reusing the "reg" field of the "ports" to indicate
> the actual hardware port number for the connections. However,
> with the rules getting stricter w.r.t to the address mismatch
> with the label, it is no longer possible to use the port address
> field for the hardware port number. Hence, we add an explicit
> property to denote the hardware port number, "coresight,hwid"
> which must be specified for each "endpoint".
>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Rob Herring <robh@kernel.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> .../devicetree/bindings/arm/coresight.txt | 29 ++++++++++---
> drivers/hwtracing/coresight/of_coresight.c | 49 +++++++++++++++++-----
> 2 files changed, 62 insertions(+), 16 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> index ed6b555..bf75ab3 100644
> --- a/Documentation/devicetree/bindings/arm/coresight.txt
> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> @@ -108,8 +108,13 @@ following properties to uniquely identify the connection details.
> "slave-mode"
>
> * Hardware Port number at the component:
> - - The hardware port number is assumed to be the address of the "port"
> - component.
> + - Each "endpoint" must define the hardware port of the local end of the
> + connection using the following property :
> +
> + "coresight,hwid" - 32bit integer, local hardware port.
> +
> + - [ ** Obsolete ** ] The hardware port number is assumed to be the address
> + of the "port" component.
>
>
>
> @@ -126,6 +131,7 @@ Example:
> etb_in_port: endpoint at 0 {
> slave-mode;
> remote-endpoint = <&replicator_out_port0>;
> + coresight,hwid = <0>;
> };
> };
> };
> @@ -140,6 +146,7 @@ Example:
> tpiu_in_port: endpoint at 0 {
> slave-mode;
> remote-endpoint = <&replicator_out_port1>;
> + coresight,hwid = <0>;
> };
> };
> };
> @@ -160,6 +167,7 @@ Example:
> reg = <0>;
> replicator_out_port0: endpoint {
> remote-endpoint = <&etb_in_port>;
> + coresight,hwid = <0>;
> };
> };
>
> @@ -167,15 +175,17 @@ Example:
> reg = <1>;
> replicator_out_port1: endpoint {
> remote-endpoint = <&tpiu_in_port>;
> + coresight,hwid = <1>;
> };
> };
>
> /* replicator input port */
> port at 2 {
> - reg = <0>;
> + reg = <1>;
> replicator_in_port0: endpoint {
> slave-mode;
> remote-endpoint = <&funnel_out_port0>;
> + coresight,hwid = <0>;
> };
> };
> };
> @@ -197,31 +207,35 @@ Example:
> funnel_out_port0: endpoint {
> remote-endpoint =
> <&replicator_in_port0>;
> + coresight,hwid = <0>;
> };
> };
>
> /* funnel input ports */
> port at 1 {
> - reg = <0>;
> + reg = <1>;
> funnel_in_port0: endpoint {
> slave-mode;
> remote-endpoint = <&ptm0_out_port>;
> + coresight,hwid = <0>;
> };
> };
>
> port at 2 {
> - reg = <1>;
> + reg = <2>;
> funnel_in_port1: endpoint {
> slave-mode;
> remote-endpoint = <&ptm1_out_port>;
> + coresight,hwid = <1>;
> };
> };
>
> port at 3 {
> - reg = <2>;
> + reg = <3>;
> funnel_in_port2: endpoint {
> slave-mode;
> remote-endpoint = <&etm0_out_port>;
> + coresight,hwid = <2>;
> };
> };
>
> @@ -239,6 +253,7 @@ Example:
> port {
> ptm0_out_port: endpoint {
> remote-endpoint = <&funnel_in_port0>;
> + coresight,hwid = <0>;
> };
> };
> };
> @@ -253,6 +268,7 @@ Example:
> port {
> ptm1_out_port: endpoint {
> remote-endpoint = <&funnel_in_port1>;
> + coresight,hwid = <0>;
> };
> };
> };
> @@ -269,6 +285,7 @@ Example:
> port {
> stm_out_port: endpoint {
> remote-endpoint = <&main_funnel_in_port2>;
> + coresight,hwid = <0>;
> };
> };
> };
For the binding part:
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index d01a9ce..d23d7dd 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -99,6 +99,31 @@ int of_coresight_get_cpu(const struct device_node *node)
> EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
>
> /*
> + * of_coresight_endpoint_get_port_id : Get the hardware port number for the
> + * given endpoint device node. Prefer the explicit "coresight,hwid" property
> + * over the endpoint register id (obsolete bindings).
> + */
> +static int of_coresight_endpoint_get_port_id(struct device *dev,
> + struct device_node *ep_node)
> +{
> + struct of_endpoint ep;
> + int rc, port_id;
> +
> +
> + if (!of_property_read_u32(ep_node, "coresight,hwid", &port_id))
> + return port_id;
> +
> + rc = of_graph_parse_endpoint(ep_node, &ep);
> + if (rc)
> + return rc;
> + dev_warn_once(dev,
> + "ep%d: Mandatory \"coresight,hwid\" property missing.\n",
> + ep.port);
> + dev_warn_once(dev, "DT uses obsolete coresight bindings\n");
> + return ep.port;
> +}
> +
> +/*
> * of_coresight_parse_endpoint : Parse the given output endpoint @ep
> * and fill the connection information in *@pconn.
> *
> @@ -109,11 +134,11 @@ EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
> * 0 - If the parsing completed without any fatal errors.
> * -Errno - Fatal error, abort the scanning.
> */
> -static int of_coresight_parse_endpoint(struct device_node *ep,
> +static int of_coresight_parse_endpoint(struct device *dev,
> + struct device_node *ep,
> struct coresight_connection **pconn)
> {
> - int ret = 0;
> - struct of_endpoint endpoint, rendpoint;
> + int ret = 0, local_port, child_port;
> struct device_node *rparent = NULL;
> struct device_node *rep = NULL;
> struct device *rdev = NULL;
> @@ -128,7 +153,8 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
> break;
>
> /* Parse the local port details */
> - if (of_graph_parse_endpoint(ep, &endpoint))
> + local_port = of_coresight_endpoint_get_port_id(dev, ep);
> + if (local_port < 0)
> break;
> /*
> * Get a handle on the remote endpoint and the device it is
> @@ -140,9 +166,6 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
> rparent = of_graph_get_port_parent(rep);
> if (!rparent)
> break;
> - if (of_graph_parse_endpoint(rep, &rendpoint))
> - break;
> -
> /* If the remote device is not available, defer probing */
> rdev = of_coresight_get_endpoint_device(rparent);
> if (!rdev) {
> @@ -150,9 +173,15 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
> break;
> }
>
> - conn->outport = endpoint.port;
> + child_port = of_coresight_endpoint_get_port_id(rdev, rep);
> + if (child_port < 0) {
> + ret = 0;
Why returning '0' on an error condition? Same for 'local_port' above.
> + break;
> + }
> +
> + conn->outport = local_port;
> conn->child_name = dev_name(rdev);
> - conn->child_port = rendpoint.port;
> + conn->child_port = child_port;
> /* Move the connection record */
> (*pconn)++;
> } while (0);
> @@ -200,7 +229,7 @@ of_get_coresight_platform_data(struct device *dev,
> ep = of_graph_get_next_endpoint(node, ep);
> if (!ep)
> break;
> - ret = of_coresight_parse_endpoint(ep, &conn);
> + ret = of_coresight_parse_endpoint(dev, ep, &conn);
> if (ret)
> return ERR_PTR(ret);
> } while (ep);
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v4 2/3] arm: shmobile: Add the R9A06G032 SMP enabler driver
From: Rob Herring @ 2018-06-08 20:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMuHMdUOqLhmb8kXOxriQ5mt_4rDQJbUqGsQiJBSkq5J5FWG7w@mail.gmail.com>
On Fri, Jun 8, 2018 at 2:47 AM, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Fri, Jun 8, 2018 at 8:50 AM, Michel Pollet
> <michel.pollet@bp.renesas.com> wrote:
>> On 07 June 2018 16:55, Rob wrote:
>>> On Thu, Jun 7, 2018 at 1:59 AM, Michel Pollet
>>> <michel.pollet@bp.renesas.com> wrote:
>>> > On 06 June 2018 22:53, Frank wrote:
>>> >> On 06/06/18 14:48, Frank Rowand wrote:
>>> >> > On 06/05/18 23:36, Michel Pollet wrote:
>>> >> >> On 05 June 2018 18:34, Frank wrote:
>>> >> >>> On 06/05/18 04:28, Michel Pollet wrote:
>>> >> >>>> The Renesas R9A06G032 second CA7 is parked in a ROM pen at boot
>>> >> >>>> time, it requires a special enable method to get it started.
>>>
>>> [...]
>>>
>>> >> >>>> + * The second CPU is parked in ROM at boot time. It requires
>>> >> >>>> +waking it after
>>> >> >>>> + * writing an address into the BOOTADDR register of sysctrl.
>>> >> >>>> + *
>>> >> >>>> + * So the default value of the "cpu-release-addr" corresponds
>>> >> >>>> +to
>>> >> >>> BOOTADDR...
>>> >> >>>> + *
>>> >> >>>> + * *However* the BOOTADDR register is not available when the
>>> >> >>>> +kernel
>>> >> >>>> + * starts in NONSEC mode.
>>> >> >>>> + *
>>> >> >>>> + * So for NONSEC mode, the bootloader re-parks the second CPU
>>> >> >>>> +into a pen
>>> >> >>>> + * in SRAM, and changes the "cpu-release-addr" of linux's DT to
>>> >> >>>> +a SRAM address,
>>> >> >>>> + * which is not restricted.
>>> >> >>>
>>> >> >>> The binding document for cpu-release-addr does not have a
>>> >> >>> definition for 32 bit arm. The existing definition is only 64
>>> >> >>> bit arm. Please add the definition for 32 bit arm to patch 1.
>>> >> >>
>>> >> >> Hmmm I do find a definition in
>>> >> >> Documentation/devicetree/bindings/arm/cpus.txt -- just under where
>>> >> >> I added my 'enable-method' -- And it is already used as 32 bits in
>>> >> >> at least arch/arm/boot/dts/stih407-family.dtsi.
>>> >> >
>>> >> > If the correct answer is for cpu-release-addr to be 64 bits in
>>> >> > certain cases (that discussion is ongoing further downthread) then
>>> >> > one approach to maintain compatibility _and_ to fix the devicetree
>>> >> > source files is to change the source code that currently gets
>>> >> > cpu-release-addr as a
>>> >> > 32 bit object to check the size of the property and get it as
>>> >> > either a
>>> >> > 32 bit or 64 bit object, based on the actual size of the property
>>> >> > in the device tree and then change the value in the devicetree
>>> >> > source files to be two cells. BUT this does not consider the
>>> >> > bootloader complication. arch/arm/boot/dts/axm5516-cpus.dtsi has a
>>> >> > note "// Fixed by the boot loader", so the boot loader also has to
>>> >> > be modified to be able to handle the possibility that the property
>>> >> > could be either
>>> >> > 32 bits or 64 bits. I don't know how to maintain compatibility
>>> >> > with the boot loader since we can't force it to change
>>> >> > synchronously with changes in the kernel.
>>> >> >
>>> >> > You can consider this comment to be a drive-by observation. I
>>> >> > think Rob and Geert and people like that are likely to be more
>>> >> > helpful with what to actually do, and you can treat my comment more
>>> >> > as pointing out the issue than as providing the perfect solution.
>>> >>
>>> >> Darn it, hit <send> too quickly.
>>> >>
>>> >> I meant to mention that there are several devicetree source files
>>> >> that have a single cell value for cpu-release-addr, and thus
>>> >> potentially face the same situation, depending on what the final
>>> >> decision is on the proper size for cpu- release-addr. As of v4.17, a git grep
>>> shows one cell values in:
>>> >>
>>> >> arch/arm/boot/dts/axm5516-cpus.dtsi
>>> >> arch/arm/boot/dts/stih407-family.dtsi
>>> >> arch/arm/boot/dts/stih418.dtsi
>>> >
>>> > Yes, I had grepped before I used 32 bits on mine...
>>> >
>>> > Now, what is the decision here? Our bootloader is already modified to
>>> > set it to 32 bits, so I propose that
>>>
>>> And too late to fix the bootloader?
>>
>>
>> Well not too late, but read further on...
>>
>>>
>>> >
>>> > + I change the driver to handle 32 and 64 bits properties
>>>
>>> That's fine if you can't fix the bootloader.
>>>
>>> > + I add this to the cpu.txt, as a separate patch:
>>> > # On other systems, the property can be either
>>> > 32 bits or 64 bits, it is the driver's responsibility
>>> > to deal with either sizes.
>>>
>>> That is definitely not what we want to say. Use of 32-bit should be
>>> considered out of spec. Yes, we have a few platforms in that category, but
>>> they already handle that themselves. Would be nice to fix them, but at least
>>> the STi platforms don't seem too active.
>>>
>>> IMO, we should delete whatever text we can here and at most just refer to
>>> the spec.
>>
>> So actually I didn't use 32 bits by plain chance, I read the cpu.txt file which says
>> that 64 bits systems use 64 bits property, concluded that in my case I ought to
>> use 32 bits, then grepped around and found other systems using 32 bits, therefore
>> I went forward and used it..
>>
>> Nothing said here that it should be 64 bits everywhere -- So the documentation
>> needs fixing somehow. Right now it certainly led me wrong.
>
> Perhaps we should add to Documentation/devicetree/bindings/ the standard
> bindings from ePAPR and successors, too?
I hope you mean *reference* here, not duplicate the bindings here. We
want to move in the other direction and move the common bindings out
of the kernel and into the spec.
The real solution here is validation which I'm working on. I had
already converted cpus.txt. Here's an example of the results of the
validation:
arch/arm/boot/dts/stih410-b2120.dt.yaml:1962:7: cpu at 0: 'enable-method'
is a dependency of 'cpu-release-addr'
arch/arm/boot/dts/stih410-b2120.dt.yaml:1965:26:
cpu at 0:cpu-release-addr: [155254948] is too short
The schema is up on my yaml-bindings branch. Will send out more details soon.
Rob
^ permalink raw reply
* [PATCH 07/20] coresight: dts: Document usage of graph bindings
From: Mathieu Poirier @ 2018-06-08 20:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528235011-30691-8-git-send-email-suzuki.poulose@arm.com>
On Tue, Jun 05, 2018 at 10:43:18PM +0100, Suzuki K Poulose wrote:
> Before we update the bindings, document the current graph bindings
> and usage of additional properties.
>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> ---
> .../devicetree/bindings/arm/coresight.txt | 31 +++++++++++++++++++---
> 1 file changed, 27 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> index 9aa30a1..ed6b555 100644
> --- a/Documentation/devicetree/bindings/arm/coresight.txt
> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> @@ -52,9 +52,7 @@ its hardware characteristcs.
> clocks the core of that coresight component. The latter clock
> is optional.
>
> - * port or ports: The representation of the component's port
> - layout using the generic DT graph presentation found in
> - "bindings/graph.txt".
> + * port or ports: see "Graph bindings for Coresight" below.
>
> * Additional required properties for System Trace Macrocells (STM):
> * reg: along with the physical base address and length of the register
> @@ -71,7 +69,7 @@ its hardware characteristcs.
> AMBA markee):
> - "arm,coresight-replicator"
>
> - * port or ports: same as above.
> + * port or ports: see "Graph bindings for Coresight" below.
>
> * Optional properties for ETM/PTMs:
>
> @@ -90,6 +88,31 @@ its hardware characteristcs.
> * arm,scatter-gather: boolean. Indicates that the TMC-ETR can safely
> use the SG mode on this system.
>
> +Graph bindings for Coresight
> +-------------------------------
> +
> +Coresight components are interconnected to create a data path for the flow of
> +trace data generated from the "sources" to their collection points "sink".
> +Each coresight component must describe the "input" and "output" connections.
> +The connections must be described via generic DT graph bindings as described
> +by the "bindings/graph.txt", where each "port" along with an "endpoint"
> +component represents a hardware port and the connection.
> +
> +Since it is possible to have multiple connections for any coresight component
> +with a specific direction of data flow, each connection must define the
> +following properties to uniquely identify the connection details.
> +
> + * Direction of the data flow w.r.t the component :
> + Each input port must have the following property defined at the "endpoint"
> + for the port.
> + "slave-mode"
> +
> + * Hardware Port number at the component:
> + - The hardware port number is assumed to be the address of the "port"
> + component.
> +
> +
> +
> Example:
>
> 1. Sinks
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH 06/20] coresight: Handle errors in finding input/output ports
From: Mathieu Poirier @ 2018-06-08 20:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528235011-30691-7-git-send-email-suzuki.poulose@arm.com>
On Tue, Jun 05, 2018 at 10:43:17PM +0100, Suzuki K Poulose wrote:
> If we fail to find the input / output port for a LINK component
> while enabling a path, we should fail gracefully rather than
> assuming port "0".
>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> drivers/hwtracing/coresight/coresight.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
> index 69e9136..3c1c058 100644
> --- a/drivers/hwtracing/coresight/coresight.c
> +++ b/drivers/hwtracing/coresight/coresight.c
> @@ -107,7 +107,7 @@ static int coresight_find_link_inport(struct coresight_device *csdev,
> dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n",
> dev_name(&parent->dev), dev_name(&csdev->dev));
>
> - return 0;
> + return -ENODEV;
> }
>
> static int coresight_find_link_outport(struct coresight_device *csdev,
> @@ -125,7 +125,7 @@ static int coresight_find_link_outport(struct coresight_device *csdev,
> dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n",
> dev_name(&csdev->dev), dev_name(&child->dev));
>
> - return 0;
> + return -ENODEV;
> }
>
> static int coresight_enable_sink(struct coresight_device *csdev, u32 mode)
> @@ -178,6 +178,9 @@ static int coresight_enable_link(struct coresight_device *csdev,
> else
> refport = 0;
>
> + if (refport < 0)
> + return refport;
> +
> if (atomic_inc_return(&csdev->refcnt[refport]) == 1) {
> if (link_ops(csdev)->enable) {
> ret = link_ops(csdev)->enable(csdev, inport, outport);
Queued for the next rc - no need to resend.
Thanks,
Mathieu
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH 05/20] coresight: platform: Cleanup coresight connection handling
From: Mathieu Poirier @ 2018-06-08 20:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528235011-30691-6-git-send-email-suzuki.poulose@arm.com>
On Tue, Jun 05, 2018 at 10:43:16PM +0100, Suzuki K Poulose wrote:
> The platform code parses the component connections and populates
> a platform-description of the output connections in arrays of fields
> (which is never freed). This is later copied in the coresight_register
> to a newly allocated area, represented by coresight_connection(s).
>
> This patch cleans up the code dealing with connections by making
> use of the "coresight_connection" structure right at the platform
> code and lets the generic driver simply re-use information provided
> by the platform.
>
> Thus making it reader friendly as well as avoiding the wastage of
> unused memory.
>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> drivers/hwtracing/coresight/coresight.c | 21 +-----------
> drivers/hwtracing/coresight/of_coresight.c | 51 ++++++++++++------------------
> include/linux/coresight.h | 9 ++----
> 3 files changed, 23 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
> index 2893cfe..69e9136 100644
> --- a/drivers/hwtracing/coresight/coresight.c
> +++ b/drivers/hwtracing/coresight/coresight.c
> @@ -953,13 +953,11 @@ postcore_initcall(coresight_init);
>
> struct coresight_device *coresight_register(struct coresight_desc *desc)
> {
> - int i;
> int ret;
> int link_subtype;
> int nr_refcnts = 1;
> atomic_t *refcnts = NULL;
> struct coresight_device *csdev;
> - struct coresight_connection *conns = NULL;
>
> csdev = kzalloc(sizeof(*csdev), GFP_KERNEL);
> if (!csdev) {
> @@ -988,22 +986,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
> csdev->nr_inport = desc->pdata->nr_inport;
> csdev->nr_outport = desc->pdata->nr_outport;
>
> - /* Initialise connections if there is at least one outport */
> - if (csdev->nr_outport) {
> - conns = kcalloc(csdev->nr_outport, sizeof(*conns), GFP_KERNEL);
> - if (!conns) {
> - ret = -ENOMEM;
> - goto err_kzalloc_conns;
> - }
> -
> - for (i = 0; i < csdev->nr_outport; i++) {
> - conns[i].outport = desc->pdata->outports[i];
> - conns[i].child_name = desc->pdata->child_names[i];
> - conns[i].child_port = desc->pdata->child_ports[i];
> - }
> - }
> -
> - csdev->conns = conns;
> + csdev->conns = desc->pdata->conns;
>
> csdev->type = desc->type;
> csdev->subtype = desc->subtype;
> @@ -1032,8 +1015,6 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
>
> return csdev;
>
> -err_kzalloc_conns:
> - kfree(refcnts);
> err_kzalloc_refcnts:
> kfree(csdev);
> err_kzalloc_csdev:
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index ada4f07..d01a9ce 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -70,26 +70,13 @@ static void of_coresight_get_ports(const struct device_node *node,
> static int of_coresight_alloc_memory(struct device *dev,
> struct coresight_platform_data *pdata)
> {
> - /* List of output port on this component */
> - pdata->outports = devm_kzalloc(dev, pdata->nr_outport *
> - sizeof(*pdata->outports),
> - GFP_KERNEL);
> - if (!pdata->outports)
> - return -ENOMEM;
> -
> - /* Children connected to this component via @outports */
> - pdata->child_names = devm_kzalloc(dev, pdata->nr_outport *
> - sizeof(*pdata->child_names),
> - GFP_KERNEL);
> - if (!pdata->child_names)
> - return -ENOMEM;
> -
> - /* Port number on the child this component is connected to */
> - pdata->child_ports = devm_kzalloc(dev, pdata->nr_outport *
> - sizeof(*pdata->child_ports),
> - GFP_KERNEL);
> - if (!pdata->child_ports)
> - return -ENOMEM;
> + if (pdata->nr_outport) {
> + pdata->conns = devm_kzalloc(dev, pdata->nr_outport *
> + sizeof(*pdata->conns),
> + GFP_KERNEL);
> + if (!pdata->conns)
> + return -ENOMEM;
> + }
>
> return 0;
> }
> @@ -113,24 +100,24 @@ EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
>
> /*
> * of_coresight_parse_endpoint : Parse the given output endpoint @ep
> - * and fill the connection information in @pdata[*@i].
> + * and fill the connection information in *@pconn.
> *
> * Parses the local port, remote device name and the remote port. Also
> - * updates *@i to point to the next index, when an entry is added.
> + * updates *@pconn to point to the next record, when an entry is added.
> *
> * Returns :
> * 0 - If the parsing completed without any fatal errors.
> * -Errno - Fatal error, abort the scanning.
> */
> static int of_coresight_parse_endpoint(struct device_node *ep,
> - struct coresight_platform_data *pdata,
> - int *i)
> + struct coresight_connection **pconn)
> {
> int ret = 0;
> struct of_endpoint endpoint, rendpoint;
> struct device_node *rparent = NULL;
> struct device_node *rep = NULL;
> struct device *rdev = NULL;
> + struct coresight_connection *conn = *pconn;
>
> do {
> /*
> @@ -163,11 +150,11 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
> break;
> }
>
> - pdata->outports[*i] = endpoint.port;
> - pdata->child_names[*i] = dev_name(rdev);
> - pdata->child_ports[*i] = rendpoint.port;
> - /* Move the index */
> - (*i)++;
> + conn->outport = endpoint.port;
> + conn->child_name = dev_name(rdev);
> + conn->child_port = rendpoint.port;
> + /* Move the connection record */
> + (*pconn)++;
> } while (0);
>
> if (rparent)
> @@ -182,8 +169,9 @@ struct coresight_platform_data *
> of_get_coresight_platform_data(struct device *dev,
> const struct device_node *node)
> {
> - int i = 0, ret = 0;
> + int ret = 0;
> struct coresight_platform_data *pdata;
> + struct coresight_connection *conn;
> struct device_node *ep = NULL;
>
> pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
> @@ -205,13 +193,14 @@ of_get_coresight_platform_data(struct device *dev,
> if (ret)
> return ERR_PTR(ret);
>
> + conn = pdata->conns;
> /* Iterate through each port to discover topology */
> do {
> /* Get a handle on a port */
> ep = of_graph_get_next_endpoint(node, ep);
> if (!ep)
> break;
> - ret = of_coresight_parse_endpoint(ep, pdata, &i);
> + ret = of_coresight_parse_endpoint(ep, &conn);
> if (ret)
> return ERR_PTR(ret);
> } while (ep);
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 69a5c9f..2a75a15 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -82,20 +82,15 @@ struct coresight_dev_subtype {
> * @cpu: the CPU a source belongs to. Only applicable for ETM/PTMs.
> * @name: name of the component as shown under sysfs.
> * @nr_inport: number of input ports for this component.
> - * @outports: list of remote endpoint port number.
> - * @child_names:name of all child components connected to this device.
> - * @child_ports:child component port number the current component is
> - connected to.
> * @nr_outport: number of output ports for this component.
> + * @conns: Array of nr_outport connections from this component
> */
> struct coresight_platform_data {
> int cpu;
> const char *name;
> int nr_inport;
> - int *outports;
> - const char **child_names;
> - int *child_ports;
> int nr_outport;
> + struct coresight_connection *conns;
> };
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
>
> /**
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH 03/20] coresight: Fix remote endpoint parsing
From: Mathieu Poirier @ 2018-06-08 20:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528235011-30691-4-git-send-email-suzuki.poulose@arm.com>
On Tue, Jun 05, 2018 at 10:43:14PM +0100, Suzuki K Poulose wrote:
> When parsing the remote endpoint of an output port, we do :
> rport = of_graph_get_remote_port(ep);
> rparent = of_graph_get_remote_port_parent(ep);
>
> and then parse the "remote_port" as if it was the remote endpoint,
> which is wrong. The code worked fine because we used endpoint number
> as the port number. Let us fix it and optimise a bit as:
>
> remote_ep = of_graph_get_remote_endpoint(ep);
> if (remote_ep)
> remote_parent = of_graph_get_port_parent(remote_ep);
>
> and then, parse the remote_ep for the port/endpoint details.
>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> drivers/hwtracing/coresight/of_coresight.c | 22 +++++++++++-----------
> 1 file changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index 8a23c63..ada4f07 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -129,7 +129,7 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
> int ret = 0;
> struct of_endpoint endpoint, rendpoint;
> struct device_node *rparent = NULL;
> - struct device_node *rport = NULL;
> + struct device_node *rep = NULL;
> struct device *rdev = NULL;
>
> do {
> @@ -144,16 +144,16 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
> if (of_graph_parse_endpoint(ep, &endpoint))
> break;
> /*
> - * Get a handle on the remote port and parent
> - * attached to it.
> + * Get a handle on the remote endpoint and the device it is
> + * attached to.
> */
> - rparent = of_graph_get_remote_port_parent(ep);
> + rep = of_graph_get_remote_endpoint(ep);
> + if (!rep)
> + break;
> + rparent = of_graph_get_port_parent(rep);
> if (!rparent)
> break;
> - rport = of_graph_get_remote_port(ep);
> - if (!rport)
> - break;
> - if (of_graph_parse_endpoint(rport, &rendpoint))
> + if (of_graph_parse_endpoint(rep, &rendpoint))
> break;
>
> /* If the remote device is not available, defer probing */
> @@ -165,15 +165,15 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
>
> pdata->outports[*i] = endpoint.port;
> pdata->child_names[*i] = dev_name(rdev);
> - pdata->child_ports[*i] = rendpoint.id;
> + pdata->child_ports[*i] = rendpoint.port;
> /* Move the index */
> (*i)++;
> } while (0);
>
> if (rparent)
> of_node_put(rparent);
> - if (rport)
> - of_node_put(rport);
> + if (rep)
> + of_node_put(rep);
>
> return ret;
> }
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
(Please add to the next iteration so that I don't have to review again)
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v5 2/4] kernel hacking: new config NO_AUTO_INLINE to disable compiler auto-inline optimizations
From: Steven Rostedt @ 2018-06-08 20:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180607091816.GT13775@localhost>
On Thu, 7 Jun 2018 11:18:16 +0200
Johan Hovold <johan@kernel.org> wrote:
> If you want to work around the warning and think you can do it in some
> non-contrived way, then go for it.
>
> Clearing the request buffer, checking for termination using strnlen, and
> then using memcpy might not be too bad.
>
> But after all, it is a false positive, so leaving things as they stand
> is fine too.
Not sure how contrived you think this is, but it solves the warning
without adding extra work in the normal case.
-- Steve
diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c
index 71aec14f8181..4fb9f1dff47d 100644
--- a/drivers/staging/greybus/fw-management.c
+++ b/drivers/staging/greybus/fw-management.c
@@ -150,15 +150,18 @@ static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt,
}
request.load_method = load_method;
- strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
+ strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE - 1);
/*
* The firmware-tag should be NULL terminated, otherwise throw error and
* fail.
*/
- if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
- dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n");
- return -EINVAL;
+ if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 2] != '\0') {
+ if (tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
+ dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n");
+ return -EINVAL;
+ }
+ request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] = '\0';
}
/* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
^ permalink raw reply related
* [PATCH 02/20] coresight: of: Fix refcounting for graph nodes
From: Mathieu Poirier @ 2018-06-08 19:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528235011-30691-3-git-send-email-suzuki.poulose@arm.com>
On Tue, Jun 05, 2018 at 10:43:13PM +0100, Suzuki K Poulose wrote:
> The coresight driver doesn't drop the references on the
> remote endpoint/port nodes. Add the missing of_node_put()
> calls. To make it easier to handle different corner cases
> cleanly, move the parsing of an endpoint to separate
> function.
Please split this as those are two different things.
>
> Reported-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> drivers/hwtracing/coresight/of_coresight.c | 139 +++++++++++++++++------------
> 1 file changed, 84 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index a33a92e..8a23c63 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -111,17 +111,80 @@ int of_coresight_get_cpu(const struct device_node *node)
> }
> EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
>
> +/*
> + * of_coresight_parse_endpoint : Parse the given output endpoint @ep
> + * and fill the connection information in @pdata[*@i].
> + *
> + * Parses the local port, remote device name and the remote port. Also
> + * updates *@i to point to the next index, when an entry is added.
> + *
> + * Returns :
> + * 0 - If the parsing completed without any fatal errors.
> + * -Errno - Fatal error, abort the scanning.
> + */
> +static int of_coresight_parse_endpoint(struct device_node *ep,
> + struct coresight_platform_data *pdata,
> + int *i)
> +{
> + int ret = 0;
> + struct of_endpoint endpoint, rendpoint;
> + struct device_node *rparent = NULL;
> + struct device_node *rport = NULL;
> + struct device *rdev = NULL;
> +
> + do {
> + /*
> + * No need to deal with input ports, processing for as
> + * processing for output ports will deal with them.
> + */
> + if (of_find_property(ep, "slave-mode", NULL))
> + break;
> +
> + /* Parse the local port details */
> + if (of_graph_parse_endpoint(ep, &endpoint))
> + break;
> + /*
> + * Get a handle on the remote port and parent
> + * attached to it.
> + */
> + rparent = of_graph_get_remote_port_parent(ep);
> + if (!rparent)
> + break;
> + rport = of_graph_get_remote_port(ep);
> + if (!rport)
> + break;
> + if (of_graph_parse_endpoint(rport, &rendpoint))
> + break;
> +
> + /* If the remote device is not available, defer probing */
> + rdev = of_coresight_get_endpoint_device(rparent);
> + if (!rdev) {
> + ret = -EPROBE_DEFER;
> + break;
> + }
> +
> + pdata->outports[*i] = endpoint.port;
> + pdata->child_names[*i] = dev_name(rdev);
> + pdata->child_ports[*i] = rendpoint.id;
> + /* Move the index */
> + (*i)++;
> + } while (0);
That's a clever way of coding a classic 'goto' block.
> +
> + if (rparent)
> + of_node_put(rparent);
> + if (rport)
> + of_node_put(rport);
Perfect - thank you for that.
> +
> + return ret;
> +}
> +
> struct coresight_platform_data *
> of_get_coresight_platform_data(struct device *dev,
> const struct device_node *node)
> {
> int i = 0, ret = 0;
> struct coresight_platform_data *pdata;
> - struct of_endpoint endpoint, rendpoint;
> - struct device *rdev;
> struct device_node *ep = NULL;
> - struct device_node *rparent = NULL;
> - struct device_node *rport = NULL;
>
> pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
> if (!pdata)
> @@ -129,63 +192,29 @@ of_get_coresight_platform_data(struct device *dev,
>
> /* Use device name as sysfs handle */
> pdata->name = dev_name(dev);
> + pdata->cpu = of_coresight_get_cpu(node);
>
> /* Get the number of input and output port for this component */
> of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
>
> - if (pdata->nr_outport) {
> - ret = of_coresight_alloc_memory(dev, pdata);
> + /* If there are not output connections, we are done */
/not/no
> + if (!pdata->nr_outport)
> + return pdata;
> +
> + ret = of_coresight_alloc_memory(dev, pdata);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + /* Iterate through each port to discover topology */
> + do {
> + /* Get a handle on a port */
> + ep = of_graph_get_next_endpoint(node, ep);
> + if (!ep)
> + break;
> + ret = of_coresight_parse_endpoint(ep, pdata, &i);
> if (ret)
> return ERR_PTR(ret);
> -
> - /* Iterate through each port to discover topology */
> - do {
> - /* Get a handle on a port */
> - ep = of_graph_get_next_endpoint(node, ep);
> - if (!ep)
> - break;
> -
> - /*
> - * No need to deal with input ports, processing for as
> - * processing for output ports will deal with them.
> - */
> - if (of_find_property(ep, "slave-mode", NULL))
> - continue;
> -
> - /* Get a handle on the local endpoint */
> - ret = of_graph_parse_endpoint(ep, &endpoint);
> -
> - if (ret)
> - continue;
> -
> - /* The local out port number */
> - pdata->outports[i] = endpoint.port;
> -
> - /*
> - * Get a handle on the remote port and parent
> - * attached to it.
> - */
> - rparent = of_graph_get_remote_port_parent(ep);
> - rport = of_graph_get_remote_port(ep);
> -
> - if (!rparent || !rport)
> - continue;
> -
> - if (of_graph_parse_endpoint(rport, &rendpoint))
> - continue;
> -
> - rdev = of_coresight_get_endpoint_device(rparent);
> - if (!rdev)
> - return ERR_PTR(-EPROBE_DEFER);
> -
> - pdata->child_names[i] = dev_name(rdev);
> - pdata->child_ports[i] = rendpoint.id;
> -
> - i++;
> - } while (ep);
> - }
> -
> - pdata->cpu = of_coresight_get_cpu(node);
> + } while (ep);
>
> return pdata;
> }
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH RESEND v4 2/2] arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS
From: Dongjiu Geng @ 2018-06-08 19:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528487320-2873-1-git-send-email-gengdongjiu@huawei.com>
For the migrating VMs, user space may need to know the exception
state. For example, in the machine A, KVM make an SError pending,
when migrate to B, KVM also needs to pend an SError.
This new IOCTL exports user-invisible states related to SError.
Together with appropriate user space changes, user space can get/set
the SError exception state to do migrate/snapshot/suspend.
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
---
change since v3:
1. Fix the memset() issue in the kvm_arm_vcpu_get_events()
change since v2:
1. Add kvm_vcpu_events structure definition for arm platform to avoid the build errors.
change since v1:
Address Marc's comments, thanks Marc's review
1. serror_has_esr always true when ARM64_HAS_RAS_EXTN is set
2. remove Spurious blank line in kvm_arm_vcpu_set_events()
3. rename pend_guest_serror() to kvm_set_sei_esr()
4. Make kvm_arm_vcpu_get_events() did all the work rather than having this split responsibility.
5. using sizeof(events) instead of sizeof(struct kvm_vcpu_events)
this series patch is separated from https://www.spinics.net/lists/kvm/msg168917.html
The user space patch is here: https://lists.gnu.org/archive/html/qemu-devel/2018-05/msg06965.html
change since V12:
1. change (vcpu->arch.hcr_el2 & HCR_VSE) to !!(vcpu->arch.hcr_el2 & HCR_VSE) in kvm_arm_vcpu_get_events()
Change since V11:
Address James's comments, thanks James
1. Align the struct of kvm_vcpu_events to 64 bytes
2. Avoid exposing the stale ESR value in the kvm_arm_vcpu_get_events()
3. Change variables 'injected' name to 'serror_pending' in the kvm_arm_vcpu_set_events()
4. Change to sizeof(events) from sizeof(struct kvm_vcpu_events) in kvm_arch_vcpu_ioctl()
Change since V10:
Address James's comments, thanks James
1. Merge the helper function with the user.
2. Move the ISS_MASK into pend_guest_serror() to clear top bits
3. Make kvm_vcpu_events struct align to 4 bytes
4. Add something check in the kvm_arm_vcpu_set_events()
5. Check kvm_arm_vcpu_get/set_events()'s return value.
6. Initialise kvm_vcpu_events to 0 so that padding transferred to user-space doesn't
contain kernel stack.
---
Documentation/virtual/kvm/api.txt | 31 ++++++++++++++++++++++++++++---
arch/arm/include/asm/kvm_host.h | 6 ++++++
arch/arm/include/uapi/asm/kvm.h | 12 ++++++++++++
arch/arm/kvm/guest.c | 12 ++++++++++++
arch/arm64/include/asm/kvm_emulate.h | 5 +++++
arch/arm64/include/asm/kvm_host.h | 7 +++++++
arch/arm64/include/uapi/asm/kvm.h | 13 +++++++++++++
arch/arm64/kvm/guest.c | 36 ++++++++++++++++++++++++++++++++++++
arch/arm64/kvm/inject_fault.c | 6 +++---
arch/arm64/kvm/reset.c | 1 +
virt/kvm/arm/arm.c | 19 +++++++++++++++++++
11 files changed, 142 insertions(+), 6 deletions(-)
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index fdac969..8896737 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -835,11 +835,13 @@ struct kvm_clock_data {
Capability: KVM_CAP_VCPU_EVENTS
Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
+Architectures: x86, arm, arm64
Type: vm ioctl
Parameters: struct kvm_vcpu_event (out)
Returns: 0 on success, -1 on error
+X86:
+
Gets currently pending exceptions, interrupts, and NMIs as well as related
states of the vcpu.
@@ -881,15 +883,32 @@ Only two fields are defined in the flags field:
- KVM_VCPUEVENT_VALID_SMM may be set in the flags field to signal that
smi contains a valid state.
+ARM, ARM64:
+
+Gets currently pending SError exceptions as well as related states of the vcpu.
+
+struct kvm_vcpu_events {
+ struct {
+ __u8 serror_pending;
+ __u8 serror_has_esr;
+ /* Align it to 8 bytes */
+ __u8 pad[6];
+ __u64 serror_esr;
+ } exception;
+ __u32 reserved[12];
+};
+
4.32 KVM_SET_VCPU_EVENTS
-Capability: KVM_CAP_VCPU_EVENTS
+Capebility: KVM_CAP_VCPU_EVENTS
Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
+Architectures: x86, arm, arm64
Type: vm ioctl
Parameters: struct kvm_vcpu_event (in)
Returns: 0 on success, -1 on error
+X86:
+
Set pending exceptions, interrupts, and NMIs as well as related states of the
vcpu.
@@ -910,6 +929,12 @@ shall be written into the VCPU.
KVM_VCPUEVENT_VALID_SMM can only be set if KVM_CAP_X86_SMM is available.
+ARM, ARM64:
+
+Set pending SError exceptions as well as related states of the vcpu.
+
+See KVM_GET_VCPU_EVENTS for the data structure.
+
4.33 KVM_GET_DEBUGREGS
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index c7c28c8..39f9901 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -213,6 +213,12 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+ struct kvm_vcpu_events *events);
+
+int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+ struct kvm_vcpu_events *events);
+
unsigned long kvm_call_hyp(void *hypfn, ...);
void force_vm_exit(const cpumask_t *mask);
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index caae484..c3e6975 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -124,6 +124,18 @@ struct kvm_sync_regs {
struct kvm_arch_memory_slot {
};
+/* for KVM_GET/SET_VCPU_EVENTS */
+struct kvm_vcpu_events {
+ struct {
+ __u8 serror_pending;
+ __u8 serror_has_esr;
+ /* Align it to 8 bytes */
+ __u8 pad[6];
+ __u64 serror_esr;
+ } exception;
+ __u32 reserved[12];
+};
+
/* If you need to interpret the index values, here is the key: */
#define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
#define KVM_REG_ARM_COPROC_SHIFT 16
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index a18f33e..c685f0e 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -261,6 +261,18 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
return -EINVAL;
}
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+ struct kvm_vcpu_events *events)
+{
+ return -EINVAL;
+}
+
+int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+ struct kvm_vcpu_events *events)
+{
+ return -EINVAL;
+}
+
int __attribute_const__ kvm_target_cpu(void)
{
switch (read_cpuid_part()) {
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 1dab3a9..18f61ff 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -81,6 +81,11 @@ static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu)
return (unsigned long *)&vcpu->arch.hcr_el2;
}
+static inline unsigned long vcpu_get_vsesr(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.vsesr_el2;
+}
+
static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
{
vcpu->arch.vsesr_el2 = vsesr;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 469de8a..357304a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -335,6 +335,11 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+ struct kvm_vcpu_events *events);
+
+int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+ struct kvm_vcpu_events *events);
#define KVM_ARCH_WANT_MMU_NOTIFIER
int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
@@ -363,6 +368,8 @@ void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
int kvm_perf_init(void);
int kvm_perf_teardown(void);
+void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 syndrome);
+
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
void __kvm_set_tpidr_el2(u64 tpidr_el2);
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 04b3256..df4faee 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -39,6 +39,7 @@
#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_READONLY_MEM
+#define __KVM_HAVE_VCPU_EVENTS
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
@@ -153,6 +154,18 @@ struct kvm_sync_regs {
struct kvm_arch_memory_slot {
};
+/* for KVM_GET/SET_VCPU_EVENTS */
+struct kvm_vcpu_events {
+ struct {
+ __u8 serror_pending;
+ __u8 serror_has_esr;
+ /* Align it to 8 bytes */
+ __u8 pad[6];
+ __u64 serror_esr;
+ } exception;
+ __u32 reserved[12];
+};
+
/* If you need to interpret the index values, here is the key: */
#define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
#define KVM_REG_ARM_COPROC_SHIFT 16
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 56a0260..4426915 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -289,6 +289,42 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
return -EINVAL;
}
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+ struct kvm_vcpu_events *events)
+{
+ memset(events, 0, sizeof(*events));
+
+ events->exception.serror_pending = !!(vcpu->arch.hcr_el2 & HCR_VSE);
+ events->exception.serror_has_esr =
+ cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
+
+ if (events->exception.serror_pending &&
+ events->exception.serror_has_esr)
+ events->exception.serror_esr = vcpu_get_vsesr(vcpu);
+ else
+ events->exception.serror_esr = 0;
+
+ return 0;
+}
+
+int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+ struct kvm_vcpu_events *events)
+{
+ bool serror_pending = events->exception.serror_pending;
+ bool has_esr = events->exception.serror_has_esr;
+
+ if (serror_pending && has_esr) {
+ if (!cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+ return -EINVAL;
+
+ kvm_set_sei_esr(vcpu, events->exception.serror_esr);
+ } else if (serror_pending) {
+ kvm_inject_vabt(vcpu);
+ }
+
+ return 0;
+}
+
int __attribute_const__ kvm_target_cpu(void)
{
unsigned long implementor = read_cpuid_implementor();
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index d8e7165..a55e91d 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -164,9 +164,9 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
inject_undef64(vcpu);
}
-static void pend_guest_serror(struct kvm_vcpu *vcpu, u64 esr)
+void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 esr)
{
- vcpu_set_vsesr(vcpu, esr);
+ vcpu_set_vsesr(vcpu, esr & ESR_ELx_ISS_MASK);
*vcpu_hcr(vcpu) |= HCR_VSE;
}
@@ -184,5 +184,5 @@ static void pend_guest_serror(struct kvm_vcpu *vcpu, u64 esr)
*/
void kvm_inject_vabt(struct kvm_vcpu *vcpu)
{
- pend_guest_serror(vcpu, ESR_ELx_ISV);
+ kvm_set_sei_esr(vcpu, ESR_ELx_ISV);
}
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 38c8a64..20e919a 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -82,6 +82,7 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
break;
case KVM_CAP_SET_GUEST_DEBUG:
case KVM_CAP_VCPU_ATTRIBUTES:
+ case KVM_CAP_VCPU_EVENTS:
r = 1;
break;
default:
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index a4c1b76..79ecba9 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1107,6 +1107,25 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = kvm_arm_vcpu_has_attr(vcpu, &attr);
break;
}
+ case KVM_GET_VCPU_EVENTS: {
+ struct kvm_vcpu_events events;
+
+ if (kvm_arm_vcpu_get_events(vcpu, &events))
+ return -EINVAL;
+
+ if (copy_to_user(argp, &events, sizeof(events)))
+ return -EFAULT;
+
+ return 0;
+ }
+ case KVM_SET_VCPU_EVENTS: {
+ struct kvm_vcpu_events events;
+
+ if (copy_from_user(&events, argp, sizeof(events)))
+ return -EFAULT;
+
+ return kvm_arm_vcpu_set_events(vcpu, &events);
+ }
default:
r = -EINVAL;
}
--
2.7.4
^ permalink raw reply related
* [PATCH RESEND v4 1/2] arm64: KVM: export the capability to set guest SError syndrome
From: Dongjiu Geng @ 2018-06-08 19:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528487320-2873-1-git-send-email-gengdongjiu@huawei.com>
For the arm64 RAS Extension, user space can inject a virtual-SError
with specified ESR. So user space needs to know whether KVM support
to inject such SError, this interface adds this query for this capability.
KVM will check whether system support RAS Extension, if supported, KVM
returns true to user space, otherwise returns false.
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
Reviewed-by: James Morse <james.morse@arm.com>
---
Documentation/virtual/kvm/api.txt | 11 +++++++++++
arch/arm64/kvm/reset.c | 3 +++
include/uapi/linux/kvm.h | 1 +
3 files changed, 15 insertions(+)
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 758bf40..fdac969 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -4603,3 +4603,14 @@ Architectures: s390
This capability indicates that kvm will implement the interfaces to handle
reset, migration and nested KVM for branch prediction blocking. The stfle
facility 82 should not be provided to the guest without this capability.
+
+8.14 KVM_CAP_ARM_SET_SERROR_ESR
+
+Architectures: arm, arm64
+
+This capability indicates that userspace can specify the syndrome value reported
+to the guest OS when guest takes a virtual SError interrupt exception.
+If KVM has this capability, userspace can only specify the ISS field for the ESR
+syndrome, it can not specify the EC field which is not under control by KVM.
+If this virtual SError is taken to EL1 using AArch64, this value will be reported
+in ISS filed of ESR_EL1.
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 3256b92..38c8a64 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -77,6 +77,9 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_ARM_PMU_V3:
r = kvm_arm_support_pmu_v3();
break;
+ case KVM_CAP_ARM_INJECT_SERROR_ESR:
+ r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
+ break;
case KVM_CAP_SET_GUEST_DEBUG:
case KVM_CAP_VCPU_ATTRIBUTES:
r = 1;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index b02c41e..e88f976 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -948,6 +948,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_S390_BPB 152
#define KVM_CAP_GET_MSR_FEATURES 153
#define KVM_CAP_HYPERV_EVENTFD 154
+#define KVM_CAP_ARM_INJECT_SERROR_ESR 155
#ifdef KVM_CAP_IRQ_ROUTING
--
2.7.4
^ permalink raw reply related
* [PATCH RESEND v4 0/2] support exception state migration and set VSESR_EL2 by user space
From: Dongjiu Geng @ 2018-06-08 19:48 UTC (permalink / raw)
To: linux-arm-kernel
This series patch is separated from https://www.spinics.net/lists/kvm/msg168917.html
1. Detect whether KVM can set set guest SError syndrome
2. Support to Set VSESR_EL2 and inject SError by user space.
3. Support live migration to keep SError pending state and VSESR_EL2 value
The user space patch is here: https://www.mail-archive.com/qemu-devel at nongnu.org/msg539534.html
Dongjiu Geng (2):
arm64: KVM: export the capability to set guest SError syndrome
arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS
Documentation/virtual/kvm/api.txt | 42 +++++++++++++++++++++++++++++++++---
arch/arm/include/asm/kvm_host.h | 6 ++++++
arch/arm/include/uapi/asm/kvm.h | 12 +++++++++++
arch/arm/kvm/guest.c | 12 +++++++++++
arch/arm64/include/asm/kvm_emulate.h | 5 +++++
arch/arm64/include/asm/kvm_host.h | 7 ++++++
arch/arm64/include/uapi/asm/kvm.h | 13 +++++++++++
arch/arm64/kvm/guest.c | 36 +++++++++++++++++++++++++++++++
arch/arm64/kvm/inject_fault.c | 6 +++---
arch/arm64/kvm/reset.c | 4 ++++
include/uapi/linux/kvm.h | 1 +
virt/kvm/arm/arm.c | 19 ++++++++++++++++
12 files changed, 157 insertions(+), 6 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH 04/20] coresight: Cleanup platform description data
From: Mathieu Poirier @ 2018-06-08 19:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1528235011-30691-5-git-send-email-suzuki.poulose@arm.com>
On Tue, Jun 05, 2018 at 10:43:15PM +0100, Suzuki K Poulose wrote:
> Nobody uses the "clk" field in struct coresight_platform_data.
> Remove it.
>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> include/linux/coresight.h | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index e5421b8..69a5c9f 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -87,7 +87,6 @@ struct coresight_dev_subtype {
> * @child_ports:child component port number the current component is
> connected to.
> * @nr_outport: number of output ports for this component.
> - * @clk: The clock this component is associated to.
> */
> struct coresight_platform_data {
> int cpu;
> @@ -97,7 +96,6 @@ struct coresight_platform_data {
> const char **child_names;
> int *child_ports;
> int nr_outport;
> - struct clk *clk;
> };
I'm going to queue this up for the next rc. No need to send it as part of
another revision.
Thanks,
Mathieu
>
> /**
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v6 2/2] regulator: add QCOM RPMh regulator driver
From: David Collins @ 2018-06-08 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180608002653.GD88063@google.com>
Hello Matthias,
On 06/07/2018 05:26 PM, Matthias Kaehlcke wrote:
> On Mon, Jun 04, 2018 at 12:15:12PM -0700, David Collins wrote:
>> static int rpmh_regulator_send_request(struct rpmh_vreg *vreg,
>> + struct tcs_cmd *cmd, int count, bool wait_for_ack)
>>
>
> nit: as of now this is only called with a single command. If you
> anticipate that this is unlikely to change consider removing 'count',
> not having it in the calls slightly improves readability.
The count parameter was needed in the original version of the patch. That
need is no longer present after removing features in subsequent versions.
I'll remove this parameter.
>> +static int _rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
>> + unsigned int selector, bool wait_for_ack)
>> +{
>> + struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
>> + struct tcs_cmd cmd = {
>> + .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
>> + };
>> + int ret;
>> +
>> + /* VRM voltage control register is set with voltage in millivolts. */
>> + cmd.data = DIV_ROUND_UP(regulator_list_voltage_linear_range(rdev,
>> + selector), 1000);
>> +
>> + ret = rpmh_regulator_send_request(vreg, &cmd, 1, wait_for_ack);
>> + if (!ret)
>> + vreg->voltage_selector = selector;
>> +
>> + return 0;
>
> Shouldn't this return 'ret'?
Yes; good catch. I'll fix it.
>> +static int rpmh_regulator_enable(struct regulator_dev *rdev)
>> +{
>> + struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
>> + struct tcs_cmd cmd = {
>> + .addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
>> + .data = 1,
>> + };
>> + int ret;
>> +
>> + if (vreg->enabled == -EINVAL &&
>> + vreg->voltage_selector != -ENOTRECOVERABLE) {
>> + ret = _rpmh_regulator_vrm_set_voltage_sel(rdev,
>> + vreg->voltage_selector, true);
>> + if (ret < 0)
>> + return ret;
>> + }
>> +
>> + ret = rpmh_regulator_send_request(vreg, &cmd, 1, true);
>> + if (!ret)
>> + vreg->enabled = true;
>> +
>> + return ret;
>> +}
>> +
>> +static int rpmh_regulator_disable(struct regulator_dev *rdev)
>> +{
>> + struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
>> + struct tcs_cmd cmd = {
>> + .addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
>> + .data = 0,
>> + };
>> + int ret;
>> +
>> + if (vreg->enabled == -EINVAL &&
>> + vreg->voltage_selector != -ENOTRECOVERABLE) {
>> + ret = _rpmh_regulator_vrm_set_voltage_sel(rdev,
>> + vreg->voltage_selector, true);
>> + if (ret < 0)
>> + return ret;
>> + }
>> +
>> + ret = rpmh_regulator_send_request(vreg, &cmd, 1, false);
>> + if (!ret)
>> + vreg->enabled = false;
>> +
>> + return ret;
>> +}
>
> nit: rpmh_regulator_enable() and rpmh_regulator_disable() are
> essentially the same code, consider introducing a helper like
> _rpmh_regulator_enable(struct regulator_dev *rdev, bool enable).
Sure, I'll add a helper function.
>> +static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
>> + struct device_node *node, const char *pmic_id,
>> + const struct rpmh_vreg_init_data *rpmh_data)
>> +{
>> + struct regulator_config reg_config = {};
>> + char rpmh_resource_name[20] = "";
>> + struct regulator_dev *rdev;
>> + struct regulator_init_data *init_data;
>> + int ret;
>> +
>> + vreg->dev = dev;
>> +
>> + for (; rpmh_data->name; rpmh_data++)
>> + if (!strcmp(rpmh_data->name, node->name))
>> + break;
>
> nit: it's a bit odd to use the parameter itself for iteration, but I
> guess it's a matter of preferences.
I'll change this to add a specific iterator so that it is less surprising.
Thanks,
David
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH v4 3/3] arm64: Introduce command line parameter to disable CNP
From: James Morse @ 2018-06-08 17:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b4771d84-2403-3bd4-9566-4d9b1403d112@arm.com>
Hi Vladimir, Catalin,
On 24/05/18 09:20, Vladimir Murzin wrote:
> On 23/05/18 18:17, Catalin Marinas wrote:
>> On Fri, May 18, 2018 at 11:07:02AM +0100, Vladimir Murzin wrote:
>>> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
>>> index 11fc28e..8f59d47 100644
>>> --- a/Documentation/admin-guide/kernel-parameters.txt
>>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>>> @@ -2636,6 +2636,10 @@
>>> + nocnp [ARM64]
>>> + Disable CNP (Common not Private translations)
>>> + even if it is supported by processor.
>> Do we actually have a use-case for this command line option? I'm not
>> considering hardware errata as these are handled separately in the
>> kernel.
> Well, I cannot count all cases, yet we might see CnP support advertised
> by CPU via ID register (where CPU meant to be part of bL) but not really
> doing optimisations in hardware.
>
> Probably, some userspace (benchmarks) might not benefit of CnP; otoh maybe
> better way for such case would be user-space asking kernel to {dis,en}able
> CnP...
>
> I have no strong opinion on patch, so I'm fine to drop it and come back
> when/if we get results from real hardware.
We may want to disable CNP without rebuilding the kernel, which would also have
the affect of code-layout changes...
Thanks,
James
^ permalink raw reply
* [PATCH v4 2/3] arm64: KVM: Enable Common Not Private translations
From: James Morse @ 2018-06-08 17:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526638022-4137-3-git-send-email-vladimir.murzin@arm.com>
Hi Vladimir,
On 18/05/18 11:07, Vladimir Murzin wrote:
> We rely on cpufeature framework to detect and enable CNP so for KVM we
> need to patch hyp to set CNP bit just before TTBR0_EL2 gets written.
>
> For the guest we encode CNP bit while building vttbr, so we don't need
> to bother with that in a world switch.
With the bare-constant fix suggested by Catalin,
Reviewed-by: James Morse <james.morse@arm.com>
Thanks,
James
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox