@@ -264,39 +264,47 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
264264 struct device * dev = context ;
265265 acpi_status status = AE_NOT_FOUND ;
266266
267- if (node -> type == ACPI_IORT_NODE_NAMED_COMPONENT ) {
267+ if (node -> type == ACPI_IORT_NODE_NAMED_COMPONENT ||
268+ node -> type == ACPI_IORT_NODE_IWB ) {
268269 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER , NULL };
269- struct acpi_device * adev ;
270270 struct acpi_iort_named_component * ncomp ;
271- struct device * nc_dev = dev ;
271+ struct acpi_iort_iwb * iwb ;
272+ struct device * cdev = dev ;
273+ struct acpi_device * adev ;
274+ const char * device_name ;
272275
273276 /*
274277 * Walk the device tree to find a device with an
275278 * ACPI companion; there is no point in scanning
276- * IORT for a device matching a named component if
279+ * IORT for a device matching a named component or IWB if
277280 * the device does not have an ACPI companion to
278281 * start with.
279282 */
280283 do {
281- adev = ACPI_COMPANION (nc_dev );
284+ adev = ACPI_COMPANION (cdev );
282285 if (adev )
283286 break ;
284287
285- nc_dev = nc_dev -> parent ;
286- } while (nc_dev );
288+ cdev = cdev -> parent ;
289+ } while (cdev );
287290
288291 if (!adev )
289292 goto out ;
290293
291294 status = acpi_get_name (adev -> handle , ACPI_FULL_PATHNAME , & buf );
292295 if (ACPI_FAILURE (status )) {
293- dev_warn (nc_dev , "Can't get device full path name\n" );
296+ dev_warn (cdev , "Can't get device full path name\n" );
294297 goto out ;
295298 }
296299
297- ncomp = (struct acpi_iort_named_component * )node -> node_data ;
298- status = !strcmp (ncomp -> device_name , buf .pointer ) ?
299- AE_OK : AE_NOT_FOUND ;
300+ if (node -> type == ACPI_IORT_NODE_NAMED_COMPONENT ) {
301+ ncomp = (struct acpi_iort_named_component * )node -> node_data ;
302+ device_name = ncomp -> device_name ;
303+ } else {
304+ iwb = (struct acpi_iort_iwb * )node -> node_data ;
305+ device_name = iwb -> device_name ;
306+ }
307+ status = !strcmp (device_name , buf .pointer ) ? AE_OK : AE_NOT_FOUND ;
300308 acpi_os_free (buf .pointer );
301309 } else if (node -> type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ) {
302310 struct acpi_iort_root_complex * pci_rc ;
@@ -317,12 +325,28 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
317325 return status ;
318326}
319327
328+ static acpi_status iort_match_iwb_callback (struct acpi_iort_node * node , void * context )
329+ {
330+ struct acpi_iort_iwb * iwb ;
331+ u32 * id = context ;
332+
333+ if (node -> type != ACPI_IORT_NODE_IWB )
334+ return AE_NOT_FOUND ;
335+
336+ iwb = (struct acpi_iort_iwb * )node -> node_data ;
337+ if (iwb -> iwb_index != * id )
338+ return AE_NOT_FOUND ;
339+
340+ return AE_OK ;
341+ }
342+
320343static int iort_id_map (struct acpi_iort_id_mapping * map , u8 type , u32 rid_in ,
321344 u32 * rid_out , bool check_overlap )
322345{
323346 /* Single mapping does not care for input id */
324347 if (map -> flags & ACPI_IORT_ID_SINGLE_MAPPING ) {
325348 if (type == ACPI_IORT_NODE_NAMED_COMPONENT ||
349+ type == ACPI_IORT_NODE_IWB ||
326350 type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ) {
327351 * rid_out = map -> output_base ;
328352 return 0 ;
@@ -392,6 +416,7 @@ static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
392416
393417 if (map -> flags & ACPI_IORT_ID_SINGLE_MAPPING ) {
394418 if (node -> type == ACPI_IORT_NODE_NAMED_COMPONENT ||
419+ node -> type == ACPI_IORT_NODE_IWB ||
395420 node -> type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ||
396421 node -> type == ACPI_IORT_NODE_SMMU_V3 ||
397422 node -> type == ACPI_IORT_NODE_PMCG ) {
@@ -562,9 +587,14 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
562587 return node ;
563588 /*
564589 * if not, then it should be a platform device defined in
565- * DSDT/SSDT (with Named Component node in IORT)
590+ * DSDT/SSDT (with Named Component node in IORT) or an
591+ * IWB device in the DSDT/SSDT.
566592 */
567- return iort_scan_node (ACPI_IORT_NODE_NAMED_COMPONENT ,
593+ node = iort_scan_node (ACPI_IORT_NODE_NAMED_COMPONENT ,
594+ iort_match_node_callback , dev );
595+ if (node )
596+ return node ;
597+ return iort_scan_node (ACPI_IORT_NODE_IWB ,
568598 iort_match_node_callback , dev );
569599 }
570600
@@ -595,45 +625,45 @@ u32 iort_msi_map_id(struct device *dev, u32 input_id)
595625}
596626
597627/**
598- * iort_pmsi_get_dev_id () - Get the device id for a device
628+ * iort_msi_xlate () - Map a MSI input ID for a device
599629 * @dev: The device for which the mapping is to be done.
600- * @dev_id: The device ID found.
630+ * @input_id: The device input ID.
631+ * @fwnode: Pointer to store the fwnode.
601632 *
602- * Returns: 0 for successful find a dev id, -ENODEV on error
633+ * Returns: mapped MSI ID on success, input ID otherwise
634+ * On success, the fwnode pointer is initialized to the MSI
635+ * controller fwnode handle.
603636 */
604- int iort_pmsi_get_dev_id (struct device * dev , u32 * dev_id )
637+ u32 iort_msi_xlate (struct device * dev , u32 input_id , struct fwnode_handle * * fwnode )
605638{
606- int i , index ;
639+ struct acpi_iort_its_group * its ;
607640 struct acpi_iort_node * node ;
641+ u32 dev_id ;
608642
609643 node = iort_find_dev_node (dev );
610644 if (!node )
611- return - ENODEV ;
645+ return input_id ;
612646
613- index = iort_get_id_mapping_index (node );
614- /* if there is a valid index, go get the dev_id directly */
615- if (index >= 0 ) {
616- if (iort_node_get_id (node , dev_id , index ))
617- return 0 ;
618- } else {
619- for (i = 0 ; i < node -> mapping_count ; i ++ ) {
620- if (iort_node_map_platform_id (node , dev_id ,
621- IORT_MSI_TYPE , i ))
622- return 0 ;
623- }
624- }
647+ node = iort_node_map_id (node , input_id , & dev_id , IORT_MSI_TYPE );
648+ if (!node )
649+ return input_id ;
625650
626- return - ENODEV ;
651+ /* Move to ITS specific data */
652+ its = (struct acpi_iort_its_group * )node -> node_data ;
653+
654+ * fwnode = iort_find_domain_token (its -> identifiers [0 ]);
655+
656+ return dev_id ;
627657}
628658
629- static int __maybe_unused iort_find_its_base ( u32 its_id , phys_addr_t * base )
659+ int iort_its_translate_pa ( struct fwnode_handle * node , phys_addr_t * base )
630660{
631661 struct iort_its_msi_chip * its_msi_chip ;
632662 int ret = - ENODEV ;
633663
634664 spin_lock (& iort_msi_chip_lock );
635665 list_for_each_entry (its_msi_chip , & iort_msi_chip_list , list ) {
636- if (its_msi_chip -> translation_id == its_id ) {
666+ if (its_msi_chip -> fw_node == node ) {
637667 * base = its_msi_chip -> base_addr ;
638668 ret = 0 ;
639669 break ;
@@ -644,6 +674,62 @@ static int __maybe_unused iort_find_its_base(u32 its_id, phys_addr_t *base)
644674 return ret ;
645675}
646676
677+ static int __maybe_unused iort_find_its_base (u32 its_id , phys_addr_t * base )
678+ {
679+ struct fwnode_handle * fwnode = iort_find_domain_token (its_id );
680+
681+ if (!fwnode )
682+ return - ENODEV ;
683+
684+ return iort_its_translate_pa (fwnode , base );
685+ }
686+
687+ /**
688+ * iort_pmsi_get_msi_info() - Get the device id and translate frame PA for a device
689+ * @dev: The device for which the mapping is to be done.
690+ * @dev_id: The device ID found.
691+ * @pa: optional pointer to store translate frame address.
692+ *
693+ * Returns: 0 for successful devid and pa retrieval, -ENODEV on error
694+ */
695+ int iort_pmsi_get_msi_info (struct device * dev , u32 * dev_id , phys_addr_t * pa )
696+ {
697+ struct acpi_iort_node * node , * parent = NULL ;
698+ struct acpi_iort_its_group * its ;
699+ int i , index ;
700+
701+ node = iort_find_dev_node (dev );
702+ if (!node )
703+ return - ENODEV ;
704+
705+ index = iort_get_id_mapping_index (node );
706+ /* if there is a valid index, go get the dev_id directly */
707+ if (index >= 0 ) {
708+ parent = iort_node_get_id (node , dev_id , index );
709+ } else {
710+ for (i = 0 ; i < node -> mapping_count ; i ++ ) {
711+ parent = iort_node_map_platform_id (node , dev_id ,
712+ IORT_MSI_TYPE , i );
713+ if (parent )
714+ break ;
715+ }
716+ }
717+
718+ if (!parent )
719+ return - ENODEV ;
720+
721+ if (pa ) {
722+ int ret ;
723+
724+ its = (struct acpi_iort_its_group * )node -> node_data ;
725+ ret = iort_find_its_base (its -> identifiers [0 ], pa );
726+ if (ret )
727+ return ret ;
728+ }
729+
730+ return 0 ;
731+ }
732+
647733/**
648734 * iort_dev_find_its_id() - Find the ITS identifier for a device
649735 * @dev: The device.
@@ -703,6 +789,35 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
703789 return irq_find_matching_fwnode (handle , bus_token );
704790}
705791
792+ struct fwnode_handle * iort_iwb_handle (u32 iwb_id )
793+ {
794+ struct fwnode_handle * fwnode ;
795+ struct acpi_iort_node * node ;
796+ struct acpi_device * device ;
797+ struct acpi_iort_iwb * iwb ;
798+ acpi_status status ;
799+ acpi_handle handle ;
800+
801+ /* find its associated IWB node */
802+ node = iort_scan_node (ACPI_IORT_NODE_IWB , iort_match_iwb_callback , & iwb_id );
803+ if (!node )
804+ return NULL ;
805+
806+ iwb = (struct acpi_iort_iwb * )node -> node_data ;
807+ status = acpi_get_handle (NULL , iwb -> device_name , & handle );
808+ if (ACPI_FAILURE (status ))
809+ return NULL ;
810+
811+ device = acpi_get_acpi_dev (handle );
812+ if (!device )
813+ return NULL ;
814+
815+ fwnode = acpi_fwnode_handle (device );
816+ acpi_put_acpi_dev (device );
817+
818+ return fwnode ;
819+ }
820+
706821static void iort_set_device_domain (struct device * dev ,
707822 struct acpi_iort_node * node )
708823{
@@ -763,8 +878,14 @@ static struct irq_domain *iort_get_platform_device_domain(struct device *dev)
763878 /* find its associated iort node */
764879 node = iort_scan_node (ACPI_IORT_NODE_NAMED_COMPONENT ,
765880 iort_match_node_callback , dev );
766- if (!node )
767- return NULL ;
881+ if (!node ) {
882+ /* find its associated iort node */
883+ node = iort_scan_node (ACPI_IORT_NODE_IWB ,
884+ iort_match_node_callback , dev );
885+
886+ if (!node )
887+ return NULL ;
888+ }
768889
769890 /* then find its msi parent node */
770891 for (i = 0 ; i < node -> mapping_count ; i ++ ) {
0 commit comments