aboutsummaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorLinus Torvalds2017-05-09 10:01:15 -0700
committerLinus Torvalds2017-05-09 10:01:15 -0700
commit0160e00ae8e987be8822745fb166aa76451c9bcc (patch)
treedeca2d09a729155ed0cb631f2bc8f557e634ab06 /drivers/base
parentc81ee18e97e4e3162169a749eb7f2b79b3510c7a (diff)
parentb6942b68f85ed3161c91741791ec6f1779574919 (diff)
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson: "Driver updates for ARM SoCs: Reset subsystem, merged through arm-soc by tradition: - Make bool drivers explicitly non-modular - New support for i.MX7 and Arria10 reset controllers PATA driver for Palmchip BK371 (acked by Tejun) Power domain drivers for i.MX (GPC, GPCv2) - Moved out of mach-imx for GPC - Bunch of tweaks, fixes, etc PMC support for Tegra186 SoC detection support for Renesas RZ/G1H and RZ/G1N Move Tegra flow controller driver from mach directory to drivers/soc - (Power management / CPU power driver) Misc smaller tweaks for other platforms" * tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (60 commits) soc: pm-domain: Fix the mangled urls soc: renesas: rcar-sysc: Add support for R-Car H3 ES2.0 soc: renesas: rcar-sysc: Add support for fixing up power area tables soc: renesas: Register SoC device early soc: imx: gpc: add workaround for i.MX6QP to the GPC PD driver dt-bindings: imx-gpc: add i.MX6 QuadPlus compatible soc: imx: gpc: add defines for domain index soc: imx: Add GPCv2 power gating driver dt-bindings: Add GPCv2 power gating driver ARM/clk: move the ICST library to drivers/clk ARM: plat-versatile: remove stale clock header ARM: keystone: Drop PM domain support for k2g soc: ti: Add ti_sci_pm_domains driver dt-bindings: Add TI SCI PM Domains PM / Domains: Do not check if simple providers have phandle cells PM / Domains: Add generic data pointer to genpd data struct soc/tegra: Add initial flowctrl support for Tegra132/210 soc/tegra: flowctrl: Add basic platform driver soc/tegra: Move Tegra flowctrl driver ARM: tegra: Remove unnecessary inclusion of flowctrl header ...
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/domain.c2
-rw-r--r--drivers/base/soc.c52
2 files changed, 34 insertions, 20 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index ad196427b4f2..da49a8383dc3 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1636,8 +1636,6 @@ static struct generic_pm_domain *genpd_xlate_simple(
struct of_phandle_args *genpdspec,
void *data)
{
- if (genpdspec->args_count != 0)
- return ERR_PTR(-EINVAL);
return data;
}
diff --git a/drivers/base/soc.c b/drivers/base/soc.c
index dc26e5949a32..909dedae4c4e 100644
--- a/drivers/base/soc.c
+++ b/drivers/base/soc.c
@@ -109,15 +109,18 @@ static void soc_release(struct device *dev)
kfree(soc_dev);
}
+static struct soc_device_attribute *early_soc_dev_attr;
+
struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr)
{
struct soc_device *soc_dev;
int ret;
if (!soc_bus_type.p) {
- ret = bus_register(&soc_bus_type);
- if (ret)
- goto out1;
+ if (early_soc_dev_attr)
+ return ERR_PTR(-EBUSY);
+ early_soc_dev_attr = soc_dev_attr;
+ return NULL;
}
soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL);
@@ -159,45 +162,53 @@ void soc_device_unregister(struct soc_device *soc_dev)
ida_simple_remove(&soc_ida, soc_dev->soc_dev_num);
device_unregister(&soc_dev->dev);
+ early_soc_dev_attr = NULL;
}
static int __init soc_bus_register(void)
{
- if (soc_bus_type.p)
- return 0;
+ int ret;
- return bus_register(&soc_bus_type);
+ ret = bus_register(&soc_bus_type);
+ if (ret)
+ return ret;
+
+ if (early_soc_dev_attr)
+ return PTR_ERR(soc_device_register(early_soc_dev_attr));
+
+ return 0;
}
core_initcall(soc_bus_register);
-static int soc_device_match_one(struct device *dev, void *arg)
+static int soc_device_match_attr(const struct soc_device_attribute *attr,
+ const struct soc_device_attribute *match)
{
- struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
- const struct soc_device_attribute *match = arg;
-
if (match->machine &&
- (!soc_dev->attr->machine ||
- !glob_match(match->machine, soc_dev->attr->machine)))
+ (!attr->machine || !glob_match(match->machine, attr->machine)))
return 0;
if (match->family &&
- (!soc_dev->attr->family ||
- !glob_match(match->family, soc_dev->attr->family)))
+ (!attr->family || !glob_match(match->family, attr->family)))
return 0;
if (match->revision &&
- (!soc_dev->attr->revision ||
- !glob_match(match->revision, soc_dev->attr->revision)))
+ (!attr->revision || !glob_match(match->revision, attr->revision)))
return 0;
if (match->soc_id &&
- (!soc_dev->attr->soc_id ||
- !glob_match(match->soc_id, soc_dev->attr->soc_id)))
+ (!attr->soc_id || !glob_match(match->soc_id, attr->soc_id)))
return 0;
return 1;
}
+static int soc_device_match_one(struct device *dev, void *arg)
+{
+ struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
+
+ return soc_device_match_attr(soc_dev->attr, arg);
+}
+
/*
* soc_device_match - identify the SoC in the machine
* @matches: zero-terminated array of possible matches
@@ -230,6 +241,11 @@ const struct soc_device_attribute *soc_device_match(
break;
ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches,
soc_device_match_one);
+ if (ret < 0 && early_soc_dev_attr)
+ ret = soc_device_match_attr(early_soc_dev_attr,
+ matches);
+ if (ret < 0)
+ return NULL;
if (!ret)
matches++;
else