* [PATCH v2 01/13] iommu/rockchip: Request irqs in rk_iommu_probe()
[not found] ` <20180116132540.18939-2-jeffy.chen@rock-chips.com>
@ 2018-01-17 4:21 ` Tomasz Figa
[not found] ` <5A5EF672.6040304@rock-chips.com>
2018-01-17 12:18 ` Robin Murphy
1 sibling, 1 reply; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 4:21 UTC (permalink / raw)
To: linux-arm-kernel
Hi Jeffy,
Thanks for the patch. Please see my comments inline.
On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
Please add patch description.
> Suggested-by: Robin Murphy <robin.murphy@arm.com>
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> ---
[snip]
> - for (i = 0; i < iommu->num_irq; i++) {
> - iommu->irq[i] = platform_get_irq(pdev, i);
> - if (iommu->irq[i] < 0) {
> - dev_err(dev, "Failed to get IRQ, %d\n", iommu->irq[i]);
> + num_irq = of_irq_count(dev->of_node);
> + for (i = 0; i < num_irq; i++) {
> + irq = platform_get_irq(pdev, i);
This lacks consistency. of_irq_count() is used for counting, but
platform_get_irq() is used for getting. Either platform_ or of_ API
should be used for both and I'd lean for platform_, since it's more
general.
> + if (irq < 0) {
> + dev_err(dev, "Failed to get IRQ, %d\n", irq);
> return -ENXIO;
> }
> + err = devm_request_irq(iommu->dev, irq, rk_iommu_irq,
> + IRQF_SHARED, dev_name(dev), iommu);
> + if (err)
> + return err;
> }
Looks like there is some more initialization below. Is the driver okay
with the IRQ being potentially fired right here? (Shared IRQ handlers
might be run at request_irq() time for testing.)
>
> iommu->reset_disabled = device_property_read_bool(dev,
^^
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 02/13] iommu/rockchip: Suppress unbinding
[not found] ` <20180116132540.18939-3-jeffy.chen@rock-chips.com>
@ 2018-01-17 4:23 ` Tomasz Figa
2018-01-17 5:32 ` Tomasz Figa
0 siblings, 1 reply; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 4:23 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
> It's not safe to unbind rockchip IOMMU driver.
Might be good to explain why it is not safe and actually add that it
does not make any sense for such low level devices.
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 04/13] iommu/rockchip: Fix error handling in probe
[not found] ` <20180116132540.18939-5-jeffy.chen@rock-chips.com>
@ 2018-01-17 5:22 ` Tomasz Figa
0 siblings, 0 replies; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 5:22 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
> Add missing iommu_device_sysfs_remove in error path.
>
> Also adjust sequence of deinit functions in the remove.
>
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> ---
>
> Changes in v2: None
>
> drivers/iommu/rockchip-iommu.c | 12 +++++++-----
> 1 file changed, 7 insertions(+), 5 deletions(-)
>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 05/13] iommu/rockchip: Fix error handling in init
[not found] ` <20180116132540.18939-6-jeffy.chen@rock-chips.com>
@ 2018-01-17 5:26 ` Tomasz Figa
[not found] ` <5A5EF7D3.90405@rock-chips.com>
2018-01-17 11:36 ` Robin Murphy
0 siblings, 2 replies; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 5:26 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
> It's hard to undo bus_set_iommu() in the error path, so move it to the
> end of rk_iommu_probe().
Does this work fine now? I remember we used to need this called in an
early initcall for all the ARM/ARM64 DMA stuff to work.
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 02/13] iommu/rockchip: Suppress unbinding
2018-01-17 4:23 ` [PATCH v2 02/13] iommu/rockchip: Suppress unbinding Tomasz Figa
@ 2018-01-17 5:32 ` Tomasz Figa
0 siblings, 0 replies; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 5:32 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Jan 17, 2018 at 1:23 PM, Tomasz Figa <tfiga@chromium.org> wrote:
> On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
>> It's not safe to unbind rockchip IOMMU driver.
>
> Might be good to explain why it is not safe and actually add that it
> does not make any sense for such low level devices.
Actually, shouldn't we also remove support for .remove() and module
exit? I don't think it's actually feasible to unload this driver. We
actually even have ROCKCHIP_IOMMU Kconfig entry defined as bool, so
the driver can be only built-in.
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 10/13] iommu/rockchip: Use IOMMU device for dma mapping operations
[not found] ` <20180116132540.18939-11-jeffy.chen@rock-chips.com>
@ 2018-01-17 5:37 ` Tomasz Figa
0 siblings, 0 replies; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 5:37 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
> 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>
> ---
>
> Changes in v2: None
>
> drivers/iommu/rockchip-iommu.c | 91 +++++++++++-------------------------------
> 1 file changed, 24 insertions(+), 67 deletions(-)
Looks good to me, but we need to remove platform driver .remove(), as
it was done for Exynos IOMMU as well. With that fixed (probably
squashed to the patch that prohibits unbind):
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 11/13] iommu/rockchip: Use OF_IOMMU to attach devices automatically
[not found] ` <20180116132540.18939-12-jeffy.chen@rock-chips.com>
@ 2018-01-17 5:44 ` Tomasz Figa
[not found] ` <5A5EF94E.7010806@rock-chips.com>
0 siblings, 1 reply; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 5:44 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
> 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>
> ---
>
> Changes in v2: None
>
> drivers/iommu/rockchip-iommu.c | 116 +++++++++++------------------------------
> 1 file changed, 31 insertions(+), 85 deletions(-)
>
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 51e4f982c4a6..c2d3ac82184e 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
[snip]
> +static int rk_iommu_of_xlate(struct device *dev,
> + struct of_phandle_args *args)
> +{
> + struct platform_device *iommu_dev;
> +
> + iommu_dev = of_find_device_by_node(args->np);
> + if (!iommu_dev) {
> + dev_err(dev, "iommu %pOF not found\n", args->np);
> + return -ENODEV;
> + }
> +
> + dev->archdata.iommu = platform_get_drvdata(iommu_dev);
This will work only if that iommu was already probed. Do we have any
guarantees that this callback is not called earlier?
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 12/13] iommu/rockchip: Add runtime PM support
[not found] ` <20180116132540.18939-13-jeffy.chen@rock-chips.com>
@ 2018-01-17 6:20 ` Tomasz Figa
[not found] ` <5A5EFAB2.7040001@rock-chips.com>
0 siblings, 1 reply; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 6:20 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
> When the power domain is powered off, the IOMMU cannot be accessed and
> register programming must be deferred until the power domain becomes
> enabled.
>
> Add runtime PM support, and use runtime PM device link from IOMMU to
> master to startup and shutdown IOMMU.
[snip]
> @@ -875,28 +889,19 @@ static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,
>
> static struct rk_iommu *rk_iommu_from_dev(struct device *dev)
> {
> - return dev->archdata.iommu;
> + struct rk_iommudata *data = dev->archdata.iommu;
> +
> + return data ? data->iommu : NULL;
> }
Is this change intentionally added to this patch? I see this
potentially relevant for the previous patch in this series.
[snip]
> +static int rk_iommu_startup(struct rk_iommu *iommu)
> {
> - struct rk_iommu *iommu;
> + struct iommu_domain *domain = iommu->domain;
> struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
> - unsigned long flags;
> int ret, i;
>
> - /*
> - * Allow 'virtual devices' (e.g., drm) to attach to domain.
> - * Such a device does not belong to an iommu group.
> - */
> - iommu = rk_iommu_from_dev(dev);
> - if (!iommu)
> - return 0;
> -
> - if (iommu->domain)
> - rk_iommu_detach_device(iommu->domain, dev);
> -
> ret = rk_iommu_enable_clocks(iommu);
> if (ret)
> return ret;
>
Don't we need to check here (and in _shutdown() too) if we have a
domain attached?
> + mutex_lock(&iommu->pm_mutex);
> ret = rk_iommu_enable_stall(iommu);
> if (ret)
> - goto err_disable_clocks;
> + goto err_unlock_mutex;
[snip]
> + iommu->domain = NULL;
> +
> + spin_lock_irqsave(&rk_domain->iommus_lock, flags);
> + list_del_init(&iommu->node);
> + spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
> +
> + if (pm_runtime_get_if_in_use(iommu->dev) > 0) {
Actually, if the above call returns -EINVAL, don't we still need to
call rk_iommu_shutdown(), because it just means runtime PM is disabled
and the IOMMU is always powered on?
> + rk_iommu_shutdown(iommu);
> + pm_runtime_put(iommu->dev);
> + }
> +}
[snip]
> + spin_lock_irqsave(&rk_domain->iommus_lock, flags);
> + list_add_tail(&iommu->node, &rk_domain->iommus);
> + spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
> +
> + if (pm_runtime_get_if_in_use(iommu->dev) <= 0)
Ditto.
> + return 0;
> +
> + ret = rk_iommu_startup(iommu);
> + if (ret)
> + rk_iommu_detach_device(data->domain, dev);
[snip]
> @@ -1108,7 +1175,9 @@ static int rk_iommu_of_xlate(struct device *dev,
> return -ENODEV;
> }
>
> - dev->archdata.iommu = platform_get_drvdata(iommu_dev);
> + data->iommu = platform_get_drvdata(iommu_dev);
> + dev->archdata.iommu = data;
> +
I think this change might be mistakenly squashed to this patch instead
of previous.
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 01/13] iommu/rockchip: Request irqs in rk_iommu_probe()
[not found] ` <5A5EF672.6040304@rock-chips.com>
@ 2018-01-17 7:16 ` Tomasz Figa
2018-01-17 7:45 ` JeffyChen
0 siblings, 1 reply; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 7:16 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Jan 17, 2018 at 4:08 PM, JeffyChen <jeffy.chen@rock-chips.com> wrote:
> Hi Tomasz,
>
> Thanks for your reply.
>
> On 01/17/2018 12:21 PM, Tomasz Figa wrote:
>>
>> Hi Jeffy,
>>
>> Thanks for the patch. Please see my comments inline.
>>
>> On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com>
>> wrote:
>>
>> Please add patch description.
>
>
> ok, will do.
>>
>>
>>> Suggested-by: Robin Murphy <robin.murphy@arm.com>
>>> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
>>> ---
>>
>> [snip]
>>>
>>> - for (i = 0; i < iommu->num_irq; i++) {
>>> - iommu->irq[i] = platform_get_irq(pdev, i);
>>> - if (iommu->irq[i] < 0) {
>>> - dev_err(dev, "Failed to get IRQ, %d\n",
>>> iommu->irq[i]);
>>> + num_irq = of_irq_count(dev->of_node);
>>> + for (i = 0; i < num_irq; i++) {
>>> + irq = platform_get_irq(pdev, i);
>>
>>
>> This lacks consistency. of_irq_count() is used for counting, but
>> platform_get_irq() is used for getting. Either platform_ or of_ API
>> should be used for both and I'd lean for platform_, since it's more
>> general.
>
> hmmm, right, i was thinking of removing num_irq, and do something like:
> while (nr++) {
> err = platform_get_irq(dev, nr);
> if (err == -EPROBE_DEFER)
> break;
> if (err < 0)
> return err;
> ....
> }
>
> but forgot to do that..
Was there anything wrong with platform_irq_count() used by existing code?
>
>>
>>> + if (irq < 0) {
>>> + dev_err(dev, "Failed to get IRQ, %d\n", irq);
>>> return -ENXIO;
>>> }
>>> + err = devm_request_irq(iommu->dev, irq, rk_iommu_irq,
>>> + IRQF_SHARED, dev_name(dev),
>>> iommu);
>>> + if (err)
>>> + return err;
>>> }
>>
>>
>> Looks like there is some more initialization below. Is the driver okay
>> with the IRQ being potentially fired right here? (Shared IRQ handlers
>> might be run at request_irq() time for testing.)
>>
> right, forget about that. maybe we can check iommu->domain not NULL in
> rk_iommu_irq()
Maybe we could just move IRQ requesting to the end of probe?
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 05/13] iommu/rockchip: Fix error handling in init
[not found] ` <5A5EF7D3.90405@rock-chips.com>
@ 2018-01-17 7:19 ` Tomasz Figa
2018-01-17 12:27 ` Tomasz Figa
0 siblings, 1 reply; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 7:19 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Jan 17, 2018 at 4:14 PM, JeffyChen <jeffy.chen@rock-chips.com> wrote:
> Hi Tomasz,
>
> On 01/17/2018 01:26 PM, Tomasz Figa wrote:
>>
>> On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com>
>> wrote:
>>>
>>> It's hard to undo bus_set_iommu() in the error path, so move it to the
>>> end of rk_iommu_probe().
>>
>>
>> Does this work fine now? I remember we used to need this called in an
>> early initcall for all the ARM/ARM64 DMA stuff to work.
>>
> yes, i think it works now, i saw there are some other iommu drivers also do
> this(arm-smmu-v3, mtk_iommu) :)
Okay, if so:
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Best regards,
Tomasz
P.S. Looks like your email client is set to HTML messages. Your
messages might end up dropped from the mailing list.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 11/13] iommu/rockchip: Use OF_IOMMU to attach devices automatically
[not found] ` <5A5EF94E.7010806@rock-chips.com>
@ 2018-01-17 7:30 ` Tomasz Figa
2018-01-17 7:47 ` JeffyChen
0 siblings, 1 reply; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 7:30 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Jan 17, 2018 at 4:20 PM, JeffyChen <jeffy.chen@rock-chips.com> wrote:
> Hi Tomasz,
>
> Thanks for your reply.
>
>
> On 01/17/2018 01:44 PM, Tomasz Figa wrote:
>>
>> On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com>
>> wrote:
>>>
>>> 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>
>>> ---
>>>
>>> Changes in v2: None
>>>
>>> drivers/iommu/rockchip-iommu.c | 116
>>> +++++++++++------------------------------
>>> 1 file changed, 31 insertions(+), 85 deletions(-)
>>>
>>> diff --git a/drivers/iommu/rockchip-iommu.c
>>> b/drivers/iommu/rockchip-iommu.c
>>> index 51e4f982c4a6..c2d3ac82184e 100644
>>> --- a/drivers/iommu/rockchip-iommu.c
>>> +++ b/drivers/iommu/rockchip-iommu.c
>>
>> [snip]
>>>
>>> +static int rk_iommu_of_xlate(struct device *dev,
>>> + struct of_phandle_args *args)
>>> +{
>>> + struct platform_device *iommu_dev;
>>> +
>>> + iommu_dev = of_find_device_by_node(args->np);
>>> + if (!iommu_dev) {
>>> + dev_err(dev, "iommu %pOF not found\n", args->np);
>>> + return -ENODEV;
>>> + }
>>> +
>>> + dev->archdata.iommu = platform_get_drvdata(iommu_dev);
>>
>>
>> This will work only if that iommu was already probed. Do we have any
>> guarantees that this callback is not called earlier?
>
> in of_iommu.c, the of_iommu_xlate would check for fwnode before calling
> this.
Right, looks like deferred probe is handled there.
>
> but it's possible the probe failed after calling iommu_device_set_fwnode, so
> i'll try to add some checks here, and maybe adjust probe() to prevent it
> too.
I think iommu_device_set_fwnode() is not enough for of_iommu_xlate()
to find the IOMMU. The IOMMU is actually added to the IOMMU list by
iommu_device_register(), which is last in the sequence, so I guess we
should be fine.
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 12/13] iommu/rockchip: Add runtime PM support
[not found] ` <5A5EFAB2.7040001@rock-chips.com>
@ 2018-01-17 7:38 ` Tomasz Figa
2018-01-17 7:52 ` JeffyChen
0 siblings, 1 reply; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 7:38 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Jan 17, 2018 at 4:26 PM, JeffyChen <jeffy.chen@rock-chips.com> wrote:
> Hi Tomasz,
>
> Thanks for your reply.
>
> On 01/17/2018 02:20 PM, Tomasz Figa wrote:
>>
>> On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com>
>> [snip]
>>>
>>> +static int rk_iommu_startup(struct rk_iommu *iommu)
>>> {
>>> - struct rk_iommu *iommu;
>>> + struct iommu_domain *domain = iommu->domain;
>>> struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
>>> - unsigned long flags;
>>> int ret, i;
>>>
>>> - /*
>>> - * Allow 'virtual devices' (e.g., drm) to attach to domain.
>>> - * Such a device does not belong to an iommu group.
>>> - */
>>> - iommu = rk_iommu_from_dev(dev);
>>> - if (!iommu)
>>> - return 0;
>>> -
>>> - if (iommu->domain)
>>> - rk_iommu_detach_device(iommu->domain, dev);
>>> -
>>> ret = rk_iommu_enable_clocks(iommu);
>>> if (ret)
>>> return ret;
>>>
>>
>> Don't we need to check here (and in _shutdown() too) if we have a
>> domain attached?
>
> hmmm, right, the startup might been called by resume, so should check
> iommu->domain here.
>
> but the shutdown would be called at the end of detach or suspend, it could
> be not attached or attached.
If startup might be called by resume, without domain attached, what
prevents shutdown from being called by suspend after that resume,
still without domain attached? Is it guaranteed that if resume is
called, someone will attach a domain before suspend is called?
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 01/13] iommu/rockchip: Request irqs in rk_iommu_probe()
2018-01-17 7:16 ` Tomasz Figa
@ 2018-01-17 7:45 ` JeffyChen
0 siblings, 0 replies; 25+ messages in thread
From: JeffyChen @ 2018-01-17 7:45 UTC (permalink / raw)
To: linux-arm-kernel
Hi Tomasz,
On 01/17/2018 03:16 PM, Tomasz Figa wrote:
>>> >>
>>> >>This lacks consistency. of_irq_count() is used for counting, but
>>> >>platform_get_irq() is used for getting. Either platform_ or of_ API
>>> >>should be used for both and I'd lean for platform_, since it's more
>>> >>general.
>> >
>> >hmmm, right, i was thinking of removing num_irq, and do something like:
>> >while (nr++) {
>> > err = platform_get_irq(dev, nr);
>> > if (err == -EPROBE_DEFER)
>> > break;
>> > if (err < 0)
>> > return err;
>> > ....
>> >}
>> >
>> >but forgot to do that..
> Was there anything wrong with platform_irq_count() used by existing code?
just thought the platform_irq_count might ignore some errors(except for
EPROBE_DEFER):
int platform_irq_count(struct platform_device *dev)
{
int ret, nr = 0;
while ((ret = platform_get_irq(dev, nr)) >= 0)
nr++;
if (ret == -EPROBE_DEFER)
return ret;
return nr;
}
but guess that would not matter..
>
>> >
>>> >>
>>>> >>>+ if (irq < 0) {
>>>> >>>+ dev_err(dev, "Failed to get IRQ, %d\n", irq);
>>>> >>> return -ENXIO;
>>>> >>> }
>>>> >>>+ err = devm_request_irq(iommu->dev, irq, rk_iommu_irq,
>>>> >>>+ IRQF_SHARED, dev_name(dev),
>>>> >>>iommu);
>>>> >>>+ if (err)
>>>> >>>+ return err;
>>>> >>> }
>>> >>
>>> >>
>>> >>Looks like there is some more initialization below. Is the driver okay
>>> >>with the IRQ being potentially fired right here? (Shared IRQ handlers
>>> >>might be run at request_irq() time for testing.)
>>> >>
>> >right, forget about that. maybe we can check iommu->domain not NULL in
>> >rk_iommu_irq()
> Maybe we could just move IRQ requesting to the end of probe?
>
ok, that should work too.
and maybe we should also check power status in the irq handler? if it
get fired after powered off...
> Best regards,
> Tomasz
>
>
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 11/13] iommu/rockchip: Use OF_IOMMU to attach devices automatically
2018-01-17 7:30 ` Tomasz Figa
@ 2018-01-17 7:47 ` JeffyChen
0 siblings, 0 replies; 25+ messages in thread
From: JeffyChen @ 2018-01-17 7:47 UTC (permalink / raw)
To: linux-arm-kernel
On 01/17/2018 03:30 PM, Tomasz Figa wrote:
>> >but it's possible the probe failed after calling iommu_device_set_fwnode, so
>> >i'll try to add some checks here, and maybe adjust probe() to prevent it
>> >too.
> I think iommu_device_set_fwnode() is not enough for of_iommu_xlate()
> to find the IOMMU. The IOMMU is actually added to the IOMMU list by
> iommu_device_register(), which is last in the sequence, so I guess we
> should be fine.
>
hmmm, the later patch would change that ;) i'll fix it in the next version.
> Best regards,
> Tomasz
>
>
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 12/13] iommu/rockchip: Add runtime PM support
2018-01-17 7:38 ` Tomasz Figa
@ 2018-01-17 7:52 ` JeffyChen
2018-01-17 8:48 ` JeffyChen
0 siblings, 1 reply; 25+ messages in thread
From: JeffyChen @ 2018-01-17 7:52 UTC (permalink / raw)
To: linux-arm-kernel
Hi Tomasz,
On 01/17/2018 03:38 PM, Tomasz Figa wrote:
>>> >>Don't we need to check here (and in _shutdown() too) if we have a
>>> >>domain attached?
>> >
>> >hmmm, right, the startup might been called by resume, so should check
>> >iommu->domain here.
>> >
>> >but the shutdown would be called at the end of detach or suspend, it could
>> >be not attached or attached.
> If startup might be called by resume, without domain attached, what
> prevents shutdown from being called by suspend after that resume,
> still without domain attached? Is it guaranteed that if resume is
> called, someone will attach a domain before suspend is called?
>
no, the shutdown would be called by:
1/ end of detach_dev
so it would be not attached at that time
2/ suspend
so it could be attached, and also could be not attached
anyway, i think the shutdown would work without domain attached(just
disable paging and clear the iommu bases) ;)
> Best regards,
> Tomasz
>
>
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 12/13] iommu/rockchip: Add runtime PM support
2018-01-17 7:52 ` JeffyChen
@ 2018-01-17 8:48 ` JeffyChen
0 siblings, 0 replies; 25+ messages in thread
From: JeffyChen @ 2018-01-17 8:48 UTC (permalink / raw)
To: linux-arm-kernel
Hi Tomasz,
On 01/17/2018 03:52 PM, JeffyChen wrote:
> Hi Tomasz,
>
> On 01/17/2018 03:38 PM, Tomasz Figa wrote:
>>>> >>Don't we need to check here (and in _shutdown() too) if we have a
>>>> >>domain attached?
>>> >
>>> >hmmm, right, the startup might been called by resume, so should check
>>> >iommu->domain here.
>>> >
>>> >but the shutdown would be called at the end of detach or suspend, it
>>> could
>>> >be not attached or attached.
>> If startup might be called by resume, without domain attached, what
>> prevents shutdown from being called by suspend after that resume,
>> still without domain attached? Is it guaranteed that if resume is
>> called, someone will attach a domain before suspend is called?
>>
> no, the shutdown would be called by:
> 1/ end of detach_dev
> so it would be not attached at that time
>
> 2/ suspend
> so it could be attached, and also could be not attached
>
>
> anyway, i think the shutdown would work without domain attached(just
> disable paging and clear the iommu bases) ;)
>
hmmm, i see the problem.
so we need to:
1/ move shutdown a little earlier in detach_dev, so it could still see
the iommu->domain
2/ check iommu->domain in shutdown, to prevent unnecessary shutdown
or maybe just add iommu->domain check in suspend and resume.
>> Best regards,
>> Tomasz
>>
>>
>>
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 05/13] iommu/rockchip: Fix error handling in init
2018-01-17 5:26 ` [PATCH v2 05/13] iommu/rockchip: Fix error handling in init Tomasz Figa
[not found] ` <5A5EF7D3.90405@rock-chips.com>
@ 2018-01-17 11:36 ` Robin Murphy
1 sibling, 0 replies; 25+ messages in thread
From: Robin Murphy @ 2018-01-17 11:36 UTC (permalink / raw)
To: linux-arm-kernel
On 17/01/18 05:26, Tomasz Figa wrote:
> On Tue, Jan 16, 2018 at 10:25 PM, Jeffy Chen <jeffy.chen@rock-chips.com> wrote:
>> It's hard to undo bus_set_iommu() in the error path, so move it to the
>> end of rk_iommu_probe().
>
> Does this work fine now? I remember we used to need this called in an
> early initcall for all the ARM/ARM64 DMA stuff to work.
It will do once we get to patch #11 (where the IOMMU_OF_DECLARE ensures
that masters defer until iommu_register() has set ops with a non-NULL
.of_xlate callback); in the meantime you might end up depending on DT
probe order as to whether the master uses the IOMMU or not. I'd say it's
up to you guys whether you consider that a bisection-breaker or not.
Robin.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 01/13] iommu/rockchip: Request irqs in rk_iommu_probe()
[not found] ` <20180116132540.18939-2-jeffy.chen@rock-chips.com>
2018-01-17 4:21 ` [PATCH v2 01/13] iommu/rockchip: Request irqs in rk_iommu_probe() Tomasz Figa
@ 2018-01-17 12:18 ` Robin Murphy
2018-01-17 12:46 ` JeffyChen
1 sibling, 1 reply; 25+ messages in thread
From: Robin Murphy @ 2018-01-17 12:18 UTC (permalink / raw)
To: linux-arm-kernel
On 16/01/18 13:25, Jeffy Chen wrote:
> Suggested-by: Robin Murphy <robin.murphy@arm.com>
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> ---
>
> Changes in v2: None
>
> drivers/iommu/rockchip-iommu.c | 38 +++++++++++---------------------------
> 1 file changed, 11 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 9d991c2d8767..4a12d4746095 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_irq.h>
> #include <linux/of_platform.h>
> #include <linux/platform_device.h>
> #include <linux/slab.h>
> @@ -91,7 +92,6 @@ struct rk_iommu {
> void __iomem **bases;
> int num_mmu;
> int *irq;
Nit: irq seems to be redundant now as well.
> - int num_irq;
> bool reset_disabled;
> struct iommu_device iommu;
> struct list_head node; /* entry in rk_iommu_domain.iommus */
> @@ -830,13 +830,6 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
>
> 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);
> @@ -885,9 +878,6 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
> }
> 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");
> @@ -1138,7 +1128,7 @@ static int rk_iommu_probe(struct platform_device *pdev)
> struct rk_iommu *iommu;
> struct resource *res;
> int num_res = pdev->num_resources;
> - int err, i;
> + int err, i, irq, num_irq;
>
> iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL);
> if (!iommu)
> @@ -1165,23 +1155,17 @@ static int rk_iommu_probe(struct platform_device *pdev)
> if (iommu->num_mmu == 0)
> return PTR_ERR(iommu->bases[0]);
>
> - iommu->num_irq = platform_irq_count(pdev);
> - if (iommu->num_irq < 0)
> - return iommu->num_irq;
> - if (iommu->num_irq == 0)
> - return -ENXIO;
> -
> - iommu->irq = devm_kcalloc(dev, iommu->num_irq, sizeof(*iommu->irq),
> - GFP_KERNEL);
> - if (!iommu->irq)
> - return -ENOMEM;
> -
> - for (i = 0; i < iommu->num_irq; i++) {
> - iommu->irq[i] = platform_get_irq(pdev, i);
> - if (iommu->irq[i] < 0) {
> - dev_err(dev, "Failed to get IRQ, %d\n", iommu->irq[i]);
> + num_irq = of_irq_count(dev->of_node);
To follow up on the other reply, I'm not sure you really need to count
the IRQs beforehand at all - you're going to be looping through
platform_get_irq() and handling errors anyway, so you may as well just
start at 0 and keep going until -ENOENT (or use platform_get_resource()
to double-check whether an index should be valid, as we do in arm_smmu).
Otherwise, it looks like everything that the IRQ handler needs in the
iommu struct (dev, num_mmu and bases) is already initialised by this
point, so we should be OK with respect to races.
Robin.
> + for (i = 0; i < num_irq; i++) {
> + irq = platform_get_irq(pdev, i);
> + if (irq < 0) {
> + dev_err(dev, "Failed to get IRQ, %d\n", irq);
> return -ENXIO;
> }
> + err = devm_request_irq(iommu->dev, irq, rk_iommu_irq,
> + IRQF_SHARED, dev_name(dev), iommu);
> + if (err)
> + return err;
> }
>
> iommu->reset_disabled = device_property_read_bool(dev,
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 05/13] iommu/rockchip: Fix error handling in init
2018-01-17 7:19 ` Tomasz Figa
@ 2018-01-17 12:27 ` Tomasz Figa
0 siblings, 0 replies; 25+ messages in thread
From: Tomasz Figa @ 2018-01-17 12:27 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Jan 17, 2018 at 4:19 PM, Tomasz Figa <tfiga@chromium.org> wrote:
>
> P.S. Looks like your email client is set to HTML messages. Your
> messages might end up dropped from the mailing list.
Never mind. Looks like gmail started displaying quotations in plain
text as graphics.
Best regards,
Tomasz
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 09/13] iommu/rockchip: Use iommu_group_get_for_dev() for add_device
[not found] ` <20180116132540.18939-10-jeffy.chen@rock-chips.com>
@ 2018-01-17 12:31 ` Robin Murphy
2018-01-17 12:47 ` JeffyChen
0 siblings, 1 reply; 25+ messages in thread
From: Robin Murphy @ 2018-01-17 12:31 UTC (permalink / raw)
To: linux-arm-kernel
On 16/01/18 13:25, Jeffy Chen wrote:
> 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.
FWIW that's not 100% true: what arm64 relies on is the group having a
default DMA ops domain. Technically, you *could* open-code that in the
driver's group allocation, but obviously using the appropriate existing
API is nicer :)
[...]
> @@ -1182,6 +1164,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) {
This check is pointless - if dev->iommu_group were non-NULL you wouldn't
have been called in the first place.
Robin.
> + 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,
> @@ -1193,6 +1198,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,
> };
>
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 01/13] iommu/rockchip: Request irqs in rk_iommu_probe()
2018-01-17 12:18 ` Robin Murphy
@ 2018-01-17 12:46 ` JeffyChen
0 siblings, 0 replies; 25+ messages in thread
From: JeffyChen @ 2018-01-17 12:46 UTC (permalink / raw)
To: linux-arm-kernel
Hi Robin,
On 01/17/2018 08:18 PM, Robin Murphy wrote:
>>
>> @@ -91,7 +92,6 @@ struct rk_iommu {
>> void __iomem **bases;
>> int num_mmu;
>> int *irq;
>
> Nit: irq seems to be redundant now as well.
oops, will fix it.
>
>> - int num_irq;
>> bool reset_disabled;
>> struct iommu_device iommu;
>> struct list_head node; /* entry in rk_iommu_domain.iommus */
>> @@ -830,13 +830,6 @@ static int rk_iommu_attach_device(struct
>> iommu_domain *domain,
>> 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);
>> @@ -885,9 +878,6 @@ static void rk_iommu_detach_device(struct
>> iommu_domain *domain,
>> }
>> 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");
>> @@ -1138,7 +1128,7 @@ static int rk_iommu_probe(struct platform_device
>> *pdev)
>> struct rk_iommu *iommu;
>> struct resource *res;
>> int num_res = pdev->num_resources;
>> - int err, i;
>> + int err, i, irq, num_irq;
>> iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL);
>> if (!iommu)
>> @@ -1165,23 +1155,17 @@ static int rk_iommu_probe(struct
>> platform_device *pdev)
>> if (iommu->num_mmu == 0)
>> return PTR_ERR(iommu->bases[0]);
>> - iommu->num_irq = platform_irq_count(pdev);
>> - if (iommu->num_irq < 0)
>> - return iommu->num_irq;
>> - if (iommu->num_irq == 0)
>> - return -ENXIO;
>> -
>> - iommu->irq = devm_kcalloc(dev, iommu->num_irq, sizeof(*iommu->irq),
>> - GFP_KERNEL);
>> - if (!iommu->irq)
>> - return -ENOMEM;
>> -
>> - for (i = 0; i < iommu->num_irq; i++) {
>> - iommu->irq[i] = platform_get_irq(pdev, i);
>> - if (iommu->irq[i] < 0) {
>> - dev_err(dev, "Failed to get IRQ, %d\n", iommu->irq[i]);
>> + num_irq = of_irq_count(dev->of_node);
>
> To follow up on the other reply, I'm not sure you really need to count
> the IRQs beforehand at all - you're going to be looping through
> platform_get_irq() and handling errors anyway, so you may as well just
> start at 0 and keep going until -ENOENT (or use platform_get_resource()
> to double-check whether an index should be valid, as we do in arm_smmu).
ok, will do that.
>
> Otherwise, it looks like everything that the IRQ handler needs in the
> iommu struct (dev, num_mmu and bases) is already initialised by this
> point, so we should be OK with respect to races.
ok.
>
> Robin.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 09/13] iommu/rockchip: Use iommu_group_get_for_dev() for add_device
2018-01-17 12:31 ` [PATCH v2 09/13] iommu/rockchip: Use iommu_group_get_for_dev() for add_device Robin Murphy
@ 2018-01-17 12:47 ` JeffyChen
2018-01-17 12:53 ` JeffyChen
0 siblings, 1 reply; 25+ messages in thread
From: JeffyChen @ 2018-01-17 12:47 UTC (permalink / raw)
To: linux-arm-kernel
Hi Robin,
On 01/17/2018 08:31 PM, Robin Murphy wrote:
> On 16/01/18 13:25, Jeffy Chen wrote:
>> 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.
>
> FWIW that's not 100% true: what arm64 relies on is the group having a
> default DMA ops domain. Technically, you *could* open-code that in the
> driver's group allocation, but obviously using the appropriate existing
> API is nicer :)
ok, will rewrite the commit message.
>
> [...]
>> @@ -1182,6 +1164,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) {
>
> This check is pointless - if dev->iommu_group were non-NULL you wouldn't
> have been called in the first place.
right, it's allocated in the probe.
>
> Robin.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 09/13] iommu/rockchip: Use iommu_group_get_for_dev() for add_device
2018-01-17 12:47 ` JeffyChen
@ 2018-01-17 12:53 ` JeffyChen
0 siblings, 0 replies; 25+ messages in thread
From: JeffyChen @ 2018-01-17 12:53 UTC (permalink / raw)
To: linux-arm-kernel
On 01/17/2018 08:47 PM, JeffyChen wrote:
>>>
>>> +static struct iommu_group *rk_iommu_device_group(struct device *dev)
>>> +{
>>> + struct iommu_group *group;
>>> + int ret;
>>> +
>>> + group = iommu_group_get(dev);
>>> + if (!group) {
>>
>> This check is pointless - if dev->iommu_group were non-NULL you wouldn't
>> have been called in the first place.
> right, it's allocated in the probe.
oops, sorry, i see, this is not needed because device_group() is only be
called when iommu_group_get() returns NULL
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 13/13] iommu/rockchip: Support sharing IOMMU between masters
[not found] ` <20180116132540.18939-14-jeffy.chen@rock-chips.com>
@ 2018-01-17 13:00 ` Robin Murphy
2018-01-17 13:32 ` JeffyChen
0 siblings, 1 reply; 25+ messages in thread
From: Robin Murphy @ 2018-01-17 13:00 UTC (permalink / raw)
To: linux-arm-kernel
On 16/01/18 13:25, Jeffy Chen wrote:
> There would be some masters sharing the same IOMMU device. Put them in
> the same iommu group and share the same iommu domain.
>
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> ---
>
> Changes in v2: None
>
> drivers/iommu/rockchip-iommu.c | 39 +++++++++++++++++++++++++++++++--------
> 1 file changed, 31 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index c8de1456a016..6c316dd0dd2d 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -100,11 +100,13 @@ struct rk_iommu {
> struct iommu_device iommu;
> struct list_head node; /* entry in rk_iommu_domain.iommus */
> struct iommu_domain *domain; /* domain to which iommu is attached */
> + struct iommu_group *group;
> struct mutex pm_mutex; /* serializes power transitions */
> };
>
> struct rk_iommudata {
> struct device_link *link; /* runtime PM link from IOMMU to master */
> + struct iommu_domain *domain; /* domain to which device is attached */
I don't see why this is needed - for example, mtk_iommu does the same
thing without needing to track the active domain in more than one place.
Fundamentally, for this kind of IOMMU without the notion of multiple
translation contexts, the logic should look like:
iommudrv_attach_device(dev, domain) {
iommu = dev_get_iommu(dev);
if (iommu->curr_domain != domain) {
update_hw_state(iommu, domain);
iommu->curr_domain = domain;
}
}
which I think is essentially what you have anyway. When a group contains
multiple devices, you update the IOMMU state for the first device, then
calls for subsequent devices in the group do nothing since they see the
IOMMU state is already up-to-date with the new domain.
Robin.
> struct rk_iommu *iommu;
> };
>
> @@ -964,6 +966,7 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
> {
> struct rk_iommu *iommu;
> struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
> + struct rk_iommudata *data = dev->archdata.iommu;
> unsigned long flags;
>
> /* Allow 'virtual devices' (eg drm) to detach from domain */
> @@ -971,6 +974,12 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
> if (!iommu)
> return;
>
> + /* device already detached */
> + if (data->domain != domain)
> + return;
> +
> + data->domain = NULL;
> +
> dev_dbg(dev, "Detaching from iommu domain\n");
>
> /* iommu already detached */
> @@ -994,6 +1003,7 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
> {
> struct rk_iommu *iommu;
> struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
> + struct rk_iommudata *data = dev->archdata.iommu;
> unsigned long flags;
> int ret;
>
> @@ -1005,15 +1015,21 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
> if (!iommu)
> return 0;
>
> + /* device already attached */
> + if (data->domain == domain)
> + return 0;
> +
> + if (data->domain)
> + rk_iommu_detach_device(data->domain, dev);
> +
> + data->domain = domain;
> +
> dev_dbg(dev, "Attaching to iommu domain\n");
>
> /* iommu already attached */
> if (iommu->domain == domain)
> return 0;
>
> - if (iommu->domain)
> - rk_iommu_detach_device(iommu->domain, dev);
> -
> iommu->domain = domain;
>
> spin_lock_irqsave(&rk_domain->iommus_lock, flags);
> @@ -1150,13 +1166,11 @@ static void rk_iommu_remove_device(struct device *dev)
>
> static struct iommu_group *rk_iommu_device_group(struct device *dev)
> {
> - struct iommu_group *group;
> + struct rk_iommu *iommu;
>
> - group = iommu_group_get(dev);
> - if (!group)
> - group = iommu_group_alloc();
> + iommu = rk_iommu_from_dev(dev);
>
> - return group;
> + return iommu ? iommu->group : NULL;
> }
>
> static int rk_iommu_of_xlate(struct device *dev,
> @@ -1263,6 +1277,12 @@ static int rk_iommu_probe(struct platform_device *pdev)
> if (err)
> goto err_remove_sysfs;
>
> + iommu->group = iommu_group_alloc();
> + if (IS_ERR(iommu->group)) {
> + err = PTR_ERR(iommu->group);
> + goto err_unreg_iommu;
> + }
> +
> /*
> * Use the first registered IOMMU device for domain to use with DMA
> * API, since a domain might not physically correspond to a single
> @@ -1276,6 +1296,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
> pm_runtime_enable(dev);
>
> return 0;
> +err_unreg_iommu:
> + iommu_device_unregister(&iommu->iommu);
> err_remove_sysfs:
> iommu_device_sysfs_remove(&iommu->iommu);
> err_put_clocks:
> @@ -1289,6 +1311,7 @@ static int rk_iommu_remove(struct platform_device *pdev)
>
> pm_runtime_disable(&pdev->dev);
>
> + iommu_group_put(iommu->group);
> iommu_device_unregister(&iommu->iommu);
> iommu_device_sysfs_remove(&iommu->iommu);
> rk_iommu_put_clocks(iommu);
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 13/13] iommu/rockchip: Support sharing IOMMU between masters
2018-01-17 13:00 ` [PATCH v2 13/13] iommu/rockchip: Support sharing IOMMU between masters Robin Murphy
@ 2018-01-17 13:32 ` JeffyChen
0 siblings, 0 replies; 25+ messages in thread
From: JeffyChen @ 2018-01-17 13:32 UTC (permalink / raw)
To: linux-arm-kernel
Hi Robin,
On 01/17/2018 09:00 PM, Robin Murphy wrote:
> On 16/01/18 13:25, Jeffy Chen wrote:
>> There would be some masters sharing the same IOMMU device. Put them in
>> the same iommu group and share the same iommu domain.
>>
>> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
>> ---
>>
>> Changes in v2: None
>>
>> drivers/iommu/rockchip-iommu.c | 39
>> +++++++++++++++++++++++++++++++--------
>> 1 file changed, 31 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/iommu/rockchip-iommu.c
>> b/drivers/iommu/rockchip-iommu.c
>> index c8de1456a016..6c316dd0dd2d 100644
>> --- a/drivers/iommu/rockchip-iommu.c
>> +++ b/drivers/iommu/rockchip-iommu.c
>> @@ -100,11 +100,13 @@ struct rk_iommu {
>> struct iommu_device iommu;
>> struct list_head node; /* entry in rk_iommu_domain.iommus */
>> struct iommu_domain *domain; /* domain to which iommu is
>> attached */
>> + struct iommu_group *group;
>> struct mutex pm_mutex; /* serializes power transitions */
>> };
>> struct rk_iommudata {
>> struct device_link *link; /* runtime PM link from IOMMU to
>> master */
>> + struct iommu_domain *domain; /* domain to which device is
>> attached */
>
> I don't see why this is needed - for example, mtk_iommu does the same
> thing without needing to track the active domain in more than one place.
>
> Fundamentally, for this kind of IOMMU without the notion of multiple
> translation contexts, the logic should look like:
>
> iommudrv_attach_device(dev, domain) {
> iommu = dev_get_iommu(dev);
> if (iommu->curr_domain != domain) {
> update_hw_state(iommu, domain);
> iommu->curr_domain = domain;
> }
> }
>
> which I think is essentially what you have anyway. When a group contains
> multiple devices, you update the IOMMU state for the first device, then
> calls for subsequent devices in the group do nothing since they see the
> IOMMU state is already up-to-date with the new domain.
>
right, will remove it.
> Robin.
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2018-01-17 13:32 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20180116132540.18939-1-jeffy.chen@rock-chips.com>
[not found] ` <20180116132540.18939-3-jeffy.chen@rock-chips.com>
2018-01-17 4:23 ` [PATCH v2 02/13] iommu/rockchip: Suppress unbinding Tomasz Figa
2018-01-17 5:32 ` Tomasz Figa
[not found] ` <20180116132540.18939-5-jeffy.chen@rock-chips.com>
2018-01-17 5:22 ` [PATCH v2 04/13] iommu/rockchip: Fix error handling in probe Tomasz Figa
[not found] ` <20180116132540.18939-6-jeffy.chen@rock-chips.com>
2018-01-17 5:26 ` [PATCH v2 05/13] iommu/rockchip: Fix error handling in init Tomasz Figa
[not found] ` <5A5EF7D3.90405@rock-chips.com>
2018-01-17 7:19 ` Tomasz Figa
2018-01-17 12:27 ` Tomasz Figa
2018-01-17 11:36 ` Robin Murphy
[not found] ` <20180116132540.18939-11-jeffy.chen@rock-chips.com>
2018-01-17 5:37 ` [PATCH v2 10/13] iommu/rockchip: Use IOMMU device for dma mapping operations Tomasz Figa
[not found] ` <20180116132540.18939-12-jeffy.chen@rock-chips.com>
2018-01-17 5:44 ` [PATCH v2 11/13] iommu/rockchip: Use OF_IOMMU to attach devices automatically Tomasz Figa
[not found] ` <5A5EF94E.7010806@rock-chips.com>
2018-01-17 7:30 ` Tomasz Figa
2018-01-17 7:47 ` JeffyChen
[not found] ` <20180116132540.18939-13-jeffy.chen@rock-chips.com>
2018-01-17 6:20 ` [PATCH v2 12/13] iommu/rockchip: Add runtime PM support Tomasz Figa
[not found] ` <5A5EFAB2.7040001@rock-chips.com>
2018-01-17 7:38 ` Tomasz Figa
2018-01-17 7:52 ` JeffyChen
2018-01-17 8:48 ` JeffyChen
[not found] ` <20180116132540.18939-2-jeffy.chen@rock-chips.com>
2018-01-17 4:21 ` [PATCH v2 01/13] iommu/rockchip: Request irqs in rk_iommu_probe() Tomasz Figa
[not found] ` <5A5EF672.6040304@rock-chips.com>
2018-01-17 7:16 ` Tomasz Figa
2018-01-17 7:45 ` JeffyChen
2018-01-17 12:18 ` Robin Murphy
2018-01-17 12:46 ` JeffyChen
[not found] ` <20180116132540.18939-10-jeffy.chen@rock-chips.com>
2018-01-17 12:31 ` [PATCH v2 09/13] iommu/rockchip: Use iommu_group_get_for_dev() for add_device Robin Murphy
2018-01-17 12:47 ` JeffyChen
2018-01-17 12:53 ` JeffyChen
[not found] ` <20180116132540.18939-14-jeffy.chen@rock-chips.com>
2018-01-17 13:00 ` [PATCH v2 13/13] iommu/rockchip: Support sharing IOMMU between masters Robin Murphy
2018-01-17 13:32 ` JeffyChen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).