lkml.org 
[lkml]   [2018]   [Apr]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/6 v3] iommu: of: make of_pci_map_rid() available for other devices too
    Date
    iommu-map property is also used by devices with fsl-mc. This
    patch moves the of_pci_map_rid to generic location, so that it
    can be used by other busses too.

    'of_pci_map_rid' is renamed here to 'of_map_rid' and there is no
    functional change done in the API.

    Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
    ---
    drivers/iommu/of_iommu.c | 6 +--
    drivers/of/address.c | 102 +++++++++++++++++++++++++++++++++++++++++++++
    drivers/of/irq.c | 7 ++--
    drivers/pci/of.c | 101 --------------------------------------------
    include/linux/of_address.h | 11 +++++
    include/linux/of_pci.h | 10 -----
    6 files changed, 120 insertions(+), 117 deletions(-)

    diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
    index 5c36a8b..ea9ecef 100644
    --- a/drivers/iommu/of_iommu.c
    +++ b/drivers/iommu/of_iommu.c
    @@ -21,6 +21,7 @@
    #include <linux/iommu.h>
    #include <linux/limits.h>
    #include <linux/of.h>
    +#include <linux/of_address.h>
    #include <linux/of_iommu.h>
    #include <linux/of_pci.h>
    #include <linux/slab.h>
    @@ -149,9 +150,8 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
    struct of_phandle_args iommu_spec = { .args_count = 1 };
    int err;

    - err = of_pci_map_rid(info->np, alias, "iommu-map",
    - "iommu-map-mask", &iommu_spec.np,
    - iommu_spec.args);
    + err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask",
    + &iommu_spec.np, iommu_spec.args);
    if (err)
    return err == -ENODEV ? NO_IOMMU : err;

    diff --git a/drivers/of/address.c b/drivers/of/address.c
    index 5334991..4163f24 100644
    --- a/drivers/of/address.c
    +++ b/drivers/of/address.c
    @@ -985,3 +985,105 @@ bool of_dma_is_coherent(struct device_node *np)
    return false;
    }
    EXPORT_SYMBOL_GPL(of_dma_is_coherent);
    +
    +/**
    + * of_map_rid - Translate a requester ID through a downstream mapping.
    + * @np: root complex device node.
    + * @rid: device requester ID to map.
    + * @map_name: property name of the map to use.
    + * @map_mask_name: optional property name of the mask to use.
    + * @target: optional pointer to a target device node.
    + * @id_out: optional pointer to receive the translated ID.
    + *
    + * Given a device requester ID, look up the appropriate implementation-defined
    + * platform ID and/or the target device which receives transactions on that
    + * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
    + * @id_out may be NULL if only the other is required. If @target points to
    + * a non-NULL device node pointer, only entries targeting that node will be
    + * matched; if it points to a NULL value, it will receive the device node of
    + * the first matching target phandle, with a reference held.
    + *
    + * Return: 0 on success or a standard error code on failure.
    + */
    +int of_map_rid(struct device_node *np, u32 rid,
    + const char *map_name, const char *map_mask_name,
    + struct device_node **target, u32 *id_out)
    +{
    + u32 map_mask, masked_rid;
    + int map_len;
    + const __be32 *map = NULL;
    +
    + if (!np || !map_name || (!target && !id_out))
    + return -EINVAL;
    +
    + map = of_get_property(np, map_name, &map_len);
    + if (!map) {
    + if (target)
    + return -ENODEV;
    + /* Otherwise, no map implies no translation */
    + *id_out = rid;
    + return 0;
    + }
    +
    + if (!map_len || map_len % (4 * sizeof(*map))) {
    + pr_err("%pOF: Error: Bad %s length: %d\n", np,
    + map_name, map_len);
    + return -EINVAL;
    + }
    +
    + /* The default is to select all bits. */
    + map_mask = 0xffffffff;
    +
    + /*
    + * Can be overridden by "{iommu,msi}-map-mask" property.
    + * If of_property_read_u32() fails, the default is used.
    + */
    + if (map_mask_name)
    + of_property_read_u32(np, map_mask_name, &map_mask);
    +
    + masked_rid = map_mask & rid;
    + for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
    + struct device_node *phandle_node;
    + u32 rid_base = be32_to_cpup(map + 0);
    + u32 phandle = be32_to_cpup(map + 1);
    + u32 out_base = be32_to_cpup(map + 2);
    + u32 rid_len = be32_to_cpup(map + 3);
    +
    + if (rid_base & ~map_mask) {
    + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
    + np, map_name, map_name,
    + map_mask, rid_base);
    + return -EFAULT;
    + }
    +
    + if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
    + continue;
    +
    + phandle_node = of_find_node_by_phandle(phandle);
    + if (!phandle_node)
    + return -ENODEV;
    +
    + if (target) {
    + if (*target)
    + of_node_put(phandle_node);
    + else
    + *target = phandle_node;
    +
    + if (*target != phandle_node)
    + continue;
    + }
    +
    + if (id_out)
    + *id_out = masked_rid - rid_base + out_base;
    +
    + pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
    + np, map_name, map_mask, rid_base, out_base,
    + rid_len, rid, masked_rid - rid_base + out_base);
    + return 0;
    + }
    +
    + pr_err("%pOF: Invalid %s translation - no match for rid 0x%x on %pOF\n",
    + np, map_name, rid, target && *target ? *target : NULL);
    + return -EFAULT;
    +}
    +EXPORT_SYMBOL_GPL(of_map_rid);
    diff --git a/drivers/of/irq.c b/drivers/of/irq.c
    index 02ad93a..e9ebe1e 100644
    --- a/drivers/of/irq.c
    +++ b/drivers/of/irq.c
    @@ -21,8 +21,9 @@
    #include <linux/list.h>
    #include <linux/module.h>
    #include <linux/of.h>
    +#include <linux/of_address.h>
    #include <linux/of_irq.h>
    -#include <linux/of_pci.h>
    +#include <linux/of_iommu.h>
    #include <linux/string.h>
    #include <linux/slab.h>

    @@ -588,8 +589,8 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
    * "msi-map" property.
    */
    for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
    - if (!of_pci_map_rid(parent_dev->of_node, rid_in, "msi-map",
    - "msi-map-mask", np, &rid_out))
    + if (!of_map_rid(parent_dev->of_node, rid_in, "msi-map",
    + "msi-map-mask", np, &rid_out))
    break;
    return rid_out;
    }
    diff --git a/drivers/pci/of.c b/drivers/pci/of.c
    index a28355c..d2cebbe 100644
    --- a/drivers/pci/of.c
    +++ b/drivers/pci/of.c
    @@ -362,107 +362,6 @@ int of_pci_get_host_bridge_resources(struct device_node *dev,
    EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
    #endif /* CONFIG_OF_ADDRESS */

    -/**
    - * of_pci_map_rid - Translate a requester ID through a downstream mapping.
    - * @np: root complex device node.
    - * @rid: PCI requester ID to map.
    - * @map_name: property name of the map to use.
    - * @map_mask_name: optional property name of the mask to use.
    - * @target: optional pointer to a target device node.
    - * @id_out: optional pointer to receive the translated ID.
    - *
    - * Given a PCI requester ID, look up the appropriate implementation-defined
    - * platform ID and/or the target device which receives transactions on that
    - * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
    - * @id_out may be NULL if only the other is required. If @target points to
    - * a non-NULL device node pointer, only entries targeting that node will be
    - * matched; if it points to a NULL value, it will receive the device node of
    - * the first matching target phandle, with a reference held.
    - *
    - * Return: 0 on success or a standard error code on failure.
    - */
    -int of_pci_map_rid(struct device_node *np, u32 rid,
    - const char *map_name, const char *map_mask_name,
    - struct device_node **target, u32 *id_out)
    -{
    - u32 map_mask, masked_rid;
    - int map_len;
    - const __be32 *map = NULL;
    -
    - if (!np || !map_name || (!target && !id_out))
    - return -EINVAL;
    -
    - map = of_get_property(np, map_name, &map_len);
    - if (!map) {
    - if (target)
    - return -ENODEV;
    - /* Otherwise, no map implies no translation */
    - *id_out = rid;
    - return 0;
    - }
    -
    - if (!map_len || map_len % (4 * sizeof(*map))) {
    - pr_err("%pOF: Error: Bad %s length: %d\n", np,
    - map_name, map_len);
    - return -EINVAL;
    - }
    -
    - /* The default is to select all bits. */
    - map_mask = 0xffffffff;
    -
    - /*
    - * Can be overridden by "{iommu,msi}-map-mask" property.
    - * If of_property_read_u32() fails, the default is used.
    - */
    - if (map_mask_name)
    - of_property_read_u32(np, map_mask_name, &map_mask);
    -
    - masked_rid = map_mask & rid;
    - for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
    - struct device_node *phandle_node;
    - u32 rid_base = be32_to_cpup(map + 0);
    - u32 phandle = be32_to_cpup(map + 1);
    - u32 out_base = be32_to_cpup(map + 2);
    - u32 rid_len = be32_to_cpup(map + 3);
    -
    - if (rid_base & ~map_mask) {
    - pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
    - np, map_name, map_name,
    - map_mask, rid_base);
    - return -EFAULT;
    - }
    -
    - if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
    - continue;
    -
    - phandle_node = of_find_node_by_phandle(phandle);
    - if (!phandle_node)
    - return -ENODEV;
    -
    - if (target) {
    - if (*target)
    - of_node_put(phandle_node);
    - else
    - *target = phandle_node;
    -
    - if (*target != phandle_node)
    - continue;
    - }
    -
    - if (id_out)
    - *id_out = masked_rid - rid_base + out_base;
    -
    - pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
    - np, map_name, map_mask, rid_base, out_base,
    - rid_len, rid, masked_rid - rid_base + out_base);
    - return 0;
    - }
    -
    - pr_err("%pOF: Invalid %s translation - no match for rid 0x%x on %pOF\n",
    - np, map_name, rid, target && *target ? *target : NULL);
    - return -EFAULT;
    -}
    -
    #if IS_ENABLED(CONFIG_OF_IRQ)
    /**
    * of_irq_parse_pci - Resolve the interrupt for a PCI device
    diff --git a/include/linux/of_address.h b/include/linux/of_address.h
    index 30e40fb..25cd3f1 100644
    --- a/include/linux/of_address.h
    +++ b/include/linux/of_address.h
    @@ -120,6 +120,10 @@ static inline bool of_dma_is_coherent(struct device_node *np)
    extern int of_address_to_resource(struct device_node *dev, int index,
    struct resource *r);
    void __iomem *of_iomap(struct device_node *node, int index);
    +int of_map_rid(struct device_node *np, u32 rid,
    + const char *map_name, const char *map_mask_name,
    + struct device_node **target, u32 *id_out);
    +
    #else
    static inline int of_address_to_resource(struct device_node *dev, int index,
    struct resource *r)
    @@ -131,6 +135,13 @@ static inline void __iomem *of_iomap(struct device_node *device, int index)
    {
    return NULL;
    }
    +
    +static inline int of_map_rid(struct device_node *np, u32 rid,
    + const char *map_name, const char *map_mask_name,
    + struct device_node **target, u32 *id_out)
    +{
    + return -EINVAL;
    +}
    #endif

    #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)
    diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
    index 091033a..a23b44a 100644
    --- a/include/linux/of_pci.h
    +++ b/include/linux/of_pci.h
    @@ -17,9 +17,6 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
    int of_get_pci_domain_nr(struct device_node *node);
    int of_pci_get_max_link_speed(struct device_node *node);
    void of_pci_check_probe_only(void);
    -int of_pci_map_rid(struct device_node *np, u32 rid,
    - const char *map_name, const char *map_mask_name,
    - struct device_node **target, u32 *id_out);
    #else
    static inline struct device_node *of_pci_find_child_device(struct device_node *parent,
    unsigned int devfn)
    @@ -44,13 +41,6 @@ static inline int of_pci_get_devfn(struct device_node *np)
    return -1;
    }

    -static inline int of_pci_map_rid(struct device_node *np, u32 rid,
    - const char *map_name, const char *map_mask_name,
    - struct device_node **target, u32 *id_out)
    -{
    - return -EINVAL;
    -}
    -
    static inline int
    of_pci_get_max_link_speed(struct device_node *node)
    {
    --
    1.9.1
    \
     
     \ /
      Last update: 2018-04-27 12:30    [W:4.659 / U:1.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site