mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
ACPI: LoongArch: Add support for acpi_iommu_configure_id()
acpi_iommu_configure_id() currently only supports IORT and VIOT. Add support for LoongArch's IOVT as well. Acked-by: Rafael J. Wysocki (Intel) <rafael@kernel.org> Signed-off-by: Bibo Mao <maobibo@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
This commit is contained in:
parent
a9b0c34507
commit
33e3401608
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/acpi_iovt.h>
|
||||
#include <linux/pci.h>
|
||||
#include "init.h"
|
||||
|
||||
|
|
@ -209,3 +210,49 @@ void __init acpi_iovt_late_init(void)
|
|||
iovt_init_devices(hdr);
|
||||
acpi_put_table(hdr);
|
||||
}
|
||||
|
||||
static int iovt_pci_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
|
||||
{
|
||||
struct iovt_fwnode *np;
|
||||
struct iovt_device_entry *entry;
|
||||
struct device *aliased_dev = data;
|
||||
u32 domain = pci_domain_nr(pdev->bus);
|
||||
|
||||
list_for_each_entry(np, &iovt_fwnode_list, list) {
|
||||
if (domain != np->segment)
|
||||
continue;
|
||||
|
||||
/* We're not translating ourself */
|
||||
if (dev_id == np->devid)
|
||||
return -EINVAL;
|
||||
|
||||
if (np->flag & ACPI_IOVT_IOMMU_MAGAGE_BY_SEGMENT)
|
||||
goto found;
|
||||
|
||||
list_for_each_entry(entry, &np->ep_list, list) {
|
||||
if (dev_id >= entry->start_devid && dev_id <= entry->end_devid)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
|
||||
found:
|
||||
return acpi_iommu_fwspec_init(aliased_dev, (domain << 16) + dev_id, np->fwnode);
|
||||
}
|
||||
|
||||
/*
|
||||
* iovt_iommu_configure_id - Set-up IOMMU configuration for a device.
|
||||
*
|
||||
* @dev: device to configure
|
||||
* @id_in: optional input id const value pointer
|
||||
*
|
||||
* Returns: 0 on success, <0 on failure
|
||||
*/
|
||||
int iovt_iommu_configure_id(struct device *dev, const u32 *id_in)
|
||||
{
|
||||
if (!dev_is_pci(dev))
|
||||
return -ENODEV;
|
||||
|
||||
return pci_for_each_dma_alias(to_pci_dev(dev), iovt_pci_iommu_init, dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/acpi_iort.h>
|
||||
#include <linux/acpi_iovt.h>
|
||||
#include <linux/acpi_rimt.h>
|
||||
#include <linux/acpi_viot.h>
|
||||
#include <linux/iommu.h>
|
||||
|
|
@ -1625,6 +1626,8 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
|
|||
err = iort_iommu_configure_id(dev, id_in);
|
||||
if (err && err != -EPROBE_DEFER)
|
||||
err = rimt_iommu_configure_id(dev, id_in);
|
||||
if (err && err != -EPROBE_DEFER)
|
||||
err = iovt_iommu_configure_id(dev, id_in);
|
||||
if (err && err != -EPROBE_DEFER)
|
||||
err = viot_iommu_configure(dev);
|
||||
|
||||
|
|
|
|||
13
include/linux/acpi_iovt.h
Normal file
13
include/linux/acpi_iovt.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __ACPI_IOVT_H__
|
||||
#define __ACPI_IOVT_H__
|
||||
|
||||
#ifdef CONFIG_ACPI_IOVT
|
||||
int iovt_iommu_configure_id(struct device *dev, const u32 *id_in);
|
||||
#else
|
||||
static inline int iovt_iommu_configure_id(struct device *dev, const u32 *id_in)
|
||||
{ return -ENODEV; }
|
||||
#endif
|
||||
|
||||
#endif /* __ACPI_IOVT_H__ */
|
||||
Loading…
Reference in New Issue
Block a user