Linux 3.14-rc5

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJTE+9XAAoJEHm+PkMAQRiGrMQIAKI2V49Kj8WlnwGchFvsbGJB
 SLALwNi33T/IBKdZRhrfryBu02Zj7eVvZ2ML35dJEnmF88O+dJBDMTkKV1xalrip
 mtkBrjUnfAI04fq/daLQ1TsAy4qqlra5tSTuDCw8ILOnGPwT0VydIEHNdtmoUIfw
 xlZLxHzny1MslZ78d7uR/cUnV9ylKRRajWzfw1HT8hL51fCt8nRWY0sCvwvl+kMJ
 LsK+6I7mHDUuzA7QBmBI+dhzQgos5+JkkrnpmqHAqwmIh+AI3ksmjUCQ4dM7owrO
 IvEx+ZNDqxAdLcm1WAxATNfxddFXHc62JTvKuuKqTVWuaxVfK1Aqt8MjDMIPeAQ=
 =yV5u
 -----END PGP SIGNATURE-----

Merge tag 'v3.14-rc5' into HEAD

Linux 3.14-rc5
This commit is contained in:
Grant Likely 2014-03-04 16:44:10 +08:00
commit dab2310d9d
1196 changed files with 14561 additions and 7288 deletions

View file

@ -99,11 +99,12 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr)
static int of_bus_pci_match(struct device_node *np)
{
/*
* "pciex" is PCI Express
* "vci" is for the /chaos bridge on 1st-gen PCI powermacs
* "ht" is hypertransport
*/
return !strcmp(np->type, "pci") || !strcmp(np->type, "vci") ||
!strcmp(np->type, "ht");
return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex") ||
!strcmp(np->type, "vci") || !strcmp(np->type, "ht");
}
static void of_bus_pci_count_cells(struct device_node *np,

View file

@ -342,27 +342,72 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
}
EXPORT_SYMBOL(of_get_cpu_node);
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
/**
* __of_device_is_compatible() - Check if the node matches given constraints
* @device: pointer to node
* @compat: required compatible string, NULL or "" for any match
* @type: required device_type value, NULL or "" for any match
* @name: required node name, NULL or "" for any match
*
* Checks if the given @compat, @type and @name strings match the
* properties of the given @device. A constraints can be skipped by
* passing NULL or an empty string as the constraint.
*
* Returns 0 for no match, and a positive integer on match. The return
* value is a relative score with larger values indicating better
* matches. The score is weighted for the most specific compatible value
* to get the highest score. Matching type is next, followed by matching
* name. Practically speaking, this results in the following priority
* order for matches:
*
* 1. specific compatible && type && name
* 2. specific compatible && type
* 3. specific compatible && name
* 4. specific compatible
* 5. general compatible && type && name
* 6. general compatible && type
* 7. general compatible && name
* 8. general compatible
* 9. type && name
* 10. type
* 11. name
*/
static int __of_device_is_compatible(const struct device_node *device,
const char *compat)
const char *compat, const char *type, const char *name)
{
const char* cp;
int cplen, l;
struct property *prop;
const char *cp;
int index = 0, score = 0;
cp = __of_get_property(device, "compatible", &cplen);
if (cp == NULL)
return 0;
while (cplen > 0) {
if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
return 1;
l = strlen(cp) + 1;
cp += l;
cplen -= l;
/* Compatible match has highest priority */
if (compat && compat[0]) {
prop = __of_find_property(device, "compatible", NULL);
for (cp = of_prop_next_string(prop, NULL); cp;
cp = of_prop_next_string(prop, cp), index++) {
if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
score = INT_MAX/2 - (index << 2);
break;
}
}
if (!score)
return 0;
}
return 0;
/* Matching type is better than matching name */
if (type && type[0]) {
if (!device->type || of_node_cmp(type, device->type))
return 0;
score += 2;
}
/* Matching name is a bit better than not */
if (name && name[0]) {
if (!device->name || of_node_cmp(name, device->name))
return 0;
score++;
}
return score;
}
/** Checks if the given "compat" string matches one of the strings in
@ -375,7 +420,7 @@ int of_device_is_compatible(const struct device_node *device,
int res;
raw_spin_lock_irqsave(&devtree_lock, flags);
res = __of_device_is_compatible(device, compat);
res = __of_device_is_compatible(device, compat, NULL, NULL);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return res;
}
@ -681,10 +726,7 @@ struct device_node *of_find_compatible_node(struct device_node *from,
raw_spin_lock_irqsave(&devtree_lock, flags);
np = from ? from->allnext : of_allnodes;
for (; np; np = np->allnext) {
if (type
&& !(np->type && (of_node_cmp(np->type, type) == 0)))
continue;
if (__of_device_is_compatible(np, compatible) &&
if (__of_device_is_compatible(np, compatible, type, NULL) &&
of_node_get(np))
break;
}
@ -734,43 +776,22 @@ static
const struct of_device_id *__of_match_node(const struct of_device_id *matches,
const struct device_node *node)
{
const char *cp;
int cplen, l;
const struct of_device_id *best_match = NULL;
int score, best_score = 0;
if (!matches)
return NULL;
cp = __of_get_property(node, "compatible", &cplen);
do {
const struct of_device_id *m = matches;
/* Check against matches with current compatible string */
while (m->name[0] || m->type[0] || m->compatible[0]) {
int match = 1;
if (m->name[0])
match &= node->name
&& !strcmp(m->name, node->name);
if (m->type[0])
match &= node->type
&& !strcmp(m->type, node->type);
if (m->compatible[0])
match &= cp
&& !of_compat_cmp(m->compatible, cp,
strlen(m->compatible));
if (match)
return m;
m++;
for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
score = __of_device_is_compatible(node, matches->compatible,
matches->type, matches->name);
if (score > best_score) {
best_match = matches;
best_score = score;
}
}
/* Get node's next compatible string */
if (cp) {
l = strlen(cp) + 1;
cp += l;
cplen -= l;
}
} while (cp && (cplen > 0));
return NULL;
return best_match;
}
/**
@ -778,10 +799,7 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
* @matches: array of of device match structures to search in
* @node: the of device structure to match against
*
* Low level utility function used by device matching. Matching order
* is to compare each of the node's compatibles with all given matches
* first. This implies node's compatible is sorted from specific to
* generic while matches can be in any order.
* Low level utility function used by device matching.
*/
const struct of_device_id *of_match_node(const struct of_device_id *matches,
const struct device_node *node)

