[2/2] iommu/arm-smmu: Allow client devices to select direct mapping
diff mbox series

Message ID 813cc5b2da10c27db982254b274bf26008a9e6da.1579692800.git.saiprakash.ranjan@codeaurora.org
State New
Headers show
Series
  • iommu/arm-smmu: Allow client devices to select direct mapping
Related show

Commit Message

Sai Prakash Ranjan Jan. 22, 2020, 11:48 a.m. UTC
From: Jordan Crouse <jcrouse@codeaurora.org>

Some client devices want to directly map the IOMMU themselves instead
of using the DMA domain. Allow those devices to opt in to direct
mapping by way of a list of compatible strings.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Co-developed-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
---
 drivers/iommu/arm-smmu-qcom.c | 39 +++++++++++++++++++++++++++++++++++
 drivers/iommu/arm-smmu.c      |  3 +++
 drivers/iommu/arm-smmu.h      |  5 +++++
 3 files changed, 47 insertions(+)

Comments

Evan Green April 13, 2020, 11:12 p.m. UTC | #1
On Wed, Jan 22, 2020 at 3:48 AM Sai Prakash Ranjan
<saiprakash.ranjan@codeaurora.org> wrote:
>
> From: Jordan Crouse <jcrouse@codeaurora.org>
>
> Some client devices want to directly map the IOMMU themselves instead
> of using the DMA domain. Allow those devices to opt in to direct
> mapping by way of a list of compatible strings.
>
> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
> Co-developed-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
> ---
>  drivers/iommu/arm-smmu-qcom.c | 39 +++++++++++++++++++++++++++++++++++
>  drivers/iommu/arm-smmu.c      |  3 +++
>  drivers/iommu/arm-smmu.h      |  5 +++++
>  3 files changed, 47 insertions(+)
>
> diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
> index 64a4ab270ab7..ff746acd1c81 100644
> --- a/drivers/iommu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm-smmu-qcom.c
> @@ -3,6 +3,7 @@
>   * Copyright (c) 2019, The Linux Foundation. All rights reserved.
>   */
>
> +#include <linux/of_device.h>
>  #include <linux/qcom_scm.h>
>
>  #include "arm-smmu.h"
> @@ -11,6 +12,43 @@ struct qcom_smmu {
>         struct arm_smmu_device smmu;
>  };
>
> +static const struct arm_smmu_client_match_data qcom_adreno = {
> +       .direct_mapping = true,
> +};
> +
> +static const struct arm_smmu_client_match_data qcom_mdss = {
> +       .direct_mapping = true,

I don't actually see direct_mapping being used. Shouldn't this member
be checked somewhere?

-Evan
Sai Prakash Ranjan April 14, 2020, 4:18 p.m. UTC | #2
Hi Evan,

On 2020-04-14 04:42, Evan Green wrote:
> On Wed, Jan 22, 2020 at 3:48 AM Sai Prakash Ranjan
> <saiprakash.ranjan@codeaurora.org> wrote:
>> 
>> From: Jordan Crouse <jcrouse@codeaurora.org>
>> 
>> Some client devices want to directly map the IOMMU themselves instead
>> of using the DMA domain. Allow those devices to opt in to direct
>> mapping by way of a list of compatible strings.
>> 
>> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
>> Co-developed-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
>> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
>> ---
>>  drivers/iommu/arm-smmu-qcom.c | 39 
>> +++++++++++++++++++++++++++++++++++
>>  drivers/iommu/arm-smmu.c      |  3 +++
>>  drivers/iommu/arm-smmu.h      |  5 +++++
>>  3 files changed, 47 insertions(+)
>> 
>> diff --git a/drivers/iommu/arm-smmu-qcom.c 
>> b/drivers/iommu/arm-smmu-qcom.c
>> index 64a4ab270ab7..ff746acd1c81 100644
>> --- a/drivers/iommu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm-smmu-qcom.c
>> @@ -3,6 +3,7 @@
>>   * Copyright (c) 2019, The Linux Foundation. All rights reserved.
>>   */
>> 
>> +#include <linux/of_device.h>
>>  #include <linux/qcom_scm.h>
>> 
>>  #include "arm-smmu.h"
>> @@ -11,6 +12,43 @@ struct qcom_smmu {
>>         struct arm_smmu_device smmu;
>>  };
>> 
>> +static const struct arm_smmu_client_match_data qcom_adreno = {
>> +       .direct_mapping = true,
>> +};
>> +
>> +static const struct arm_smmu_client_match_data qcom_mdss = {
>> +       .direct_mapping = true,
> 
> I don't actually see direct_mapping being used. Shouldn't this member
> be checked somewhere?
> 

Thanks for spotting this, my bad. It should be checked in 
qcom_smmu_request_domain().

diff --git a/drivers/iommu/arm-smmu-qcom.c 
b/drivers/iommu/arm-smmu-qcom.c
index ff746acd1c81..3ff62ca13ad5 100644
--- a/drivers/iommu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm-smmu-qcom.c
@@ -43,7 +43,7 @@ static int qcom_smmu_request_domain(struct device 
*dev)
         const struct arm_smmu_client_match_data *client;

         client = qcom_smmu_client_data(dev);
-       if (client)
+       if (client && client->direct_mapping)
                 iommu_request_dm_for_dev(dev);

         return 0;

-Sai
Robin Murphy April 16, 2020, 1:58 p.m. UTC | #3
On 2020-01-22 11:48 am, Sai Prakash Ranjan wrote:
> From: Jordan Crouse <jcrouse@codeaurora.org>
> 
> Some client devices want to directly map the IOMMU themselves instead
> of using the DMA domain. Allow those devices to opt in to direct
> mapping by way of a list of compatible strings.
> 
> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
> Co-developed-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
> ---
>   drivers/iommu/arm-smmu-qcom.c | 39 +++++++++++++++++++++++++++++++++++
>   drivers/iommu/arm-smmu.c      |  3 +++
>   drivers/iommu/arm-smmu.h      |  5 +++++
>   3 files changed, 47 insertions(+)
> 
> diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
> index 64a4ab270ab7..ff746acd1c81 100644
> --- a/drivers/iommu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm-smmu-qcom.c
> @@ -3,6 +3,7 @@
>    * Copyright (c) 2019, The Linux Foundation. All rights reserved.
>    */
>   
> +#include <linux/of_device.h>
>   #include <linux/qcom_scm.h>
>   
>   #include "arm-smmu.h"
> @@ -11,6 +12,43 @@ struct qcom_smmu {
>   	struct arm_smmu_device smmu;
>   };
>   
> +static const struct arm_smmu_client_match_data qcom_adreno = {
> +	.direct_mapping = true,
> +};
> +
> +static const struct arm_smmu_client_match_data qcom_mdss = {
> +	.direct_mapping = true,
> +};

Might it make sense to group these by the desired SMMU behaviour rather 
than (apparently) what kind of device the client happens to be, which 
seems like a completely arbitrary distinction from the SMMU driver's PoV?

> +
> +static const struct of_device_id qcom_smmu_client_of_match[] = {
> +	{ .compatible = "qcom,adreno", .data = &qcom_adreno },
> +	{ .compatible = "qcom,mdp4", .data = &qcom_mdss },
> +	{ .compatible = "qcom,mdss", .data = &qcom_mdss },
> +	{ .compatible = "qcom,sc7180-mdss", .data = &qcom_mdss },
> +	{ .compatible = "qcom,sdm845-mdss", .data = &qcom_mdss },
> +	{},
> +};
> +
> +static const struct arm_smmu_client_match_data *
> +qcom_smmu_client_data(struct device *dev)
> +{
> +	const struct of_device_id *match =
> +		of_match_device(qcom_smmu_client_of_match, dev);
> +
> +	return match ? match->data : NULL;

of_device_get_match_data() is your friend.

> +}
> +
> +static int qcom_smmu_request_domain(struct device *dev)
> +{
> +	const struct arm_smmu_client_match_data *client;
> +
> +	client = qcom_smmu_client_data(dev);
> +	if (client)
> +		iommu_request_dm_for_dev(dev);
> +
> +	return 0;
> +}
> +
>   static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
>   {
>   	int ret;
> @@ -41,6 +79,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
>   }
>   
>   static const struct arm_smmu_impl qcom_smmu_impl = {
> +	.req_domain = qcom_smmu_request_domain,
>   	.reset = qcom_smmu500_reset,
>   };
>   
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 16c4b87af42b..67dd9326247a 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -1448,6 +1448,9 @@ static int arm_smmu_add_device(struct device *dev)
>   	device_link_add(dev, smmu->dev,
>   			DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
>   
> +	if (smmu->impl && smmu->impl->req_domain)
> +		return smmu->impl->req_domain(dev);
> +

There are about 5 different patchsets flying around at the moment that 
all touch default domain allocation, so this is a fast-moving target, 
but I think where the dust should settle is with arm_smmu_ops forwarding 
.def_domain_type (or whatever it ends up as) calls to arm_smmu_impl as 
appropriate.

>   	return 0;
>   
>   out_cfg_free:
> diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
> index 8d1cd54d82a6..059dc9c39f64 100644
> --- a/drivers/iommu/arm-smmu.h
> +++ b/drivers/iommu/arm-smmu.h
> @@ -244,6 +244,10 @@ enum arm_smmu_arch_version {
>   	ARM_SMMU_V2,
>   };
>   
> +struct arm_smmu_client_match_data {
> +	bool direct_mapping;
> +};

Does this need to be public? I don't see the other users...

Robin.

> +
>   enum arm_smmu_implementation {
>   	GENERIC_SMMU,
>   	ARM_MMU500,
> @@ -386,6 +390,7 @@ struct arm_smmu_impl {
>   	int (*init_context)(struct arm_smmu_domain *smmu_domain);
>   	void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync,
>   			 int status);
> +	int (*req_domain)(struct device *dev);
>   };
>   
>   static inline void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n)
>
Sai Prakash Ranjan April 16, 2020, 4:23 p.m. UTC | #4
Hi Robin,

On 2020-04-16 19:28, Robin Murphy wrote:
> On 2020-01-22 11:48 am, Sai Prakash Ranjan wrote:
>> From: Jordan Crouse <jcrouse@codeaurora.org>
>> 
>> Some client devices want to directly map the IOMMU themselves instead
>> of using the DMA domain. Allow those devices to opt in to direct
>> mapping by way of a list of compatible strings.
>> 
>> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
>> Co-developed-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
>> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
>> ---
>>   drivers/iommu/arm-smmu-qcom.c | 39 
>> +++++++++++++++++++++++++++++++++++
>>   drivers/iommu/arm-smmu.c      |  3 +++
>>   drivers/iommu/arm-smmu.h      |  5 +++++
>>   3 files changed, 47 insertions(+)
>> 
>> diff --git a/drivers/iommu/arm-smmu-qcom.c 
>> b/drivers/iommu/arm-smmu-qcom.c
>> index 64a4ab270ab7..ff746acd1c81 100644
>> --- a/drivers/iommu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm-smmu-qcom.c
>> @@ -3,6 +3,7 @@
>>    * Copyright (c) 2019, The Linux Foundation. All rights reserved.
>>    */
>>   +#include <linux/of_device.h>
>>   #include <linux/qcom_scm.h>
>>     #include "arm-smmu.h"
>> @@ -11,6 +12,43 @@ struct qcom_smmu {
>>   	struct arm_smmu_device smmu;
>>   };
>>   +static const struct arm_smmu_client_match_data qcom_adreno = {
>> +	.direct_mapping = true,
>> +};
>> +
>> +static const struct arm_smmu_client_match_data qcom_mdss = {
>> +	.direct_mapping = true,
>> +};
> 
> Might it make sense to group these by the desired SMMU behaviour
> rather than (apparently) what kind of device the client happens to be,
> which seems like a completely arbitrary distinction from the SMMU
> driver's PoV?
> 

Sorry, I did not get the "grouping by the desired SMMU behaviour" thing.
Could you please give some more details?

>> +
>> +static const struct of_device_id qcom_smmu_client_of_match[] = {
>> +	{ .compatible = "qcom,adreno", .data = &qcom_adreno },
>> +	{ .compatible = "qcom,mdp4", .data = &qcom_mdss },
>> +	{ .compatible = "qcom,mdss", .data = &qcom_mdss },
>> +	{ .compatible = "qcom,sc7180-mdss", .data = &qcom_mdss },
>> +	{ .compatible = "qcom,sdm845-mdss", .data = &qcom_mdss },
>> +	{},
>> +};
>> +
>> +static const struct arm_smmu_client_match_data *
>> +qcom_smmu_client_data(struct device *dev)
>> +{
>> +	const struct of_device_id *match =
>> +		of_match_device(qcom_smmu_client_of_match, dev);
>> +
>> +	return match ? match->data : NULL;
> 
> of_device_get_match_data() is your friend.
> 

Ok will use it.

>> +}
>> +
>> +static int qcom_smmu_request_domain(struct device *dev)
>> +{
>> +	const struct arm_smmu_client_match_data *client;
>> +
>> +	client = qcom_smmu_client_data(dev);
>> +	if (client)
>> +		iommu_request_dm_for_dev(dev);
>> +
>> +	return 0;
>> +}
>> +
>>   static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
>>   {
>>   	int ret;
>> @@ -41,6 +79,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device 
>> *smmu)
>>   }
>>     static const struct arm_smmu_impl qcom_smmu_impl = {
>> +	.req_domain = qcom_smmu_request_domain,
>>   	.reset = qcom_smmu500_reset,
>>   };
>>   diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index 16c4b87af42b..67dd9326247a 100644
>> --- a/drivers/iommu/arm-smmu.c
>> +++ b/drivers/iommu/arm-smmu.c
>> @@ -1448,6 +1448,9 @@ static int arm_smmu_add_device(struct device 
>> *dev)
>>   	device_link_add(dev, smmu->dev,
>>   			DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
>>   +	if (smmu->impl && smmu->impl->req_domain)
>> +		return smmu->impl->req_domain(dev);
>> +
> 
> There are about 5 different patchsets flying around at the moment that
> all touch default domain allocation, so this is a fast-moving target,
> but I think where the dust should settle is with arm_smmu_ops
> forwarding .def_domain_type (or whatever it ends up as) calls to
> arm_smmu_impl as appropriate.
> 

I'll wait till the dust settles down and then post the next version.

>>   	return 0;
>>     out_cfg_free:
>> diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
>> index 8d1cd54d82a6..059dc9c39f64 100644
>> --- a/drivers/iommu/arm-smmu.h
>> +++ b/drivers/iommu/arm-smmu.h
>> @@ -244,6 +244,10 @@ enum arm_smmu_arch_version {
>>   	ARM_SMMU_V2,
>>   };
>>   +struct arm_smmu_client_match_data {
>> +	bool direct_mapping;
>> +};
> 
> Does this need to be public? I don't see the other users...
> 

Will move this out.

Thanks,
Sai
Robin Murphy April 16, 2020, 5:17 p.m. UTC | #5
On 2020-04-16 5:23 pm, Sai Prakash Ranjan wrote:
> Hi Robin,
> 
> On 2020-04-16 19:28, Robin Murphy wrote:
>> On 2020-01-22 11:48 am, Sai Prakash Ranjan wrote:
>>> From: Jordan Crouse <jcrouse@codeaurora.org>
>>>
>>> Some client devices want to directly map the IOMMU themselves instead
>>> of using the DMA domain. Allow those devices to opt in to direct
>>> mapping by way of a list of compatible strings.
>>>
>>> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
>>> Co-developed-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
>>> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
>>> ---
>>>   drivers/iommu/arm-smmu-qcom.c | 39 +++++++++++++++++++++++++++++++++++
>>>   drivers/iommu/arm-smmu.c      |  3 +++
>>>   drivers/iommu/arm-smmu.h      |  5 +++++
>>>   3 files changed, 47 insertions(+)
>>>
>>> diff --git a/drivers/iommu/arm-smmu-qcom.c 
>>> b/drivers/iommu/arm-smmu-qcom.c
>>> index 64a4ab270ab7..ff746acd1c81 100644
>>> --- a/drivers/iommu/arm-smmu-qcom.c
>>> +++ b/drivers/iommu/arm-smmu-qcom.c
>>> @@ -3,6 +3,7 @@
>>>    * Copyright (c) 2019, The Linux Foundation. All rights reserved.
>>>    */
>>>   +#include <linux/of_device.h>
>>>   #include <linux/qcom_scm.h>
>>>     #include "arm-smmu.h"
>>> @@ -11,6 +12,43 @@ struct qcom_smmu {
>>>       struct arm_smmu_device smmu;
>>>   };
>>>   +static const struct arm_smmu_client_match_data qcom_adreno = {
>>> +    .direct_mapping = true,
>>> +};
>>> +
>>> +static const struct arm_smmu_client_match_data qcom_mdss = {
>>> +    .direct_mapping = true,
>>> +};
>>
>> Might it make sense to group these by the desired SMMU behaviour
>> rather than (apparently) what kind of device the client happens to be,
>> which seems like a completely arbitrary distinction from the SMMU
>> driver's PoV?
>>
> 
> Sorry, I did not get the "grouping by the desired SMMU behaviour" thing.
> Could you please give some more details?

I mean this pattern:

device_a_data {
	.thing = this;
}

device_b_data {
	.thing = this;
}

device_c_data {
	.thing = that;
}

match[] = {
	{ .compatible = "A", .data = &device_a_data },
	{ .compatible = "B", .data = &device_b_data },
	{ .compatible = "C", .data = &device_c_data },
};

...vs. this pattern:

do_this {
	.thing = this;
}

do_that {
	.thing = that;
}

match[] = {
	{ .compatible = "A", .data = &do_this },
	{ .compatible = "B", .data = &do_this },
	{ .compatible = "C", .data = &do_that },
};

 From the perspective of the thing doing the thing, grouping the data by 
device is meaningless if all that matters is whether to do this or that. 
The second pattern expresses that more naturally.

Of course if every device turns out to need a unique combination of 
several behaviours, then there ends up being no practical difference 
except that it's probably easier to come up with nice names under the 
first pattern. I guess it's up to how you see this developing in future; 
whether you're likely to need fine-grained per-device control, or don't 
expect it to go much beyond domain type.

Robin.
Sai Prakash Ranjan April 16, 2020, 5:43 p.m. UTC | #6
Hi Robin,

On 2020-04-16 22:47, Robin Murphy wrote:
> On 2020-04-16 5:23 pm, Sai Prakash Ranjan wrote:
>> Hi Robin,
>> 
>> On 2020-04-16 19:28, Robin Murphy wrote:
>>> On 2020-01-22 11:48 am, Sai Prakash Ranjan wrote:
>>>> From: Jordan Crouse <jcrouse@codeaurora.org>
>>>> 
>>>> Some client devices want to directly map the IOMMU themselves 
>>>> instead
>>>> of using the DMA domain. Allow those devices to opt in to direct
>>>> mapping by way of a list of compatible strings.
>>>> 
>>>> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
>>>> Co-developed-by: Sai Prakash Ranjan 
>>>> <saiprakash.ranjan@codeaurora.org>
>>>> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
>>>> ---
>>>>   drivers/iommu/arm-smmu-qcom.c | 39 
>>>> +++++++++++++++++++++++++++++++++++
>>>>   drivers/iommu/arm-smmu.c      |  3 +++
>>>>   drivers/iommu/arm-smmu.h      |  5 +++++
>>>>   3 files changed, 47 insertions(+)
>>>> 
>>>> diff --git a/drivers/iommu/arm-smmu-qcom.c 
>>>> b/drivers/iommu/arm-smmu-qcom.c
>>>> index 64a4ab270ab7..ff746acd1c81 100644
>>>> --- a/drivers/iommu/arm-smmu-qcom.c
>>>> +++ b/drivers/iommu/arm-smmu-qcom.c
>>>> @@ -3,6 +3,7 @@
>>>>    * Copyright (c) 2019, The Linux Foundation. All rights reserved.
>>>>    */
>>>>   +#include <linux/of_device.h>
>>>>   #include <linux/qcom_scm.h>
>>>>     #include "arm-smmu.h"
>>>> @@ -11,6 +12,43 @@ struct qcom_smmu {
>>>>       struct arm_smmu_device smmu;
>>>>   };
>>>>   +static const struct arm_smmu_client_match_data qcom_adreno = {
>>>> +    .direct_mapping = true,
>>>> +};
>>>> +
>>>> +static const struct arm_smmu_client_match_data qcom_mdss = {
>>>> +    .direct_mapping = true,
>>>> +};
>>> 
>>> Might it make sense to group these by the desired SMMU behaviour
>>> rather than (apparently) what kind of device the client happens to 
>>> be,
>>> which seems like a completely arbitrary distinction from the SMMU
>>> driver's PoV?
>>> 
>> 
>> Sorry, I did not get the "grouping by the desired SMMU behaviour" 
>> thing.
>> Could you please give some more details?
> 
> I mean this pattern:
> 
> device_a_data {
> 	.thing = this;
> }
> 
> device_b_data {
> 	.thing = this;
> }
> 
> device_c_data {
> 	.thing = that;
> }
> 
> match[] = {
> 	{ .compatible = "A", .data = &device_a_data },
> 	{ .compatible = "B", .data = &device_b_data },
> 	{ .compatible = "C", .data = &device_c_data },
> };
> 
> ...vs. this pattern:
> 
> do_this {
> 	.thing = this;
> }
> 
> do_that {
> 	.thing = that;
> }
> 
> match[] = {
> 	{ .compatible = "A", .data = &do_this },
> 	{ .compatible = "B", .data = &do_this },
> 	{ .compatible = "C", .data = &do_that },
> };
> 
> From the perspective of the thing doing the thing, grouping the data
> by device is meaningless if all that matters is whether to do this or
> that. The second pattern expresses that more naturally.
> 
> Of course if every device turns out to need a unique combination of
> several behaviours, then there ends up being no practical difference
> except that it's probably easier to come up with nice names under the
> first pattern. I guess it's up to how you see this developing in
> future; whether you're likely to need fine-grained per-device control,
> or don't expect it to go much beyond domain type.
> 

Thanks for explaining *this thing* :)
I will update the patch to follow the 2nd pattern as it makes more sense
to do_this or do_that directly. I'm not expecting anything other than
domain type atleast for now but hey we can always add the functionality
if the need arises.

Thanks,
Sai

Patch
diff mbox series

diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
index 64a4ab270ab7..ff746acd1c81 100644
--- a/drivers/iommu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm-smmu-qcom.c
@@ -3,6 +3,7 @@ 
  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
  */
 
+#include <linux/of_device.h>
 #include <linux/qcom_scm.h>
 
 #include "arm-smmu.h"
@@ -11,6 +12,43 @@  struct qcom_smmu {
 	struct arm_smmu_device smmu;
 };
 
+static const struct arm_smmu_client_match_data qcom_adreno = {
+	.direct_mapping = true,
+};
+
+static const struct arm_smmu_client_match_data qcom_mdss = {
+	.direct_mapping = true,
+};
+
+static const struct of_device_id qcom_smmu_client_of_match[] = {
+	{ .compatible = "qcom,adreno", .data = &qcom_adreno },
+	{ .compatible = "qcom,mdp4", .data = &qcom_mdss },
+	{ .compatible = "qcom,mdss", .data = &qcom_mdss },
+	{ .compatible = "qcom,sc7180-mdss", .data = &qcom_mdss },
+	{ .compatible = "qcom,sdm845-mdss", .data = &qcom_mdss },
+	{},
+};
+
+static const struct arm_smmu_client_match_data *
+qcom_smmu_client_data(struct device *dev)
+{
+	const struct of_device_id *match =
+		of_match_device(qcom_smmu_client_of_match, dev);
+
+	return match ? match->data : NULL;
+}
+
+static int qcom_smmu_request_domain(struct device *dev)
+{
+	const struct arm_smmu_client_match_data *client;
+
+	client = qcom_smmu_client_data(dev);
+	if (client)
+		iommu_request_dm_for_dev(dev);
+
+	return 0;
+}
+
 static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
 {
 	int ret;
@@ -41,6 +79,7 @@  static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
 }
 
 static const struct arm_smmu_impl qcom_smmu_impl = {
+	.req_domain = qcom_smmu_request_domain,
 	.reset = qcom_smmu500_reset,
 };
 
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 16c4b87af42b..67dd9326247a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1448,6 +1448,9 @@  static int arm_smmu_add_device(struct device *dev)
 	device_link_add(dev, smmu->dev,
 			DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
 
+	if (smmu->impl && smmu->impl->req_domain)
+		return smmu->impl->req_domain(dev);
+
 	return 0;
 
 out_cfg_free:
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index 8d1cd54d82a6..059dc9c39f64 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -244,6 +244,10 @@  enum arm_smmu_arch_version {
 	ARM_SMMU_V2,
 };
 
+struct arm_smmu_client_match_data {
+	bool direct_mapping;
+};
+
 enum arm_smmu_implementation {
 	GENERIC_SMMU,
 	ARM_MMU500,
@@ -386,6 +390,7 @@  struct arm_smmu_impl {
 	int (*init_context)(struct arm_smmu_domain *smmu_domain);
 	void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync,
 			 int status);
+	int (*req_domain)(struct device *dev);
 };
 
 static inline void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n)