From 35049f08312147a88270c493c20c8a103daf29a9 Mon Sep 17 00:00:00 2001 From: Donghyeok Choe Date: Mon, 18 Mar 2019 11:27:27 +0900 Subject: [PATCH] [RAMEN9610-14210][COMMON] samsung: handler: introduce exynos-handler functions This patch adds new feature of exynos-hanlder. It can include several specific interrupt handler for debugging. Change-Id: I23f1a9775ea7ea44ec07d9b1979666f621a9d047 Signed-off-by: Donghyeok Choe --- drivers/soc/samsung/debug/Makefile | 1 + drivers/soc/samsung/debug/exynos-handler.c | 112 +++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 drivers/soc/samsung/debug/exynos-handler.c diff --git a/drivers/soc/samsung/debug/Makefile b/drivers/soc/samsung/debug/Makefile index 388e0b1a3f64..b8df2478710f 100644 --- a/drivers/soc/samsung/debug/Makefile +++ b/drivers/soc/samsung/debug/Makefile @@ -14,5 +14,6 @@ obj-$(CONFIG_EXYNOS_ITMON) += exynos9820-itmon.o endif ifeq ($(CONFIG_DEBUG_SNAPSHOT),y) obj-$(CONFIG_ARCH_EXYNOS) += exynos-helper.o +obj-$(CONFIG_ARCH_EXYNOS) += exynos-handler.o endif obj-$(CONFIG_EXYNOS_CORESIGHT_ETM) += exynos-coresight-etm.o diff --git a/drivers/soc/samsung/debug/exynos-handler.c b/drivers/soc/samsung/debug/exynos-handler.c new file mode 100644 index 000000000000..401ec4acb330 --- /dev/null +++ b/drivers/soc/samsung/debug/exynos-handler.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Exynos - Support SoC specific handler + * Author: Hosung Kim + * Youngmin Nam + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct dbg_snapshot_helper_ops *dss_soc_ops; + +struct exynos_handler { + int irq; + char name[SZ_16]; + irqreturn_t (*handle_irq)(int irq, void *data); +}; + +static int handler_nr_irq; +static struct exynos_handler *ecc_handler; + +static irqreturn_t exynos_ecc_handler(int irq, void *data) +{ + struct exynos_handler *ecc = (struct exynos_handler *)data; + + dss_soc_ops->soc_dump_info(NULL); + + panic("Detected ECC error: irq: %d, name: %s", ecc->irq, ecc->name); + return 0; +} + +static int __init exynos_handler_setup(struct device_node *np) +{ + int err = 0, i; + + if (of_property_read_u32(np, "handler_nr_irq", &handler_nr_irq)) { + handler_nr_irq = 0; + pr_err("%s: handler_nr_irq property is not defined in device tree\n", __func__); + } + pr_info("%s: handler_nr_irq = %d\n", __func__, handler_nr_irq); + + /* memory alloc for handler */ + if (handler_nr_irq > 0) { + ecc_handler = kzalloc(sizeof(struct exynos_handler) * handler_nr_irq, + GFP_KERNEL); + if (!ecc_handler) { + pr_err("%s: fail to kzalloc\n", __func__); + err = -ENOMEM; + goto out; + } + } + + /* setup ecc_handler */ + for (i = 0; i < handler_nr_irq; i++) { + ecc_handler[i].irq = irq_of_parse_and_map(np, i); + snprintf(ecc_handler[i].name, sizeof(ecc_handler[i].name), + "ecc_handler%d", i); + ecc_handler[i].handle_irq = exynos_ecc_handler; + + err = request_irq(ecc_handler[i].irq, + ecc_handler[i].handle_irq, + IRQ_TYPE_LEVEL_HIGH | IRQF_NOBALANCING | IRQF_GIC_MULTI_TARGET, + ecc_handler[i].name, &ecc_handler[i]); + if (err) { + pr_err("unable to request irq%d for %s ecc handler\n", + ecc_handler[i].irq, ecc_handler[i].name); + break; + } else { + pr_info("Success to request irq%d for %s ecc handler\n", + ecc_handler[i].irq, ecc_handler[i].name); + } + } + +out: + of_node_put(np); + return err; +} + +static const struct of_device_id handler_of_match[] __initconst = { + { .compatible = "samsung,exynos-handler", .data = exynos_handler_setup}, + {}, +}; + +typedef int (*handler_initcall_t)(const struct device_node *); +static int __init exynos_handler_init(void) +{ + struct device_node *np; + const struct of_device_id *matched_np; + handler_initcall_t init_fn; + + np = of_find_matching_node_and_match(NULL, handler_of_match, &matched_np); + if (!np) + return -ENODEV; + + init_fn = (handler_initcall_t)matched_np->data; + + return init_fn(np); +} +subsys_initcall(exynos_handler_init); -- 2.20.1