| From 746c9e9f92dde2789908e51a354ba90a1962a2eb Mon Sep 17 00:00:00 2001 |
| From: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
| Date: Fri, 14 Nov 2014 17:55:03 +1100 |
| Subject: of/base: Fix PowerPC address parsing hack |
| |
| From: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
| |
| commit 746c9e9f92dde2789908e51a354ba90a1962a2eb upstream. |
| |
| We have a historical hack that treats missing ranges properties as the |
| equivalent of an empty one. This is needed for ancient PowerMac "bad" |
| device-trees, and shouldn't be enabled for any other PowerPC platform, |
| otherwise we get some nasty layout of devices in sysfs or even |
| duplication when a set of otherwise identically named devices is |
| created multiple times under a different parent node with no ranges |
| property. |
| |
| This fix is needed for the PowerNV i2c busses to be exposed properly |
| and will fix a number of other embedded cases. |
| |
| Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
| Acked-by: Grant Likely <grant.likely@linaro.org> |
| Signed-off-by: Rob Herring <robh@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/of/address.c | 19 ++++++++++++++++--- |
| 1 file changed, 16 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/of/address.c |
| +++ b/drivers/of/address.c |
| @@ -401,6 +401,21 @@ static struct of_bus *of_match_bus(struc |
| return NULL; |
| } |
| |
| +static int of_empty_ranges_quirk(void) |
| +{ |
| + if (IS_ENABLED(CONFIG_PPC)) { |
| + /* To save cycles, we cache the result */ |
| + static int quirk_state = -1; |
| + |
| + if (quirk_state < 0) |
| + quirk_state = |
| + of_machine_is_compatible("Power Macintosh") || |
| + of_machine_is_compatible("MacRISC"); |
| + return quirk_state; |
| + } |
| + return false; |
| +} |
| + |
| static int of_translate_one(struct device_node *parent, struct of_bus *bus, |
| struct of_bus *pbus, __be32 *addr, |
| int na, int ns, int pna, const char *rprop) |
| @@ -426,12 +441,10 @@ static int of_translate_one(struct devic |
| * This code is only enabled on powerpc. --gcl |
| */ |
| ranges = of_get_property(parent, rprop, &rlen); |
| -#if !defined(CONFIG_PPC) |
| - if (ranges == NULL) { |
| + if (ranges == NULL && !of_empty_ranges_quirk()) { |
| pr_err("OF: no ranges; cannot translate\n"); |
| return 1; |
| } |
| -#endif /* !defined(CONFIG_PPC) */ |
| if (ranges == NULL || rlen == 0) { |
| offset = of_read_number(addr, na); |
| memset(addr, 0, pna * 4); |