[PATCH] arm64: reboot driver missing dts entry and ACPI support for storm platform.
Feng Kan
fkan at apm.com
Fri Nov 8 14:13:30 EST 2013
Signed-off-by: Feng Kan <fkan at apm.com>
---
arch/arm64/boot/dts/apm-storm.dtsi | 5 ++
drivers/power/reset/Kconfig | 5 +-
drivers/power/reset/xgene-reboot.c | 94 +++++++++++++++++++++++++++++++-----
3 files changed, 88 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
index bfdc578..4478bee 100644
--- a/arch/arm64/boot/dts/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm-storm.dtsi
@@ -112,5 +112,10 @@
interrupt-parent = <&gic>;
interrupts = <0x0 0x4c 0x4>;
};
+
+ reboot at 17000014 {
+ compatible = "apm,xgene-reboot";
+ reg = <0x0 0x17000014 0x0 0x4>;
+ };
};
};
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 9b3ea53..84883bc 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -39,7 +39,7 @@ config POWER_RESET_RESTART
config POWER_RESET_VEXPRESS
bool "ARM Versatile Express power-off and reset driver"
- depends on ARM || ARM64
+ depends on (ARM || ARM64) && ARCH_VEXPRESS
depends on POWER_RESET && VEXPRESS_CONFIG
help
Power off and reset support for the ARM Ltd. Versatile
@@ -47,7 +47,6 @@ config POWER_RESET_VEXPRESS
config POWER_RESET_XGENE
bool "APM SoC X-Gene reset driver"
- depends on ARM64
- depends on POWER_RESET
+ default y if (ARM64 && ARCH_XGENE && POWER_RESET)
help
Reboot support for the APM SoC X-Gene Eval boards.
diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index ecd55f8..856fed1 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -30,6 +30,8 @@
#include <linux/platform_device.h>
#include <linux/stat.h>
#include <linux/slab.h>
+#include <linux/acpi.h>
+#include <linux/efi.h>
#include <asm/system_misc.h>
struct xgene_reboot_context {
@@ -40,7 +42,7 @@ struct xgene_reboot_context {
static struct xgene_reboot_context *xgene_restart_ctx;
-static void xgene_restart(char str, const char *cmd)
+static void xgene_restart(enum reboot_mode reboot_mode, const char *cmd)
{
struct xgene_reboot_context *ctx = xgene_restart_ctx;
unsigned long timeout;
@@ -56,48 +58,114 @@ static void xgene_restart(char str, const char *cmd)
dev_emerg(&ctx->pdev->dev, "Unable to restart system\n");
}
+static int xgene_reboot_get_resource(struct platform_device *pdev, int index,
+ struct resource *res)
+{
+ struct resource *regs;
+ if (efi_enabled(EFI_BOOT)) {
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, index);
+ if (regs == NULL)
+ return -ENODEV;
+ *res = *regs;
+ return 0;
+ }
+ return of_address_to_resource(pdev->dev.of_node, index, res);
+}
+
+static int xgene_reboot_get_u32_param(struct platform_device *pdev,
+ const char *of_name, char *acpi_name,
+ u32 *param)
+{
+#ifdef CONFIG_ACPI
+ if (efi_enabled(EFI_BOOT)) {
+ unsigned long long value;
+ acpi_status status;
+ if (acpi_name == NULL)
+ return -ENODEV;
+ status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
+ acpi_name, NULL, &value);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+ *param = value;
+ return 0;
+ }
+#endif
+ if (of_name == NULL)
+ return -ENODEV;
+ return of_property_read_u32(pdev->dev.of_node, of_name, param);
+}
+
static int xgene_reboot_probe(struct platform_device *pdev)
{
struct xgene_reboot_context *ctx;
+ struct resource res;
+ int rc;
+
+ /* Skip the ACPI probe if booting via DTS */
+ if (!efi_enabled(EFI_BOOT) && !pdev->dev.of_node)
+ goto error;
+
+ rc = xgene_reboot_get_resource(pdev, 0, &res);
+ if (rc) {
+ dev_err(&pdev->dev, "no resource address\n");
+ goto error;
+ }
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
dev_err(&pdev->dev, "out of memory for context\n");
- return -ENODEV;
+ goto error;
}
- ctx->csr = of_iomap(pdev->dev.of_node, 0);
+ ctx->csr = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
if (!ctx->csr) {
- devm_kfree(&pdev->dev, ctx);
- dev_err(&pdev->dev, "can not map resource\n");
- return -ENODEV;
+ dev_err(&pdev->dev, "can't map CSR resource\n");
+ rc = -ENOMEM;
+ goto error;
}
- if (of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask))
- ctx->mask = 0xFFFFFFFF;
+ ctx->mask = 0x1;
+
+ dev_info(&pdev->dev, "X-Gene register reboot driver\n");
ctx->pdev = pdev;
arm_pm_restart = xgene_restart;
xgene_restart_ctx = ctx;
-
return 0;
+
+error:
+ if (ctx->csr)
+ devm_iounmap(&pdev->dev, ctx->csr);
+ devm_kfree(&pdev->dev, ctx);
+ return rc;
}
static struct of_device_id xgene_reboot_of_match[] = {
- { .compatible = "apm,xgene-reboot" },
+ {.compatible = "apm,xgene-reboot"},
{}
};
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id xgene_reset_acpi_ids[] = {
+ {"APMC0D00", 0},
+ {}
+};
+#endif
+
static struct platform_driver xgene_reboot_driver = {
.probe = xgene_reboot_probe,
.driver = {
- .name = "xgene-reboot",
- .of_match_table = xgene_reboot_of_match,
- },
+ .name = "xgene-reboot",
+ .of_match_table = xgene_reboot_of_match,
+#ifdef CONFIG_ACPI
+ .acpi_match_table = ACPI_PTR(xgene_reset_acpi_ids),
+#endif
+ }
};
static int __init xgene_reboot_init(void)
{
return platform_driver_register(&xgene_reboot_driver);
}
+
device_initcall(xgene_reboot_init);
--
1.7.6.1
More information about the linux-arm-kernel
mailing list