summaryrefslogtreecommitdiff
path: root/drivers/of
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/fdt.c32
-rw-r--r--drivers/of/fdt_address.c11
-rw-r--r--drivers/of/irq.c27
-rw-r--r--drivers/of/of_mdio.c39
-rw-r--r--drivers/of/of_pci.c1
5 files changed, 74 insertions, 36 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 655f79db7899..e2295b2c9836 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -796,14 +796,13 @@ static inline void early_init_dt_check_for_initrd(unsigned long node)
#endif /* CONFIG_BLK_DEV_INITRD */
#ifdef CONFIG_SERIAL_EARLYCON
-extern struct of_device_id __earlycon_of_table[];
static int __init early_init_dt_scan_chosen_serial(void)
{
int offset;
- const char *p;
+ const char *p, *q, *options = NULL;
int l;
- const struct of_device_id *match = __earlycon_of_table;
+ const struct earlycon_id *match;
const void *fdt = initial_boot_params;
offset = fdt_path_offset(fdt, "/chosen");
@@ -818,27 +817,26 @@ static int __init early_init_dt_scan_chosen_serial(void)
if (!p || !l)
return -ENOENT;
- /* Remove console options if present */
- l = strchrnul(p, ':') - p;
+ q = strchrnul(p, ':');
+ if (*q != '\0')
+ options = q + 1;
+ l = q - p;
/* Get the node specified by stdout-path */
offset = fdt_path_offset_namelen(fdt, p, l);
- if (offset < 0)
- return -ENODEV;
-
- while (match->compatible[0]) {
- u64 addr;
+ if (offset < 0) {
+ pr_warn("earlycon: stdout-path %.*s not found\n", l, p);
+ return 0;
+ }
- if (fdt_node_check_compatible(fdt, offset, match->compatible)) {
- match++;
+ for (match = __earlycon_table; match < __earlycon_table_end; match++) {
+ if (!match->compatible[0])
continue;
- }
- addr = fdt_translate_address(fdt, offset);
- if (addr == OF_BAD_ADDR)
- return -ENXIO;
+ if (fdt_node_check_compatible(fdt, offset, match->compatible))
+ continue;
- of_setup_earlycon(addr, match->data);
+ of_setup_earlycon(match, offset, options);
return 0;
}
return -ENODEV;
diff --git a/drivers/of/fdt_address.c b/drivers/of/fdt_address.c
index 8d3dc6fbdb7a..dca8f9b93745 100644
--- a/drivers/of/fdt_address.c
+++ b/drivers/of/fdt_address.c
@@ -161,7 +161,7 @@ static int __init fdt_translate_one(const void *blob, int parent,
* that can be mapped to a cpu physical address). This is not really specified
* that way, but this is traditionally the way IBM at least do things
*/
-u64 __init fdt_translate_address(const void *blob, int node_offset)
+static u64 __init fdt_translate_address(const void *blob, int node_offset)
{
int parent, len;
const struct of_bus *bus, *pbus;
@@ -239,3 +239,12 @@ u64 __init fdt_translate_address(const void *blob, int node_offset)
bail:
return result;
}
+
+/**
+ * of_flat_dt_translate_address - translate DT addr into CPU phys addr
+ * @node: node in the flat blob
+ */
+u64 __init of_flat_dt_translate_address(unsigned long node)
+{
+ return fdt_translate_address(initial_boot_params, node);
+}
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 706e3ff67f8b..e7bfc175b8e1 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -635,6 +635,13 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
msi_base = be32_to_cpup(msi_map + 2);
rid_len = be32_to_cpup(msi_map + 3);
+ if (rid_base & ~map_mask) {
+ dev_err(parent_dev,
+ "Invalid msi-map translation - msi-map-mask (0x%x) ignores rid-base (0x%x)\n",
+ map_mask, rid_base);
+ return rid_out;
+ }
+
msi_controller_node = of_find_node_by_phandle(phandle);
matched = (masked_rid >= rid_base &&
@@ -654,7 +661,7 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
if (!matched)
return rid_out;
- rid_out = masked_rid + msi_base;
+ rid_out = masked_rid - rid_base + msi_base;
dev_dbg(dev,
"msi-map at: %s, using mask %08x, rid-base: %08x, msi-base: %08x, length: %08x, rid: %08x -> %08x\n",
dev_name(parent_dev), map_mask, rid_base, msi_base,
@@ -679,18 +686,6 @@ u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
return __of_msi_map_rid(dev, &msi_np, rid_in);
}
-static struct irq_domain *__of_get_msi_domain(struct device_node *np,
- enum irq_domain_bus_token token)
-{
- struct irq_domain *d;
-
- d = irq_find_matching_host(np, token);
- if (!d)
- d = irq_find_host(np);
-
- return d;
-}
-
/**
* of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
* @dev: device for which the mapping is to be done.
@@ -706,7 +701,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid)
struct device_node *np = NULL;
__of_msi_map_rid(dev, &np, rid);
- return __of_get_msi_domain(np, DOMAIN_BUS_PCI_MSI);
+ return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI);
}
/**
@@ -730,7 +725,7 @@ struct irq_domain *of_msi_get_domain(struct device *dev,
/* Check for a single msi-parent property */
msi_np = of_parse_phandle(np, "msi-parent", 0);
if (msi_np && !of_property_read_bool(msi_np, "#msi-cells")) {
- d = __of_get_msi_domain(msi_np, token);
+ d = irq_find_matching_host(msi_np, token);
if (!d)
of_node_put(msi_np);
return d;
@@ -744,7 +739,7 @@ struct irq_domain *of_msi_get_domain(struct device *dev,
while (!of_parse_phandle_with_args(np, "msi-parent",
"#msi-cells",
index, &args)) {
- d = __of_get_msi_domain(args.np, token);
+ d = irq_find_matching_host(args.np, token);
if (d)
return d;
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 86829f8064a6..365dc7e83ab4 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -143,11 +143,32 @@ int of_mdio_parse_addr(struct device *dev, const struct device_node *np)
}
EXPORT_SYMBOL(of_mdio_parse_addr);
+/* The following is a list of PHY compatible strings which appear in
+ * some DTBs. The compatible string is never matched against a PHY
+ * driver, so is pointless. We only expect devices which are not PHYs
+ * to have a compatible string, so they can be matched to an MDIO
+ * driver. Encourage users to upgrade their DT blobs to remove these.
+ */
+static const struct of_device_id whitelist_phys[] = {
+ { .compatible = "brcm,40nm-ephy" },
+ { .compatible = "marvell,88E1111", },
+ { .compatible = "marvell,88e1116", },
+ { .compatible = "marvell,88e1118", },
+ { .compatible = "marvell,88e1145", },
+ { .compatible = "marvell,88e1149r", },
+ { .compatible = "marvell,88e1310", },
+ { .compatible = "marvell,88E1510", },
+ { .compatible = "marvell,88E1514", },
+ { .compatible = "moxa,moxart-rtl8201cp", },
+ {}
+};
+
/*
* Return true if the child node is for a phy. It must either:
* o Compatible string of "ethernet-phy-idX.X"
* o Compatible string of "ethernet-phy-ieee802.3-c45"
* o Compatible string of "ethernet-phy-ieee802.3-c22"
+ * o In the white list above (and issue a warning)
* o No compatibility string
*
* A device which is not a phy is expected to have a compatible string
@@ -166,6 +187,13 @@ static bool of_mdiobus_child_is_phy(struct device_node *child)
if (of_device_is_compatible(child, "ethernet-phy-ieee802.3-c22"))
return true;
+ if (of_match_node(whitelist_phys, child)) {
+ pr_warn(FW_WARN
+ "%s: Whitelisted compatible string. Please remove\n",
+ child->full_name);
+ return true;
+ }
+
if (!of_find_property(child, "compatible", NULL))
return true;
@@ -256,11 +284,19 @@ static int of_phy_match(struct device *dev, void *phy_np)
struct phy_device *of_phy_find_device(struct device_node *phy_np)
{
struct device *d;
+ struct mdio_device *mdiodev;
+
if (!phy_np)
return NULL;
d = bus_find_device(&mdio_bus_type, NULL, phy_np, of_phy_match);
- return d ? to_phy_device(d) : NULL;
+ if (d) {
+ mdiodev = to_mdio_device(d);
+ if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY)
+ return to_phy_device(d);
+ }
+
+ return NULL;
}
EXPORT_SYMBOL(of_phy_find_device);
@@ -269,6 +305,7 @@ EXPORT_SYMBOL(of_phy_find_device);
* @dev: pointer to net_device claiming the phy
* @phy_np: Pointer to device tree node for the PHY
* @hndlr: Link state callback for the network device
+ * @flags: flags to pass to the PHY
* @iface: PHY data interface type
*
* If successful, returns a pointer to the phy_device with the embedded
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index b1449f71601c..13f4fed38048 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -5,7 +5,6 @@
#include <linux/of_device.h>
#include <linux/of_pci.h>
#include <linux/slab.h>
-#include <asm-generic/pci-bridge.h>
static inline int __of_pci_pci_compare(struct device_node *node,
unsigned int data)