View file

@ -24,7 +24,11 @@ MODULE_LICENSE("GPL");
static void of_set_phy_supported(struct phy_device *phydev, u32 max_speed)
{
phydev->supported |= PHY_DEFAULT_FEATURES;
/* The default values for phydev->supported are provided by the PHY
* driver "features" member, we want to reset to sane defaults fist
* before supporting higher speeds.
*/
phydev->supported &= PHY_DEFAULT_FEATURES;
switch (max_speed) {
default:
@ -44,7 +48,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
{
struct phy_device *phy;
bool is_c45;
int rc, prev_irq;
int rc;
u32 max_speed = 0;
is_c45 = of_device_is_compatible(child,
@ -54,12 +58,14 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
if (!phy || IS_ERR(phy))
return 1;
if (mdio->irq) {
prev_irq = mdio->irq[addr];
mdio->irq[addr] =
irq_of_parse_and_map(child, 0);
if (!mdio->irq[addr])
mdio->irq[addr] = prev_irq;
rc = irq_of_parse_and_map(child, 0);
if (rc > 0) {
phy->irq = rc;
if (mdio->irq)
mdio->irq[addr] = rc;
} else {
if (mdio->irq)
phy->irq = mdio->irq[addr];
}
/* Associate the OF node with the device structure so it

View file

@ -300,6 +300,72 @@ static void __init of_selftest_parse_interrupts_extended(void)
of_node_put(np);
}
static struct of_device_id match_node_table[] = {
{ .data = "A", .name = "name0", }, /* Name alone is lowest priority */
{ .data = "B", .type = "type1", }, /* followed by type alone */
{ .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */
{ .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */
{ .data = "Cc", .name = "name2", .type = "type2", },
{ .data = "E", .compatible = "compat3" },
{ .data = "G", .compatible = "compat2", },
{ .data = "H", .compatible = "compat2", .name = "name5", },
{ .data = "I", .compatible = "compat2", .type = "type1", },
{ .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", },
{ .data = "K", .compatible = "compat2", .name = "name9", },
{}
};
static struct {
const char *path;
const char *data;
} match_node_tests[] = {
{ .path = "/testcase-data/match-node/name0", .data = "A", },
{ .path = "/testcase-data/match-node/name1", .data = "B", },
{ .path = "/testcase-data/match-node/a/name2", .data = "Ca", },
{ .path = "/testcase-data/match-node/b/name2", .data = "Cb", },
{ .path = "/testcase-data/match-node/c/name2", .data = "Cc", },
{ .path = "/testcase-data/match-node/name3", .data = "E", },
{ .path = "/testcase-data/match-node/name4", .data = "G", },
{ .path = "/testcase-data/match-node/name5", .data = "H", },
{ .path = "/testcase-data/match-node/name6", .data = "G", },
{ .path = "/testcase-data/match-node/name7", .data = "I", },
{ .path = "/testcase-data/match-node/name8", .data = "J", },
{ .path = "/testcase-data/match-node/name9", .data = "K", },
};
static void __init of_selftest_match_node(void)
{
struct device_node *np;
const struct of_device_id *match;
int i;
for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) {
np = of_find_node_by_path(match_node_tests[i].path);
if (!np) {
selftest(0, "missing testcase node %s\n",
match_node_tests[i].path);
continue;
}
match = of_match_node(match_node_table, np);
if (!match) {
selftest(0, "%s didn't match anything\n",
match_node_tests[i].path);
continue;
}
if (strcmp(match->data, match_node_tests[i].data) != 0) {
selftest(0, "%s got wrong match. expected %s, got %s\n",
match_node_tests[i].path, match_node_tests[i].data,
(const char *)match->data);
continue;
}
selftest(1, "passed");
}
}
static int __init of_selftest(void)
{
struct device_node *np;
@ -316,6 +382,7 @@ static int __init of_selftest(void)
of_selftest_property_match_string();
of_selftest_parse_interrupts();
of_selftest_parse_interrupts_extended();
of_selftest_match_node();
pr_info("end of selftest - %i passed, %i failed\n",
selftest_results.passed, selftest_results.failed);
return 0;

View file

@ -0,0 +1,3 @@
#include "tests-phandle.dtsi"
#include "tests-interrupts.dtsi"
#include "tests-match.dtsi"

View file

@ -0,0 +1,58 @@
/ {
testcase-data {
interrupts {
#address-cells = <1>;
#size-cells = <1>;
test_intc0: intc0 {
interrupt-controller;
#interrupt-cells = <1>;
};
test_intc1: intc1 {
interrupt-controller;
#interrupt-cells = <3>;
};
test_intc2: intc2 {
interrupt-controller;
#interrupt-cells = <2>;
};
test_intmap0: intmap0 {
#interrupt-cells = <1>;
#address-cells = <0>;
interrupt-map = <1 &test_intc0 9>,
<2 &test_intc1 10 11 12>,
<3 &test_intc2 13 14>,
<4 &test_intc2 15 16>;
};
test_intmap1: intmap1 {
#interrupt-cells = <2>;
interrupt-map = <0x5000 1 2 &test_intc0 15>;
};
interrupts0 {
interrupt-parent = <&test_intc0>;
interrupts = <1>, <2>, <3>, <4>;
};
interrupts1 {
interrupt-parent = <&test_intmap0>;
interrupts = <1>, <2>, <3>, <4>;
};
interrupts-extended0 {
reg = <0x5000 0x100>;
interrupts-extended = <&test_intc0 1>,
<&test_intc1 2 3 4>,
<&test_intc2 5 6>,
<&test_intmap0 1>,
<&test_intmap0 2>,
<&test_intmap0 3>,
<&test_intmap1 1 2>;
};
};
};
};

View file

@ -0,0 +1,19 @@
/ {
testcase-data {
match-node {
name0 { };
name1 { device_type = "type1"; };
a { name2 { device_type = "type1"; }; };
b { name2 { }; };
c { name2 { device_type = "type2"; }; };
name3 { compatible = "compat3"; };
name4 { compatible = "compat2", "compat3"; };
name5 { compatible = "compat2", "compat3"; };
name6 { compatible = "compat1", "compat2", "compat3"; };
name7 { compatible = "compat2"; device_type = "type1"; };
name8 { compatible = "compat2"; device_type = "type1"; };
name9 { compatible = "compat2"; };
};
};
};

View file

@ -0,0 +1,39 @@
/ {
testcase-data {
phandle-tests {
provider0: provider0 {
#phandle-cells = <0>;
};
provider1: provider1 {
#phandle-cells = <1>;
};
provider2: provider2 {
#phandle-cells = <2>;
};
provider3: provider3 {
#phandle-cells = <3>;
};
consumer-a {
phandle-list = <&provider1 1>,
<&provider2 2 0>,
<0>,
<&provider3 4 4 3>,
<&provider2 5 100>,
<&provider0>,
<&provider1 7>;
phandle-list-names = "first", "second", "third";
phandle-list-bad-phandle = <12345678 0 0>;
phandle-list-bad-args = <&provider2 1 0>,
<&provider3 0>;
empty-property;
unterminated-string = [40 41 42 43];
};
};
};
};