F: drivers/clk/clk-apple-nco.c
F: drivers/cpufreq/apple-soc-cpufreq.c
F: drivers/dma/apple-admac.c
+F: drivers/genpd/apple/
F: drivers/i2c/busses/i2c-pasemi-core.c
F: drivers/i2c/busses/i2c-pasemi-platform.c
F: drivers/iommu/apple-dart.c
# SPDX-License-Identifier: GPL-2.0-only
obj-y += actions/
obj-y += amlogic/
+obj-y += apple/
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_APPLE_PMGR_PWRSTATE) += pmgr-pwrstate.o
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Apple SoC PMGR device power state driver
+ *
+ * Copyright The Asahi Linux Contributors
+ */
+
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/reset-controller.h>
+#include <linux/module.h>
+
+#define APPLE_PMGR_RESET BIT(31)
+#define APPLE_PMGR_AUTO_ENABLE BIT(28)
+#define APPLE_PMGR_PS_AUTO GENMASK(27, 24)
+#define APPLE_PMGR_PS_MIN GENMASK(19, 16)
+#define APPLE_PMGR_PARENT_OFF BIT(11)
+#define APPLE_PMGR_DEV_DISABLE BIT(10)
+#define APPLE_PMGR_WAS_CLKGATED BIT(9)
+#define APPLE_PMGR_WAS_PWRGATED BIT(8)
+#define APPLE_PMGR_PS_ACTUAL GENMASK(7, 4)
+#define APPLE_PMGR_PS_TARGET GENMASK(3, 0)
+
+#define APPLE_PMGR_FLAGS (APPLE_PMGR_WAS_CLKGATED | APPLE_PMGR_WAS_PWRGATED)
+
+#define APPLE_PMGR_PS_ACTIVE 0xf
+#define APPLE_PMGR_PS_CLKGATE 0x4
+#define APPLE_PMGR_PS_PWRGATE 0x0
+
+#define APPLE_PMGR_PS_SET_TIMEOUT 100
+#define APPLE_PMGR_RESET_TIME 1
+
+struct apple_pmgr_ps {
+ struct device *dev;
+ struct generic_pm_domain genpd;
+ struct reset_controller_dev rcdev;
+ struct regmap *regmap;
+ u32 offset;
+ u32 min_state;
+};
+
+#define genpd_to_apple_pmgr_ps(_genpd) container_of(_genpd, struct apple_pmgr_ps, genpd)
+#define rcdev_to_apple_pmgr_ps(_rcdev) container_of(_rcdev, struct apple_pmgr_ps, rcdev)
+
+static int apple_pmgr_ps_set(struct generic_pm_domain *genpd, u32 pstate, bool auto_enable)
+{
+ int ret;
+ struct apple_pmgr_ps *ps = genpd_to_apple_pmgr_ps(genpd);
+ u32 reg;
+
+ ret = regmap_read(ps->regmap, ps->offset, ®);
+ if (ret < 0)
+ return ret;
+
+ /* Resets are synchronous, and only work if the device is powered and clocked. */
+ if (reg & APPLE_PMGR_RESET && pstate != APPLE_PMGR_PS_ACTIVE)
+ dev_err(ps->dev, "PS %s: powering off with RESET active\n",
+ genpd->name);
+
+ reg &= ~(APPLE_PMGR_AUTO_ENABLE | APPLE_PMGR_FLAGS | APPLE_PMGR_PS_TARGET);
+ reg |= FIELD_PREP(APPLE_PMGR_PS_TARGET, pstate);
+
+ dev_dbg(ps->dev, "PS %s: pwrstate = 0x%x: 0x%x\n", genpd->name, pstate, reg);
+
+ regmap_write(ps->regmap, ps->offset, reg);
+
+ ret = regmap_read_poll_timeout_atomic(
+ ps->regmap, ps->offset, reg,
+ (FIELD_GET(APPLE_PMGR_PS_ACTUAL, reg) == pstate), 1,
+ APPLE_PMGR_PS_SET_TIMEOUT);
+ if (ret < 0)
+ dev_err(ps->dev, "PS %s: Failed to reach power state 0x%x (now: 0x%x)\n",
+ genpd->name, pstate, reg);
+
+ if (auto_enable) {
+ /* Not all devices implement this; this is a no-op where not implemented. */
+ reg &= ~APPLE_PMGR_FLAGS;
+ reg |= APPLE_PMGR_AUTO_ENABLE;
+ regmap_write(ps->regmap, ps->offset, reg);
+ }
+
+ return ret;
+}
+
+static bool apple_pmgr_ps_is_active(struct apple_pmgr_ps *ps)
+{
+ u32 reg = 0;
+
+ regmap_read(ps->regmap, ps->offset, ®);
+ /*
+ * We consider domains as active if they are actually on, or if they have auto-PM
+ * enabled and the intended target is on.
+ */
+ return (FIELD_GET(APPLE_PMGR_PS_ACTUAL, reg) == APPLE_PMGR_PS_ACTIVE ||
+ (FIELD_GET(APPLE_PMGR_PS_TARGET, reg) == APPLE_PMGR_PS_ACTIVE &&
+ reg & APPLE_PMGR_AUTO_ENABLE));
+}
+
+static int apple_pmgr_ps_power_on(struct generic_pm_domain *genpd)
+{
+ return apple_pmgr_ps_set(genpd, APPLE_PMGR_PS_ACTIVE, true);
+}
+
+static int apple_pmgr_ps_power_off(struct generic_pm_domain *genpd)
+{
+ return apple_pmgr_ps_set(genpd, APPLE_PMGR_PS_PWRGATE, false);
+}
+
+static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ps->genpd.slock, flags);
+
+ if (ps->genpd.status == GENPD_STATE_OFF)
+ dev_err(ps->dev, "PS 0x%x: asserting RESET while powered down\n", ps->offset);
+
+ dev_dbg(ps->dev, "PS 0x%x: assert reset\n", ps->offset);
+ /* Quiesce device before asserting reset */
+ regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_DEV_DISABLE,
+ APPLE_PMGR_DEV_DISABLE);
+ regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET,
+ APPLE_PMGR_RESET);
+
+ spin_unlock_irqrestore(&ps->genpd.slock, flags);
+
+ return 0;
+}
+
+static int apple_pmgr_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ps->genpd.slock, flags);
+
+ dev_dbg(ps->dev, "PS 0x%x: deassert reset\n", ps->offset);
+ regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET, 0);
+ regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_DEV_DISABLE, 0);
+
+ if (ps->genpd.status == GENPD_STATE_OFF)
+ dev_err(ps->dev, "PS 0x%x: RESET was deasserted while powered down\n", ps->offset);
+
+ spin_unlock_irqrestore(&ps->genpd.slock, flags);
+
+ return 0;
+}
+
+static int apple_pmgr_reset_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ int ret;
+
+ ret = apple_pmgr_reset_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ usleep_range(APPLE_PMGR_RESET_TIME, 2 * APPLE_PMGR_RESET_TIME);
+
+ return apple_pmgr_reset_deassert(rcdev, id);
+}
+
+static int apple_pmgr_reset_status(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
+ u32 reg = 0;
+
+ regmap_read(ps->regmap, ps->offset, ®);
+
+ return !!(reg & APPLE_PMGR_RESET);
+}
+
+const struct reset_control_ops apple_pmgr_reset_ops = {
+ .assert = apple_pmgr_reset_assert,
+ .deassert = apple_pmgr_reset_deassert,
+ .reset = apple_pmgr_reset_reset,
+ .status = apple_pmgr_reset_status,
+};
+
+static int apple_pmgr_reset_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+ return 0;
+}
+
+static int apple_pmgr_ps_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct apple_pmgr_ps *ps;
+ struct regmap *regmap;
+ struct of_phandle_iterator it;
+ int ret;
+ const char *name;
+ bool active;
+
+ regmap = syscon_node_to_regmap(node->parent);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ ps = devm_kzalloc(dev, sizeof(*ps), GFP_KERNEL);
+ if (!ps)
+ return -ENOMEM;
+
+ ps->dev = dev;
+ ps->regmap = regmap;
+
+ ret = of_property_read_string(node, "label", &name);
+ if (ret < 0) {
+ dev_err(dev, "missing label property\n");
+ return ret;
+ }
+
+ ret = of_property_read_u32(node, "reg", &ps->offset);
+ if (ret < 0) {
+ dev_err(dev, "missing reg property\n");
+ return ret;
+ }
+
+ ps->genpd.flags |= GENPD_FLAG_IRQ_SAFE;
+ ps->genpd.name = name;
+ ps->genpd.power_on = apple_pmgr_ps_power_on;
+ ps->genpd.power_off = apple_pmgr_ps_power_off;
+
+ ret = of_property_read_u32(node, "apple,min-state", &ps->min_state);
+ if (ret == 0 && ps->min_state <= APPLE_PMGR_PS_ACTIVE)
+ regmap_update_bits(regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_PS_MIN,
+ FIELD_PREP(APPLE_PMGR_PS_MIN, ps->min_state));
+
+ active = apple_pmgr_ps_is_active(ps);
+ if (of_property_read_bool(node, "apple,always-on")) {
+ ps->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
+ if (!active) {
+ dev_warn(dev, "always-on domain %s is not on at boot\n", name);
+ /* Turn it on so pm_genpd_init does not fail */
+ active = apple_pmgr_ps_power_on(&ps->genpd) == 0;
+ }
+ }
+
+ /* Turn on auto-PM if the domain is already on */
+ if (active)
+ regmap_update_bits(regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_AUTO_ENABLE,
+ APPLE_PMGR_AUTO_ENABLE);
+
+ ret = pm_genpd_init(&ps->genpd, NULL, !active);
+ if (ret < 0) {
+ dev_err(dev, "pm_genpd_init failed\n");
+ return ret;
+ }
+
+ ret = of_genpd_add_provider_simple(node, &ps->genpd);
+ if (ret < 0) {
+ dev_err(dev, "of_genpd_add_provider_simple failed\n");
+ return ret;
+ }
+
+ of_for_each_phandle(&it, ret, node, "power-domains", "#power-domain-cells", -1) {
+ struct of_phandle_args parent, child;
+
+ parent.np = it.node;
+ parent.args_count = of_phandle_iterator_args(&it, parent.args, MAX_PHANDLE_ARGS);
+ child.np = node;
+ child.args_count = 0;
+ ret = of_genpd_add_subdomain(&parent, &child);
+
+ if (ret == -EPROBE_DEFER) {
+ of_node_put(parent.np);
+ goto err_remove;
+ } else if (ret < 0) {
+ dev_err(dev, "failed to add to parent domain: %d (%s -> %s)\n",
+ ret, it.node->name, node->name);
+ of_node_put(parent.np);
+ goto err_remove;
+ }
+ }
+
+ /*
+ * Do not participate in regular PM; parent power domains are handled via the
+ * genpd hierarchy.
+ */
+ pm_genpd_remove_device(dev);
+
+ ps->rcdev.owner = THIS_MODULE;
+ ps->rcdev.nr_resets = 1;
+ ps->rcdev.ops = &apple_pmgr_reset_ops;
+ ps->rcdev.of_node = dev->of_node;
+ ps->rcdev.of_reset_n_cells = 0;
+ ps->rcdev.of_xlate = apple_pmgr_reset_xlate;
+
+ ret = devm_reset_controller_register(dev, &ps->rcdev);
+ if (ret < 0)
+ goto err_remove;
+
+ return 0;
+err_remove:
+ of_genpd_del_provider(node);
+ pm_genpd_remove(&ps->genpd);
+ return ret;
+}
+
+static const struct of_device_id apple_pmgr_ps_of_match[] = {
+ { .compatible = "apple,pmgr-pwrstate" },
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, apple_pmgr_ps_of_match);
+
+static struct platform_driver apple_pmgr_ps_driver = {
+ .probe = apple_pmgr_ps_probe,
+ .driver = {
+ .name = "apple-pmgr-pwrstate",
+ .of_match_table = apple_pmgr_ps_of_match,
+ },
+};
+
+MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
+MODULE_DESCRIPTION("PMGR power state driver for Apple SoCs");
+
+module_platform_driver(apple_pmgr_ps_driver);
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_APPLE_PMGR_PWRSTATE) += apple-pmgr-pwrstate.o
-
obj-$(CONFIG_APPLE_RTKIT) += apple-rtkit.o
apple-rtkit-y = rtkit.o rtkit-crashlog.o
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-only OR MIT
-/*
- * Apple SoC PMGR device power state driver
- *
- * Copyright The Asahi Linux Contributors
- */
-
-#include <linux/bitops.h>
-#include <linux/bitfield.h>
-#include <linux/err.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/pm_domain.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
-#include <linux/reset-controller.h>
-#include <linux/module.h>
-
-#define APPLE_PMGR_RESET BIT(31)
-#define APPLE_PMGR_AUTO_ENABLE BIT(28)
-#define APPLE_PMGR_PS_AUTO GENMASK(27, 24)
-#define APPLE_PMGR_PS_MIN GENMASK(19, 16)
-#define APPLE_PMGR_PARENT_OFF BIT(11)
-#define APPLE_PMGR_DEV_DISABLE BIT(10)
-#define APPLE_PMGR_WAS_CLKGATED BIT(9)
-#define APPLE_PMGR_WAS_PWRGATED BIT(8)
-#define APPLE_PMGR_PS_ACTUAL GENMASK(7, 4)
-#define APPLE_PMGR_PS_TARGET GENMASK(3, 0)
-
-#define APPLE_PMGR_FLAGS (APPLE_PMGR_WAS_CLKGATED | APPLE_PMGR_WAS_PWRGATED)
-
-#define APPLE_PMGR_PS_ACTIVE 0xf
-#define APPLE_PMGR_PS_CLKGATE 0x4
-#define APPLE_PMGR_PS_PWRGATE 0x0
-
-#define APPLE_PMGR_PS_SET_TIMEOUT 100
-#define APPLE_PMGR_RESET_TIME 1
-
-struct apple_pmgr_ps {
- struct device *dev;
- struct generic_pm_domain genpd;
- struct reset_controller_dev rcdev;
- struct regmap *regmap;
- u32 offset;
- u32 min_state;
-};
-
-#define genpd_to_apple_pmgr_ps(_genpd) container_of(_genpd, struct apple_pmgr_ps, genpd)
-#define rcdev_to_apple_pmgr_ps(_rcdev) container_of(_rcdev, struct apple_pmgr_ps, rcdev)
-
-static int apple_pmgr_ps_set(struct generic_pm_domain *genpd, u32 pstate, bool auto_enable)
-{
- int ret;
- struct apple_pmgr_ps *ps = genpd_to_apple_pmgr_ps(genpd);
- u32 reg;
-
- ret = regmap_read(ps->regmap, ps->offset, ®);
- if (ret < 0)
- return ret;
-
- /* Resets are synchronous, and only work if the device is powered and clocked. */
- if (reg & APPLE_PMGR_RESET && pstate != APPLE_PMGR_PS_ACTIVE)
- dev_err(ps->dev, "PS %s: powering off with RESET active\n",
- genpd->name);
-
- reg &= ~(APPLE_PMGR_AUTO_ENABLE | APPLE_PMGR_FLAGS | APPLE_PMGR_PS_TARGET);
- reg |= FIELD_PREP(APPLE_PMGR_PS_TARGET, pstate);
-
- dev_dbg(ps->dev, "PS %s: pwrstate = 0x%x: 0x%x\n", genpd->name, pstate, reg);
-
- regmap_write(ps->regmap, ps->offset, reg);
-
- ret = regmap_read_poll_timeout_atomic(
- ps->regmap, ps->offset, reg,
- (FIELD_GET(APPLE_PMGR_PS_ACTUAL, reg) == pstate), 1,
- APPLE_PMGR_PS_SET_TIMEOUT);
- if (ret < 0)
- dev_err(ps->dev, "PS %s: Failed to reach power state 0x%x (now: 0x%x)\n",
- genpd->name, pstate, reg);
-
- if (auto_enable) {
- /* Not all devices implement this; this is a no-op where not implemented. */
- reg &= ~APPLE_PMGR_FLAGS;
- reg |= APPLE_PMGR_AUTO_ENABLE;
- regmap_write(ps->regmap, ps->offset, reg);
- }
-
- return ret;
-}
-
-static bool apple_pmgr_ps_is_active(struct apple_pmgr_ps *ps)
-{
- u32 reg = 0;
-
- regmap_read(ps->regmap, ps->offset, ®);
- /*
- * We consider domains as active if they are actually on, or if they have auto-PM
- * enabled and the intended target is on.
- */
- return (FIELD_GET(APPLE_PMGR_PS_ACTUAL, reg) == APPLE_PMGR_PS_ACTIVE ||
- (FIELD_GET(APPLE_PMGR_PS_TARGET, reg) == APPLE_PMGR_PS_ACTIVE &&
- reg & APPLE_PMGR_AUTO_ENABLE));
-}
-
-static int apple_pmgr_ps_power_on(struct generic_pm_domain *genpd)
-{
- return apple_pmgr_ps_set(genpd, APPLE_PMGR_PS_ACTIVE, true);
-}
-
-static int apple_pmgr_ps_power_off(struct generic_pm_domain *genpd)
-{
- return apple_pmgr_ps_set(genpd, APPLE_PMGR_PS_PWRGATE, false);
-}
-
-static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
-{
- struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
- unsigned long flags;
-
- spin_lock_irqsave(&ps->genpd.slock, flags);
-
- if (ps->genpd.status == GENPD_STATE_OFF)
- dev_err(ps->dev, "PS 0x%x: asserting RESET while powered down\n", ps->offset);
-
- dev_dbg(ps->dev, "PS 0x%x: assert reset\n", ps->offset);
- /* Quiesce device before asserting reset */
- regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_DEV_DISABLE,
- APPLE_PMGR_DEV_DISABLE);
- regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET,
- APPLE_PMGR_RESET);
-
- spin_unlock_irqrestore(&ps->genpd.slock, flags);
-
- return 0;
-}
-
-static int apple_pmgr_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
-{
- struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
- unsigned long flags;
-
- spin_lock_irqsave(&ps->genpd.slock, flags);
-
- dev_dbg(ps->dev, "PS 0x%x: deassert reset\n", ps->offset);
- regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET, 0);
- regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_DEV_DISABLE, 0);
-
- if (ps->genpd.status == GENPD_STATE_OFF)
- dev_err(ps->dev, "PS 0x%x: RESET was deasserted while powered down\n", ps->offset);
-
- spin_unlock_irqrestore(&ps->genpd.slock, flags);
-
- return 0;
-}
-
-static int apple_pmgr_reset_reset(struct reset_controller_dev *rcdev, unsigned long id)
-{
- int ret;
-
- ret = apple_pmgr_reset_assert(rcdev, id);
- if (ret)
- return ret;
-
- usleep_range(APPLE_PMGR_RESET_TIME, 2 * APPLE_PMGR_RESET_TIME);
-
- return apple_pmgr_reset_deassert(rcdev, id);
-}
-
-static int apple_pmgr_reset_status(struct reset_controller_dev *rcdev, unsigned long id)
-{
- struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
- u32 reg = 0;
-
- regmap_read(ps->regmap, ps->offset, ®);
-
- return !!(reg & APPLE_PMGR_RESET);
-}
-
-const struct reset_control_ops apple_pmgr_reset_ops = {
- .assert = apple_pmgr_reset_assert,
- .deassert = apple_pmgr_reset_deassert,
- .reset = apple_pmgr_reset_reset,
- .status = apple_pmgr_reset_status,
-};
-
-static int apple_pmgr_reset_xlate(struct reset_controller_dev *rcdev,
- const struct of_phandle_args *reset_spec)
-{
- return 0;
-}
-
-static int apple_pmgr_ps_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct device_node *node = dev->of_node;
- struct apple_pmgr_ps *ps;
- struct regmap *regmap;
- struct of_phandle_iterator it;
- int ret;
- const char *name;
- bool active;
-
- regmap = syscon_node_to_regmap(node->parent);
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- ps = devm_kzalloc(dev, sizeof(*ps), GFP_KERNEL);
- if (!ps)
- return -ENOMEM;
-
- ps->dev = dev;
- ps->regmap = regmap;
-
- ret = of_property_read_string(node, "label", &name);
- if (ret < 0) {
- dev_err(dev, "missing label property\n");
- return ret;
- }
-
- ret = of_property_read_u32(node, "reg", &ps->offset);
- if (ret < 0) {
- dev_err(dev, "missing reg property\n");
- return ret;
- }
-
- ps->genpd.flags |= GENPD_FLAG_IRQ_SAFE;
- ps->genpd.name = name;
- ps->genpd.power_on = apple_pmgr_ps_power_on;
- ps->genpd.power_off = apple_pmgr_ps_power_off;
-
- ret = of_property_read_u32(node, "apple,min-state", &ps->min_state);
- if (ret == 0 && ps->min_state <= APPLE_PMGR_PS_ACTIVE)
- regmap_update_bits(regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_PS_MIN,
- FIELD_PREP(APPLE_PMGR_PS_MIN, ps->min_state));
-
- active = apple_pmgr_ps_is_active(ps);
- if (of_property_read_bool(node, "apple,always-on")) {
- ps->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
- if (!active) {
- dev_warn(dev, "always-on domain %s is not on at boot\n", name);
- /* Turn it on so pm_genpd_init does not fail */
- active = apple_pmgr_ps_power_on(&ps->genpd) == 0;
- }
- }
-
- /* Turn on auto-PM if the domain is already on */
- if (active)
- regmap_update_bits(regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_AUTO_ENABLE,
- APPLE_PMGR_AUTO_ENABLE);
-
- ret = pm_genpd_init(&ps->genpd, NULL, !active);
- if (ret < 0) {
- dev_err(dev, "pm_genpd_init failed\n");
- return ret;
- }
-
- ret = of_genpd_add_provider_simple(node, &ps->genpd);
- if (ret < 0) {
- dev_err(dev, "of_genpd_add_provider_simple failed\n");
- return ret;
- }
-
- of_for_each_phandle(&it, ret, node, "power-domains", "#power-domain-cells", -1) {
- struct of_phandle_args parent, child;
-
- parent.np = it.node;
- parent.args_count = of_phandle_iterator_args(&it, parent.args, MAX_PHANDLE_ARGS);
- child.np = node;
- child.args_count = 0;
- ret = of_genpd_add_subdomain(&parent, &child);
-
- if (ret == -EPROBE_DEFER) {
- of_node_put(parent.np);
- goto err_remove;
- } else if (ret < 0) {
- dev_err(dev, "failed to add to parent domain: %d (%s -> %s)\n",
- ret, it.node->name, node->name);
- of_node_put(parent.np);
- goto err_remove;
- }
- }
-
- /*
- * Do not participate in regular PM; parent power domains are handled via the
- * genpd hierarchy.
- */
- pm_genpd_remove_device(dev);
-
- ps->rcdev.owner = THIS_MODULE;
- ps->rcdev.nr_resets = 1;
- ps->rcdev.ops = &apple_pmgr_reset_ops;
- ps->rcdev.of_node = dev->of_node;
- ps->rcdev.of_reset_n_cells = 0;
- ps->rcdev.of_xlate = apple_pmgr_reset_xlate;
-
- ret = devm_reset_controller_register(dev, &ps->rcdev);
- if (ret < 0)
- goto err_remove;
-
- return 0;
-err_remove:
- of_genpd_del_provider(node);
- pm_genpd_remove(&ps->genpd);
- return ret;
-}
-
-static const struct of_device_id apple_pmgr_ps_of_match[] = {
- { .compatible = "apple,pmgr-pwrstate" },
- {}
-};
-
-MODULE_DEVICE_TABLE(of, apple_pmgr_ps_of_match);
-
-static struct platform_driver apple_pmgr_ps_driver = {
- .probe = apple_pmgr_ps_probe,
- .driver = {
- .name = "apple-pmgr-pwrstate",
- .of_match_table = apple_pmgr_ps_of_match,
- },
-};
-
-MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
-MODULE_DESCRIPTION("PMGR power state driver for Apple SoCs");
-
-module_platform_driver(apple_pmgr_ps_driver);