* [PATCHv2 3/3] phy: omap-usb2-phy: disable PHY charger detect
From: Roger Quadros @ 2020-06-02 11:46 UTC (permalink / raw)
To: kishon, robh+dt
Cc: linux-kernel, devicetree, Roger Quadros, Bin Liu, Sekhar Nori
In-Reply-To: <20200602114606.32045-1-rogerq@ti.com>
AM654x PG1.0 has a silicon bug that D+ is pulled high after POR, which
could cause enumeration failure with some USB hubs. Disabling the
USB2_PHY Charger Detect function will put D+ into the normal state.
Using property "ti,dis-chg-det-quirk" in the DT usb2-phy node to
enable this workaround for AM654x PG1.0.
This addresses Silicon Errata:
i2075 - "USB2PHY: USB2PHY Charger Detect is Enabled by Default Without VBUS
Presence"
Signed-off-by: Bin Liu <b-liu@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
drivers/phy/ti/phy-omap-usb2.c | 35 +++++++++++++++++++++++++++-------
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c
index cb2dd3230fa7..8ab8b94511d4 100644
--- a/drivers/phy/ti/phy-omap-usb2.c
+++ b/drivers/phy/ti/phy-omap-usb2.c
@@ -26,6 +26,10 @@
#define USB2PHY_ANA_CONFIG1 0x4c
#define USB2PHY_DISCON_BYP_LATCH BIT(31)
+#define USB2PHY_CHRG_DET 0x14
+#define USB2PHY_CHRG_DET_USE_CHG_DET_REG BIT(29)
+#define USB2PHY_CHRG_DET_DIS_CHG_DET BIT(28)
+
/* SoC Specific USB2_OTG register definitions */
#define AM654_USB2_OTG_PD BIT(8)
#define AM654_USB2_VBUS_DET_EN BIT(5)
@@ -43,6 +47,7 @@
#define OMAP_USB2_HAS_START_SRP BIT(0)
#define OMAP_USB2_HAS_SET_VBUS BIT(1)
#define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT BIT(2)
+#define OMAP_USB2_DISABLE_CHRG_DET BIT(3)
struct omap_usb {
struct usb_phy phy;
@@ -236,6 +241,13 @@ static int omap_usb_init(struct phy *x)
omap_usb_writel(phy->phy_base, USB2PHY_ANA_CONFIG1, val);
}
+ if (phy->flags & OMAP_USB2_DISABLE_CHRG_DET) {
+ val = omap_usb_readl(phy->phy_base, USB2PHY_CHRG_DET);
+ val |= USB2PHY_CHRG_DET_USE_CHG_DET_REG |
+ USB2PHY_CHRG_DET_DIS_CHG_DET;
+ omap_usb_writel(phy->phy_base, USB2PHY_CHRG_DET, val);
+ }
+
return 0;
}
@@ -366,14 +378,12 @@ static int omap_usb2_probe(struct platform_device *pdev)
phy->mask = phy_data->mask;
phy->power_on = phy_data->power_on;
phy->power_off = phy_data->power_off;
+ phy->flags = phy_data->flags;
- if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- phy->phy_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(phy->phy_base))
- return PTR_ERR(phy->phy_base);
- phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT;
- }
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ phy->phy_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(phy->phy_base))
+ return PTR_ERR(phy->phy_base);
phy->syscon_phy_power = syscon_regmap_lookup_by_phandle(node,
"syscon-phy-power");
@@ -405,6 +415,17 @@ static int omap_usb2_probe(struct platform_device *pdev)
}
}
+ /*
+ * Errata i2075: USB2PHY: USB2PHY Charger Detect is Enabled by
+ * Default Without VBUS Presence.
+ *
+ * AM654x SR1.0 has a silicon bug due to which D+ is pulled high after
+ * POR, which could cause enumeration failure with some USB hubs.
+ * Disabling the USB2_PHY Charger Detect function will put D+
+ * into the normal state.
+ */
+ if (of_property_read_bool(node, "ti,dis-chg-det-quirk"))
+ phy->flags |= OMAP_USB2_DISABLE_CHRG_DET;
phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
if (IS_ERR(phy->wkupclk)) {
--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
^ permalink raw reply related
* [PATCHv2 0/3] phy: omap-usb2: add quirk to disable charger detection
From: Roger Quadros @ 2020-06-02 11:46 UTC (permalink / raw)
To: kishon, robh+dt; +Cc: linux-kernel, devicetree, Roger Quadros
Hi,
- convert DT binding to YAML
- add DT property to disable charger detection
(Errata i2075 for AM65 SR1.0)
Changelog:
v2
- Address Rob's comments on YAML schema.
cheers,
-roger
Bin Liu (1):
dts: am65: add ti,dis-chg-det-quirk flag to usb phy nodes
Roger Quadros (3):
dt-binding: phy: convert ti,omap-usb2 to YAML
dt-binding: phy: ti,omap-usb2: Add quirk to disable charger detection
phy: omap-usb2-phy: disable PHY charger detect
.../devicetree/bindings/phy/ti,omap-usb2.yaml | 74 +++++++++++++++++++
.../devicetree/bindings/phy/ti-phy.txt | 37 ----------
drivers/phy/ti/phy-omap-usb2.c | 35 +++++++--
3 files changed, 102 insertions(+), 44 deletions(-)
create mode 100644 Documentation/devicetree/bindings/phy/ti,omap-usb2.yaml
--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
^ permalink raw reply
* Re: [PATCH v4 4/5] regulator: qcom: Add labibb driver
From: Mark Brown @ 2020-06-02 11:32 UTC (permalink / raw)
To: Sumit Semwal
Cc: agross, bjorn.andersson, lgirdwood, robh+dt, nishakumari,
linux-arm-msm, linux-kernel, devicetree, kgunda, rnayak
In-Reply-To: <20200602100924.26256-5-sumit.semwal@linaro.org>
[-- Attachment #1: Type: text/plain, Size: 1497 bytes --]
On Tue, Jun 02, 2020 at 03:39:23PM +0530, Sumit Semwal wrote:
> +static int qcom_labibb_regulator_is_enabled(struct regulator_dev *rdev)
> +{
> + int ret;
> + unsigned int val;
> + struct labibb_regulator *reg = rdev_get_drvdata(rdev);
> +
> + ret = regmap_read(reg->regmap, reg->base + REG_LABIBB_STATUS1, &val);
> + if (ret < 0) {
> + dev_err(reg->dev, "Read register failed ret = %d\n", ret);
> + return ret;
> + }
> + return !!(val & LABIBB_STATUS1_VREG_OK_BIT);
> +}
This should be a get_status() callback...
> +static int qcom_labibb_regulator_enable(struct regulator_dev *rdev)
> +{
> + return regulator_enable_regmap(rdev);
> +}
> +
> +static int qcom_labibb_regulator_disable(struct regulator_dev *rdev)
> +{
> + return regulator_disable_regmap(rdev);
> +}
...is_enabled() should just be regulator_is_enabled_regmap() and these
functions should just be removed entirely, you can use the regmap
operations directly as the ops without the wrapper.
> + match = of_match_device(qcom_labibb_match, &pdev->dev);
> + if (!match)
> + return -ENODEV;
> +
> + for (reg_data = match->data; reg_data->name; reg_data++) {
> + child = of_get_child_by_name(pdev->dev.of_node, reg_data->name);
> +
> + if (WARN_ON(child == NULL))
> + return -EINVAL;
This feels like the DT bindings are confused - why do we need to search
like this?
> + dev_info(dev, "Registering %s regulator\n", child->full_name);
This is noise, remove it. The regulator framework will announce new
regulators anyway.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v4 1/5] regulator: Allow regulators to verify enabled during enable()
From: Mark Brown @ 2020-06-02 11:24 UTC (permalink / raw)
To: Sumit Semwal
Cc: agross, bjorn.andersson, lgirdwood, robh+dt, nishakumari,
linux-arm-msm, linux-kernel, devicetree, kgunda, rnayak
In-Reply-To: <20200602100924.26256-2-sumit.semwal@linaro.org>
[-- Attachment #1: Type: text/plain, Size: 409 bytes --]
On Tue, Jun 02, 2020 at 03:39:20PM +0530, Sumit Semwal wrote:
> +
> + if (time_remaining <= 0) {
> + rdev_err(rdev, "Enabled check failed.\n");
> + return -ETIMEDOUT;
s/failed/timed out/
> + * @poll_enabled_time: Maximum time (in uS) to poll if the regulator is
> + * actually enabled, after enable() call
> + *
This comment needs updating to reflect the new implementation.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v2 00/91] drm/vc4: Support BCM2711 Display Pipelin
From: Maxime Ripard @ 2020-06-02 11:04 UTC (permalink / raw)
To: Jian-Hong Pan
Cc: Daniel Drake, Nicolas Saenz Julienne, Eric Anholt, dri-devel,
linux-rpi-kernel, bcm-kernel-feedback-list, linux-arm-kernel,
Linux Kernel, devicetree, linux-clk, linux-i2c,
Linux Upstreaming Team
In-Reply-To: <CAPpJ_ec1KRwUrHGVVZrReaDPz4iga-Nvj5H652-tTKmkXL=Xmg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1807 bytes --]
Hi,
On Mon, Jun 01, 2020 at 03:58:26PM +0800, Jian-Hong Pan wrote:
> Maxime Ripard <maxime@cerno.tech> 於 2020年5月28日 週四 下午3:30寫道:
> >
> > Hi Daniel,
> >
> > On Wed, May 27, 2020 at 05:15:12PM +0800, Daniel Drake wrote:
> > > On Wed, May 27, 2020 at 5:13 PM Maxime Ripard <maxime@cerno.tech> wrote:
> > > > I'm about to send a v3 today or tomorrow, I can Cc you (and Jian-Hong) if you
> > > > want.
> > >
> > > That would be great, although given the potentially inconsistent
> > > results we've been seeing so far it would be great if you could
> > > additionally push a git branch somewhere.
> > > That way we can have higher confidence that we are applying exactly
> > > the same patches to the same base etc.
> >
> > So I sent a new iteration yesterday, and of course forgot to cc you... Sorry for
> > that.
> >
> > I've pushed my current branch here:
> > https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git/log/?h=rpi4-kms
>
> Thanks to Maxime!
>
> I have tried your repository on branch rpi4-kms. The DRM VC4 is used!
> But got some issues:
> 1. Some weird error message in dmesg. Not sure it is related, or not
> [ 5.219321] [drm:vc5_hdmi_init_resources] *ERROR* Failed to get
> HDMI state machine clock
> https://gist.github.com/starnight/3f317dca121065a361cf08e91225e389
That's a deferred probing. The first time the HDMI driver is being
probed, the firmware clock driver has not been probed yet. It's making
another attempt later on, which succeeds.
> 2. The screen flashes suddenly sometimes.
>
> 3. The higher resolutions, like 1920x1080 ... are lost after hot
> re-plug HDMI cable (HDMI0)
I'm not sure on how to exactly reproduce those issues (or what they are)
though, can you expand on this?
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [RFC v1 2/3] drivers: nvmem: Add driver for QTI qfprom-efuse support
From: Srinivas Kandagatla @ 2020-06-02 10:56 UTC (permalink / raw)
To: Doug Anderson
Cc: Ravi Kumar Bokka (Temp), Rob Herring, LKML,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Rajendra Nayak, Sai Prakash Ranjan, dhavalp, mturney, sparate,
c_rbokka, mkurumel
In-Reply-To: <CAD=FV=VcfYVQMmWvSkBG0VNBcqt5a3Y_b4eNBgDenPB5wUNGaw@mail.gmail.com>
On 01/06/2020 19:08, Doug Anderson wrote:
>> Am not 100% sure if "qcom,fuse-blow-frequency" is something integration
>> specific or SoC Specific, My idea was that this will give more
>> flexibility in future. As adding new SoC Support does not need driver
>> changes.
>>
>> Having said that, Am okay either way!
> Yeah, it's always a balance. I guess the question is: why do we think
> driver changes are worse than dts changes? The value still needs to
> be somewhere and having it in the driver isn't a terrible place.
>
TBH, its an overkill if we are using same IP version across multiple SoCs.
>
>> Incase we go compatible way, I would like to see compatible strings
>> having proper IP versions to have ip version rather than SoC names.
>>
>> Having SoC names in compatible string means both driver and bindings
>> need update for every new SoC which can be overhead very soon!
> Almost certainly the compatible strings should have SoC names in them.
> Yes it means a binding update every time a new SoC comes up but that
> is just how device tree works. Presumably there's enough chatter on
> this that Rob H has totally tuned it out at this point in time, but
> there are many other instances of this.
>
> NOTE: just because we have the SoC name in the compatible string
> _doesn't_ mean that the driver has to change. You already said that
> the IP version can be detected earlier in this thread, right? You
> said:
>
> I found out that there is a version register at offset of 0x6000 which
> can give MAJOR, MINOR and STEP numbers.
>
> So how about this:
>
> a) Compatible contains "SoC" version and the generic "qcom,qfrom", so:
>
> compatible = "qcom,sdm845-qfprom", "qcom,qfrom"
>
> b) Bindings will need to be updated for every new SoC, but that's
> normal and should be a trivial patch to just add a new SoC to the
> list.
>
> c) If the driver can be made to make its decisions about frequencies /
> timings completely by MAJOR/MINOR/STEP numbers then it can use those
> in its decision and it will never need to use the SoC-specific
> compatible string. The SoC-specific compatible string will only be
> present as a fallback "oops we have to workaround a bug that we didn't
> know about".
This makes more sense to me, I would still stay with MAJOR/MINOR/STEP
numbers mostly unless we are dealing with some corner cases.
thanks,
srini
>
>
>> Rob can help review once we have v2 bindings out!
> Sounds good. If you're still not convinced by my arguments we can see
> if we can get Rob to clarify once we have a v2.:-)
>
>
^ permalink raw reply
* [PATCH] ARM: dts: imx6sll: Make ssi node name same as other platforms
From: Shengjiu Wang @ 2020-06-02 10:44 UTC (permalink / raw)
To: robh+dt, shawnguo, s.hauer, kernel, festevam, linux-imx,
devicetree, linux-arm-kernel, linux-kernel
In imx6sll.dtsi, the ssi node name is different with other
platforms (imx6qdl, imx6sl, imx6sx), but the
sound/soc/fsl/fsl-asoc-card.c machine driver needs to check
ssi node name for audmux configuration, then different ssi
node name causes issue on imx6sll platform.
So we change ssi node name to make all platforms have same
name.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
arch/arm/boot/dts/imx6sll.dtsi | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
index edd3abb9a9f1..51e59e16f6c9 100644
--- a/arch/arm/boot/dts/imx6sll.dtsi
+++ b/arch/arm/boot/dts/imx6sll.dtsi
@@ -271,7 +271,7 @@
status = "disabled";
};
- ssi1: ssi-controller@2028000 {
+ ssi1: ssi@2028000 {
compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi";
reg = <0x02028000 0x4000>;
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
@@ -284,7 +284,7 @@
status = "disabled";
};
- ssi2: ssi-controller@202c000 {
+ ssi2: ssi@202c000 {
compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi";
reg = <0x0202c000 0x4000>;
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
@@ -297,7 +297,7 @@
status = "disabled";
};
- ssi3: ssi-controller@2030000 {
+ ssi3: ssi@2030000 {
compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi";
reg = <0x02030000 0x4000>;
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
--
2.21.0
^ permalink raw reply related
* [PATCH V3 2/3] mmc: sdhci: Allow platform controlled voltage switching
From: Veerabhadrarao Badiganti @ 2020-06-02 10:47 UTC (permalink / raw)
To: adrian.hunter, ulf.hansson, bjorn.andersson, robh+dt
Cc: linux-mmc, linux-kernel, linux-arm-msm, devicetree,
Vijay Viswanath, Veerabhadrarao Badiganti
In-Reply-To: <1591094883-11674-1-git-send-email-vbadigan@codeaurora.org>
From: Vijay Viswanath <vviswana@codeaurora.org>
If vendor platform drivers are controlling whole logic of voltage
switching, then sdhci driver no need control vqmmc regulator.
So skip enabling/disable vqmmc from SDHC driver.
Signed-off-by: Vijay Viswanath <vviswana@codeaurora.org>
Signed-off-by: Veerabhadrarao Badiganti <vbadigan@codeaurora.org>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci.c | 32 +++++++++++++++++++-------------
drivers/mmc/host/sdhci.h | 1 +
2 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 37b1158c1c0c..e6275c2202b0 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -4105,6 +4105,7 @@ int sdhci_setup_host(struct sdhci_host *host)
unsigned int override_timeout_clk;
u32 max_clk;
int ret;
+ bool enable_vqmmc = false;
WARN_ON(host == NULL);
if (host == NULL)
@@ -4118,9 +4119,12 @@ int sdhci_setup_host(struct sdhci_host *host)
* the host can take the appropriate action if regulators are not
* available.
*/
- ret = mmc_regulator_get_supply(mmc);
- if (ret)
- return ret;
+ if (!mmc->supply.vqmmc) {
+ ret = mmc_regulator_get_supply(mmc);
+ if (ret)
+ return ret;
+ enable_vqmmc = true;
+ }
DBG("Version: 0x%08x | Present: 0x%08x\n",
sdhci_readw(host, SDHCI_HOST_VERSION),
@@ -4377,7 +4381,15 @@ int sdhci_setup_host(struct sdhci_host *host)
mmc->caps |= MMC_CAP_NEEDS_POLL;
if (!IS_ERR(mmc->supply.vqmmc)) {
- ret = regulator_enable(mmc->supply.vqmmc);
+ if (enable_vqmmc) {
+ ret = regulator_enable(mmc->supply.vqmmc);
+ if (ret) {
+ pr_warn("%s: Failed to enable vqmmc regulator: %d\n",
+ mmc_hostname(mmc), ret);
+ mmc->supply.vqmmc = ERR_PTR(-EINVAL);
+ }
+ host->sdhci_core_to_disable_vqmmc = !ret;
+ }
/* If vqmmc provides no 1.8V signalling, then there's no UHS */
if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 1700000,
@@ -4390,12 +4402,6 @@ int sdhci_setup_host(struct sdhci_host *host)
if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 2700000,
3600000))
host->flags &= ~SDHCI_SIGNALING_330;
-
- if (ret) {
- pr_warn("%s: Failed to enable vqmmc regulator: %d\n",
- mmc_hostname(mmc), ret);
- mmc->supply.vqmmc = ERR_PTR(-EINVAL);
- }
}
if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) {
@@ -4626,7 +4632,7 @@ int sdhci_setup_host(struct sdhci_host *host)
return 0;
unreg:
- if (!IS_ERR(mmc->supply.vqmmc))
+ if (host->sdhci_core_to_disable_vqmmc)
regulator_disable(mmc->supply.vqmmc);
undma:
if (host->align_buffer)
@@ -4644,7 +4650,7 @@ void sdhci_cleanup_host(struct sdhci_host *host)
{
struct mmc_host *mmc = host->mmc;
- if (!IS_ERR(mmc->supply.vqmmc))
+ if (host->sdhci_core_to_disable_vqmmc)
regulator_disable(mmc->supply.vqmmc);
if (host->align_buffer)
@@ -4787,7 +4793,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
destroy_workqueue(host->complete_wq);
- if (!IS_ERR(mmc->supply.vqmmc))
+ if (host->sdhci_core_to_disable_vqmmc)
regulator_disable(mmc->supply.vqmmc);
if (host->align_buffer)
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0008bbd27127..0770c036e2ff 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -567,6 +567,7 @@ struct sdhci_host {
u32 caps1; /* CAPABILITY_1 */
bool read_caps; /* Capability flags have been read */
+ bool sdhci_core_to_disable_vqmmc; /* sdhci core can disable vqmmc */
unsigned int ocr_avail_sdio; /* OCR bit masks */
unsigned int ocr_avail_sd;
unsigned int ocr_avail_mmc;
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH V3 3/3] mmc: sdhci-msm: Use internal voltage control
From: Veerabhadrarao Badiganti @ 2020-06-02 10:47 UTC (permalink / raw)
To: adrian.hunter, ulf.hansson, bjorn.andersson, robh+dt
Cc: linux-mmc, linux-kernel, linux-arm-msm, devicetree,
Veerabhadrarao Badiganti, Asutosh Das, Vijay Viswanath,
Andy Gross
In-Reply-To: <1591094883-11674-1-git-send-email-vbadigan@codeaurora.org>
On qcom SD host controllers voltage switching be done after the HW
is ready for it. The HW informs its readiness through power irq.
The voltage switching should happen only then.
Use the internal voltage switching and then control the voltage
switching using power irq.
Set the regulator load as well so that regulator can be configured
in LPM mode when in is not being used.
Co-developed-by: Asutosh Das <asutoshd@codeaurora.org>
Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
Co-developed-by: Vijay Viswanath <vviswana@codeaurora.org>
Signed-off-by: Vijay Viswanath <vviswana@codeaurora.org>
Co-developed-by: Veerabhadrarao Badiganti <vbadigan@codeaurora.org>
Signed-off-by: Veerabhadrarao Badiganti <vbadigan@codeaurora.org>
---
drivers/mmc/host/sdhci-msm.c | 235 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 226 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 95cd9735e9a3..20ef90fc7dd7 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -36,7 +36,9 @@
#define CORE_PWRCTL_IO_LOW BIT(2)
#define CORE_PWRCTL_IO_HIGH BIT(3)
#define CORE_PWRCTL_BUS_SUCCESS BIT(0)
+#define CORE_PWRCTL_BUS_FAIL BIT(1)
#define CORE_PWRCTL_IO_SUCCESS BIT(2)
+#define CORE_PWRCTL_IO_FAIL BIT(3)
#define REQ_BUS_OFF BIT(0)
#define REQ_BUS_ON BIT(1)
#define REQ_IO_LOW BIT(2)
@@ -277,6 +279,8 @@ struct sdhci_msm_host {
bool uses_tassadar_dll;
u32 dll_config;
u32 ddr_config;
+ u32 vqmmc_load;
+ bool vqmmc_enabled;
};
static const struct sdhci_msm_offset *sdhci_priv_msm_offset(struct sdhci_host *host)
@@ -1339,6 +1343,91 @@ static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host,
sdhci_msm_hs400(host, &mmc->ios);
}
+static int sdhci_msm_set_vmmc(struct mmc_host *mmc)
+{
+ if (IS_ERR(mmc->supply.vmmc))
+ return 0;
+
+ return mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, mmc->ios.vdd);
+}
+
+static int msm_toggle_vqmmc(struct sdhci_msm_host *msm_host,
+ struct mmc_host *mmc, bool level)
+{
+ int ret;
+ struct mmc_ios ios;
+
+ if (msm_host->vqmmc_enabled == level)
+ return 0;
+
+ if (level) {
+ /* Set the IO voltage regulator to default voltage level */
+ if (msm_host->caps_0 & CORE_3_0V_SUPPORT)
+ ios.signal_voltage = MMC_SIGNAL_VOLTAGE_330;
+ else if (msm_host->caps_0 & CORE_1_8V_SUPPORT)
+ ios.signal_voltage = MMC_SIGNAL_VOLTAGE_180;
+
+ if (msm_host->caps_0 & CORE_VOLT_SUPPORT) {
+ ret = mmc_regulator_set_vqmmc(mmc, &ios);
+ if (ret < 0) {
+ dev_err(mmc_dev(mmc), "%s: vqmmc set volgate failed: %d\n",
+ mmc_hostname(mmc), ret);
+ goto out;
+ }
+ }
+ ret = regulator_enable(mmc->supply.vqmmc);
+ } else {
+ ret = regulator_disable(mmc->supply.vqmmc);
+ }
+
+ if (ret)
+ dev_err(mmc_dev(mmc), "%s: vqmm %sable failed: %d\n",
+ mmc_hostname(mmc), level ? "en":"dis", ret);
+ else
+ msm_host->vqmmc_enabled = level;
+out:
+ return ret;
+}
+
+static int msm_config_vqmmc_mode(struct sdhci_msm_host *msm_host,
+ struct mmc_host *mmc, bool hpm)
+{
+ int load, ret;
+
+ if (!msm_host->vqmmc_load)
+ return 0;
+
+ load = hpm ? msm_host->vqmmc_load : 0;
+ ret = regulator_set_load(mmc->supply.vqmmc, load);
+ if (ret)
+ dev_err(mmc_dev(mmc), "%s: vqmmc set load failed: %d\n",
+ mmc_hostname(mmc), ret);
+ return ret;
+}
+
+static int sdhci_msm_set_vqmmc(struct sdhci_msm_host *msm_host,
+ struct mmc_host *mmc, bool level)
+{
+ int ret;
+ bool always_on;
+
+ if (IS_ERR(mmc->supply.vqmmc) ||
+ (mmc->ios.power_mode == MMC_POWER_UNDEFINED))
+ return 0;
+ /*
+ * For eMMC don't turn off Vqmmc, Instead just configure it in LPM
+ * and HPM modes by setting the right amonut of load.
+ */
+ always_on = mmc->card && mmc_card_mmc(mmc->card);
+
+ if (always_on)
+ ret = msm_config_vqmmc_mode(msm_host, mmc, level);
+ else
+ ret = msm_toggle_vqmmc(msm_host, mmc, level);
+
+ return ret;
+}
+
static inline void sdhci_msm_init_pwr_irq_wait(struct sdhci_msm_host *msm_host)
{
init_waitqueue_head(&msm_host->pwr_irq_wait);
@@ -1442,8 +1531,9 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+ struct mmc_host *mmc = host->mmc;
u32 irq_status, irq_ack = 0;
- int retry = 10;
+ int retry = 10, ret;
u32 pwr_state = 0, io_level = 0;
u32 config;
const struct sdhci_msm_offset *msm_offset = msm_host->offset;
@@ -1481,21 +1571,42 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq)
if (irq_status & CORE_PWRCTL_BUS_ON) {
pwr_state = REQ_BUS_ON;
io_level = REQ_IO_HIGH;
- irq_ack |= CORE_PWRCTL_BUS_SUCCESS;
}
if (irq_status & CORE_PWRCTL_BUS_OFF) {
pwr_state = REQ_BUS_OFF;
io_level = REQ_IO_LOW;
- irq_ack |= CORE_PWRCTL_BUS_SUCCESS;
}
+
+ if (pwr_state) {
+ ret = sdhci_msm_set_vmmc(mmc);
+ if (!ret)
+ ret = sdhci_msm_set_vqmmc(msm_host, mmc,
+ pwr_state & REQ_BUS_ON);
+ if (!ret)
+ irq_ack |= CORE_PWRCTL_BUS_SUCCESS;
+ else
+ irq_ack |= CORE_PWRCTL_BUS_FAIL;
+ }
+
/* Handle IO LOW/HIGH */
- if (irq_status & CORE_PWRCTL_IO_LOW) {
+ if (irq_status & CORE_PWRCTL_IO_LOW)
io_level = REQ_IO_LOW;
- irq_ack |= CORE_PWRCTL_IO_SUCCESS;
- }
- if (irq_status & CORE_PWRCTL_IO_HIGH) {
+
+ if (irq_status & CORE_PWRCTL_IO_HIGH)
io_level = REQ_IO_HIGH;
+
+ if (io_level)
irq_ack |= CORE_PWRCTL_IO_SUCCESS;
+
+ if (io_level && !IS_ERR(mmc->supply.vqmmc) && !pwr_state) {
+ ret = mmc_regulator_set_vqmmc(mmc, &mmc->ios);
+ if (ret < 0) {
+ dev_err(mmc_dev(mmc), "%s: IO_level setting failed(%d). signal_voltage: %d, vdd: %d irq_status: 0x%08x\n",
+ mmc_hostname(mmc), ret,
+ mmc->ios.signal_voltage, mmc->ios.vdd,
+ irq_status);
+ irq_ack |= CORE_PWRCTL_IO_FAIL;
+ }
}
/*
@@ -1544,7 +1655,7 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq)
if (io_level)
msm_host->curr_io_level = io_level;
- pr_debug("%s: %s: Handled IRQ(%d), irq_status=0x%x, ack=0x%x\n",
+ dev_dbg(mmc_dev(mmc), "%s: %s: Handled IRQ(%d), irq_status=0x%x, ack=0x%x\n",
mmc_hostname(msm_host->mmc), __func__, irq, irq_status,
irq_ack);
}
@@ -1874,6 +1985,106 @@ static void sdhci_msm_reset(struct sdhci_host *host, u8 mask)
sdhci_reset(host, mask);
}
+static int sdhci_msm_register_vreg(struct sdhci_msm_host *msm_host)
+{
+ int ret;
+ u32 vmmc_load;
+ struct mmc_host *mmc = msm_host->mmc;
+
+ ret = mmc_regulator_get_supply(msm_host->mmc);
+ if (ret)
+ return ret;
+ device_property_read_u32(&msm_host->pdev->dev,
+ "vmmc-supply-max-microamp",
+ &vmmc_load);
+ device_property_read_u32(&msm_host->pdev->dev,
+ "vqmmc-supply-max-microamp",
+ &msm_host->vqmmc_load);
+
+ /* Set active load */
+ if (!IS_ERR(mmc->supply.vmmc) && vmmc_load) {
+ ret = regulator_set_load(mmc->supply.vmmc, vmmc_load);
+ if (ret) {
+ dev_err(mmc_dev(mmc), "%s: vmmc set active load failed: %d\n",
+ mmc_hostname(mmc), ret);
+ return ret;
+ }
+ }
+ if (!IS_ERR(mmc->supply.vqmmc) && msm_host->vqmmc_load) {
+ ret = regulator_set_load(mmc->supply.vmmc,
+ msm_host->vqmmc_load);
+ if (ret) {
+ dev_err(mmc_dev(mmc), "%s: vqmmc set active load failed: %d\n",
+ mmc_hostname(mmc), ret);
+ return ret;
+ }
+ }
+
+ sdhci_msm_set_regulator_caps(msm_host);
+ mmc->ios.power_mode = MMC_POWER_UNDEFINED;
+
+ return 0;
+}
+
+static int sdhci_msm_start_signal_voltage_switch(struct mmc_host *mmc,
+ struct mmc_ios *ios)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ u16 ctrl, status;
+
+ /*
+ * Signal Voltage Switching is only applicable for Host Controllers
+ * v3.00 and above.
+ */
+ if (host->version < SDHCI_SPEC_300)
+ return 0;
+
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+ switch (ios->signal_voltage) {
+ case MMC_SIGNAL_VOLTAGE_330:
+ if (!(host->flags & SDHCI_SIGNALING_330))
+ return -EINVAL;
+
+ /* Set 1.8V Signal Enable in the Host Control2 register to 0 */
+ ctrl &= ~SDHCI_CTRL_VDD_180;
+ break;
+ case MMC_SIGNAL_VOLTAGE_180:
+ if (!(host->flags & SDHCI_SIGNALING_180))
+ return -EINVAL;
+
+ /*
+ * Enable 1.8V Signal Enable in the Host Control2
+ * register
+ */
+ ctrl |= SDHCI_CTRL_VDD_180;
+ break;
+ case MMC_SIGNAL_VOLTAGE_120:
+ if (!(host->flags & SDHCI_SIGNALING_120))
+ return -EINVAL;
+ return 0;
+ default:
+ /* No signal voltage switch required */
+ return 0;
+ }
+
+ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+
+ /* Wait for 5ms */
+ usleep_range(5000, 5500);
+
+ /* regulator output should be stable within 5 ms */
+ status = ctrl & SDHCI_CTRL_VDD_180;
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ if ((ctrl & SDHCI_CTRL_VDD_180) == status)
+ return 0;
+
+ dev_warn(mmc_dev(mmc), "%s: Regulator output did not became stable\n",
+ mmc_hostname(mmc));
+
+ return -EAGAIN;
+}
+
#define DRIVER_NAME "sdhci_msm"
#define SDHCI_MSM_DUMP(f, x...) \
pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x)
@@ -1960,6 +2171,7 @@ void sdhci_msm_dump_vendor_regs(struct sdhci_host *host)
.write_b = sdhci_msm_writeb,
.irq = sdhci_msm_cqe_irq,
.dump_vendor_regs = sdhci_msm_dump_vendor_regs,
+ .set_power = sdhci_set_power_noreg,
};
static const struct sdhci_pltfm_data sdhci_msm_pdata = {
@@ -2169,6 +2381,10 @@ static int sdhci_msm_probe(struct platform_device *pdev)
if (core_major == 1 && core_minor >= 0x49)
msm_host->updated_ddr_cfg = true;
+ ret = sdhci_msm_register_vreg(msm_host);
+ if (ret)
+ goto clk_disable;
+
/*
* Power on reset state may trigger power irq if previous status of
* PWRCTL was either BUS_ON or IO_HIGH_V. So before enabling pwr irq
@@ -2213,6 +2429,8 @@ static int sdhci_msm_probe(struct platform_device *pdev)
MSM_MMC_AUTOSUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&pdev->dev);
+ host->mmc_host_ops.start_signal_voltage_switch =
+ sdhci_msm_start_signal_voltage_switch;
host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning;
if (of_property_read_bool(node, "supports-cqe"))
ret = sdhci_msm_cqe_add_host(host, pdev);
@@ -2220,7 +2438,6 @@ static int sdhci_msm_probe(struct platform_device *pdev)
ret = sdhci_add_host(host);
if (ret)
goto pm_runtime_disable;
- sdhci_msm_set_regulator_caps(msm_host);
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH V3 0/3] Internal voltage control for qcom SDHC
From: Veerabhadrarao Badiganti @ 2020-06-02 10:47 UTC (permalink / raw)
To: adrian.hunter, ulf.hansson, bjorn.andersson, robh+dt
Cc: linux-mmc, linux-kernel, linux-arm-msm, devicetree,
Veerabhadrarao Badiganti
In-Reply-To: <1589541535-8523-1-git-send-email-vbadigan@codeaurora.org>
On qcom SD host controllers voltage switching be done after the HW
is ready for it. The HW informs its readiness through power irq.
The voltage switching should happen only then.
So added support to register voltage regulators from the msm driver
and use them.
This patchset was posted long back but not actively pursued
https://lore.kernel.org/linux-arm-msm/1539004739-32060-1-git-send-email-vbadigan@codeaurora.org/
So posting it as fresh patchset.
Changes since V2:
- Removed redundant log from sdhci_msm_set_vmmc.
- Added the condition for skiping disabling of vqmmc for eMMC.
- Updated logic such that, setting load for vqmmc only if
it is kept ON.
- Retained ack by Adrian for second patch.
- Updated dt properties names as per Robs comments.
Changes since V1:
- Removed setting load for Vmmc regulator while turning it on/off.
Instead setting the active load once during probe.
- Simplified handlng of supplies for BUS_ON/OFF cases in shci_msm_handle_pwr_irq().
- Moved common code out of switch case in sdhci_msm_start_signal_voltage_switch().
- Updated variable name to sdhci_core_to_disable_vqmmc.
- Updated pr_err logs to dev_err logs.
Veerabhadrarao Badiganti (2):
dt-bindings: mmc: Supply max load for mmc supplies
mmc: sdhci-msm: Use internal voltage control
Vijay Viswanath (1):
mmc: sdhci: Allow platform controlled voltage switching
.../devicetree/bindings/mmc/mmc-controller.yaml | 6 +
drivers/mmc/host/sdhci-msm.c | 235 ++++++++++++++++++++-
drivers/mmc/host/sdhci.c | 32 +--
drivers/mmc/host/sdhci.h | 1 +
4 files changed, 252 insertions(+), 22 deletions(-)
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH V3 1/3] dt-bindings: mmc: Supply max load for mmc supplies
From: Veerabhadrarao Badiganti @ 2020-06-02 10:47 UTC (permalink / raw)
To: adrian.hunter, ulf.hansson, bjorn.andersson, robh+dt
Cc: linux-mmc, linux-kernel, linux-arm-msm, devicetree,
Veerabhadrarao Badiganti
In-Reply-To: <1591094883-11674-1-git-send-email-vbadigan@codeaurora.org>
Supply the max load needed for driving the mmc supplies.
Signed-off-by: Veerabhadrarao Badiganti <vbadigan@codeaurora.org>
---
Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
index acc9f10871d4..d95219721fa1 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
@@ -290,6 +290,12 @@ properties:
description:
Supply for the bus IO line power
+ vmmc-supply-max-microamp:
+ description: Maximum load for the card power.
+
+ vqmmc-supply-max-microamp:
+ description: Maximum load for the bus IO line power.
+
mmc-pwrseq:
$ref: /schemas/types.yaml#/definitions/phandle
description:
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
^ permalink raw reply related
* Re: [PATCH V6 4/5] clk: qcom: Add ipq6018 apss clock controller
From: Sivaprakash Murugesan @ 2020-06-02 10:47 UTC (permalink / raw)
To: Stephen Boyd, agross, bjorn.andersson, devicetree, linux-arm-msm,
linux-clk, linux-kernel, mturquette, robh+dt
In-Reply-To: <159104019638.69627.9161269856470136421@swboyd.mtv.corp.google.com>
On 6/2/2020 1:06 AM, Stephen Boyd wrote:
> Quoting Sivaprakash Murugesan (2020-06-01 05:41:15)
>> On 5/28/2020 7:29 AM, Stephen Boyd wrote:
>>> Quoting Sivaprakash Murugesan (2020-05-27 05:24:51)
>>>> diff --git a/drivers/clk/qcom/apss-ipq6018.c b/drivers/clk/qcom/apss-ipq6018.c
>>>> new file mode 100644
>>>> index 0000000..004f7e1
>>>> --- /dev/null
>>>> +++ b/drivers/clk/qcom/apss-ipq6018.c
>>>> @@ -0,0 +1,106 @@
>>>> + P_XO,
>>>> + P_APSS_PLL_EARLY,
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data parents_apcs_alias0_clk_src[] = {
>>>> + { .fw_name = "xo" },
>>>> + { .fw_name = "pll" },
>>> This pll clk is not described in the binding. Please add it there.
>> Sorry I did not get this, this PLL is not directly defined in this
>> driver and it comes
>>
>> from dts. do you still want to describe it in binding?
>>
> Yes, there should be a clock-names property for "pll" and a clocks
> property in the binding document. I didn't see that.
These are defined in
https://lkml.org/lkml/2020/5/27/658and
https://lkml.org/lkml/2020/5/27/659
it has been defined as part of mailbox binding, since this driver does
not have a dts node and it is child of apcs mailbox driver.
^ permalink raw reply
* Re: [PATCH v2 2/2] media: v4l: xilinx: Add Xilinx UHD-SDI Rx Subsystem driver
From: Hans Verkuil @ 2020-06-02 10:44 UTC (permalink / raw)
To: Vishal Sagar, Hyun Kwon, laurent.pinchart@ideasonboard.com,
mchehab@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com,
Michal Simek, linux-media@vger.kernel.org,
devicetree@vger.kernel.org, hans.verkuil@cisco.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Dinesh Kumar, Sandip Kothari,
Joe Perches
In-Reply-To: <DM6PR02MB6876F989682935D38AA9BF19A78A0@DM6PR02MB6876.namprd02.prod.outlook.com>
On 01/06/2020 16:59, Vishal Sagar wrote:
> Hi Hans,
>
> Thanks for reviewing!
>
>>> + case V4L2_CID_XILINX_SDIRX_TS_IS_INTERLACED:
>>> + if (!xsdirxss->vidlocked) {
>>> + dev_err(dev, "Can't get values when video not
>> locked!\n");
>>> + return -EINVAL;
>>> + }
>>> + ctrl->val = xsdirxss->ts_is_interlaced;
>>
>> This control makes no sense: the v4l2_dv_timings struct will already tell you
>> if it is an interlaced format or not. Same for v4l2_mbus_framefmt.
>>
>
> The SDI has a concept of supporting progressive, interlaced (both as we know normally) and a progressive segmented frames(psf).
> The progressive segmented frames have their video content in progressive format but the transport stream is interlaced.
> This is distinguished using the bit 6 and 7 of Byte 2 in the 4 byte ST352 payload.
> Refer to sec 5.3 in SMPTE ST 352:2010.
>
> This control can be used by the application to distinguish normal interlaced and progressive segmented frames.
Ah, interesting. So this relies on the receiver to reconstruct the progressive
frame by combining the top and bottom field, right?
I think this deserves a new v4l2_field value:
V4L2_FIELD_ALTERNATE_PROG
Basically this is identical to V4L2_FIELD_ALTERNATE, except that the two fields
combine to a single progressive frame.
Regards,
Hans
PS: I'll look at your other comments separately
^ permalink raw reply
* Re: [PATCH v6 2/2] hwrng: add sec-rng driver
From: Greg Kroah-Hartman @ 2020-06-02 10:38 UTC (permalink / raw)
To: Neal Liu
Cc: Matt Mackall, Herbert Xu, Rob Herring, Matthias Brugger,
Sean Wang, Arnd Bergmann, linux-crypto, devicetree,
linux-arm-kernel, linux-mediatek, lkml, wsd_upstream, Crystal Guo
In-Reply-To: <1591085678-22764-3-git-send-email-neal.liu@mediatek.com>
On Tue, Jun 02, 2020 at 04:14:38PM +0800, Neal Liu wrote:
> For security awareness SoCs on ARMv8 with TrustZone enabled,
> peripherals like entropy sources is not accessible from normal world
> (linux) and rather accessible from secure world (HYP/ATF/TEE) only.
> This driver aims to provide a generic interface to Arm Trusted
> Firmware or Hypervisor rng service.
>
> Signed-off-by: Neal Liu <neal.liu@mediatek.com>
> ---
> drivers/char/hw_random/Kconfig | 13 ++++
> drivers/char/hw_random/Makefile | 1 +
> drivers/char/hw_random/sec-rng.c | 155 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 169 insertions(+)
> create mode 100644 drivers/char/hw_random/sec-rng.c
>
> diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
> index 9bc46da..cb9c8a9 100644
> --- a/drivers/char/hw_random/Kconfig
> +++ b/drivers/char/hw_random/Kconfig
> @@ -474,6 +474,19 @@ config HW_RANDOM_KEYSTONE
> help
> This option enables Keystone's hardware random generator.
>
> +config HW_RANDOM_SECURE
> + tristate "Arm Security Random Number Generator support"
> + depends on HAVE_ARM_SMCCC || COMPILE_TEST
> + default HW_RANDOM
> + help
> + This driver provides kernel-side support for the Arm Security
> + Random Number Generator.
> +
> + To compile this driver as a module, choose M here. the
> + module will be called sec-rng.
> +
> + If unsure, say Y.
Why Y?
> +
> endif # HW_RANDOM
>
> config UML_RANDOM
> diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
> index a7801b4..04533d1 100644
> --- a/drivers/char/hw_random/Makefile
> +++ b/drivers/char/hw_random/Makefile
> @@ -41,3 +41,4 @@ obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
> obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
> obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
> obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
> +obj-$(CONFIG_HW_RANDOM_SECURE) += sec-rng.o
> diff --git a/drivers/char/hw_random/sec-rng.c b/drivers/char/hw_random/sec-rng.c
> new file mode 100644
> index 0000000..c6d3872
> --- /dev/null
> +++ b/drivers/char/hw_random/sec-rng.c
> @@ -0,0 +1,155 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 MediaTek Inc.
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/hw_random.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#define SMC_RET_NUM 4
> +#define SEC_RND_SIZE (sizeof(u32) * SMC_RET_NUM)
> +
> +#define HWRNG_SMC_FAST_CALL_VAL(func_num) \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
> + ARM_SMCCC_OWNER_SIP, (func_num))
> +
> +#define to_sec_rng(p) container_of(p, struct sec_rng_priv, rng)
> +
> +typedef void (sec_rng_fn)(unsigned long, unsigned long, unsigned long,
> + unsigned long, unsigned long, unsigned long,
> + unsigned long, unsigned long,
> + struct arm_smccc_res *);
Why not throw some more unsigned longs in there? :)
Seriously, no variable names for these? Why not?
And given that you only use the first parameter, why have 7 of them that
are not used at all? That feels pointless and needlessly complex.
> +
> +struct sec_rng_priv {
> + u16 func_num;
> + sec_rng_fn *rng_fn;
> + struct hwrng rng;
> +};
Nit, if you put 'struct hwrng' at the top of the structure, your
"to_sec_rng()" macro resolves to a simple cast, no math at all.
> +
> +/* Simple wrapper functions to be able to use a function pointer */
> +static void sec_rng_smc(unsigned long a0, unsigned long a1,
> + unsigned long a2, unsigned long a3,
> + unsigned long a4, unsigned long a5,
> + unsigned long a6, unsigned long a7,
> + struct arm_smccc_res *res)
> +{
> + arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
> +}
> +
> +static void sec_rng_hvc(unsigned long a0, unsigned long a1,
> + unsigned long a2, unsigned long a3,
> + unsigned long a4, unsigned long a5,
> + unsigned long a6, unsigned long a7,
> + struct arm_smccc_res *res)
> +{
> + arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
> +}
> +
> +static bool __sec_get_rnd(struct sec_rng_priv *priv, uint32_t *val)
> +{
> + struct arm_smccc_res res;
> +
> + priv->rng_fn(HWRNG_SMC_FAST_CALL_VAL(priv->func_num),
> + 0, 0, 0, 0, 0, 0, 0, &res);
See, all 0's :(
You could hard-code them in the functions above instead.
But, all of this pointer indirection is really odd, why is it needed at
all? Why not just call one or the other depending on the "type" at
runtime? Wouldn't that actually be faster (hint, it is...), if you
cared about speed here (hint, I doubt it matters).
> +
> + if (!res.a0 && !res.a1 && !res.a2 && !res.a3)
> + return false;
> +
> + val[0] = res.a0;
> + val[1] = res.a1;
> + val[2] = res.a2;
> + val[3] = res.a3;
So no values out of the random number generator can be 0? Feels like an
odd thing for a random number not to be allowed to do, why this
restriction?
> +
> + return true;
> +}
> +
> +static int sec_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
> +{
> + struct sec_rng_priv *priv = to_sec_rng(rng);
> + u32 val[4] = {0};
> + int retval = 0;
> + int i;
> +
> + while (max >= SEC_RND_SIZE) {
> + if (!__sec_get_rnd(priv, val))
> + return retval;
> +
> + for (i = 0; i < SMC_RET_NUM; i++) {
> + *(u32 *)buf = val[i];
> + buf += sizeof(u32);
Wait, what happens if buf is not a multiple of 4? Didn't you just
overwrite some memory above with the previous line?
> + }
> +
> + retval += SEC_RND_SIZE;
> + max -= SEC_RND_SIZE;
> + }
> +
> + return retval;
> +}
> +
> +static int sec_rng_probe(struct platform_device *pdev)
> +{
> + struct sec_rng_priv *priv;
> + const char *method;
> + int ret;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + if (of_property_read_string(pdev->dev.of_node, "method", &method))
> + return -ENXIO;
> +
> + if (!strncmp("smc", method, strlen("smc")))
> + priv->rng_fn = sec_rng_smc;
> + else if (!strncmp("hvc", method, strlen("hvc")))
> + priv->rng_fn = sec_rng_hvc;
> +
> + if (IS_ERR(priv->rng_fn)) {
How can this ever be true?
Just put another else on the above list and you should be fine.
> + dev_err(&pdev->dev, "method %s is not supported\n", method);
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u16(pdev->dev.of_node, "method-fid",
> + &priv->func_num))
> + return -ENXIO;
> +
> + if (of_property_read_u16(pdev->dev.of_node, "quality",
> + &priv->rng.quality))
> + return -ENXIO;
> +
> + priv->rng.name = pdev->name;
> + priv->rng.read = sec_rng_read;
> + priv->rng.priv = (unsigned long)&pdev->dev;
> +
> + ret = devm_hwrng_register(&pdev->dev, &priv->rng);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to register rng device: %d\n", ret);
Doesn't the caller print out something if this fails?
thanks,
greg k-h
^ permalink raw reply
* RE: [PATCH v7 21/24] iommu/arm-smmu-v3: Add stall support for platform devices
From: Shameerali Kolothum Thodi @ 2020-06-02 10:31 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: devicetree@vger.kernel.org, kevin.tian@intel.com, will@kernel.org,
fenghua.yu@intel.com, jgg@ziepe.ca, linux-pci@vger.kernel.org,
felix.kuehling@amd.com, hch@infradead.org, linux-mm@kvack.org,
iommu@lists.linux-foundation.org, catalin.marinas@arm.com,
zhangfei.gao@linaro.org, robin.murphy@arm.com,
christian.koenig@amd.com, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20200602093836.GA1029680@myrica>
Hi Jean,
> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces@lists.infradead.org]
> On Behalf Of Jean-Philippe Brucker
> Sent: 02 June 2020 10:39
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>
> Cc: devicetree@vger.kernel.org; kevin.tian@intel.com; will@kernel.org;
> fenghua.yu@intel.com; jgg@ziepe.ca; linux-pci@vger.kernel.org;
> felix.kuehling@amd.com; hch@infradead.org; linux-mm@kvack.org;
> iommu@lists.linux-foundation.org; catalin.marinas@arm.com;
> zhangfei.gao@linaro.org; robin.murphy@arm.com;
> christian.koenig@amd.com; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH v7 21/24] iommu/arm-smmu-v3: Add stall support for
> platform devices
>
> Hi Shameer,
>
> On Mon, Jun 01, 2020 at 12:42:15PM +0000, Shameerali Kolothum Thodi
> wrote:
> > > /* IRQ and event handlers */
> > > +static int arm_smmu_handle_evt(struct arm_smmu_device *smmu, u64
> > > +*evt) {
> > > + int ret;
> > > + u32 perm = 0;
> > > + struct arm_smmu_master *master;
> > > + bool ssid_valid = evt[0] & EVTQ_0_SSV;
> > > + u8 type = FIELD_GET(EVTQ_0_ID, evt[0]);
> > > + u32 sid = FIELD_GET(EVTQ_0_SID, evt[0]);
> > > + struct iommu_fault_event fault_evt = { };
> > > + struct iommu_fault *flt = &fault_evt.fault;
> > > +
> > > + /* Stage-2 is always pinned at the moment */
> > > + if (evt[1] & EVTQ_1_S2)
> > > + return -EFAULT;
> > > +
> > > + master = arm_smmu_find_master(smmu, sid);
> > > + if (!master)
> > > + return -EINVAL;
> > > +
> > > + if (evt[1] & EVTQ_1_READ)
> > > + perm |= IOMMU_FAULT_PERM_READ;
> > > + else
> > > + perm |= IOMMU_FAULT_PERM_WRITE;
> > > +
> > > + if (evt[1] & EVTQ_1_EXEC)
> > > + perm |= IOMMU_FAULT_PERM_EXEC;
> > > +
> > > + if (evt[1] & EVTQ_1_PRIV)
> > > + perm |= IOMMU_FAULT_PERM_PRIV;
> > > +
> > > + if (evt[1] & EVTQ_1_STALL) {
> > > + flt->type = IOMMU_FAULT_PAGE_REQ;
> > > + flt->prm = (struct iommu_fault_page_request) {
> > > + .flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
> > > + .pasid = FIELD_GET(EVTQ_0_SSID, evt[0]),
> > > + .grpid = FIELD_GET(EVTQ_1_STAG, evt[1]),
> > > + .perm = perm,
> > > + .addr = FIELD_GET(EVTQ_2_ADDR, evt[2]),
> > > + };
> > > +
> >
> > > + if (ssid_valid)
> > > + flt->prm.flags |=
> IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
> >
> > Do we need to set this for STALL mode only support? I had an issue
> > with this being set on a vSVA POC based on our D06 zip device(which is
> > a "fake " pci dev that supports STALL mode but no PRI). The issue is,
> > CMDQ_OP_RESUME doesn't have any ssid or SSV params and works on sid
> and stag only.
>
> I don't understand the problem, arm_smmu_page_response() doesn't set SSID
> or SSV when sending a CMDQ_OP_RESUME. Could you detail the flow of a stall
> event and RESUME command in your prototype? Are you getting issues with
> the host driver or the guest driver?
The issue is on the host side iommu_page_response(). The flow is something like
below.
Stall: Host:-
arm_smmu_handle_evt()
iommu_report_device_fault()
vfio_pci_iommu_dev_fault_handler()
Stall: Qemu:-
vfio_dma_fault_notifier_handler()
inject_faults()
smmuv3_inject_faults()
Stall: Guest:-
arm_smmu_handle_evt()
iommu_report_device_fault()
iommu_queue_iopf
...
iopf_handle_group()
iopf_handle_single()
handle_mm_fault()
iopf_complete()
iommu_page_response()
arm_smmu_page_response()
arm_smmu_cmdq_issue_cmd(CMDQ_OP_RESUME)
Resume: Qemu:-
smmuv3_cmdq_consume(SMMU_CMD_RESUME)
smmuv3_notify_page_resp()
vfio:ioctl(page_response) --> struct iommu_page_response is filled
with only version, grpid and code.
Resume: Host:-
ioctl(page_response)
iommu_page_response() --> fails as the pending req has PASID_VALID flag
set and it checks for a match.
arm_smmu_page_response()
Hope the above is clear.
> We do need to forward the SSV flag all the way to the guest driver, so the guest
> can find the faulting address space using the SSID. Once the guest handled the
> fault, then we don't send the SSID back to the host as part of the RESUME
> command.
True, the guest requires SSV flag to handle the page fault. But, as shown in the
flow above, the issue is on the host side iommu_page_response() where it
searches for a matching pending req based on pasid. Not sure we can bypass
that and call arm_smmu_page_response() directly but then have to delete the
pending req from the list as well.
Please let me know if there is a better way to handle the host side page
response.
Thanks,
Shameer
> Thanks,
> Jean
>
> > Hence, it is difficult for
> > Qemu SMMUv3 to populate this fields while preparing a page response. I
> > can see that this flag is being checked in iopf_handle_single() (patch
> > 04/24) as well. For POC, I used a temp fix[1] to work around this. Please let
> me know your thoughts.
> >
> > Thanks,
> > Shameer
> >
> > 1.
> > https://github.com/hisilicon/kernel-dev/commit/99ff96146e924055f38d97a
> > 5897e4becfa378d15
> >
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 6/6] MAINTAINERS: Add maintainers for MIPS core drivers
From: Marc Zyngier @ 2020-06-02 10:12 UTC (permalink / raw)
To: Serge Semin
Cc: Thomas Bogendoerfer, Thomas Gleixner, Greg Kroah-Hartman,
Serge Semin, Alexey Malahov, Paul Burton, Rob Herring,
Arnd Bergmann, Jason Cooper, Rafael J. Wysocki, Daniel Lezcano,
James Hogan, linux-mips, devicetree, linux-kernel
In-Reply-To: <20200602100921.1155-7-Sergey.Semin@baikalelectronics.ru>
On 2020-06-02 11:09, Serge Semin wrote:
> Add Thomas and myself as maintainers of the MIPS CPU and GIC IRQchip,
> MIPS
> GIC timer and MIPS CPS CPUidle drivers.
>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
>
> ---
>
> Changelog v3:
> - Keep the files list alphabetically ordered.
> - Add Thomas as the co-maintainer of the designated drivers.
> ---
> MAINTAINERS | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 2926327e4976..20532e0287d7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11278,6 +11278,17 @@
> F: arch/mips/configs/generic/board-boston.config
> F: drivers/clk/imgtec/clk-boston.c
> F: include/dt-bindings/clock/boston-clock.h
>
> +MIPS CORE DRIVERS
> +M: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> +M: Serge Semin <fancer.lancer@gmail.com>
> +L: linux-mips@vger.kernel.org
> +S: Supported
> +F: drivers/bus/mips_cdmm.c
> +F: drivers/clocksource/mips-gic-timer.c
> +F: drivers/cpuidle/cpuidle-cps.c
> +F: drivers/irqchip/irq-mips-cpu.c
> +F: drivers/irqchip/irq-mips-gic.c
> +
> MIPS GENERIC PLATFORM
> M: Paul Burton <paulburton@kernel.org>
> L: linux-mips@vger.kernel.org
Acked-by: Marc Zyngier <maz@kernel.org>
I assume this will go via the MIPS tree.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH v3 3/6] dt-bindings: bus: Add MIPS CDMM controller
From: Serge Semin @ 2020-06-02 10:09 UTC (permalink / raw)
To: Thomas Bogendoerfer, Thomas Gleixner, Greg Kroah-Hartman,
Rob Herring
Cc: Serge Semin, Serge Semin, Alexey Malahov, Paul Burton,
Arnd Bergmann, Jason Cooper, Marc Zyngier, Rafael J. Wysocki,
Daniel Lezcano, James Hogan, linux-mips, devicetree, linux-kernel,
Rob Herring
In-Reply-To: <20200602100921.1155-1-Sergey.Semin@baikalelectronics.ru>
It's a Common Device Memory Map controller embedded into the MIPS IP
cores, which dts node is supposed to have compatible and reg properties.
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Changelog prev:
- Lowercase the example hex'es.
---
.../bindings/bus/mti,mips-cdmm.yaml | 35 +++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/mti,mips-cdmm.yaml
diff --git a/Documentation/devicetree/bindings/bus/mti,mips-cdmm.yaml b/Documentation/devicetree/bindings/bus/mti,mips-cdmm.yaml
new file mode 100644
index 000000000000..b3ba98515cbe
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mti,mips-cdmm.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/mti,mips-cdmm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MIPS Common Device Memory Map
+
+description: |
+ Defines a location of the MIPS Common Device Memory Map registers.
+
+maintainers:
+ - James Hogan <jhogan@kernel.org>
+
+properties:
+ compatible:
+ const: mti,mips-cdmm
+
+ reg:
+ description: |
+ Base address and size of an unoccupied memory region, which will be
+ used to map the MIPS CDMM registers block.
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+examples:
+ - |
+ cdmm@1bde8000 {
+ compatible = "mti,mips-cdmm";
+ reg = <0 0x1bde8000 0 0x8000>;
+ };
+...
--
2.26.2
^ permalink raw reply related
* [PATCH v3 0/6] mips: Add DT bindings for MIPS CDMM and MIPS GIC
From: Serge Semin @ 2020-06-02 10:09 UTC (permalink / raw)
To: Thomas Bogendoerfer, Thomas Gleixner, Greg Kroah-Hartman
Cc: Serge Semin, Serge Semin, Alexey Malahov, Paul Burton,
Rob Herring, Arnd Bergmann, Jason Cooper, Marc Zyngier,
Rafael J. Wysocki, Daniel Lezcano, James Hogan, linux-mips,
devicetree, linux-kernel
Folks, the code and DT-related patches here have been mostly reviewed.
Please consider merge the series in or at least give me a feedback to
update the series, since merge window is getting opened and I would
really appreciate to see the leftover being merged in.
Regarding this patchset origin. Recently I've submitted a series of
patchset's which provided multiple fixes for the MIPS arch subsystem and
the MIPS GIC and DW APB Timer drivers, which were required for the
Baikal-T1 SoC correctly working with those drivers. Mostly those patchsets
have been already merged into the corresponding subsystems, but several
patches have been left floating since noone really responded for review
except Rob provided his approval regarding DT bindings. Thus in this
patchset I've collected all the leftovers so not to loose them in a pale
of the maintainers email logs.
The patchset includes the following updates: MIPS CPC and GIC DT bindings
legacy text-based file are converted to the DT schema (Rob has already
reviewed them), add MIPS CDMM DT node support to place the CDMM block at
the platform-specific MMIO range, make sure MIPS CDMM is available for
MIPS_R5 CPUs.
Seeing the series concerns the MIPS-related drivers it's better to merge
it in through the MIPS repository:
https://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git/
This patchset is rebased and tested on the mainline Linux kernel 5.7-rc4:
base-commit: 0e698dfa2822 ("Linux 5.7-rc4")
tag: v5.7-rc4
Suggestion.
Since Paul isn't looking after the MIPS arch code anymore, Ralf hasn't
been seen maintaining MIPS for a long time, Thomas is only responsible
for the next part of it:
F: Documentation/devicetree/bindings/mips/
F: Documentation/mips/
F: arch/mips/
F: drivers/platform/mips/
the MIPS-specific drivers like:
F: drivers/bus/mips_cdmm.c
F: drivers/irqchip/irq-mips-cpu.c
F: drivers/irqchip/irq-mips-gic.c
F: drivers/clocksource/mips-gic-timer.c
F: drivers/cpuidle/cpuidle-cps.c
seem to be left for the subsystems maintainers to support. So if you don't
mind or unless there is a better alternative, I can help with looking
after them to ease the maintainers review burden and since I'll be working
on our MIPS-based SoC drivers integrating into the mainline kernel repo
anyway. If you don't like this idea, please just decline the last
patch in the series.
Previous patchsets:
mips: Prepare MIPS-arch code for Baikal-T1 SoC support:
Link: https://lore.kernel.org/linux-mips/20200306124807.3596F80307C2@mail.baikalelectronics.ru
Link: https://lore.kernel.org/linux-mips/20200506174238.15385-1-Sergey.Semin@baikalelectronics.ru
Link: https://lore.kernel.org/linux-mips/20200521140725.29571-1-Sergey.Semin@baikalelectronics.ru
clocksource: Fix MIPS GIC and DW APB Timer for Baikal-T1 SoC support:
Link: https://lore.kernel.org/linux-rtc/20200324174325.14213-1-Sergey.Semin@baikalelectronics.ru
Link: https://lore.kernel.org/linux-rtc/20200506214107.25956-1-Sergey.Semin@baikalelectronics.ru
Link: https://lore.kernel.org/linux-rtc/20200521005321.12129-1-Sergey.Semin@baikalelectronics.ru
Changelog prev:
- Add yaml-based bindings file for MIPS CDMM dt-node.
- Convert mti,mips-cpc to DT schema.
- Use a shorter summary describing the bindings modification patches.
- Rearrange the SoBs with adding Alexey' co-development tag.
- Lowercase the hex numbers in the dt-bindings.
Changelog v2:
- Resend.
Link: https://lore.kernel.org/linux-mips/20200601122121.15809-1-Sergey.Semin@baikalelectronics.ru
Changelog v3:
- Keep F: MAINTAINERS section alphabetically ordered.
- Add Thomas as the co-maintainer of the MIPS CPU and GIC IRQchip, MIPS
GIC timer and MIPS CPS CPUidle drivers.
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <maz@kernel.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Serge Semin (6):
dt-bindings: power: Convert mti,mips-cpc to DT schema
dt-bindings: interrupt-controller: Convert mti,gic to DT schema
dt-bindings: bus: Add MIPS CDMM controller
mips: cdmm: Add mti,mips-cdmm dtb node support
bus: cdmm: Add MIPS R5 arch support
MAINTAINERS: Add maintainers for MIPS core drivers
.../bindings/bus/mti,mips-cdmm.yaml | 35 +++++
.../interrupt-controller/mips-gic.txt | 67 --------
.../interrupt-controller/mti,gic.yaml | 148 ++++++++++++++++++
.../bindings/power/mti,mips-cpc.txt | 8 -
.../bindings/power/mti,mips-cpc.yaml | 35 +++++
MAINTAINERS | 11 ++
drivers/bus/Kconfig | 2 +-
drivers/bus/mips_cdmm.c | 15 ++
8 files changed, 245 insertions(+), 76 deletions(-)
create mode 100644 Documentation/devicetree/bindings/bus/mti,mips-cdmm.yaml
delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/mti,gic.yaml
delete mode 100644 Documentation/devicetree/bindings/power/mti,mips-cpc.txt
create mode 100644 Documentation/devicetree/bindings/power/mti,mips-cpc.yaml
--
2.26.2
^ permalink raw reply
* [PATCH v3 1/6] dt-bindings: power: Convert mti,mips-cpc to DT schema
From: Serge Semin @ 2020-06-02 10:09 UTC (permalink / raw)
To: Thomas Bogendoerfer, Thomas Gleixner, Greg Kroah-Hartman,
Paul Burton, Rob Herring
Cc: Serge Semin, Serge Semin, Alexey Malahov, Paul Burton,
Arnd Bergmann, Jason Cooper, Marc Zyngier, Rafael J. Wysocki,
Daniel Lezcano, James Hogan, linux-mips, devicetree, linux-kernel,
Rob Herring
In-Reply-To: <20200602100921.1155-1-Sergey.Semin@baikalelectronics.ru>
It's a Cluster Power Controller embedded into the MIPS IP cores.
Currently the corresponding dts node is supposed to have compatible
and reg properties.
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Changelog prev:
- Reword the changelog summary - use shorter version.
- Lowercase the example hex'es.
---
.../bindings/power/mti,mips-cpc.txt | 8 -----
.../bindings/power/mti,mips-cpc.yaml | 35 +++++++++++++++++++
2 files changed, 35 insertions(+), 8 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/power/mti,mips-cpc.txt
create mode 100644 Documentation/devicetree/bindings/power/mti,mips-cpc.yaml
diff --git a/Documentation/devicetree/bindings/power/mti,mips-cpc.txt b/Documentation/devicetree/bindings/power/mti,mips-cpc.txt
deleted file mode 100644
index c6b82511ae8a..000000000000
--- a/Documentation/devicetree/bindings/power/mti,mips-cpc.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Binding for MIPS Cluster Power Controller (CPC).
-
-This binding allows a system to specify where the CPC registers are
-located.
-
-Required properties:
-compatible : Should be "mti,mips-cpc".
-regs: Should describe the address & size of the CPC register region.
diff --git a/Documentation/devicetree/bindings/power/mti,mips-cpc.yaml b/Documentation/devicetree/bindings/power/mti,mips-cpc.yaml
new file mode 100644
index 000000000000..9cd92a57130c
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/mti,mips-cpc.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/mti,mips-cpc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MIPS Cluster Power Controller
+
+description: |
+ Defines a location of the MIPS Cluster Power Controller registers.
+
+maintainers:
+ - Paul Burton <paulburton@kernel.org>
+
+properties:
+ compatible:
+ const: mti,mips-cpc
+
+ reg:
+ description: |
+ Base address and size of an unoccupied memory region, which will be
+ used to map the MIPS CPC registers block.
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+examples:
+ - |
+ cpc@1bde0000 {
+ compatible = "mti,mips-cpc";
+ reg = <0 0x1bde0000 0 0x8000>;
+ };
+...
--
2.26.2
^ permalink raw reply related
* [PATCH v3 4/6] mips: cdmm: Add mti,mips-cdmm dtb node support
From: Serge Semin @ 2020-06-02 10:09 UTC (permalink / raw)
To: Thomas Bogendoerfer, Thomas Gleixner, Greg Kroah-Hartman,
Serge Semin
Cc: Serge Semin, Alexey Malahov, Paul Burton, Rob Herring,
Arnd Bergmann, Jason Cooper, Marc Zyngier, Rafael J. Wysocki,
Daniel Lezcano, James Hogan, linux-mips, devicetree, linux-kernel
In-Reply-To: <20200602100921.1155-1-Sergey.Semin@baikalelectronics.ru>
Since having and mapping the CDMM block is platform specific, then
instead of just returning a zero-address, lets make the default CDMM
base address search method (mips_cdmm_phys_base()) to do something
useful. For instance to find the address in a dedicated dtb-node in
order to support of-based platforms by default.
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
---
Changelog prev:
- Use alphabetical order for the include pre-processor operator.
---
drivers/bus/mips_cdmm.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/bus/mips_cdmm.c b/drivers/bus/mips_cdmm.c
index 1b14256376d2..9f7ed1fcd428 100644
--- a/drivers/bus/mips_cdmm.c
+++ b/drivers/bus/mips_cdmm.c
@@ -13,6 +13,8 @@
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/smp.h>
@@ -337,9 +339,22 @@ static phys_addr_t mips_cdmm_cur_base(void)
* Picking a suitable physical address at which to map the CDMM region is
* platform specific, so this weak function can be overridden by platform
* code to pick a suitable value if none is configured by the bootloader.
+ * By default this method tries to find a CDMM-specific node in the system
+ * dtb. Note that this won't work for early serial console.
*/
phys_addr_t __weak mips_cdmm_phys_base(void)
{
+ struct device_node *np;
+ struct resource res;
+ int err;
+
+ np = of_find_compatible_node(NULL, NULL, "mti,mips-cdmm");
+ if (np) {
+ err = of_address_to_resource(np, 0, &res);
+ if (!err)
+ return res.start;
+ }
+
return 0;
}
--
2.26.2
^ permalink raw reply related
* [PATCH v3 6/6] MAINTAINERS: Add maintainers for MIPS core drivers
From: Serge Semin @ 2020-06-02 10:09 UTC (permalink / raw)
To: Thomas Bogendoerfer, Thomas Gleixner, Greg Kroah-Hartman
Cc: Serge Semin, Serge Semin, Alexey Malahov, Paul Burton,
Rob Herring, Arnd Bergmann, Jason Cooper, Marc Zyngier,
Rafael J. Wysocki, Daniel Lezcano, James Hogan, linux-mips,
devicetree, linux-kernel
In-Reply-To: <20200602100921.1155-1-Sergey.Semin@baikalelectronics.ru>
Add Thomas and myself as maintainers of the MIPS CPU and GIC IRQchip, MIPS
GIC timer and MIPS CPS CPUidle drivers.
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
---
Changelog v3:
- Keep the files list alphabetically ordered.
- Add Thomas as the co-maintainer of the designated drivers.
---
MAINTAINERS | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 2926327e4976..20532e0287d7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11278,6 +11278,17 @@ F: arch/mips/configs/generic/board-boston.config
F: drivers/clk/imgtec/clk-boston.c
F: include/dt-bindings/clock/boston-clock.h
+MIPS CORE DRIVERS
+M: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+M: Serge Semin <fancer.lancer@gmail.com>
+L: linux-mips@vger.kernel.org
+S: Supported
+F: drivers/bus/mips_cdmm.c
+F: drivers/clocksource/mips-gic-timer.c
+F: drivers/cpuidle/cpuidle-cps.c
+F: drivers/irqchip/irq-mips-cpu.c
+F: drivers/irqchip/irq-mips-gic.c
+
MIPS GENERIC PLATFORM
M: Paul Burton <paulburton@kernel.org>
L: linux-mips@vger.kernel.org
--
2.26.2
^ permalink raw reply related
* [PATCH v3 2/6] dt-bindings: interrupt-controller: Convert mti,gic to DT schema
From: Serge Semin @ 2020-06-02 10:09 UTC (permalink / raw)
To: Thomas Bogendoerfer, Thomas Gleixner, Greg Kroah-Hartman,
Jason Cooper, Marc Zyngier, Rob Herring
Cc: Serge Semin, Serge Semin, Alexey Malahov, Paul Burton,
Arnd Bergmann, Rafael J. Wysocki, Daniel Lezcano, James Hogan,
linux-mips, devicetree, linux-kernel, Rob Herring
In-Reply-To: <20200602100921.1155-1-Sergey.Semin@baikalelectronics.ru>
Modern device tree bindings are supposed to be created as YAML-files
in accordance with DT schema. This commit replaces MIPS GIC legacy bare
text binding with YAML file. As before the binding file states that the
corresponding dts node is supposed to be compatible with MIPS Global
Interrupt Controller indicated by the "mti,gic" compatible string and
to provide a mandatory interrupt-controller and '#interrupt-cells'
properties. There might be optional registers memory range,
"mti,reserved-cpu-vectors" and "mti,reserved-ipi-vectors" properties
specified.
MIPS GIC also includes a free-running global timer, per-CPU count/compare
timers, and a watchdog. Since currently the GIC Timer is only supported the
DT schema expects an IRQ and clock-phandler charged timer sub-node with
"mti,mips-gic-timer" compatible string.
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Reviewed-by: Rob Herring <robh@kernel.org>
---
I don't really know who is the corresponding driver maintainer, so I
added Paul to the maintainers property since he used to be looking for the
MIPS arch and Thomas looking after it now. Any idea what email should be
specified there instead?
Changelog prev:
- Since timer sub-node has no unit-address, the node shouldn't be named
with one. So alter the MIPS GIC bindings to have a pure "timer"
sub-node.
- Discard allOf: [ $ref: /schemas/interrupt-controller.yaml# ].
- Since it's a conversion patch use GPL-2.0-only SPDX header.
---
.../interrupt-controller/mips-gic.txt | 67 --------
.../interrupt-controller/mti,gic.yaml | 148 ++++++++++++++++++
2 files changed, 148 insertions(+), 67 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/mti,gic.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt b/Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt
deleted file mode 100644
index 173595305e26..000000000000
--- a/Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-MIPS Global Interrupt Controller (GIC)
-
-The MIPS GIC routes external interrupts to individual VPEs and IRQ pins.
-It also supports local (per-processor) interrupts and software-generated
-interrupts which can be used as IPIs. The GIC also includes a free-running
-global timer, per-CPU count/compare timers, and a watchdog.
-
-Required properties:
-- compatible : Should be "mti,gic".
-- interrupt-controller : Identifies the node as an interrupt controller
-- #interrupt-cells : Specifies the number of cells needed to encode an
- interrupt specifier. Should be 3.
- - The first cell is the type of interrupt, local or shared.
- See <include/dt-bindings/interrupt-controller/mips-gic.h>.
- - The second cell is the GIC interrupt number.
- - The third cell encodes the interrupt flags.
- See <include/dt-bindings/interrupt-controller/irq.h> for a list of valid
- flags.
-
-Optional properties:
-- reg : Base address and length of the GIC registers. If not present,
- the base address reported by the hardware GCR_GIC_BASE will be used.
-- mti,reserved-cpu-vectors : Specifies the list of CPU interrupt vectors
- to which the GIC may not route interrupts. Valid values are 2 - 7.
- This property is ignored if the CPU is started in EIC mode.
-- mti,reserved-ipi-vectors : Specifies the range of GIC interrupts that are
- reserved for IPIs.
- It accepts 2 values, the 1st is the starting interrupt and the 2nd is the size
- of the reserved range.
- If not specified, the driver will allocate the last 2 * number of VPEs in the
- system.
-
-Required properties for timer sub-node:
-- compatible : Should be "mti,gic-timer".
-- interrupts : Interrupt for the GIC local timer.
-
-Optional properties for timer sub-node:
-- clocks : GIC timer operating clock.
-- clock-frequency : Clock frequency at which the GIC timers operate.
-
-Note that one of clocks or clock-frequency must be specified.
-
-Example:
-
- gic: interrupt-controller@1bdc0000 {
- compatible = "mti,gic";
- reg = <0x1bdc0000 0x20000>;
-
- interrupt-controller;
- #interrupt-cells = <3>;
-
- mti,reserved-cpu-vectors = <7>;
- mti,reserved-ipi-vectors = <40 8>;
-
- timer {
- compatible = "mti,gic-timer";
- interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
- clock-frequency = <50000000>;
- };
- };
-
- uart@18101400 {
- ...
- interrupt-parent = <&gic>;
- interrupts = <GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>;
- ...
- };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/mti,gic.yaml b/Documentation/devicetree/bindings/interrupt-controller/mti,gic.yaml
new file mode 100644
index 000000000000..9f0eb3addac4
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/mti,gic.yaml
@@ -0,0 +1,148 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/mti,gic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MIPS Global Interrupt Controller
+
+maintainers:
+ - Paul Burton <paulburton@kernel.org>
+ - Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+
+description: |
+ The MIPS GIC routes external interrupts to individual VPEs and IRQ pins.
+ It also supports local (per-processor) interrupts and software-generated
+ interrupts which can be used as IPIs. The GIC also includes a free-running
+ global timer, per-CPU count/compare timers, and a watchdog.
+
+properties:
+ compatible:
+ const: mti,gic
+
+ "#interrupt-cells":
+ const: 3
+ description: |
+ The 1st cell is the type of interrupt: local or shared defined in the
+ file 'dt-bindings/interrupt-controller/mips-gic.h'. The 2nd cell is the
+ GIC interrupt number. The 3d cell encodes the interrupt flags setting up
+ the IRQ trigger modes, which are defined in the file
+ 'dt-bindings/interrupt-controller/irq.h'.
+
+ reg:
+ description: |
+ Base address and length of the GIC registers space. If not present,
+ the base address reported by the hardware GCR_GIC_BASE will be used.
+ maxItems: 1
+
+ interrupt-controller: true
+
+ mti,reserved-cpu-vectors:
+ description: |
+ Specifies the list of CPU interrupt vectors to which the GIC may not
+ route interrupts. This property is ignored if the CPU is started in EIC
+ mode.
+ allOf:
+ - $ref: /schemas/types.yaml#definitions/uint32-array
+ - minItems: 1
+ maxItems: 6
+ uniqueItems: true
+ items:
+ minimum: 2
+ maximum: 7
+
+ mti,reserved-ipi-vectors:
+ description: |
+ Specifies the range of GIC interrupts that are reserved for IPIs.
+ It accepts two values: the 1st is the starting interrupt and the 2nd is
+ the size of the reserved range. If not specified, the driver will
+ allocate the last (2 * number of VPEs in the system).
+ allOf:
+ - $ref: /schemas/types.yaml#definitions/uint32-array
+ - items:
+ - minimum: 0
+ maximum: 254
+ - minimum: 2
+ maximum: 254
+
+ timer:
+ type: object
+ description: |
+ MIPS GIC includes a free-running global timer, per-CPU count/compare
+ timers, and a watchdog. Currently only the GIC Timer is supported.
+ properties:
+ compatible:
+ const: mti,gic-timer
+
+ interrupts:
+ description: |
+ Interrupt for the GIC local timer, so normally it's suppose to be of
+ <GIC_LOCAL X IRQ_TYPE_NONE> format.
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-frequency: true
+
+ required:
+ - compatible
+ - interrupts
+
+ oneOf:
+ - required:
+ - clocks
+ - required:
+ - clock-frequency
+
+ additionalProperties: false
+
+unevaluatedProperties: false
+
+required:
+ - compatible
+ - "#interrupt-cells"
+ - interrupt-controller
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/mips-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ interrupt-controller@1bdc0000 {
+ compatible = "mti,gic";
+ reg = <0x1bdc0000 0x20000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ mti,reserved-cpu-vectors = <7>;
+ mti,reserved-ipi-vectors = <40 8>;
+
+ timer {
+ compatible = "mti,gic-timer";
+ interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
+ clock-frequency = <50000000>;
+ };
+ };
+ - |
+ #include <dt-bindings/interrupt-controller/mips-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ interrupt-controller@1bdc0000 {
+ compatible = "mti,gic";
+ reg = <0x1bdc0000 0x20000>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+
+ timer {
+ compatible = "mti,gic-timer";
+ interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
+ clocks = <&cpu_pll>;
+ };
+ };
+ - |
+ interrupt-controller {
+ compatible = "mti,gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+...
--
2.26.2
^ permalink raw reply related
* [PATCH v4 2/5] dt-bindings: regulator: Add labibb regulator
From: Sumit Semwal @ 2020-06-02 10:09 UTC (permalink / raw)
To: agross, bjorn.andersson, lgirdwood, broonie, robh+dt
Cc: nishakumari, linux-arm-msm, linux-kernel, devicetree, kgunda,
rnayak, Sumit Semwal
In-Reply-To: <20200602100924.26256-1-sumit.semwal@linaro.org>
From: Nisha Kumari <nishakumari@codeaurora.org>
Adding the devicetree binding for labibb regulator.
Signed-off-by: Nisha Kumari <nishakumari@codeaurora.org>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
[sumits: cleanup as per review comments and update to yaml]
--
v2: updated for better compatible string and names.
v3: moved to yaml
v4: fixed dt_binding_check issues
---
.../regulator/qcom-labibb-regulator.yaml | 79 +++++++++++++++++++
1 file changed, 79 insertions(+)
create mode 100644 Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml
diff --git a/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml
new file mode 100644
index 000000000000..178820ec04c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/qcom-labibb-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm's LAB(LCD AMOLED Boost)/IBB(Inverting Buck Boost) Regulator
+
+maintainers:
+ - Sumit Semwal <sumit.semwal@linaro.org>
+
+description:
+ LAB can be used as a positive boost power supply and IBB can be used as a
+ negative boost power supply for display panels. Currently implemented for
+ pmi8998.
+
+allOf:
+ - $ref: "regulator.yaml#"
+
+properties:
+ compatible:
+ const: qcom,pmi8998-lab-ibb
+
+ lab:
+ type: object
+
+ properties:
+
+ interrupts:
+ maxItems: 1
+ description:
+ Short-circuit interrupt for lab.
+
+ interrupt-names:
+ const: sc-err
+
+ required:
+ - interrupts
+ - interrupt-names
+
+ ibb:
+ type: object
+
+ properties:
+
+ interrupts:
+ maxItems: 1
+ description:
+ Short-circuit interrupt for lab.
+
+ interrupt-names:
+ const: sc-err
+
+ required:
+ - interrupts
+ - interrupt-names
+
+required:
+ - compatible
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ labibb {
+ compatible = "qcom,pmi8998-lab-ibb";
+
+ lab {
+ interrupts = <0x3 0x0 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "sc-err";
+ };
+
+ ibb {
+ interrupts = <0x3 0x2 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "sc-err";
+ };
+ };
+
+...
--
2.26.2
^ permalink raw reply related
* [PATCH v4 3/5] arm64: dts: qcom: pmi8998: Add nodes for LAB and IBB regulators
From: Sumit Semwal @ 2020-06-02 10:09 UTC (permalink / raw)
To: agross, bjorn.andersson, lgirdwood, broonie, robh+dt
Cc: nishakumari, linux-arm-msm, linux-kernel, devicetree, kgunda,
rnayak, Sumit Semwal
In-Reply-To: <20200602100924.26256-1-sumit.semwal@linaro.org>
From: Nisha Kumari <nishakumari@codeaurora.org>
This patch adds devicetree nodes for LAB and IBB regulators.
Signed-off-by: Nisha Kumari <nishakumari@codeaurora.org>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
[sumits: Updated for better compatible strings and names]
--
v2: sumits: updated for better compatible string and names
v3: sumits: updated interrupt-names as per review comments
v4: sumits: removed labibb label
---
arch/arm64/boot/dts/qcom/pmi8998.dtsi | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
index 23f9146a161e..3230b78b8048 100644
--- a/arch/arm64/boot/dts/qcom/pmi8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
@@ -25,5 +25,19 @@ pmi8998_lsid1: pmic@3 {
reg = <0x3 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
+
+ labibb {
+ compatible = "qcom,pmi8998-lab-ibb";
+
+ ibb: ibb {
+ interrupts = <0x3 0xdc 0x2 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "sc-err";
+ };
+
+ lab: lab {
+ interrupts = <0x3 0xde 0x0 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "sc-err";
+ };
+ };
};
};
--
2.26.2
^ permalink raw reply related
* [PATCH v4 5/5] regulator: qcom: labibb: Add SC interrupt handling
From: Sumit Semwal @ 2020-06-02 10:09 UTC (permalink / raw)
To: agross, bjorn.andersson, lgirdwood, broonie, robh+dt
Cc: nishakumari, linux-arm-msm, linux-kernel, devicetree, kgunda,
rnayak, Sumit Semwal
In-Reply-To: <20200602100924.26256-1-sumit.semwal@linaro.org>
From: Nisha Kumari <nishakumari@codeaurora.org>
Add Short circuit interrupt handling and recovery for the lab and ibb
regulators on qcom platforms.
The client panel drivers need to register for REGULATOR_EVENT_OVER_CURRENT
notification which will be triggered on short circuit. They should
try to enable the regulator once, and if it doesn't get enabled,
handle shutting down the panel accordingly.
Signed-off-by: Nisha Kumari <nishakumari@codeaurora.org>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
[sumits: updated to rework to use regmap_read_poll_timeout, handle it per
regulator, add REGULATOR_EVENT_OVER_CURRENT handling and
notification to clients and other cleanup]
--
v2: sumits: reworked handling to user regmap_read_poll_timeout, and handle it
per-regulator instead of clearing both lab and ibb errors on either irq
triggering. Also added REGULATOR_EVENT_OVER_CURRENT handling and
notification to clients.
v3: sumits: updated as per review comments of v2: removed spurious check for
irq in handler and some unused variables; inlined some of the code,
omitted IRQF_TRIGGER_RISING as it's coming from DT.
v4: sumits: updated 'int vreg_enabled' to 'boot enabled', made sc_irq a local var
and other review comments from v3.
---
drivers/regulator/qcom-labibb-regulator.c | 102 +++++++++++++++++++++-
1 file changed, 99 insertions(+), 3 deletions(-)
diff --git a/drivers/regulator/qcom-labibb-regulator.c b/drivers/regulator/qcom-labibb-regulator.c
index 33b764ac69d1..bca0308b26dd 100644
--- a/drivers/regulator/qcom-labibb-regulator.c
+++ b/drivers/regulator/qcom-labibb-regulator.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2020, The Linux Foundation. All rights reserved.
+#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/of.h>
@@ -18,6 +19,7 @@
#define REG_LABIBB_ENABLE_CTL 0x46
#define LABIBB_STATUS1_VREG_OK_BIT BIT(7)
#define LABIBB_CONTROL_ENABLE BIT(7)
+#define LABIBB_STATUS1_SC_DETECT_BIT BIT(6)
#define LAB_ENABLE_CTL_MASK BIT(7)
#define IBB_ENABLE_CTL_MASK (BIT(7) | BIT(6))
@@ -27,12 +29,16 @@
#define IBB_ENABLE_TIME (LABIBB_OFF_ON_DELAY * 10)
#define LABIBB_POLL_ENABLED_TIME 1000
+#define POLLING_SCP_DONE_INTERVAL_US 5000
+#define POLLING_SCP_TIMEOUT 16000
+
struct labibb_regulator {
struct regulator_desc desc;
struct device *dev;
struct regmap *regmap;
struct regulator_dev *rdev;
u16 base;
+ bool enabled;
u8 type;
};
@@ -59,12 +65,26 @@ static int qcom_labibb_regulator_is_enabled(struct regulator_dev *rdev)
static int qcom_labibb_regulator_enable(struct regulator_dev *rdev)
{
- return regulator_enable_regmap(rdev);
+ int ret;
+ struct labibb_regulator *reg = rdev_get_drvdata(rdev);
+
+ ret = regulator_enable_regmap(rdev);
+ if (ret >= 0)
+ reg->enabled = true;
+
+ return ret;
}
static int qcom_labibb_regulator_disable(struct regulator_dev *rdev)
{
- return regulator_disable_regmap(rdev);
+ int ret = 0;
+ struct labibb_regulator *reg = rdev_get_drvdata(rdev);
+
+ ret = regulator_disable_regmap(rdev);
+ if (ret >= 0)
+ reg->enabled = false;
+
+ return ret;
}
static struct regulator_ops qcom_labibb_ops = {
@@ -73,12 +93,70 @@ static struct regulator_ops qcom_labibb_ops = {
.is_enabled = qcom_labibb_regulator_is_enabled,
};
+static irqreturn_t labibb_sc_err_handler(int irq, void *_reg)
+{
+ int ret;
+ u16 reg;
+ unsigned int val;
+ struct labibb_regulator *labibb_reg = _reg;
+ bool in_sc_err, scp_done = false;
+
+ ret = regmap_read(labibb_reg->regmap,
+ labibb_reg->base + REG_LABIBB_STATUS1, &val);
+ if (ret < 0) {
+ dev_err(labibb_reg->dev, "sc_err_irq: Read failed, ret=%d\n",
+ ret);
+ return IRQ_HANDLED;
+ }
+
+ dev_dbg(labibb_reg->dev, "%s SC error triggered! STATUS1 = %d\n",
+ labibb_reg->desc.name, val);
+
+ in_sc_err = !!(val & LABIBB_STATUS1_SC_DETECT_BIT);
+
+ /*
+ * The SC(short circuit) fault would trigger PBS(Portable Batch
+ * System) to disable regulators for protection. This would
+ * cause the SC_DETECT status being cleared so that it's not
+ * able to get the SC fault status.
+ * Check if the regulator is enabled in the driver but
+ * disabled in hardware, this means a SC fault had happened
+ * and SCP handling is completed by PBS.
+ */
+ if (!in_sc_err) {
+
+ reg = labibb_reg->base + REG_LABIBB_ENABLE_CTL;
+
+ ret = regmap_read_poll_timeout(labibb_reg->regmap,
+ reg, val,
+ !(val & LABIBB_CONTROL_ENABLE),
+ POLLING_SCP_DONE_INTERVAL_US,
+ POLLING_SCP_TIMEOUT);
+
+ if (!ret && labibb_reg->enabled) {
+ dev_dbg(labibb_reg->dev,
+ "%s has been disabled by SCP\n",
+ labibb_reg->desc.name);
+ scp_done = true;
+ }
+ }
+
+ if (in_sc_err || scp_done) {
+ regulator_lock(labibb_reg->rdev);
+ regulator_notifier_call_chain(labibb_reg->rdev,
+ REGULATOR_EVENT_OVER_CURRENT,
+ NULL);
+ regulator_unlock(labibb_reg->rdev);
+ }
+ return IRQ_HANDLED;
+}
+
static struct regulator_dev *register_labibb_regulator(struct labibb_regulator *reg,
const struct labibb_regulator_data *reg_data,
struct device_node *of_node)
{
struct regulator_config cfg = {};
- int ret;
+ int ret, sc_irq;
reg->base = reg_data->base;
reg->type = reg_data->type;
@@ -95,6 +173,24 @@ static struct regulator_dev *register_labibb_regulator(struct labibb_regulator *
reg->desc.poll_enabled_time = LABIBB_POLL_ENABLED_TIME;
reg->desc.off_on_delay = LABIBB_OFF_ON_DELAY;
+ sc_irq = of_irq_get_byname(of_node, "sc-err");
+ if (sc_irq < 0) {
+ dev_err(reg->dev, "Unable to get sc-err, ret = %d\n",
+ sc_irq);
+ return ERR_PTR(sc_irq);
+ } else {
+ ret = devm_request_threaded_irq(reg->dev,
+ sc_irq,
+ NULL, labibb_sc_err_handler,
+ IRQF_ONESHOT,
+ "sc-err", reg);
+ if (ret) {
+ dev_err(reg->dev, "Failed to register sc-err irq ret=%d\n",
+ ret);
+ return ERR_PTR(ret);
+ }
+ }
+
cfg.dev = reg->dev;
cfg.driver_data = reg;
cfg.regmap = reg->regmap;
--
2.26.2
^ permalink raw reply related
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