* [PATCH 5/6] crypto: stm32-hash: convert to the new crypto engine API
From: Fabien DESSENNE @ 2018-01-11 7:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <17d0497d-5c13-f93e-4249-8adff5e71b19@st.com>
(adding my tested my)
On 10/01/18 15:24, Fabien DESSENNE wrote:
>
> On 03/01/18 21:11, Corentin Labbe wrote:
>> This patch convert the stm32-hash driver to the new crypto engine API.
>>
>> Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Tested-by: Fabien Dessenne <fabien.dessenne@st.com>
>> ---
>> drivers/crypto/stm32/stm32-hash.c | 18 +++++++++++++-----
>> 1 file changed, 13 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c
>> index 4ca4a264a833..9790c2c936c7 100644
>> --- a/drivers/crypto/stm32/stm32-hash.c
>> +++ b/drivers/crypto/stm32/stm32-hash.c
>> @@ -122,6 +122,7 @@ enum stm32_hash_data_format {
>> #define HASH_DMA_THRESHOLD 50
>>
>> struct stm32_hash_ctx {
>> + struct crypto_engine_reqctx enginectx;
>> struct stm32_hash_dev *hdev;
>> unsigned long flags;
>>
>> @@ -828,6 +829,11 @@ static int stm32_hash_hw_init(struct stm32_hash_dev *hdev,
>> return 0;
>> }
>>
>> +static int stm32_hash_one_request(struct crypto_engine *engine,
>> + void *areq);
> merge these two lines in a single one
>
>> +static int stm32_hash_prepare_req(struct crypto_engine *engine,
>> + void *areq);
> merge these two lines in a single one
>
>> +
>> static int stm32_hash_handle_queue(struct stm32_hash_dev *hdev,
>> struct ahash_request *req)
>> {
>> @@ -835,8 +841,9 @@ static int stm32_hash_handle_queue(struct stm32_hash_dev *hdev,
>> }
>>
>> static int stm32_hash_prepare_req(struct crypto_engine *engine,
>> - struct ahash_request *req)
>> + void *areq)
> merge these two lines in a single one
>
>> {
>> + struct ahash_request *req = container_of(areq, struct ahash_request, base);
> > 80 characters (CHECKPATCH)
>
>> struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
>> struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx);
>> struct stm32_hash_request_ctx *rctx;
>> @@ -855,8 +862,9 @@ static int stm32_hash_prepare_req(struct crypto_engine *engine,
>> }
>>
>> static int stm32_hash_one_request(struct crypto_engine *engine,
>> - struct ahash_request *req)
>> + void *areq)
> merge these two lines in a single one
>
>> {
>> + struct ahash_request *req = container_of(areq, struct ahash_request, base);
> > 80 characters (CHECKPATCH)
>
>> struct stm32_hash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
>> struct stm32_hash_dev *hdev = stm32_hash_find_dev(ctx);
>> struct stm32_hash_request_ctx *rctx;
>> @@ -1033,6 +1041,9 @@ static int stm32_hash_cra_init_algs(struct crypto_tfm *tfm,
>> if (algs_hmac_name)
>> ctx->flags |= HASH_FLAGS_HMAC;
>>
>> + ctx->enginectx.op.do_one_request = stm32_hash_one_request;
>> + ctx->enginectx.op.prepare_request = stm32_hash_prepare_req;
>> + ctx->enginectx.op.unprepare_request = NULL;
>> return 0;
>> }
>>
>> @@ -1493,9 +1504,6 @@ static int stm32_hash_probe(struct platform_device *pdev)
>> goto err_engine;
>> }
>>
>> - hdev->engine->prepare_hash_request = stm32_hash_prepare_req;
>> - hdev->engine->hash_one_request = stm32_hash_one_request;
>> -
>> ret = crypto_engine_start(hdev->engine);
>> if (ret)
>> goto err_engine_start;
^ permalink raw reply
* [PATCH 6/6] crypto: stm32-cryp: convert to the new crypto engine API
From: Fabien DESSENNE @ 2018-01-11 7:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ccffd847-3df7-d690-4102-5a10f6439f87@st.com>
(Adding my tested by)
On 10/01/18 15:25, Fabien DESSENNE wrote:
>
> On 03/01/18 21:11, Corentin Labbe wrote:
>> This patch convert the stm32-cryp driver to the new crypto engine API.
>> Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Tested-by: Fabien Dessenne <fabien.dessenne@st.com>
>> ---
>> drivers/crypto/stm32/stm32-cryp.c | 21 ++++++++++++++++-----
>> 1 file changed, 16 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c
>> index cf1dddbeaa2c..99e0473ef247 100644
>> --- a/drivers/crypto/stm32/stm32-cryp.c
>> +++ b/drivers/crypto/stm32/stm32-cryp.c
>> @@ -91,6 +91,7 @@
>> #define _walked_out (cryp->out_walk.offset - cryp->out_sg->offset)
>>
>> struct stm32_cryp_ctx {
>> + struct crypto_engine_reqctx enginectx;
>> struct stm32_cryp *cryp;
>> int keylen;
>> u32 key[AES_KEYSIZE_256 / sizeof(u32)];
>> @@ -494,10 +495,20 @@ static int stm32_cryp_cpu_start(struct stm32_cryp *cryp)
>> return 0;
>> }
>>
>> +static int stm32_cryp_cipher_one_req(struct crypto_engine *engine,
>> + void *areq);
> Merge these 2 lines in a single one
>
>> +static int stm32_cryp_prepare_cipher_req(struct crypto_engine *engine,
>> + void *areq);
>> +
>> static int stm32_cryp_cra_init(struct crypto_tfm *tfm)
>> {
>> + struct stm32_cryp_ctx *ctx = crypto_tfm_ctx(tfm);
>> +
>> tfm->crt_ablkcipher.reqsize = sizeof(struct stm32_cryp_reqctx);
>>
>> + ctx->enginectx.op.do_one_request = stm32_cryp_cipher_one_req;
>> + ctx->enginectx.op.prepare_request = stm32_cryp_prepare_cipher_req;
>> + ctx->enginectx.op.unprepare_request = NULL;
>> return 0;
>> }
>>
>> @@ -695,14 +706,17 @@ static int stm32_cryp_prepare_req(struct crypto_engine *engine,
>> }
>>
>> static int stm32_cryp_prepare_cipher_req(struct crypto_engine *engine,
>> - struct ablkcipher_request *req)
>> + void *areq)
>> {
>> + struct ablkcipher_request *req = container_of(areq, struct ablkcipher_request, base);
> > 80 characters (CHECKPATCH)
>
>> +
>> return stm32_cryp_prepare_req(engine, req);
>> }
>>
>> static int stm32_cryp_cipher_one_req(struct crypto_engine *engine,
>> - struct ablkcipher_request *req)
>> + void *areq)
> Merge these 2 lines in a single one
>
>> {
>> + struct ablkcipher_request *req = container_of(areq, struct ablkcipher_request, base);
> > 80 characters (CHECKPATCH)
>
>> struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx(
>> crypto_ablkcipher_reqtfm(req));
>> struct stm32_cryp *cryp = ctx->cryp;
>> @@ -1104,9 +1118,6 @@ static int stm32_cryp_probe(struct platform_device *pdev)
>> goto err_engine1;
>> }
>>
>> - cryp->engine->prepare_cipher_request = stm32_cryp_prepare_cipher_req;
>> - cryp->engine->cipher_one_request = stm32_cryp_cipher_one_req;
>> -
>> ret = crypto_engine_start(cryp->engine);
>> if (ret) {
>> dev_err(dev, "Could not start crypto engine\n");
^ permalink raw reply
* [PATCH 0/7] ARM: dts: STi: Fix DT dtc warnings
From: Patrice CHOTARD @ 2018-01-11 7:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAK8P3a0MTfmNZNnXQcgDWo8dhGAQkkKVdTJhjRvpRi_0L_wXTA@mail.gmail.com>
HI Arnd
On 01/10/2018 09:52 PM, Arnd Bergmann wrote:
> On Wed, Jan 10, 2018 at 6:17 PM, Patrice CHOTARD <patrice.chotard@st.com> wrote:
>> Hi Arnd
>>
>> On 01/10/2018 04:52 PM, Arnd Bergmann wrote:
>>> On Wed, Jan 10, 2018 at 9:21 AM, <patrice.chotard@st.com> wrote:
>>>> From: Patrice Chotard <patrice.chotard@st.com>
>>>>
>>>> This series fixes all dtc warnings related to STi platforms dt files.
>>>> It has been triggered by Rob Herring [1]
>>>>
>>>> [1] https://www.spinics.net/lists/devicetree/msg206209.html
>>>>
>>>> For most of implicated node, a simple move outside the soc node
>>>> solves the warnings.
>>>>
>>>> Patrice Chotard (7):
>>>> ARM: dts: STi: fix bindings notation
>>>> ARM: dts: STi: Add gpio polarity for "hdmi,hpd-gpio" property
>>>> ARM: dts: STi: Move clocks without reg outside soc
>>>> ARM: dts: STi: Move leds node outside soc node
>>>> ARM: dts: STi: Move usb2_picophyX nodes without reg out of soc
>>>> ARM: dts: STi: Move sound related nodes without reg out of soc
>>>> ARM: dts: STi: Add fake reg property for sti-display-subsystem
>>>
>>> Thanks a lot for addressing these!
>>>
>>> As far as I can tell, there is one patch in particular that addresses a warning
>>> we get at the default warning level: "ARM: dts: STi: Add gpio polarity for
>>> "hdmi,hpd-gpio" property". Should we merge that one for 4.15 to get closer
>>> to a clean build again? I'm not sure whether we can address the other
>>
>> How do you want to proceed with this particular patch ?
>> Do you want me to send a pull-request with this patch ?
>>
>> Patrice
>
> I'd just pick it up directly into the arm-soc fixes branch if that
> works for you.
Perfect ;-)
Thanks
Patrice
>
> Arnd
>
^ permalink raw reply
* [RFC PATCH nomadik] net: ethernet: gmac_coalesce_delay_expired() can be static
From: kbuild test robot @ 2018-01-11 8:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201801111518.om5JWZd1%fengguang.wu@intel.com>
Fixes: de0cb586c9e5 ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---
gemini.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 7258136..459bdf5a 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1624,7 +1624,7 @@ static u32 gmac_get_intr_flags(struct net_device *netdev, int i)
return val;
}
-enum hrtimer_restart gmac_coalesce_delay_expired(struct hrtimer *timer)
+static enum hrtimer_restart gmac_coalesce_delay_expired(struct hrtimer *timer)
{
struct gemini_ethernet_port *port =
container_of(timer, struct gemini_ethernet_port,
^ permalink raw reply related
* [PATCH] ARM: dts: s5pv210: add interrupt-parent for ohci
From: Krzysztof Kozlowski @ 2018-01-11 8:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180110161045.4052684-1-arnd@arndb.de>
On Wed, Jan 10, 2018 at 5:10 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> The ohci-hcd node has an interrupt number but no interrupt-parent,
> leading to a warning with current dtc versions:
>
> arch/arm/boot/dts/s5pv210-aquila.dtb: Warning (interrupts_property): Missing interrupt-parent for /soc/ohci at ec300000
> arch/arm/boot/dts/s5pv210-goni.dtb: Warning (interrupts_property): Missing interrupt-parent for /soc/ohci at ec300000
> arch/arm/boot/dts/s5pv210-smdkc110.dtb: Warning (interrupts_property): Missing interrupt-parent for /soc/ohci at ec300000
> arch/arm/boot/dts/s5pv210-smdkv210.dtb: Warning (interrupts_property): Missing interrupt-parent for /soc/ohci at ec300000
> arch/arm/boot/dts/s5pv210-torbreck.dtb: Warning (interrupts_property): Missing interrupt-parent for /soc/ohci at ec300000
>
> As seen from the related exynos dts files, the ohci and ehci controllers
> always share one interrupt number, and the number is the same here as
> well, so setting the same interrupt-parent is the reasonable solution
> here.
Your patch is correct. However my last pull request still waits and it
is quite late in this release cycle so I will apply it for v4.17 after
this merge window. On the other hand you can take it directly (in that
case: Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>).
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v2 2/2] i2c: mv64xxx: Fix clock resource by adding an optional bus clock
From: Gregory CLEMENT @ 2018-01-11 8:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180110203243.GC11260@lunn.ch>
Hi Andrew,
On mer., janv. 10 2018, Andrew Lunn <andrew@lunn.ch> wrote:
> On Wed, Jan 10, 2018 at 06:07:43PM +0100, Gregory CLEMENT wrote:
>> On Armada 7K/8K we need to explicitly enable the bus clock. The bus clock
>> is optional because not all the SoCs need them but at least for Armada
>> 7K/8K it is actually mandatory.
>>
>> The binding documentation is updating accordingly.
>>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>> .../devicetree/bindings/i2c/i2c-mv64xxx.txt | 20 ++++++++++++++++++++
>> drivers/i2c/busses/i2c-mv64xxx.c | 12 +++++++++++-
>> 2 files changed, 31 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
>> index 5c30026921ae..a835b724c738 100644
>> --- a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
>> +++ b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
>> @@ -25,6 +25,15 @@ default frequency is 100kHz
>> whenever you're using the "allwinner,sun6i-a31-i2c"
>> compatible.
>>
>> + - clocks: : pointers to the reference clocks for this device, the first
>> + one is the one used for the clock on the i2c bus, the second
>> + one is the clock used for the functional part of the
>> + controller
>> +
>> + - clock-names : names of used clocks, mandatory if the second clock is
>> + : used, the name must be "core", and "axi_clk" (the latter is
>> + only for Armada 7K/8K).
>
> Hi Gregory
>
> Are these two clocks related?
>
> Ethernet on Dove needs two clocks enabled.
>
> static const struct clk_gating_soc_desc dove_gating_desc[] __initconst = {
> { "usb0", NULL, 0, 0 },
> { "usb1", NULL, 1, 0 },
> { "ge", "gephy", 2, 0 },
> { "sata", NULL, 3, 0 },
>
> ge has a parent clock gephy. When you enable ge, the common clock code
> walks up the tree of clocks, so will also turn on gephy.
>
> Does this child/parent relationship exist with these i2c clocks?
The child/parent relationship was the wrong assumption we made when we
wrote the clock driver for Armada 7K/8K. But now with more
documentation, it turned out that these 2 clocks are independant but
both are needed for i2c on Armada 7K/8K.
Gregory
>
> Andrew
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 0/9] iommu/rockchip: Use OF_IOMMU
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
This series fixes some issues in rockchip iommu driver, and add of_iommu
support in it.
Also drop of_iommu early initialisation hooks as Robin suggested.
Jeffy Chen (5):
iommu/of: Drop early initialisation hooks
iommu/rockchip: Fix error handling in probe
iommu/rockchip: Fix error handling in init
iommu/rockchip: Use IOMMU device for dma mapping operations
iommu/rockchip: Use OF_IOMMU to attach devices automatically
Tomasz Figa (4):
iommu/rockchip: Fix error handling in attach
iommu/rockchip: Use iopoll helpers to wait for hardware
iommu/rockchip: Fix TLB flush of secondary IOMMUs
iommu/rockchip: Use iommu_group_get_for_dev() for add_device
drivers/iommu/arm-smmu-v3.c | 2 +-
drivers/iommu/arm-smmu.c | 12 +-
drivers/iommu/exynos-iommu.c | 2 +-
drivers/iommu/ipmmu-vmsa.c | 17 +--
drivers/iommu/msm_iommu.c | 24 +--
drivers/iommu/of_iommu.c | 16 --
drivers/iommu/qcom_iommu.c | 2 +-
drivers/iommu/rockchip-iommu.c | 331 ++++++++++++++++++++---------------------
include/linux/of_iommu.h | 6 +-
9 files changed, 184 insertions(+), 228 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH 1/9] iommu/of: Drop early initialisation hooks
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
With the probe-deferral mechanism, early initialisation hooks are no
longer needed.
Suggested-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/arm-smmu-v3.c | 2 +-
drivers/iommu/arm-smmu.c | 12 ++++++------
drivers/iommu/exynos-iommu.c | 2 +-
drivers/iommu/ipmmu-vmsa.c | 17 ++---------------
drivers/iommu/msm_iommu.c | 24 +++++++-----------------
drivers/iommu/of_iommu.c | 16 ----------------
drivers/iommu/qcom_iommu.c | 2 +-
include/linux/of_iommu.h | 6 ++----
8 files changed, 20 insertions(+), 61 deletions(-)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 744592d330ca..3f2f1fc68b52 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2971,7 +2971,7 @@ static struct platform_driver arm_smmu_driver = {
};
module_platform_driver(arm_smmu_driver);
-IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
+IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3");
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 78d4c6b8f1ba..69e7c60792a8 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2211,12 +2211,12 @@ static struct platform_driver arm_smmu_driver = {
};
module_platform_driver(arm_smmu_driver);
-IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", NULL);
-IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", NULL);
-IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", NULL);
-IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", NULL);
-IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", NULL);
-IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", NULL);
+IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1");
+IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2");
+IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400");
+IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401");
+IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500");
+IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2");
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 79c45650f8de..1c7f926fad0e 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1394,4 +1394,4 @@ static int __init exynos_iommu_init(void)
}
core_initcall(exynos_iommu_init);
-IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu", NULL);
+IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu");
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 8dce3a9de9d8..07b711bb4b16 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -1081,12 +1081,8 @@ static struct platform_driver ipmmu_driver = {
static int __init ipmmu_init(void)
{
- static bool setup_done;
int ret;
- if (setup_done)
- return 0;
-
ret = platform_driver_register(&ipmmu_driver);
if (ret < 0)
return ret;
@@ -1096,7 +1092,6 @@ static int __init ipmmu_init(void)
bus_set_iommu(&platform_bus_type, &ipmmu_ops);
#endif
- setup_done = true;
return 0;
}
@@ -1109,16 +1104,8 @@ subsys_initcall(ipmmu_init);
module_exit(ipmmu_exit);
#ifdef CONFIG_IOMMU_DMA
-static int __init ipmmu_vmsa_iommu_of_setup(struct device_node *np)
-{
- ipmmu_init();
- return 0;
-}
-
-IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa",
- ipmmu_vmsa_iommu_of_setup);
-IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795",
- ipmmu_vmsa_iommu_of_setup);
+IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa");
+IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795");
#endif
MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 04f4d51ffacb..a41d4251b0a9 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -856,7 +856,7 @@ static struct platform_driver msm_iommu_driver = {
.remove = msm_iommu_remove,
};
-static int __init msm_iommu_driver_init(void)
+static int __init msm_iommu_init(void)
{
int ret;
@@ -864,30 +864,20 @@ static int __init msm_iommu_driver_init(void)
if (ret != 0)
pr_err("Failed to register IOMMU driver\n");
+ bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
+
return ret;
}
-static void __exit msm_iommu_driver_exit(void)
+static void __exit msm_iommu_exit(void)
{
platform_driver_unregister(&msm_iommu_driver);
}
-subsys_initcall(msm_iommu_driver_init);
-module_exit(msm_iommu_driver_exit);
-
-static int __init msm_iommu_init(void)
-{
- bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
- return 0;
-}
-
-static int __init msm_iommu_of_setup(struct device_node *np)
-{
- msm_iommu_init();
- return 0;
-}
+subsys_initcall(msm_iommu_init);
+module_exit(msm_iommu_exit);
-IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", msm_iommu_of_setup);
+IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 50947ebb6d17..5c36a8b7656a 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -231,19 +231,3 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
return ops;
}
-
-static int __init of_iommu_init(void)
-{
- struct device_node *np;
- const struct of_device_id *match, *matches = &__iommu_of_table;
-
- for_each_matching_node_and_match(np, matches, &match) {
- const of_iommu_init_fn init_fn = match->data;
-
- if (init_fn && init_fn(np))
- pr_err("Failed to initialise IOMMU %pOF\n", np);
- }
-
- return 0;
-}
-postcore_initcall_sync(of_iommu_init);
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
index e07f02d00c68..65b9c99707f8 100644
--- a/drivers/iommu/qcom_iommu.c
+++ b/drivers/iommu/qcom_iommu.c
@@ -947,7 +947,7 @@ static void __exit qcom_iommu_exit(void)
module_init(qcom_iommu_init);
module_exit(qcom_iommu_exit);
-IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1", NULL);
+IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1");
MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations");
MODULE_LICENSE("GPL v2");
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index cddfaff4d0b7..ae03752e8e3a 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -34,9 +34,7 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
extern struct of_device_id __iommu_of_table;
-typedef int (*of_iommu_init_fn)(struct device_node *);
-
-#define IOMMU_OF_DECLARE(name, compat, fn) \
- _OF_DECLARE(iommu, name, compat, fn, of_iommu_init_fn)
+#define IOMMU_OF_DECLARE(name, compat) \
+ OF_DECLARE_1(iommu, name, compat, NULL)
#endif /* __OF_IOMMU_H */
--
2.11.0
^ permalink raw reply related
* [PATCH 2/9] iommu/rockchip: Fix error handling in attach
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
From: Tomasz Figa <tfiga@chromium.org>
Currently if the driver encounters an error while attaching device, it
will leave the IOMMU in an inconsistent state. Even though it shouldn't
really happen in reality, let's just add proper error path to keep
things consistent.
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 9d991c2d8767..ee805e1dfba7 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -826,17 +826,10 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
ret = rk_iommu_force_reset(iommu);
if (ret)
- return ret;
+ goto err_disable_stall;
iommu->domain = domain;
- for (i = 0; i < iommu->num_irq; i++) {
- ret = devm_request_irq(iommu->dev, iommu->irq[i], rk_iommu_irq,
- IRQF_SHARED, dev_name(dev), iommu);
- if (ret)
- return ret;
- }
-
for (i = 0; i < iommu->num_mmu; i++) {
rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
rk_domain->dt_dma);
@@ -844,9 +837,16 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
}
+ for (i = 0; i < iommu->num_irq; i++) {
+ ret = devm_request_irq(iommu->dev, iommu->irq[i], rk_iommu_irq,
+ IRQF_SHARED, dev_name(dev), iommu);
+ if (ret)
+ goto err_free_irq;
+ }
+
ret = rk_iommu_enable_paging(iommu);
if (ret)
- return ret;
+ goto err_free_irq;
spin_lock_irqsave(&rk_domain->iommus_lock, flags);
list_add_tail(&iommu->node, &rk_domain->iommus);
@@ -857,6 +857,14 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
rk_iommu_disable_stall(iommu);
return 0;
+
+err_free_irq:
+ while (i--)
+ devm_free_irq(iommu->dev, iommu->irq[i], iommu);
+err_disable_stall:
+ rk_iommu_disable_stall(iommu);
+
+ return ret;
}
static void rk_iommu_detach_device(struct iommu_domain *domain,
--
2.11.0
^ permalink raw reply related
* [PATCH 3/9] iommu/rockchip: Fix error handling in probe
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
Add missing iommu_device_sysfs_remove in error path.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ee805e1dfba7..a05844cabb45 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1201,8 +1201,12 @@ static int rk_iommu_probe(struct platform_device *pdev)
iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
err = iommu_device_register(&iommu->iommu);
+ if (err) {
+ iommu_device_sysfs_remove(&iommu->iommu);
+ return err;
+ }
- return err;
+ return 0;
}
static int rk_iommu_remove(struct platform_device *pdev)
--
2.11.0
^ permalink raw reply related
* [PATCH 4/9] iommu/rockchip: Fix error handling in init
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
It's hard to undo bus_set_iommu() in the error path, so move it to the
end of init call.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index a05844cabb45..5f141390b4d7 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1247,17 +1247,25 @@ static int __init rk_iommu_init(void)
of_node_put(np);
- ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
- if (ret)
- return ret;
-
ret = platform_driver_register(&rk_iommu_domain_driver);
if (ret)
return ret;
ret = platform_driver_register(&rk_iommu_driver);
if (ret)
- platform_driver_unregister(&rk_iommu_domain_driver);
+ goto err_unreg_domain_drv;
+
+ ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
+ if (ret)
+ goto err_unreg_iommu_drv;
+
+ return 0;
+
+err_unreg_iommu_drv:
+ platform_driver_unregister(&rk_iommu_driver);
+err_unreg_domain_drv:
+ platform_driver_unregister(&rk_iommu_domain_driver);
+
return ret;
}
static void __exit rk_iommu_exit(void)
--
2.11.0
^ permalink raw reply related
* [PATCH 5/9] iommu/rockchip: Use iopoll helpers to wait for hardware
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
From: Tomasz Figa <tfiga@chromium.org>
This patch converts the rockchip-iommu driver to use the in-kernel
iopoll helpers to wait for certain status bits to change in registers
instead of an open-coded custom macro.
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 68 ++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 36 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 5f141390b4d7..6b797e085340 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -13,7 +13,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iommu.h>
-#include <linux/jiffies.h>
+#include <linux/iopoll.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/module.h>
@@ -36,7 +36,8 @@
#define RK_MMU_AUTO_GATING 0x24
#define DTE_ADDR_DUMMY 0xCAFEBABE
-#define FORCE_RESET_TIMEOUT 100 /* ms */
+#define FORCE_RESET_TIMEOUT 100000 /* us */
+#define POLL_TIMEOUT 1000 /* us */
/* RK_MMU_STATUS fields */
#define RK_MMU_STATUS_PAGING_ENABLED BIT(0)
@@ -73,8 +74,6 @@
*/
#define RK_IOMMU_PGSIZE_BITMAP 0x007ff000
-#define IOMMU_REG_POLL_COUNT_FAST 1000
-
struct rk_iommu_domain {
struct list_head iommus;
struct platform_device *pdev;
@@ -111,27 +110,6 @@ static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
return container_of(dom, struct rk_iommu_domain, domain);
}
-/**
- * Inspired by _wait_for in intel_drv.h
- * This is NOT safe for use in interrupt context.
- *
- * Note that it's important that we check the condition again after having
- * timed out, since the timeout could be due to preemption or similar and
- * we've never had a chance to check the condition before the timeout.
- */
-#define rk_wait_for(COND, MS) ({ \
- unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \
- int ret__ = 0; \
- while (!(COND)) { \
- if (time_after(jiffies, timeout__)) { \
- ret__ = (COND) ? 0 : -ETIMEDOUT; \
- break; \
- } \
- usleep_range(50, 100); \
- } \
- ret__; \
-})
-
/*
* The Rockchip rk3288 iommu uses a 2-level page table.
* The first level is the "Directory Table" (DT).
@@ -335,9 +313,21 @@ static bool rk_iommu_is_paging_enabled(struct rk_iommu *iommu)
return enable;
}
+static bool rk_iommu_is_reset_done(struct rk_iommu *iommu)
+{
+ bool done = true;
+ int i;
+
+ for (i = 0; i < iommu->num_mmu; i++)
+ done &= rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR) == 0;
+
+ return done;
+}
+
static int rk_iommu_enable_stall(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (rk_iommu_is_stall_active(iommu))
return 0;
@@ -348,7 +338,8 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_STALL);
- ret = rk_wait_for(rk_iommu_is_stall_active(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
+ val, 100, POLL_TIMEOUT);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Enable stall request timed out, status: %#08x\n",
@@ -360,13 +351,15 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu)
static int rk_iommu_disable_stall(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (!rk_iommu_is_stall_active(iommu))
return 0;
rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_STALL);
- ret = rk_wait_for(!rk_iommu_is_stall_active(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_stall_active, iommu, val,
+ !val, 100, POLL_TIMEOUT);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Disable stall request timed out, status: %#08x\n",
@@ -378,13 +371,15 @@ static int rk_iommu_disable_stall(struct rk_iommu *iommu)
static int rk_iommu_enable_paging(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (rk_iommu_is_paging_enabled(iommu))
return 0;
rk_iommu_command(iommu, RK_MMU_CMD_ENABLE_PAGING);
- ret = rk_wait_for(rk_iommu_is_paging_enabled(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val,
+ val, 100, POLL_TIMEOUT);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Enable paging request timed out, status: %#08x\n",
@@ -396,13 +391,15 @@ static int rk_iommu_enable_paging(struct rk_iommu *iommu)
static int rk_iommu_disable_paging(struct rk_iommu *iommu)
{
int ret, i;
+ bool val;
if (!rk_iommu_is_paging_enabled(iommu))
return 0;
rk_iommu_command(iommu, RK_MMU_CMD_DISABLE_PAGING);
- ret = rk_wait_for(!rk_iommu_is_paging_enabled(iommu), 1);
+ ret = readx_poll_timeout(rk_iommu_is_paging_enabled, iommu, val,
+ !val, 100, POLL_TIMEOUT);
if (ret)
for (i = 0; i < iommu->num_mmu; i++)
dev_err(iommu->dev, "Disable paging request timed out, status: %#08x\n",
@@ -415,6 +412,7 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
{
int ret, i;
u32 dte_addr;
+ bool val;
if (iommu->reset_disabled)
return 0;
@@ -435,13 +433,11 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu)
rk_iommu_command(iommu, RK_MMU_CMD_FORCE_RESET);
- for (i = 0; i < iommu->num_mmu; i++) {
- ret = rk_wait_for(rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR) == 0x00000000,
- FORCE_RESET_TIMEOUT);
- if (ret) {
- dev_err(iommu->dev, "FORCE_RESET command timed out\n");
- return ret;
- }
+ ret = readx_poll_timeout(rk_iommu_is_reset_done, iommu, val,
+ val, 100, FORCE_RESET_TIMEOUT);
+ if (ret) {
+ dev_err(iommu->dev, "FORCE_RESET command timed out\n");
+ return ret;
}
return 0;
--
2.11.0
^ permalink raw reply related
* [PATCH 6/9] iommu/rockchip: Fix TLB flush of secondary IOMMUs
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
From: Tomasz Figa <tfiga@chromium.org>
Due to the bug in current code, only first IOMMU has the TLB lines
flushed in rk_iommu_zap_lines. This patch fixes the inner loop to
execute for all IOMMUs and properly flush the TLB.
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 6b797e085340..cfeafbf54096 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -274,19 +274,21 @@ static void rk_iommu_base_command(void __iomem *base, u32 command)
{
writel(command, base + RK_MMU_COMMAND);
}
-static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova,
+static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova_start,
size_t size)
{
int i;
-
- dma_addr_t iova_end = iova + size;
+ dma_addr_t iova_end = iova_start + size;
/*
* TODO(djkurtz): Figure out when it is more efficient to shootdown the
* entire iotlb rather than iterate over individual iovas.
*/
- for (i = 0; i < iommu->num_mmu; i++)
- for (; iova < iova_end; iova += SPAGE_SIZE)
+ for (i = 0; i < iommu->num_mmu; i++) {
+ dma_addr_t iova;
+
+ for (iova = iova_start; iova < iova_end; iova += SPAGE_SIZE)
rk_iommu_write(iommu->bases[i], RK_MMU_ZAP_ONE_LINE, iova);
+ }
}
static bool rk_iommu_is_stall_active(struct rk_iommu *iommu)
--
2.11.0
^ permalink raw reply related
* [PATCH 7/9] iommu/rockchip: Use iommu_group_get_for_dev() for add_device
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
From: Tomasz Figa <tfiga@chromium.org>
IOMMU drivers are supposed to call this function instead of manually
creating a group in their .add_device callback. This behavior is not
strictly required by ARM DMA mapping implementation, but ARM64 already
relies on it. This patch fixes the rockchip-iommu driver to comply with
this requirement.
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 122 +++++++++++++++++++++--------------------
1 file changed, 64 insertions(+), 58 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index cfeafbf54096..86f8190d7bed 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -802,6 +802,40 @@ static struct rk_iommu *rk_iommu_from_dev(struct device *dev)
return rk_iommu;
}
+static void rk_iommu_detach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct rk_iommu *iommu;
+ struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
+ unsigned long flags;
+ int i;
+
+ /* Allow 'virtual devices' (eg drm) to detach from domain */
+ iommu = rk_iommu_from_dev(dev);
+ if (!iommu)
+ return;
+
+ spin_lock_irqsave(&rk_domain->iommus_lock, flags);
+ list_del_init(&iommu->node);
+ spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
+
+ /* Ignore error while disabling, just keep going */
+ rk_iommu_enable_stall(iommu);
+ rk_iommu_disable_paging(iommu);
+ for (i = 0; i < iommu->num_mmu; i++) {
+ rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 0);
+ rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, 0);
+ }
+ rk_iommu_disable_stall(iommu);
+
+ for (i = 0; i < iommu->num_irq; i++)
+ devm_free_irq(iommu->dev, iommu->irq[i], iommu);
+
+ iommu->domain = NULL;
+
+ dev_dbg(dev, "Detached from iommu domain\n");
+}
+
static int rk_iommu_attach_device(struct iommu_domain *domain,
struct device *dev)
{
@@ -818,6 +852,9 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
if (!iommu)
return 0;
+ if (iommu->domain)
+ rk_iommu_detach_device(domain, dev);
+
ret = rk_iommu_enable_stall(iommu);
if (ret)
return ret;
@@ -865,40 +902,6 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
return ret;
}
-static void rk_iommu_detach_device(struct iommu_domain *domain,
- struct device *dev)
-{
- struct rk_iommu *iommu;
- struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
- unsigned long flags;
- int i;
-
- /* Allow 'virtual devices' (eg drm) to detach from domain */
- iommu = rk_iommu_from_dev(dev);
- if (!iommu)
- return;
-
- spin_lock_irqsave(&rk_domain->iommus_lock, flags);
- list_del_init(&iommu->node);
- spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
-
- /* Ignore error while disabling, just keep going */
- rk_iommu_enable_stall(iommu);
- rk_iommu_disable_paging(iommu);
- for (i = 0; i < iommu->num_mmu; i++) {
- rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 0);
- rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, 0);
- }
- rk_iommu_disable_stall(iommu);
-
- for (i = 0; i < iommu->num_irq; i++)
- devm_free_irq(iommu->dev, iommu->irq[i], iommu);
-
- iommu->domain = NULL;
-
- dev_dbg(dev, "Detached from iommu domain\n");
-}
-
static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
{
struct rk_iommu_domain *rk_domain;
@@ -1049,41 +1052,20 @@ static int rk_iommu_add_device(struct device *dev)
{
struct iommu_group *group;
struct rk_iommu *iommu;
- int ret;
if (!rk_iommu_is_dev_iommu_master(dev))
return -ENODEV;
- group = iommu_group_get(dev);
- if (!group) {
- group = iommu_group_alloc();
- if (IS_ERR(group)) {
- dev_err(dev, "Failed to allocate IOMMU group\n");
- return PTR_ERR(group);
- }
- }
-
- ret = iommu_group_add_device(group, dev);
- if (ret)
- goto err_put_group;
-
- ret = rk_iommu_group_set_iommudata(group, dev);
- if (ret)
- goto err_remove_device;
+ group = iommu_group_get_for_dev(dev);
+ if (IS_ERR(group))
+ return PTR_ERR(group);
iommu = rk_iommu_from_dev(dev);
if (iommu)
iommu_device_link(&iommu->iommu, dev);
iommu_group_put(group);
-
return 0;
-
-err_remove_device:
- iommu_group_remove_device(dev);
-err_put_group:
- iommu_group_put(group);
- return ret;
}
static void rk_iommu_remove_device(struct device *dev)
@@ -1100,6 +1082,29 @@ static void rk_iommu_remove_device(struct device *dev)
iommu_group_remove_device(dev);
}
+static struct iommu_group *rk_iommu_device_group(struct device *dev)
+{
+ struct iommu_group *group;
+ int ret;
+
+ group = iommu_group_get(dev);
+ if (!group) {
+ group = iommu_group_alloc();
+ if (IS_ERR(group))
+ return group;
+ }
+
+ ret = rk_iommu_group_set_iommudata(group, dev);
+ if (ret)
+ goto err_put_group;
+
+ return group;
+
+err_put_group:
+ iommu_group_put(group);
+ return ERR_PTR(ret);
+}
+
static const struct iommu_ops rk_iommu_ops = {
.domain_alloc = rk_iommu_domain_alloc,
.domain_free = rk_iommu_domain_free,
@@ -1111,6 +1116,7 @@ static const struct iommu_ops rk_iommu_ops = {
.add_device = rk_iommu_add_device,
.remove_device = rk_iommu_remove_device,
.iova_to_phys = rk_iommu_iova_to_phys,
+ .device_group = rk_iommu_device_group,
.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
};
--
2.11.0
^ permalink raw reply related
* [PATCH 8/9] iommu/rockchip: Use IOMMU device for dma mapping operations
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
Use the first registered IOMMU device for dma mapping operations, and
drop the domain platform device.
This is similar to exynos iommu driver.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 96 ++++++++++++------------------------------
1 file changed, 28 insertions(+), 68 deletions(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 86f8190d7bed..ab18a80fdd12 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -76,7 +76,6 @@
struct rk_iommu_domain {
struct list_head iommus;
- struct platform_device *pdev;
u32 *dt; /* page directory table */
dma_addr_t dt_dma;
spinlock_t iommus_lock; /* lock for iommus list */
@@ -97,12 +96,14 @@ struct rk_iommu {
struct iommu_domain *domain; /* domain to which iommu is attached */
};
+static struct device *dma_dev;
+
static inline void rk_table_flush(struct rk_iommu_domain *dom, dma_addr_t dma,
unsigned int count)
{
size_t size = count * sizeof(u32); /* count of u32 entry */
- dma_sync_single_for_device(&dom->pdev->dev, dma, size, DMA_TO_DEVICE);
+ dma_sync_single_for_device(dma_dev, dma, size, DMA_TO_DEVICE);
}
static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
@@ -606,7 +607,6 @@ static void rk_iommu_zap_iova_first_last(struct rk_iommu_domain *rk_domain,
static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
dma_addr_t iova)
{
- struct device *dev = &rk_domain->pdev->dev;
u32 *page_table, *dte_addr;
u32 dte_index, dte;
phys_addr_t pt_phys;
@@ -624,9 +624,9 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
if (!page_table)
return ERR_PTR(-ENOMEM);
- pt_dma = dma_map_single(dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);
- if (dma_mapping_error(dev, pt_dma)) {
- dev_err(dev, "DMA mapping error while allocating page table\n");
+ pt_dma = dma_map_single(dma_dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);
+ if (dma_mapping_error(dma_dev, pt_dma)) {
+ dev_err(dma_dev, "DMA mapping error while allocating page table\n");
free_page((unsigned long)page_table);
return ERR_PTR(-ENOMEM);
}
@@ -905,29 +905,20 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
{
struct rk_iommu_domain *rk_domain;
- struct platform_device *pdev;
- struct device *iommu_dev;
if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
return NULL;
- /* Register a pdev per domain, so DMA API can base on this *dev
- * even some virtual master doesn't have an iommu slave
- */
- pdev = platform_device_register_simple("rk_iommu_domain",
- PLATFORM_DEVID_AUTO, NULL, 0);
- if (IS_ERR(pdev))
+ if (!dma_dev)
return NULL;
- rk_domain = devm_kzalloc(&pdev->dev, sizeof(*rk_domain), GFP_KERNEL);
+ rk_domain = devm_kzalloc(dma_dev, sizeof(*rk_domain), GFP_KERNEL);
if (!rk_domain)
- goto err_unreg_pdev;
-
- rk_domain->pdev = pdev;
+ return NULL;
if (type == IOMMU_DOMAIN_DMA &&
iommu_get_dma_cookie(&rk_domain->domain))
- goto err_unreg_pdev;
+ return NULL;
/*
* rk32xx iommus use a 2 level pagetable.
@@ -938,11 +929,10 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
if (!rk_domain->dt)
goto err_put_cookie;
- iommu_dev = &pdev->dev;
- rk_domain->dt_dma = dma_map_single(iommu_dev, rk_domain->dt,
+ rk_domain->dt_dma = dma_map_single(dma_dev, rk_domain->dt,
SPAGE_SIZE, DMA_TO_DEVICE);
- if (dma_mapping_error(iommu_dev, rk_domain->dt_dma)) {
- dev_err(iommu_dev, "DMA map error for DT\n");
+ if (dma_mapping_error(dma_dev, rk_domain->dt_dma)) {
+ dev_err(dma_dev, "DMA map error for DT\n");
goto err_free_dt;
}
@@ -963,8 +953,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
err_put_cookie:
if (type == IOMMU_DOMAIN_DMA)
iommu_put_dma_cookie(&rk_domain->domain);
-err_unreg_pdev:
- platform_device_unregister(pdev);
return NULL;
}
@@ -981,20 +969,18 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
if (rk_dte_is_pt_valid(dte)) {
phys_addr_t pt_phys = rk_dte_pt_address(dte);
u32 *page_table = phys_to_virt(pt_phys);
- dma_unmap_single(&rk_domain->pdev->dev, pt_phys,
+ dma_unmap_single(dma_dev, pt_phys,
SPAGE_SIZE, DMA_TO_DEVICE);
free_page((unsigned long)page_table);
}
}
- dma_unmap_single(&rk_domain->pdev->dev, rk_domain->dt_dma,
+ dma_unmap_single(dma_dev, rk_domain->dt_dma,
SPAGE_SIZE, DMA_TO_DEVICE);
free_page((unsigned long)rk_domain->dt);
if (domain->type == IOMMU_DOMAIN_DMA)
iommu_put_dma_cookie(&rk_domain->domain);
-
- platform_device_unregister(rk_domain->pdev);
}
static bool rk_iommu_is_dev_iommu_master(struct device *dev)
@@ -1120,30 +1106,6 @@ static const struct iommu_ops rk_iommu_ops = {
.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
};
-static int rk_iommu_domain_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
-
- dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL);
- if (!dev->dma_parms)
- return -ENOMEM;
-
- /* Set dma_ops for dev, otherwise it would be dummy_dma_ops */
- arch_setup_dma_ops(dev, 0, DMA_BIT_MASK(32), NULL, false);
-
- dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
- dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
-
- return 0;
-}
-
-static struct platform_driver rk_iommu_domain_driver = {
- .probe = rk_iommu_domain_probe,
- .driver = {
- .name = "rk_iommu_domain",
- },
-};
-
static int rk_iommu_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1210,6 +1172,14 @@ static int rk_iommu_probe(struct platform_device *pdev)
return err;
}
+ /*
+ * Use the first registered IOMMU device for domain to use with DMA
+ * API, since a domain might not physically correspond to a single
+ * IOMMU device..
+ */
+ if (!dma_dev)
+ dma_dev = &pdev->dev;
+
return 0;
}
@@ -1251,31 +1221,21 @@ static int __init rk_iommu_init(void)
of_node_put(np);
- ret = platform_driver_register(&rk_iommu_domain_driver);
- if (ret)
- return ret;
-
ret = platform_driver_register(&rk_iommu_driver);
if (ret)
- goto err_unreg_domain_drv;
+ return ret;
ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
- if (ret)
- goto err_unreg_iommu_drv;
+ if (ret) {
+ platform_driver_unregister(&rk_iommu_driver);
+ return ret;
+ }
return 0;
-
-err_unreg_iommu_drv:
- platform_driver_unregister(&rk_iommu_driver);
-err_unreg_domain_drv:
- platform_driver_unregister(&rk_iommu_domain_driver);
-
- return ret;
}
static void __exit rk_iommu_exit(void)
{
platform_driver_unregister(&rk_iommu_driver);
- platform_driver_unregister(&rk_iommu_domain_driver);
}
subsys_initcall(rk_iommu_init);
--
2.11.0
^ permalink raw reply related
* [PATCH 9/9] iommu/rockchip: Use OF_IOMMU to attach devices automatically
From: Jeffy Chen @ 2018-01-11 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com>
Converts the rockchip-iommu driver to use the OF_IOMMU infrastructure,
which allows attaching master devices to their IOMMUs automatically
according to DT properties.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index ab18a80fdd12..c375a2522bfd 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -18,6 +18,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_iommu.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@@ -1091,6 +1092,13 @@ static struct iommu_group *rk_iommu_device_group(struct device *dev)
return ERR_PTR(ret);
}
+static int rk_iommu_of_xlate(struct device *dev,
+ struct of_phandle_args *spec)
+{
+ /* We don't have any phandle args, so just return 0. */
+ return 0;
+}
+
static const struct iommu_ops rk_iommu_ops = {
.domain_alloc = rk_iommu_domain_alloc,
.domain_free = rk_iommu_domain_free,
@@ -1104,6 +1112,7 @@ static const struct iommu_ops rk_iommu_ops = {
.iova_to_phys = rk_iommu_iova_to_phys,
.device_group = rk_iommu_device_group,
.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
+ .of_xlate = rk_iommu_of_xlate,
};
static int rk_iommu_probe(struct platform_device *pdev)
@@ -1166,6 +1175,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
return err;
iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops);
+ iommu_device_set_fwnode(&iommu->iommu, &dev->of_node->fwnode);
+
err = iommu_device_register(&iommu->iommu);
if (err) {
iommu_device_sysfs_remove(&iommu->iommu);
@@ -1241,6 +1252,8 @@ static void __exit rk_iommu_exit(void)
subsys_initcall(rk_iommu_init);
module_exit(rk_iommu_exit);
+IOMMU_OF_DECLARE(rk_iommu_of, "rockchip,iommu");
+
MODULE_DESCRIPTION("IOMMU API for Rockchip");
MODULE_AUTHOR("Simon Xue <xxm@rock-chips.com> and Daniel Kurtz <djkurtz@chromium.org>");
MODULE_ALIAS("platform:rockchip-iommu");
--
2.11.0
^ permalink raw reply related
* [PATCH linux dev-4.10 0/6] Add support PECI and PECI hwmon drivers
From: Joel Stanley @ 2018-01-11 8:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111073038.GA3600@kroah.com>
On Wed, Jan 10, 2018 at 11:30 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Wed, Jan 10, 2018 at 01:46:34PM -0800, Jae Hyun Yoo wrote:
>> Thanks for your pointing it out and I totally agree with you. Actually, we
>> are preparing 4.13 update for now and an another update will be followed up.
>> As I answered above, I'll rebase this patch set onto the latest kernel.org
>> mainline. Sorry for my misunderstanding of upstream process.
>
> 4.13? Why that kernel? It too is obsolete and insecure and
> unsupported.
It contains support for our hardware that I have integrated from work
in progress patches and upstream commits.
The OpenBMC project, with myself as the kernel maintainer, have
intentions to regularly move to upstream releases. This takes time and
effort. This time and effort is balanced with submitting our drivers
upstream.
> What keeps you all from just always tracking the latest tree from Linus?
Linus' tree does not contain all of the drivers required to boot
systems. Many of them are still under review on lkml, and others still
require rewrite from the vendor tree.
> What is in your tree that is not upstream that requires you to have a
> kernel tree at all?
We have PECI, video compression, crypto, USB CDC, DRM (graphics),
serial GPIO, LPC mailbox for the ASPEED SoC.
Another silicon vendor has recently joined the project and that brings
an entire SoC that is not upstream. We have patches on the ARM that
are under review for this SoC, with more drivers undergoing cleanup in
order to submit them to the relevant maintainers.
>
> And if you do have out-of-tree code, why not use a process that makes it
> trivial to update the base kernel version so that you can keep up to
> date very easily? (hint, just using 'git' is not a good way to do
> this...)
We have a process that we've been developing under for the past few
years. I find git to be a great tool for managing Linux kernel trees.
What would you recommend for managing kernel trees?
Cheers,
Joel
^ permalink raw reply
* [PATCH] ARM64: dts: meson-axg: add RMII pins for ethernet controller
From: Jerome Brunet @ 2018-01-11 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111030411.197054-1-yixun.lan@amlogic.com>
On Thu, 2018-01-11 at 11:04 +0800, Yixun Lan wrote:
> Comparing to RGMII interface, the RMII interface require few pins.
> So it's worth describing them here.
>
> Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
The only axg platform we have upstream is the s400 and is using rgmii.
May I ask how this was tested ?
^ permalink raw reply
* [PATCH linux dev-4.10 0/6] Add support PECI and PECI hwmon drivers
From: Greg KH @ 2018-01-11 8:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACPK8Xe9Jti8S2px=QOcSMA2v+TZ4eGDGQND4qmBUBXeBpsBZQ@mail.gmail.com>
On Thu, Jan 11, 2018 at 12:28:48AM -0800, Joel Stanley wrote:
> On Wed, Jan 10, 2018 at 11:30 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> > On Wed, Jan 10, 2018 at 01:46:34PM -0800, Jae Hyun Yoo wrote:
> >> Thanks for your pointing it out and I totally agree with you. Actually, we
> >> are preparing 4.13 update for now and an another update will be followed up.
> >> As I answered above, I'll rebase this patch set onto the latest kernel.org
> >> mainline. Sorry for my misunderstanding of upstream process.
> >
> > 4.13? Why that kernel? It too is obsolete and insecure and
> > unsupported.
>
> It contains support for our hardware that I have integrated from work
> in progress patches and upstream commits.
>
> The OpenBMC project, with myself as the kernel maintainer, have
> intentions to regularly move to upstream releases. This takes time and
> effort. This time and effort is balanced with submitting our drivers
> upstream.
Of course, but please do not have your "users" use a kernel that is
known to have bugs and can not be supported. That would not be good at
all, don't you think?
> > What keeps you all from just always tracking the latest tree from Linus?
>
> Linus' tree does not contain all of the drivers required to boot
> systems. Many of them are still under review on lkml, and others still
> require rewrite from the vendor tree.
Merging vendor trees into your tree has got to be a complicated mess.
Why try to keep it all together in one place?
And who is responsible for getting the vendor code upstream? The
individual drivers? Individual driver submissions should be quite easy,
what is preventing them from getting merged?
> > What is in your tree that is not upstream that requires you to have a
> > kernel tree at all?
>
> We have PECI, video compression, crypto, USB CDC, DRM (graphics),
> serial GPIO, LPC mailbox for the ASPEED SoC.
What "USB CDC" do you have that is not upstream? I'll pick on this one
specifically as I don't think I've seen any patches recently submitted
for that driver at all. Am I just missing them?
The other ones should also all be easy to get merged, with maybe the
exception of the drm stuff due to the speed that subsystem moves at.
But even there, the community is very helpful in getting stuff upstream,
have you asked for help?
> Another silicon vendor has recently joined the project and that brings
> an entire SoC that is not upstream. We have patches on the ARM that
> are under review for this SoC, with more drivers undergoing cleanup in
> order to submit them to the relevant maintainers.
Why are you merging all SoC trees together into one place? That seems
like a nightmare to manage, especially with git.
> > And if you do have out-of-tree code, why not use a process that makes it
> > trivial to update the base kernel version so that you can keep up to
> > date very easily? (hint, just using 'git' is not a good way to do
> > this...)
>
> We have a process that we've been developing under for the past few
> years. I find git to be a great tool for managing Linux kernel trees.
>
> What would you recommend for managing kernel trees?
quilt is best for a tree that you can not rebase (i.e. a public git
tree). Otherwise you end up getting patches all mushed together and
hard to extract in any simple way.
Take a clue from the distros that have been managing kernels for decades
and deal with an updated kernel all the time easily.
Good luck, it sounds like you will need it :)
thanks,
greg k-h
^ permalink raw reply
* [RFC PATCH 09/12] mmc: sdhci: Use software timer when timeout greater than hardware capablility
From: Adrian Hunter @ 2018-01-11 8:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2da01441-84d0-0d96-610d-2f9a3055ccc7@ti.com>
On 04/01/18 14:59, Kishon Vijay Abraham I wrote:
> Hi Adrian,
>
> On Wednesday 20 December 2017 07:41 PM, Adrian Hunter wrote:
>> On 14/12/17 15:09, Kishon Vijay Abraham I wrote:
>>> Errata i834 in AM572x Sitara Processors Silicon Revision 2.0, 1.1
>>> (SPRZ429K July 2014?Revised March 2017 [1]) mentions
>>> Under high speed HS200 and SDR104 modes, the functional clock for MMC
>>> modules will reach up to 192 MHz. At this frequency, the maximum obtainable
>>> timeout (DTO = 0xE) through MMC host controller is (1/192MHz)*2^27 = 700ms.
>>> Commands taking longer than 700ms may be affected by this small window
>>> frame. Workaround for this errata is use a software timer instead of
>>> hardware timer to provide the delay requested by the upper layer.
>>>
>>> While this errata is specific to AM572x, it is applicable to all sdhci
>>> based controllers when a particular request require timeout greater
>>> than hardware capability.
>>
>> It doesn't work for our controllers. Even if the data timeout interrupt is
>> disabled, it seems like the timeout still "happens" in some fashion - after
>> which the host controller starts misbehaving.
>
> even if the data timeout doesn't get disabled, count = 0xE is still present. So
> ideally this shouldn't break any existing platforms no?
I don't want to hide this kind of variation in the hardware behaviour.
>>
>> So you will need to add a quirk.
>>
>>>
>>> Re-use the software timer already implemented in sdhci to program the
>>> correct timeout value and also disable the hardware timeout when
>>> the required timeout is greater than hardware capabiltiy in order to
>>> avoid spurious timeout interrupts.
>>>
>>> This patch is based on the earlier patch implemented for omap_hsmmc [2]
>>>
>>> [1] -> http://www.ti.com/lit/er/sprz429k/sprz429k.pdf
>>> [2] -> https://patchwork.kernel.org/patch/9791449/
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>> drivers/mmc/host/sdhci.c | 41 +++++++++++++++++++++++++++++++++++++++--
>>> drivers/mmc/host/sdhci.h | 11 +++++++++++
>>> 2 files changed, 50 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>>> index e9290a3439d5..d0655e1d2cc7 100644
>>> --- a/drivers/mmc/host/sdhci.c
>>> +++ b/drivers/mmc/host/sdhci.c
>>> @@ -673,6 +673,27 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
>>> }
>>> }
>>>
>>> +static void sdhci_calc_sw_timeout(struct sdhci_host *host,
>>> + struct mmc_command *cmd,
>>> + unsigned int target_timeout)
>>> +{
>>> + struct mmc_host *mmc = host->mmc;
>>> + struct mmc_ios *ios = &mmc->ios;
>>> + struct mmc_data *data = cmd->data;
>>> + unsigned long long transfer_time;
>>> +
>>> + if (data) {
>>> + transfer_time = MMC_BLOCK_TRANSFER_TIME_MS(data->blksz,
>>> + ios->bus_width,
>>> + ios->clock);
>>
>> If it has a value, actual_clock is better than ios->clock.
>
> okay.
>>
>>> + /* calculate timeout for the entire data */
>>> + host->data_timeout = (data->blocks * (target_timeout +
>>> + transfer_time));
>>> + } else if (cmd->flags & MMC_RSP_BUSY) {
>>> + host->data_timeout = cmd->busy_timeout * MSEC_PER_SEC;
>>
>> Doesn't need MSEC_PER_SEC multiplier.
>
> right.
>>
>>> + }
>>> +}
>>> +
>>> static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
>>> {
>>> u8 count;
>>> @@ -732,8 +753,12 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
>>> }
>>>
>>> if (count >= 0xF) {
>>> - DBG("Too large timeout 0x%x requested for CMD%d!\n",
>>> - count, cmd->opcode);
>>> + DBG("Too large timeout.. using SW timeout for CMD%d!\n",
>>> + cmd->opcode);
>>> + sdhci_calc_sw_timeout(host, cmd, target_timeout);
>>> + host->ier &= ~SDHCI_INT_DATA_TIMEOUT;
>>> + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
>>> + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
>>> count = 0xE;
>>> }
>>>
>>> @@ -1198,6 +1223,14 @@ static void sdhci_finish_command(struct sdhci_host *host)
>>> {
>>> struct mmc_command *cmd = host->cmd;
>>>
>>> + if (host->data_timeout) {
>>> + unsigned long timeout;
>>> +
>>> + timeout = jiffies +
>>> + msecs_to_jiffies(host->data_timeout);
>>> + sdhci_mod_timer(host, host->cmd->mrq, timeout);
>>
>> cmd could be the sbc or a stop cmd or a command during transfer, so this
>> needs more logic.
>
> host->data_timeout gets set only for data commands or commands with busy
> timeout. But I guess for commands during data transfer, host->data_timeout
> might still be set?
>
> Checking sdhci_data_line_cmd(mrq->cmd) in addition to host->data_timeout should
> take care of all cases right?
I suggest you make the timeout calculation allow for the commands as well
and then reorder sdhci_mod_timer() to be called after sdhci_prepare_data()
and make sdhci_mod_timer() do the right thing.
>>
>>> + }
>>> +
>>> host->cmd = NULL;
>>>
>>> if (cmd->flags & MMC_RSP_PRESENT) {
>>> @@ -2341,6 +2374,10 @@ static bool sdhci_request_done(struct sdhci_host *host)
>>> return true;
>>> }
>>>
>>> + host->data_timeout = 0;
>>> + host->ier |= SDHCI_INT_DATA_TIMEOUT;
>>> + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
>>> + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
>>
>> sdhci can have 2 requests in progress to allow for commands to be sent while
>> a data transfer is in progress, so this is not necessarily the data transfer
>> request that is done. Also we want to avoid unnecessary register writes.
>>
>
> okay.. got it.
>>> sdhci_del_timer(host, mrq);
>>>
>>> /*
>>> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
>>> index 54bc444c317f..e6e0278bea1a 100644
>>> --- a/drivers/mmc/host/sdhci.h
>>> +++ b/drivers/mmc/host/sdhci.h
>>> @@ -332,6 +332,15 @@ struct sdhci_adma2_64_desc {
>>> /* Allow for a a command request and a data request at the same time */
>>> #define SDHCI_MAX_MRQS 2
>>>
>>> +/*
>>> + * Time taken for transferring one block. It is multiplied by a constant
>>> + * factor '2' to account for any errors
>>> + */
>>> +#define MMC_BLOCK_TRANSFER_TIME_MS(blksz, bus_width, freq) \
>>> + ((unsigned long long) \
>>> + (2 * (((blksz) * MSEC_PER_SEC * \
>>> + (8 / (bus_width))) / (freq))))
>>
>> I don't think the macro helps make the code more readable. Might just as
>> well write a nice function to calculate the entire data request timeout.
>
> okay.
>>
>>> +
>>> enum sdhci_cookie {
>>> COOKIE_UNMAPPED,
>>> COOKIE_PRE_MAPPED, /* mapped by sdhci_pre_req() */
>>> @@ -546,6 +555,8 @@ struct sdhci_host {
>>> /* Host SDMA buffer boundary. */
>>> u32 sdma_boundary;
>>>
>>> + unsigned long long data_timeout;
>>
>> msecs_to_jiffies() will truncate to 'unsigned int' anyway, so this might as
>> well be 'unsigned int'.
>>
>
> okay.
>
> Thanks
> Kishon
>
^ permalink raw reply
* [PATCH RFC v1] arm64: Handle traps from accessing CNTVCT/CNTFRQ for CONFIG_COMPAT
From: Marc Zyngier @ 2018-01-11 8:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515645816-14063-1-git-send-email-nicoleotsuka@gmail.com>
On 11/01/18 04:43, Nicolin Chen wrote:
> CONFIG_COMPAT allows ARM64 machine to run 32-bit instructions.
> Since the ARCH_TIMER_USR_VCT_ACCESS_EN might be disabled if a
> timer workaround is detected, accessing cntvct via mrrc will
> also trigger a trap.
>
> So this patch adds support to handle this situation.
>
> Tested with a user program generated by 32-bit compiler:
> int main()
> {
> unsigned long long cval;
> asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
> return 0;
> }
>
> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
>
> [ I also added cntfrq here for safety as theoretically it could
> trigger the trap as well. However, my another test case (with
> mrc insturction) doesn't seem to trigger a trap. So I would
> drop it in the next version if someone can confirm it's not
> required. Thanks -- Nicolin ]
See my previous series on this very subject[1] as well as Will's reply.
>
> arch/arm64/include/asm/esr.h | 25 +++++++++++++++++++
> arch/arm64/include/asm/ptrace.h | 15 ++++++++++++
> arch/arm64/kernel/entry.S | 4 ++--
> arch/arm64/kernel/traps.c | 53 +++++++++++++++++++++++++++++++++++++++--
> 4 files changed, 93 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index 014d7d8..55dea62 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -220,6 +220,31 @@
> (((e) & ESR_ELx_SYS64_ISS_OP2_MASK) >> \
> ESR_ELx_SYS64_ISS_OP2_SHIFT))
>
> +/* ISS fields for MRC and MRS are very similar, so reuse SYS64 macros */
> +#define ESR_ELx_CP15_32_ISS_MRC_MASK ESR_ELx_SYS64_ISS_SYS_MASK
> +#define ESR_ELx_CP15_32_ISS_MRC_CNTFRQ (ESR_ELx_SYS64_ISS_SYS_VAL(0, 0, 0, 14, 0) | \
> + ESR_ELx_SYS64_ISS_DIR_READ)
> +
> +/* ISS field definitions for CP15 MRRC/MCRR instructions (same for CP14) */
> +#define ESR_ELx_CP15_64_ISS_OPC1_SHIFT 16
> +#define ESR_ELx_CP15_64_ISS_OPC1_MASK (UL(0xf) << ESR_ELx_CP15_64_ISS_OPC1_SHIFT)
> +#define ESR_ELx_CP15_64_ISS_RT2_SHIFT 10
> +#define ESR_ELx_CP15_64_ISS_RT2_MASK (UL(0x1f) << ESR_ELx_CP15_64_ISS_RT2_SHIFT)
> +#define ESR_ELx_CP15_64_ISS_RT_SHIFT 5
> +#define ESR_ELx_CP15_64_ISS_RT_MASK (UL(0x1f) << ESR_ELx_CP15_64_ISS_RT_SHIFT)
> +#define ESR_ELx_CP15_64_ISS_CRM_SHIFT 1
> +#define ESR_ELx_CP15_64_ISS_CRM_MASK (UL(0xf) << ESR_ELx_CP15_64_ISS_CRM_SHIFT)
> +#define ESR_ELx_CP15_64_ISS_MRRC_MASK (ESR_ELx_CP15_64_ISS_OPC1_MASK | \
> + ESR_ELx_CP15_64_ISS_CRM_MASK| \
> + ESR_ELx_SYS64_ISS_DIR_MASK)
> +
> +#define ESR_ELx_CP15_64_ISS_MRRC_VAL(opc1, crm) \
> + (((opc1) << ESR_ELx_CP15_64_ISS_OPC1_SHIFT) | \
> + ((crm) << ESR_ELx_CP15_64_ISS_CRM_SHIFT))
> +
> +#define ESR_ELx_CP15_64_ISS_MRRC_CNTVCT (ESR_ELx_CP15_64_ISS_MRRC_VAL(1, 14) | \
> + ESR_ELx_SYS64_ISS_DIR_READ)
> +
> #ifndef __ASSEMBLY__
> #include <asm/types.h>
>
> diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
> index 6069d66..50caf11 100644
> --- a/arch/arm64/include/asm/ptrace.h
> +++ b/arch/arm64/include/asm/ptrace.h
> @@ -243,6 +243,21 @@ static inline void pt_regs_write_reg(struct pt_regs *regs, int r,
> regs->regs[r] = val;
> }
>
> +/*
> + * Write two registers given architectural register index r and r2.
> + * Used by 32-bit MRRC and MCRR instrutions for 64-bit results
> + */
> +static inline void pt_regs_write_regs(struct pt_regs *regs, int r, int r2,
> + unsigned long val)
> +{
> + if (r != 31 && r2 != 31) {
> + /* Save lower 32 bits to register r */
> + regs->regs[r] = val & 0xffffffff;
> + /* Save higher 32 bits to register r2 */
> + regs->regs[r2] = val >> 32;
> + }
> +}
> +
> /* Valid only for Kernel mode traps. */
> static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
> {
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 6d14b8f..9d6cd95 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -636,9 +636,9 @@ el0_sync_compat:
> cmp x24, #ESR_ELx_EC_UNKNOWN // unknown exception in EL0
> b.eq el0_undef
> cmp x24, #ESR_ELx_EC_CP15_32 // CP15 MRC/MCR trap
> - b.eq el0_undef
> + b.eq el0_sys
> cmp x24, #ESR_ELx_EC_CP15_64 // CP15 MRRC/MCRR trap
> - b.eq el0_undef
> + b.eq el0_sys
> cmp x24, #ESR_ELx_EC_CP14_MR // CP14 MRC/MCR trap
> b.eq el0_undef
> cmp x24, #ESR_ELx_EC_CP14_LS // CP14 LDC/STC trap
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index 3d3588f..211cce7 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -454,6 +454,17 @@ static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
> arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE);
> }
>
> +#ifdef CONFIG_COMPAT
> +static void cntvct_read_32_handler(unsigned int esr, struct pt_regs *regs)
> +{
> + int rt2 = (esr & ESR_ELx_CP15_64_ISS_RT2_MASK) >> ESR_ELx_CP15_64_ISS_RT2_SHIFT;
> + int rt = (esr & ESR_ELx_CP15_64_ISS_RT_MASK) >> ESR_ELx_CP15_64_ISS_RT_SHIFT;
> +
> + pt_regs_write_regs(regs, rt, rt2, arch_counter_get_cntvct());
> + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE);
> +}
> +#endif
> +
> static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs)
> {
> int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
> @@ -495,11 +506,49 @@ static struct sys64_hook sys64_hooks[] = {
> {},
> };
>
> +#ifdef CONFIG_COMPAT
> +static struct sys64_hook cp15_32_hooks[] = {
> + {
> + /* Trap read access to CNTFRQ via 32-bit insturction MRC */
> + .esr_mask = ESR_ELx_CP15_32_ISS_MRC_MASK,
> + .esr_val = ESR_ELx_CP15_32_ISS_MRC_CNTFRQ,
> + .handler = cntfrq_read_handler,
> + },
> + {},
> +};
> +
> +static struct sys64_hook cp15_64_hooks[] = {
> + {
> + /* Trap read access to CNTVCT via 32-bit insturction MRRC */
> + .esr_mask = ESR_ELx_CP15_64_ISS_MRRC_MASK,
> + .esr_val = ESR_ELx_CP15_64_ISS_MRRC_CNTVCT,
> + .handler = cntvct_read_32_handler,
> + },
> + {},
> +};
> +#endif
> +
> asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
> {
> - struct sys64_hook *hook;
> + struct sys64_hook *hook = NULL;
> +
> + switch (ESR_ELx_EC(esr)) {
> +#ifdef CONFIG_COMPAT
> + case ESR_ELx_EC_CP15_32:
> + hook = cp15_32_hooks;
> + break;
> + case ESR_ELx_EC_CP15_64:
> + hook = cp15_64_hooks;
> + break;
> +#endif
> + case ESR_ELx_EC_SYS64:
> + hook = sys64_hooks;
> + break;
> + default:
> + break;
> + }
>
> - for (hook = sys64_hooks; hook->handler; hook++)
> + for (; hook && hook->handler; hook++)
> if ((hook->esr_mask & esr) == hook->esr_val) {
> hook->handler(esr, regs);
> return;
>
Also, this code is fairly broken in its handling of conditional
instructions.
Thanks,
M.
[1]
http://lists.infradead.org/pipermail/linux-arm-kernel/2017-July/520426.html
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH linux dev-4.10 0/6] Add support PECI and PECI hwmon drivers
From: Benjamin Herrenschmidt @ 2018-01-11 8:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180111073038.GA3600@kroah.com>
On Thu, 2018-01-11 at 08:30 +0100, Greg KH wrote:
> 4.13? Why that kernel? It too is obsolete and insecure and
> unsupported.
Haha, it's n-1. come on :-)
> What keeps you all from just always tracking the latest tree from Linus?
> What is in your tree that is not upstream that requires you to have a
> kernel tree at all?
There are a couple of ARM based SoC families for which we are in the
process of rewriting all the driver in upstreamable form. This takes
time.
To respond to your other email about the USB CDC, it's mine, I haven't
resubmited it yet because it had a dependency on some the aspeed clk
driver to function properly (so is unusable without it) and it took 2
kernel versions to get that clk stuff upstream for a number of reasons.
So it's all getting upstream and eventually there will be (we hope) no
"OpenBMC" kernel, it's just a way for us to get functional code with
non-upstream-quality (read: vendor) drivers until we are one rewriting
& upstreaming them all.
> And if you do have out-of-tree code, why not use a process that makes it
> trivial to update the base kernel version so that you can keep up to
> date very easily? (hint, just using 'git' is not a good way to do
> this...)
Joel and I both find git perfectly fine for that. I've not touched
quilt in eons and frankly don't regret it ;-)
That said, Jae should definitely submit a driver against upstream, not
against some random OpenBMC tree.
Jae, for example when I submitted the original USB stuff back then, I
did it from a local upstream based branch (with just a few hacks to
work around the lack of the clk stuff).
I will rebase it in the next few days to upstream merged with Stephen's
clk tree to get the finally merged clk stuff, verify it works, and
submit patches against upstream.
There should be no mention of dev-4.10 or 4.13 on lkml or other
upstream submission lists. Development work should happen upstream
*first* and eventually be backported to our older kernels while they
exist (hopefully I prefer if we are more aggressive at forward porting
the crappy drivers so we can keep our tree more up to date but that's a
different discussion).
Cheers,
Ben.
> thanks,
>
> greg k-h
^ permalink raw reply
* [PATCH linux dev-4.10 3/6] drivers/misc: Add driver for Aspeed PECI and generic PECI headers
From: Benjamin Herrenschmidt @ 2018-01-11 9:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180110101840.GB5822@kroah.com>
On Wed, 2018-01-10 at 11:18 +0100, Greg KH wrote:
> On Tue, Jan 09, 2018 at 02:31:23PM -0800, Jae Hyun Yoo wrote:
> > This commit adds driver implementation for Aspeed PECI. Also adds
> > generic peci.h and peci_ioctl.h files to provide compatibility
> > to peci drivers that can be implemented later e.g. Nuvoton's BMC
> > SoC family.
>
> We don't add code that could be used "sometime in the future". Only
> include stuff that we use now.
>
> Please fix up this series based on that and resubmit. There should not
> be any need for any uapi file then, right?
No Greg, I think you misunderstood (unless I misread myself).
What Jae means is that since PECI is a standard and other drivers
implementing the same ioctl interface and messages will eventually go
upstream, instead of having the ioctl definitions in a driver specific
locations, they go in a generic spot, as they define a generic API for
all PECI drivers, including the one that's getting merged now.
IE. This doesn't add unused stuff, it just puts the API parts of it
into a generic location.
At least that's my understanding from a, granted cursory, look at the
patch.
That said, I do have a problem with the structure definitions of the
various packet types as they use "long" which has a variable size and
unclear alignment. It should be using __u8, __u16 and __u32...
Cheers,
Ben.
^ permalink raw reply
* [PATCH v2 1/6] arm: Add BTB invalidation on switch_mm for Cortex-A9, A12 and A17
From: Marc Zyngier @ 2018-01-11 9:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87c06809-e035-52d7-0822-5fffb402c1dd@ti.com>
On 10/01/18 21:52, Nishanth Menon wrote:
> On 01/10/2018 11:57 AM, Marc Zyngier wrote:
>> On 10/01/18 17:53, Tony Lindgren wrote:
>>> * Marc Zyngier <marc.zyngier@arm.com> [180108 19:00]:
>>>> In order to avoid aliasing attacks against the branch predictor,
>>>> some implementations require to invalidate the BTB when switching
>>>> from one user context to another.
>>>>
>>>> For this, we reuse the existing implementation for Cortex-A8, and
>>>> apply it to A9, A12 and A17.
>>>
>>> I suspect we now must also make sure Cortex-A8 has the IBE bit
>>> set unconditionally for this to work. Currently the assumption is
>>> that IBE bit needs to be set only on the earlier CPU revisions
>>> that suffer from ARM_ERRATA_430973.
>>>
>>>> --- a/arch/arm/mm/proc-v7-2level.S
>>>> +++ b/arch/arm/mm/proc-v7-2level.S
>>>> @@ -41,7 +41,7 @@
>>>> * even on Cortex-A8 revisions not affected by 430973.
>>>> * If IBE is not set, the flush BTAC/BTB won't do anything.
>>>> */
>>>> -ENTRY(cpu_ca8_switch_mm)
>>>> +ENTRY(cpu_v7_btbinv_switch_mm)
>>>> #ifdef CONFIG_MMU
>>>> mov r2, #0
>>>> mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
>>>
>>> So without IBE set, as the comments above say, the flush won't
>>> do anything.
>>
>> Indeed. Firmware/bootloaders must be updated to set IBE, just like on
>> Cortex-A15. I'll add a note to that effect.
> OK. in u-boot, I had helped on the following:
> http://git.denx.de/?p=u-boot.git;a=commitdiff;h=5902f4ce0f2bd1411e40dc0ece3598a0fc19b2ae
>
> maybe be build off that?
Turn that into something unconditional, and you'll be good.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH linux dev-4.10 3/6] drivers/misc: Add driver for Aspeed PECI and generic PECI headers
From: Benjamin Herrenschmidt @ 2018-01-11 9:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180109223126.13093-4-jae.hyun.yoo@linux.intel.com>
On Tue, 2018-01-09 at 14:31 -0800, Jae Hyun Yoo wrote:
> +struct peci_rd_ia_msr_msg {
> + unsigned char target;
> + unsigned char thread_id;
> + unsigned short address;
> + unsigned long value;
> +};
Those types are representing messages on the wire ?
In that case those types aren't suitable. For example "long" will have
a different size and alignment for 32 and 64-bit userspace. There are
size-explicit userspace types available.
Also I didn't see any endianness annotations in there. Is that expected
? IE are those wire format packets ?
Cheers,
Ben.
^ 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