[PATCH v3 6/8] arm_mpam: Add support for memory controller MSC on DT platforms

Yin Li yin.li at oss.qualcomm.com
Mon Oct 12 03:11:12 PDT 2026



On 10/9/2026 5:29 AM, Rob Herring wrote:
> On Thu, Oct 08, 2026 at 02:41:15PM +0800, Yin Li wrote:
>> From: Shanker Donthineni <sdonthineni at nvidia.com>
>>
>> The MPAM DT path only handles cache MSCs. Memory-controller MSCs
>> cannot be probed yet.
>>
>> Add support to discover memory-controller MSCs from the device tree:
>> derive the component id from the NUMA node and create a 'memory' class
>> RIS, and treat a memory parent as accessible from all CPUs.
> 
> Where's an actual user?
> 

Hi Rob,

The Kaanapali platform in this series only uses cache MSCs. This patch
is inherited from Shanker and James's work; They may have a platform in 
mind, but we do not have one to point to at the moment.

The binding already includes 'arm,mpam-memory-controller-msc' and the
corresponding example, so if the driver support is dropped the binding
entry should go too, to keep the two consistent.

We are happy to drop both. Shanker, James, please let us know if you
have a platform that needs this before we do.

Thanks,
Yin


>> Signed-off-by: Shanker Donthineni <sdonthineni at nvidia.com>
>> [ morse: split out of a bigger patch, added affinity piece ]
>> Signed-off-by: James Morse <james.morse at arm.com>
>> [ Yin Li: fix context offset conflicts; use of_node_get() for the memory
>>    parent to avoid a refcount underflow; use u32 instead of unsigned long
>>    for component_id and compare against ~0U ]
>> Signed-off-by: Yin Li <yin.li at oss.qualcomm.com>
>> ---
>>   drivers/resctrl/mpam_devices.c | 55 ++++++++++++++++++++++++++++++------------
>>   1 file changed, 40 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
>> index 0640690eae2c..048d32e69f55 100644
>> --- a/drivers/resctrl/mpam_devices.c
>> +++ b/drivers/resctrl/mpam_devices.c
>> @@ -263,10 +263,12 @@ static int mpam_dt_parse_resource(struct mpam_msc *msc, struct device_node *np,
>>   				  u8 ris_idx)
>>   {
>>   	int err = 0;
>> -	u32 level = 0;
>> -	u32 cache_id;
>> +	u32 class_id = 0;
>> +	u32 component_id = 0;
>>   	struct device *dev = &msc->pdev->dev;
>> +	enum mpam_class_types type = MPAM_CLASS_UNKNOWN;
>>   	struct device_node *cache __free(device_node) = NULL;
>> +	struct device_node *memory __free(device_node) = NULL;
>>   	struct device_node *parent __free(device_node) = of_get_parent(np);
>>   
>>   	if (of_device_is_compatible(np, "arm,mpam-cache")) {
>> @@ -275,27 +277,48 @@ static int mpam_dt_parse_resource(struct mpam_msc *msc, struct device_node *np,
>>   			dev_err_once(dev, "Failed to read phandle\n");
>>   			return -EINVAL;
>>   		}
>> +		type = MPAM_CLASS_CACHE;
>> +
>>   	} else if (of_device_is_compatible(parent, "cache")) {
>>   		cache = of_node_get(parent);
>> +		type = MPAM_CLASS_CACHE;
>> +	} else if (of_device_is_compatible(np, "arm,mpam-memory")) {
>> +		memory = of_parse_phandle(np, "arm,mpam-device", 0);
>> +		if (!memory) {
>> +			dev_err_once(dev, "Failed to read phandle\n");
>> +			return -EINVAL;
>> +		}
>> +		type = MPAM_CLASS_MEMORY;
>> +	} else if (of_device_is_compatible(np, "arm,mpam-memory-controller-msc")) {
>> +		memory = of_node_get(parent);
>> +		type = MPAM_CLASS_MEMORY;
>>   	} else {
>> -		/* For now, only caches are supported */
>> -		cache = NULL;
>> -		return err;
>> -	}
>> -
>> -	err = of_property_read_u32(cache, "cache-level", &level);
>> -	if (err) {
>> -		dev_err_once(dev, "Failed to read cache-level\n");
>> +		/*
>> +		 * For now, only caches and memory controllers are
>> +		 * supported.
>> +		 */
>>   		return err;
>>   	}
>>   
>> -	cache_id = cache_of_calculate_id(cache);
>> -	if (cache_id == ~0U) {
>> -		dev_err_once(dev, "Failed to calculate cache-id\n");
>> -		return -ENOENT;
>> +	/* Determine the class and component ids, based on type. */
>> +	if (type == MPAM_CLASS_CACHE) {
>> +		err = of_property_read_u32(cache, "cache-level", &class_id);
>> +		if (err) {
>> +			dev_err_once(dev, "Failed to read cache-level\n");
>> +			return err;
>> +		}
>> +		component_id = cache_of_calculate_id(cache);
>> +		if (component_id == ~0U) {
>> +			dev_err_once(dev, "Failed to calculate cache-id\n");
>> +			return -ENOENT;
>> +		}
>> +	} else if (type == MPAM_CLASS_MEMORY) {
>> +		err = of_node_to_nid(np);
>> +		component_id = (err == NUMA_NO_NODE) ? 0 : err;
>> +		class_id = MPAM_CLASS_ID_DEFAULT;
>>   	}
>>   
>> -	return mpam_ris_create(msc, ris_idx, MPAM_CLASS_CACHE, level, cache_id);
>> +	return mpam_ris_create(msc, ris_idx, type, class_id, component_id);
>>   }
>>   
>>   static int mpam_dt_parse_resources(struct mpam_msc *msc, void *ignored)
>> @@ -2169,6 +2192,8 @@ static void update_msc_accessibility(struct mpam_msc *msc)
>>   	} else {
>>   		if (of_device_is_compatible(parent, "cache"))
>>   			get_cpumask_from_cache(parent, &msc->accessibility);
>> +		else if (of_device_is_compatible(parent, "memory"))
>> +			cpumask_copy(&msc->accessibility, cpu_possible_mask);
>>   		else
>>   			dev_err_once(dev, "Cannot determine accessibility of MSC.\n");
>>   	}
>>
>> -- 
>> 2.34.1
>>

-- 
Thx and BRs,
Yin




More information about the linux-arm-kernel mailing list