hisi: fiq_debugger: Add fiq support

Adds a new configuration, "android,fiq-hi6220-uart", where an fiq
handler is registered with trusty instead of using an irq.

Change-Id: I967db3080600e0c03cbf84e87db656f5ca0e0012
Signed-off-by: Arve Hjønnevåg <arve@android.com>
This commit is contained in:
Arve Hjønnevåg
2017-11-22 14:42:27 -08:00
parent 7c9f462e1a
commit b0d53faa78
+71 -19
View File
@@ -27,12 +27,17 @@
#include <linux/stacktrace.h>
#include <linux/uaccess.h>
#include <linux/amba/serial.h>
#include <linux/trusty/trusty.h>
#include <linux/trusty/smcall.h>
#include "../../staging/android/fiq_debugger/fiq_debugger.h"
struct hi6220_fiq_debugger {
struct fiq_debugger_pdata pdata;
void __iomem *debug_port_base;
struct device *trusty_dev;
int lfiq;
int tfiq;
};
static inline void uart_write(struct hi6220_fiq_debugger *t,
@@ -106,10 +111,33 @@ static int debug_resume(struct platform_device *pdev)
return debug_port_init(pdev);
}
static void trusty_fiq_enable(struct platform_device *pdev,
unsigned int fiq, bool enable)
{
int ret;
struct hi6220_fiq_debugger *t;
t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
if (fiq != t->lfiq) {
dev_err(&pdev->dev, "unexpected virtual fiq, %d != %d\n",
fiq, t->lfiq);
return;
}
ret = trusty_fast_call32(t->trusty_dev, SMC_FC_REQUEST_FIQ,
t->tfiq, enable, 0);
if (ret)
dev_err(&pdev->dev, "SMC_FC_REQUEST_FIQ failed: %d\n", ret);
}
static int hi6220_fiq_debugger_id;
static int __hi6220_serial_debug_init(unsigned int base, int fiq, int irq,
struct clk *clk, int signal_irq, int wakeup_irq)
static int __hi6220_serial_debug_init(unsigned int base,
int lfiq, int tfiq, int irq,
struct clk *clk,
int signal_irq, int wakeup_irq,
struct device *trusty_dev)
{
struct hi6220_fiq_debugger *t;
struct platform_device *pdev;
@@ -130,6 +158,10 @@ static int __hi6220_serial_debug_init(unsigned int base, int fiq, int irq,
t->pdata.uart_dev_suspend = debug_suspend;
t->pdata.uart_dev_resume = debug_resume;
if (trusty_dev)
t->pdata.fiq_enable = trusty_fiq_enable;
t->trusty_dev = trusty_dev;
t->debug_port_base = ioremap(base, PAGE_SIZE);
if (!t->debug_port_base) {
pr_err("Failed to ioremap for fiq debugger\n");
@@ -148,11 +180,13 @@ static int __hi6220_serial_debug_init(unsigned int base, int fiq, int irq,
goto out3;
};
if (fiq >= 0) {
if (lfiq >= 0) {
res[0].flags = IORESOURCE_IRQ;
res[0].start = fiq;
res[0].end = fiq;
res[0].start = lfiq;
res[0].end = lfiq;
res[0].name = "fiq";
t->lfiq = lfiq;
t->tfiq = tfiq;
} else {
res[0].flags = IORESOURCE_IRQ;
res[0].start = irq;
@@ -201,19 +235,33 @@ out1:
return ret;
}
int hi6220_serial_debug_init_irq_mode(unsigned int base, int irq,
struct clk *clk, int signal_irq, int wakeup_irq)
{
return __hi6220_serial_debug_init(base, -1, irq, clk, signal_irq,
wakeup_irq);
}
#define HI6220_SERIAL_DEBUG_MODE_IRQ ((void *)0)
#define HI6220_SERIAL_DEBUG_MODE_FIQ ((void *)1)
static const struct of_device_id hi6220_serial_debug_match[] = {
{
.compatible = "android,irq-hi6220-uart",
.data = HI6220_SERIAL_DEBUG_MODE_IRQ,
},
{
.compatible = "android,fiq-hi6220-uart",
.data = HI6220_SERIAL_DEBUG_MODE_FIQ,
},
{}
};
MODULE_DEVICE_TABLE(of, hi6220_serial_debug_match);
static int hi6220_serial_debug_probe(struct platform_device *pdev)
{
struct resource *res;
int fiq;
int lfiq = -1;
int tfiq = -1;
int irq = -1;
int signal_irq;
int wakeup_irq;
const struct of_device_id *of_id;
struct device *trusty_dev = NULL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -239,19 +287,23 @@ static int hi6220_serial_debug_probe(struct platform_device *pdev)
wakeup_irq = -1;
}
return hi6220_serial_debug_init_irq_mode(res->start, fiq, NULL,
signal_irq, wakeup_irq);
}
of_id = of_match_node(hi6220_serial_debug_match, pdev->dev.of_node);
if (of_id->data == HI6220_SERIAL_DEBUG_MODE_FIQ) {
trusty_dev = pdev->dev.parent->parent;
lfiq = fiq;
tfiq = irqd_to_hwirq(irq_get_irq_data(fiq));
} else {
irq = fiq;
}
static const struct of_device_id hi6220_serial_debug_match[] = {
{ .compatible = "android,irq-hi6220-uart", },
{}
};
return __hi6220_serial_debug_init(res->start, lfiq, tfiq, irq, NULL,
signal_irq, wakeup_irq, trusty_dev);
}
static struct platform_driver hi6220_serial_debug_driver = {
.probe = hi6220_serial_debug_probe,
.driver = {
.name = "hi6220-irq-debug",
.name = "hi6220-serial-debug",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(hi6220_serial_debug_match),
},