mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
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:
commit
dab2310d9d
1196 changed files with 14561 additions and 7288 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
3
drivers/of/testcase-data/testcases.dtsi
Normal file
3
drivers/of/testcase-data/testcases.dtsi
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#include "tests-phandle.dtsi"
|
||||
#include "tests-interrupts.dtsi"
|
||||
#include "tests-match.dtsi"
|
||||
58
drivers/of/testcase-data/tests-interrupts.dtsi
Normal file
58
drivers/of/testcase-data/tests-interrupts.dtsi
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
19
drivers/of/testcase-data/tests-match.dtsi
Normal file
19
drivers/of/testcase-data/tests-match.dtsi
Normal 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"; };
|
||||
};
|
||||
};
|
||||
};
|
||||
39
drivers/of/testcase-data/tests-phandle.dtsi
Normal file
39
drivers/of/testcase-data/tests-phandle.dtsi
Normal 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];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
Loading…
Reference in a new issue