Commit 5e3b06d3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'rproc-v5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc

Pull remoteproc updates from Bjorn Andersson:
 "This adds support for booting the modem processor on Qualcomm MSM8998
  and carries some cleanup up and bug fixes to the framework and the
  stm32 driver"

* tag 'rproc-v5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc:
  Revert "dt-bindings: remoteproc: stm32: add wakeup-source"
  remoteproc: stm32: fix probe error case
  remoteproc: stm32: wakeup the system by wdg irq
  dt-bindings: remoteproc: stm32: add wakeup-source
  remoteproc: Fix wrong rvring index computation
  remoteproc: stm32: use workqueue to treat mailbox callback
  remoteproc: fix argument 2 of rproc_mem_entry_init
  remoteproc: qcom_q6v5_mss: Add support for MSM8998
  dt-bindings: remoteproc: qcom: Add Q6v5 Modem PIL binding for MSM8998
  remoteproc: debug: Remove unneeded NULL check
  remoteproc: remove useless typedef
parents 3265568d e3cb40d4
...@@ -12,6 +12,7 @@ on the Qualcomm Hexagon core. ...@@ -12,6 +12,7 @@ on the Qualcomm Hexagon core.
"qcom,msm8916-mss-pil", "qcom,msm8916-mss-pil",
"qcom,msm8974-mss-pil" "qcom,msm8974-mss-pil"
"qcom,msm8996-mss-pil" "qcom,msm8996-mss-pil"
"qcom,msm8998-mss-pil"
"qcom,sdm845-mss-pil" "qcom,sdm845-mss-pil"
- reg: - reg:
...@@ -41,6 +42,7 @@ on the Qualcomm Hexagon core. ...@@ -41,6 +42,7 @@ on the Qualcomm Hexagon core.
qcom,msm8974-mss-pil: qcom,msm8974-mss-pil:
must be "wdog", "fatal", "ready", "handover", "stop-ack" must be "wdog", "fatal", "ready", "handover", "stop-ack"
qcom,msm8996-mss-pil: qcom,msm8996-mss-pil:
qcom,msm8998-mss-pil:
qcom,sdm845-mss-pil: qcom,sdm845-mss-pil:
must be "wdog", "fatal", "ready", "handover", "stop-ack", must be "wdog", "fatal", "ready", "handover", "stop-ack",
"shutdown-ack" "shutdown-ack"
...@@ -70,6 +72,9 @@ on the Qualcomm Hexagon core. ...@@ -70,6 +72,9 @@ on the Qualcomm Hexagon core.
qcom,msm8996-mss-pil: qcom,msm8996-mss-pil:
must be "iface", "bus", "mem", "xo", "gpll0_mss", must be "iface", "bus", "mem", "xo", "gpll0_mss",
"snoc_axi", "mnoc_axi", "pnoc", "qdss" "snoc_axi", "mnoc_axi", "pnoc", "qdss"
qcom,msm8998-mss-pil:
must be "iface", "bus", "mem", "xo", "gpll0_mss",
"snoc_axi", "mnoc_axi", "qdss"
qcom,sdm845-mss-pil: qcom,sdm845-mss-pil:
must be "iface", "bus", "mem", "xo", "gpll0_mss", must be "iface", "bus", "mem", "xo", "gpll0_mss",
"snoc_axi", "mnoc_axi", "prng" "snoc_axi", "mnoc_axi", "prng"
...@@ -137,6 +142,7 @@ For the compatible string below the following supplies are required: ...@@ -137,6 +142,7 @@ For the compatible string below the following supplies are required:
qcom,msm8974-mss-pil: qcom,msm8974-mss-pil:
no power-domain names required no power-domain names required
qcom,msm8996-mss-pil: qcom,msm8996-mss-pil:
qcom,msm8998-mss-pil:
must be "cx", "mx" must be "cx", "mx"
qcom,sdm845-mss-pil: qcom,sdm845-mss-pil:
must be "cx", "mx", "mss", "load_state" must be "cx", "mx", "mss", "load_state"
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
#define QDSP6SS_GFMUX_CTL_REG 0x020 #define QDSP6SS_GFMUX_CTL_REG 0x020
#define QDSP6SS_PWR_CTL_REG 0x030 #define QDSP6SS_PWR_CTL_REG 0x030
#define QDSP6SS_MEM_PWR_CTL 0x0B0 #define QDSP6SS_MEM_PWR_CTL 0x0B0
#define QDSP6V6SS_MEM_PWR_CTL 0x034
#define QDSP6SS_STRAP_ACC 0x110 #define QDSP6SS_STRAP_ACC 0x110
/* AXI Halt Register Offsets */ /* AXI Halt Register Offsets */
...@@ -196,6 +197,7 @@ enum { ...@@ -196,6 +197,7 @@ enum {
MSS_MSM8916, MSS_MSM8916,
MSS_MSM8974, MSS_MSM8974,
MSS_MSM8996, MSS_MSM8996,
MSS_MSM8998,
MSS_SDM845, MSS_SDM845,
}; };
...@@ -498,7 +500,10 @@ static int q6v5proc_reset(struct q6v5 *qproc) ...@@ -498,7 +500,10 @@ static int q6v5proc_reset(struct q6v5 *qproc)
} }
goto pbl_wait; goto pbl_wait;
} else if (qproc->version == MSS_MSM8996) { } else if (qproc->version == MSS_MSM8996 ||
qproc->version == MSS_MSM8998) {
int mem_pwr_ctl;
/* Override the ACC value if required */ /* Override the ACC value if required */
writel(QDSP6SS_ACC_OVERRIDE_VAL, writel(QDSP6SS_ACC_OVERRIDE_VAL,
qproc->reg_base + QDSP6SS_STRAP_ACC); qproc->reg_base + QDSP6SS_STRAP_ACC);
...@@ -543,17 +548,24 @@ static int q6v5proc_reset(struct q6v5 *qproc) ...@@ -543,17 +548,24 @@ static int q6v5proc_reset(struct q6v5 *qproc)
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
/* Turn on L1, L2, ETB and JU memories 1 at a time */ /* Turn on L1, L2, ETB and JU memories 1 at a time */
val = readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL); if (qproc->version == MSS_MSM8996) {
for (i = 19; i >= 0; i--) { mem_pwr_ctl = QDSP6SS_MEM_PWR_CTL;
i = 19;
} else {
/* MSS_MSM8998 */
mem_pwr_ctl = QDSP6V6SS_MEM_PWR_CTL;
i = 28;
}
val = readl(qproc->reg_base + mem_pwr_ctl);
for (; i >= 0; i--) {
val |= BIT(i); val |= BIT(i);
writel(val, qproc->reg_base + writel(val, qproc->reg_base + mem_pwr_ctl);
QDSP6SS_MEM_PWR_CTL);
/* /*
* Read back value to ensure the write is done then * Read back value to ensure the write is done then
* wait for 1us for both memory peripheral and data * wait for 1us for both memory peripheral and data
* array to turn on. * array to turn on.
*/ */
val |= readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL); val |= readl(qproc->reg_base + mem_pwr_ctl);
udelay(1); udelay(1);
} }
/* Remove word line clamp */ /* Remove word line clamp */
...@@ -1571,6 +1583,33 @@ static const struct rproc_hexagon_res sdm845_mss = { ...@@ -1571,6 +1583,33 @@ static const struct rproc_hexagon_res sdm845_mss = {
.version = MSS_SDM845, .version = MSS_SDM845,
}; };
static const struct rproc_hexagon_res msm8998_mss = {
.hexagon_mba_image = "mba.mbn",
.proxy_clk_names = (char*[]){
"xo",
"qdss",
"mem",
NULL
},
.active_clk_names = (char*[]){
"iface",
"bus",
"mem",
"gpll0_mss",
"mnoc_axi",
"snoc_axi",
NULL
},
.proxy_pd_names = (char*[]){
"cx",
"mx",
NULL
},
.need_mem_protection = true,
.has_alt_reset = false,
.version = MSS_MSM8998,
};
static const struct rproc_hexagon_res msm8996_mss = { static const struct rproc_hexagon_res msm8996_mss = {
.hexagon_mba_image = "mba.mbn", .hexagon_mba_image = "mba.mbn",
.proxy_supply = (struct qcom_mss_reg_res[]) { .proxy_supply = (struct qcom_mss_reg_res[]) {
...@@ -1677,6 +1716,7 @@ static const struct of_device_id q6v5_of_match[] = { ...@@ -1677,6 +1716,7 @@ static const struct of_device_id q6v5_of_match[] = {
{ .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss}, { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},
{ .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss}, { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
{ .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss}, { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss},
{ .compatible = "qcom,msm8998-mss-pil", .data = &msm8998_mss},
{ .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss}, { .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss},
{ }, { },
}; };
......
...@@ -44,8 +44,6 @@ ...@@ -44,8 +44,6 @@
static DEFINE_MUTEX(rproc_list_mutex); static DEFINE_MUTEX(rproc_list_mutex);
static LIST_HEAD(rproc_list); static LIST_HEAD(rproc_list);
typedef int (*rproc_handle_resources_t)(struct rproc *rproc,
struct resource_table *table, int len);
typedef int (*rproc_handle_resource_t)(struct rproc *rproc, typedef int (*rproc_handle_resource_t)(struct rproc *rproc,
void *, int offset, int avail); void *, int offset, int avail);
...@@ -336,7 +334,8 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i) ...@@ -336,7 +334,8 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
return -ENOMEM; return -ENOMEM;
} else { } else {
/* Register carveout in in list */ /* Register carveout in in list */
mem = rproc_mem_entry_init(dev, 0, 0, size, rsc->vring[i].da, mem = rproc_mem_entry_init(dev, NULL, 0,
size, rsc->vring[i].da,
rproc_alloc_carveout, rproc_alloc_carveout,
rproc_release_carveout, rproc_release_carveout,
"vdev%dvring%d", "vdev%dvring%d",
...@@ -400,7 +399,7 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i) ...@@ -400,7 +399,7 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
void rproc_free_vring(struct rproc_vring *rvring) void rproc_free_vring(struct rproc_vring *rvring)
{ {
struct rproc *rproc = rvring->rvdev->rproc; struct rproc *rproc = rvring->rvdev->rproc;
int idx = rvring->rvdev->vring - rvring; int idx = rvring - rvring->rvdev->vring;
struct fw_rsc_vdev *rsc; struct fw_rsc_vdev *rsc;
idr_remove(&rproc->notifyids, rvring->notifyid); idr_remove(&rproc->notifyids, rvring->notifyid);
...@@ -913,7 +912,7 @@ static int rproc_handle_carveout(struct rproc *rproc, ...@@ -913,7 +912,7 @@ static int rproc_handle_carveout(struct rproc *rproc,
} }
/* Register carveout in in list */ /* Register carveout in in list */
carveout = rproc_mem_entry_init(dev, 0, 0, rsc->len, rsc->da, carveout = rproc_mem_entry_init(dev, NULL, 0, rsc->len, rsc->da,
rproc_alloc_carveout, rproc_alloc_carveout,
rproc_release_carveout, rsc->name); rproc_release_carveout, rsc->name);
if (!carveout) { if (!carveout) {
......
...@@ -333,9 +333,6 @@ struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, ...@@ -333,9 +333,6 @@ struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc,
void rproc_delete_debug_dir(struct rproc *rproc) void rproc_delete_debug_dir(struct rproc *rproc)
{ {
if (!rproc->dbg_dir)
return;
debugfs_remove_recursive(rproc->dbg_dir); debugfs_remove_recursive(rproc->dbg_dir);
} }
......
...@@ -15,9 +15,11 @@ ...@@ -15,9 +15,11 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_reserved_mem.h> #include <linux/of_reserved_mem.h>
#include <linux/pm_wakeirq.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/remoteproc.h> #include <linux/remoteproc.h>
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/workqueue.h>
#include "remoteproc_internal.h" #include "remoteproc_internal.h"
...@@ -31,7 +33,9 @@ ...@@ -31,7 +33,9 @@
#define STM32_SMC_REG_WRITE 0x1 #define STM32_SMC_REG_WRITE 0x1
#define STM32_MBX_VQ0 "vq0" #define STM32_MBX_VQ0 "vq0"
#define STM32_MBX_VQ0_ID 0
#define STM32_MBX_VQ1 "vq1" #define STM32_MBX_VQ1 "vq1"
#define STM32_MBX_VQ1_ID 1
#define STM32_MBX_SHUTDOWN "shutdown" #define STM32_MBX_SHUTDOWN "shutdown"
struct stm32_syscon { struct stm32_syscon {
...@@ -58,6 +62,7 @@ struct stm32_mbox { ...@@ -58,6 +62,7 @@ struct stm32_mbox {
const unsigned char name[10]; const unsigned char name[10];
struct mbox_chan *chan; struct mbox_chan *chan;
struct mbox_client client; struct mbox_client client;
struct work_struct vq_work;
int vq_id; int vq_id;
}; };
...@@ -65,9 +70,11 @@ struct stm32_rproc { ...@@ -65,9 +70,11 @@ struct stm32_rproc {
struct reset_control *rst; struct reset_control *rst;
struct stm32_syscon hold_boot; struct stm32_syscon hold_boot;
struct stm32_syscon pdds; struct stm32_syscon pdds;
int wdg_irq;
u32 nb_rmems; u32 nb_rmems;
struct stm32_rproc_mem *rmems; struct stm32_rproc_mem *rmems;
struct stm32_mbox mb[MBOX_NB_MBX]; struct stm32_mbox mb[MBOX_NB_MBX];
struct workqueue_struct *workqueue;
bool secured_soc; bool secured_soc;
}; };
...@@ -261,13 +268,22 @@ static irqreturn_t stm32_rproc_wdg(int irq, void *data) ...@@ -261,13 +268,22 @@ static irqreturn_t stm32_rproc_wdg(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void stm32_rproc_mb_vq_work(struct work_struct *work)
{
struct stm32_mbox *mb = container_of(work, struct stm32_mbox, vq_work);
struct rproc *rproc = dev_get_drvdata(mb->client.dev);
if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE)
dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id);
}
static void stm32_rproc_mb_callback(struct mbox_client *cl, void *data) static void stm32_rproc_mb_callback(struct mbox_client *cl, void *data)
{ {
struct rproc *rproc = dev_get_drvdata(cl->dev); struct rproc *rproc = dev_get_drvdata(cl->dev);
struct stm32_mbox *mb = container_of(cl, struct stm32_mbox, client); struct stm32_mbox *mb = container_of(cl, struct stm32_mbox, client);
struct stm32_rproc *ddata = rproc->priv;
if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE) queue_work(ddata->workqueue, &mb->vq_work);
dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id);
} }
static void stm32_rproc_free_mbox(struct rproc *rproc) static void stm32_rproc_free_mbox(struct rproc *rproc)
...@@ -285,7 +301,7 @@ static void stm32_rproc_free_mbox(struct rproc *rproc) ...@@ -285,7 +301,7 @@ static void stm32_rproc_free_mbox(struct rproc *rproc)
static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = { static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = {
{ {
.name = STM32_MBX_VQ0, .name = STM32_MBX_VQ0,
.vq_id = 0, .vq_id = STM32_MBX_VQ0_ID,
.client = { .client = {
.rx_callback = stm32_rproc_mb_callback, .rx_callback = stm32_rproc_mb_callback,
.tx_block = false, .tx_block = false,
...@@ -293,7 +309,7 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = { ...@@ -293,7 +309,7 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = {
}, },
{ {
.name = STM32_MBX_VQ1, .name = STM32_MBX_VQ1,
.vq_id = 1, .vq_id = STM32_MBX_VQ1_ID,
.client = { .client = {
.rx_callback = stm32_rproc_mb_callback, .rx_callback = stm32_rproc_mb_callback,
.tx_block = false, .tx_block = false,
...@@ -310,11 +326,12 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = { ...@@ -310,11 +326,12 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = {
} }
}; };
static void stm32_rproc_request_mbox(struct rproc *rproc) static int stm32_rproc_request_mbox(struct rproc *rproc)
{ {
struct stm32_rproc *ddata = rproc->priv; struct stm32_rproc *ddata = rproc->priv;
struct device *dev = &rproc->dev; struct device *dev = &rproc->dev;
unsigned int i; unsigned int i;
int j;
const unsigned char *name; const unsigned char *name;
struct mbox_client *cl; struct mbox_client *cl;
...@@ -329,10 +346,24 @@ static void stm32_rproc_request_mbox(struct rproc *rproc) ...@@ -329,10 +346,24 @@ static void stm32_rproc_request_mbox(struct rproc *rproc)
ddata->mb[i].chan = mbox_request_channel_byname(cl, name); ddata->mb[i].chan = mbox_request_channel_byname(cl, name);
if (IS_ERR(ddata->mb[i].chan)) { if (IS_ERR(ddata->mb[i].chan)) {
if (PTR_ERR(ddata->mb[i].chan) == -EPROBE_DEFER)
goto err_probe;
dev_warn(dev, "cannot get %s mbox\n", name); dev_warn(dev, "cannot get %s mbox\n", name);
ddata->mb[i].chan = NULL; ddata->mb[i].chan = NULL;
} }
if (ddata->mb[i].vq_id >= 0) {
INIT_WORK(&ddata->mb[i].vq_work,
stm32_rproc_mb_vq_work);
}
} }
return 0;
err_probe:
for (j = i - 1; j >= 0; j--)
if (ddata->mb[j].chan)
mbox_free_channel(ddata->mb[j].chan);
return -EPROBE_DEFER;
} }
static int stm32_rproc_set_hold_boot(struct rproc *rproc, bool hold) static int stm32_rproc_set_hold_boot(struct rproc *rproc, bool hold)
...@@ -528,6 +559,13 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev) ...@@ -528,6 +559,13 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev)
return err; return err;
} }
ddata->wdg_irq = irq;
if (of_property_read_bool(np, "wakeup-source")) {
device_init_wakeup(dev, true);
dev_pm_set_wake_irq(dev, irq);
}
dev_info(dev, "wdg irq registered\n"); dev_info(dev, "wdg irq registered\n");
} }
...@@ -589,14 +627,22 @@ static int stm32_rproc_probe(struct platform_device *pdev) ...@@ -589,14 +627,22 @@ static int stm32_rproc_probe(struct platform_device *pdev)
rproc->has_iommu = false; rproc->has_iommu = false;
ddata = rproc->priv; ddata = rproc->priv;
ddata->workqueue = create_workqueue(dev_name(dev));
if (!ddata->workqueue) {
dev_err(dev, "cannot create workqueue\n");
ret = -ENOMEM;
goto free_rproc;
}
platform_set_drvdata(pdev, rproc); platform_set_drvdata(pdev, rproc);
ret = stm32_rproc_parse_dt(pdev); ret = stm32_rproc_parse_dt(pdev);
if (ret) if (ret)
goto free_rproc; goto free_wkq;
stm32_rproc_request_mbox(rproc); ret = stm32_rproc_request_mbox(rproc);
if (ret)
goto free_rproc;
ret = rproc_add(rproc); ret = rproc_add(rproc);
if (ret) if (ret)
...@@ -606,7 +652,13 @@ static int stm32_rproc_probe(struct platform_device *pdev) ...@@ -606,7 +652,13 @@ static int stm32_rproc_probe(struct platform_device *pdev)
free_mb: free_mb:
stm32_rproc_free_mbox(rproc); stm32_rproc_free_mbox(rproc);
free_wkq:
destroy_workqueue(ddata->workqueue);
free_rproc: free_rproc:
if (device_may_wakeup(dev)) {
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
rproc_free(rproc); rproc_free(rproc);
return ret; return ret;
} }
...@@ -614,22 +666,56 @@ static int stm32_rproc_probe(struct platform_device *pdev) ...@@ -614,22 +666,56 @@ static int stm32_rproc_probe(struct platform_device *pdev)
static int stm32_rproc_remove(struct platform_device *pdev) static int stm32_rproc_remove(struct platform_device *pdev)
{ {
struct rproc *rproc = platform_get_drvdata(pdev); struct rproc *rproc = platform_get_drvdata(pdev);
struct stm32_rproc *ddata = rproc->priv;
struct device *dev = &pdev->dev;
if (atomic_read(&rproc->power) > 0) if (atomic_read(&rproc->power) > 0)
rproc_shutdown(rproc); rproc_shutdown(rproc);
rproc_del(rproc); rproc_del(rproc);
stm32_rproc_free_mbox(rproc); stm32_rproc_free_mbox(rproc);
destroy_workqueue(ddata->workqueue);
if (device_may_wakeup(dev)) {
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
rproc_free(rproc); rproc_free(rproc);
return 0; return 0;
} }
static int __maybe_unused stm32_rproc_suspend(struct device *dev)
{
struct rproc *rproc = dev_get_drvdata(dev);
struct stm32_rproc *ddata = rproc->priv;
if (device_may_wakeup(dev))
return enable_irq_wake(ddata->wdg_irq);
return 0;
}
static int __maybe_unused stm32_rproc_resume(struct device *dev)
{
struct rproc *rproc = dev_get_drvdata(dev);
struct stm32_rproc *ddata = rproc->priv;
if (device_may_wakeup(dev))
return disable_irq_wake(ddata->wdg_irq);
return 0;
}
static SIMPLE_DEV_PM_OPS(stm32_rproc_pm_ops,
stm32_rproc_suspend, stm32_rproc_resume);
static struct platform_driver stm32_rproc_driver = { static struct platform_driver stm32_rproc_driver = {
.probe = stm32_rproc_probe, .probe = stm32_rproc_probe,
.remove = stm32_rproc_remove, .remove = stm32_rproc_remove,
.driver = { .driver = {
.name = "stm32-rproc", .name = "stm32-rproc",
.pm = &stm32_rproc_pm_ops,
.of_match_table = of_match_ptr(stm32_rproc_match), .of_match_table = of_match_ptr(stm32_rproc_match),
}, },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment