Commit 7b2c9e41 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mailbox-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox

Pull mailbox updates from Jassi Brar:

 - imx: add support for TX Doorbell v2

 - mtk: implement runtime PM

 - zynqmp: add destination mailbox compatible

 - qcom:
    - add another clock provider for IPQ
    - add SM8650 compatible

 - misc: use preferred device_get_match_data()

* tag 'mailbox-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox:
  dt-bindings: mailbox: qcom-ipcc: document the SM8650 Inter-Processor Communication Controller
  mailbox: mtk-cmdq-mailbox: Implement Runtime PM with autosuspend
  mailbox: Use device_get_match_data()
  dt-bindings: zynqmp: add destination mailbox compatible
  dt-bindings: mailbox: qcom: add one more clock provider for IPQ mailbox
  mailbox: imx: support channel type tx doorbell v2
  dt-bindings: mailbox: fsl,mu: add new tx doorbell channel
parents 77fa2fbe 96cb7a4e
...@@ -72,9 +72,9 @@ properties: ...@@ -72,9 +72,9 @@ properties:
type : Channel type type : Channel type
channel : Channel number channel : Channel number
This MU support 5 type of unidirectional channels, each type This MU support 6 type of unidirectional channels, each type
has 4 channels except RST channel which only has 1 channel. has 4 channels except RST channel which only has 1 channel.
A total of 17 channels. Following types are A total of 21 channels. Following types are
supported: supported:
0 - TX channel with 32bit transmit register and IRQ transmit 0 - TX channel with 32bit transmit register and IRQ transmit
acknowledgment support. acknowledgment support.
...@@ -82,6 +82,7 @@ properties: ...@@ -82,6 +82,7 @@ properties:
2 - TX doorbell channel. Without own register and no ACK support. 2 - TX doorbell channel. Without own register and no ACK support.
3 - RX doorbell channel. 3 - RX doorbell channel.
4 - RST channel 4 - RST channel
5 - Tx doorbell channel. With S/W ACK from the other side.
const: 2 const: 2
clocks: clocks:
......
...@@ -125,10 +125,12 @@ allOf: ...@@ -125,10 +125,12 @@ allOf:
items: items:
- description: primary pll parent of the clock driver - description: primary pll parent of the clock driver
- description: XO clock - description: XO clock
- description: GCC GPLL0 clock source
clock-names: clock-names:
items: items:
- const: pll - const: pll
- const: xo - const: xo
- const: gpll0
- if: - if:
properties: properties:
......
...@@ -34,6 +34,7 @@ properties: ...@@ -34,6 +34,7 @@ properties:
- qcom,sm8350-ipcc - qcom,sm8350-ipcc
- qcom,sm8450-ipcc - qcom,sm8450-ipcc
- qcom,sm8550-ipcc - qcom,sm8550-ipcc
- qcom,sm8650-ipcc
- const: qcom,ipcc - const: qcom,ipcc
reg: reg:
......
...@@ -74,6 +74,10 @@ patternProperties: ...@@ -74,6 +74,10 @@ patternProperties:
type: object # DT nodes are json objects type: object # DT nodes are json objects
additionalProperties: false additionalProperties: false
properties: properties:
compatible:
const: xlnx,zynqmp-ipi-dest-mailbox
xlnx,ipi-id: xlnx,ipi-id:
description: description:
Remote Xilinx IPI agent ID of which the mailbox is connected to. Remote Xilinx IPI agent ID of which the mailbox is connected to.
...@@ -95,6 +99,7 @@ patternProperties: ...@@ -95,6 +99,7 @@ patternProperties:
- const: remote_response_region - const: remote_response_region
required: required:
- compatible
- reg - reg
- reg-names - reg-names
- "#mbox-cells" - "#mbox-cells"
...@@ -124,6 +129,7 @@ examples: ...@@ -124,6 +129,7 @@ examples:
ranges; ranges;
mailbox: mailbox@ff9905c0 { mailbox: mailbox@ff9905c0 {
compatible = "xlnx,zynqmp-ipi-dest-mailbox";
reg = <0x0 0xff9905c0 0x0 0x20>, reg = <0x0 0xff9905c0 0x0 0x20>,
<0x0 0xff9905e0 0x0 0x20>, <0x0 0xff9905e0 0x0 0x20>,
<0x0 0xff990e80 0x0 0x20>, <0x0 0xff990e80 0x0 0x20>,
......
...@@ -33,10 +33,9 @@ ...@@ -33,10 +33,9 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/mailbox_controller.h> #include <linux/mailbox_controller.h>
#include <linux/mailbox/brcm-message.h> #include <linux/mailbox/brcm-message.h>
...@@ -1494,7 +1493,6 @@ static int pdc_dt_read(struct platform_device *pdev, struct pdc_state *pdcs) ...@@ -1494,7 +1493,6 @@ static int pdc_dt_read(struct platform_device *pdev, struct pdc_state *pdcs)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *dn = pdev->dev.of_node; struct device_node *dn = pdev->dev.of_node;
const struct of_device_id *match;
const int *hw_type; const int *hw_type;
int err; int err;
...@@ -1509,11 +1507,9 @@ static int pdc_dt_read(struct platform_device *pdev, struct pdc_state *pdcs) ...@@ -1509,11 +1507,9 @@ static int pdc_dt_read(struct platform_device *pdev, struct pdc_state *pdcs)
pdcs->hw_type = PDC_HW; pdcs->hw_type = PDC_HW;
match = of_match_device(of_match_ptr(pdc_mbox_of_match), dev); hw_type = device_get_match_data(dev);
if (match != NULL) { if (hw_type)
hw_type = match->data;
pdcs->hw_type = *hw_type; pdcs->hw_type = *hw_type;
}
return 0; return 0;
} }
......
...@@ -20,7 +20,9 @@ ...@@ -20,7 +20,9 @@
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/slab.h> #include <linux/slab.h>
#define IMX_MU_CHANS 17 #include "mailbox.h"
#define IMX_MU_CHANS 24
/* TX0/RX0/RXDB[0-3] */ /* TX0/RX0/RXDB[0-3] */
#define IMX_MU_SCU_CHANS 6 #define IMX_MU_SCU_CHANS 6
/* TX0/RX0 */ /* TX0/RX0 */
...@@ -39,6 +41,7 @@ enum imx_mu_chan_type { ...@@ -39,6 +41,7 @@ enum imx_mu_chan_type {
IMX_MU_TYPE_TXDB = 2, /* Tx doorbell */ IMX_MU_TYPE_TXDB = 2, /* Tx doorbell */
IMX_MU_TYPE_RXDB = 3, /* Rx doorbell */ IMX_MU_TYPE_RXDB = 3, /* Rx doorbell */
IMX_MU_TYPE_RST = 4, /* Reset */ IMX_MU_TYPE_RST = 4, /* Reset */
IMX_MU_TYPE_TXDB_V2 = 5, /* Tx doorbell with S/W ACK */
}; };
enum imx_mu_xcr { enum imx_mu_xcr {
...@@ -226,6 +229,9 @@ static int imx_mu_generic_tx(struct imx_mu_priv *priv, ...@@ -226,6 +229,9 @@ static int imx_mu_generic_tx(struct imx_mu_priv *priv,
imx_mu_xcr_rmw(priv, IMX_MU_GCR, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0); imx_mu_xcr_rmw(priv, IMX_MU_GCR, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0);
tasklet_schedule(&cp->txdb_tasklet); tasklet_schedule(&cp->txdb_tasklet);
break; break;
case IMX_MU_TYPE_TXDB_V2:
imx_mu_xcr_rmw(priv, IMX_MU_GCR, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0);
break;
default: default:
dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type); dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
return -EINVAL; return -EINVAL;
...@@ -554,6 +560,9 @@ static int imx_mu_startup(struct mbox_chan *chan) ...@@ -554,6 +560,9 @@ static int imx_mu_startup(struct mbox_chan *chan)
int ret; int ret;
pm_runtime_get_sync(priv->dev); pm_runtime_get_sync(priv->dev);
if (cp->type == IMX_MU_TYPE_TXDB_V2)
return 0;
if (cp->type == IMX_MU_TYPE_TXDB) { if (cp->type == IMX_MU_TYPE_TXDB) {
/* Tx doorbell don't have ACK support */ /* Tx doorbell don't have ACK support */
tasklet_init(&cp->txdb_tasklet, imx_mu_txdb_tasklet, tasklet_init(&cp->txdb_tasklet, imx_mu_txdb_tasklet,
...@@ -595,6 +604,11 @@ static void imx_mu_shutdown(struct mbox_chan *chan) ...@@ -595,6 +604,11 @@ static void imx_mu_shutdown(struct mbox_chan *chan)
int ret; int ret;
u32 sr; u32 sr;
if (cp->type == IMX_MU_TYPE_TXDB_V2) {
pm_runtime_put_sync(priv->dev);
return;
}
if (cp->type == IMX_MU_TYPE_TXDB) { if (cp->type == IMX_MU_TYPE_TXDB) {
tasklet_kill(&cp->txdb_tasklet); tasklet_kill(&cp->txdb_tasklet);
pm_runtime_put_sync(priv->dev); pm_runtime_put_sync(priv->dev);
...@@ -671,6 +685,7 @@ static struct mbox_chan *imx_mu_specific_xlate(struct mbox_controller *mbox, ...@@ -671,6 +685,7 @@ static struct mbox_chan *imx_mu_specific_xlate(struct mbox_controller *mbox,
static struct mbox_chan * imx_mu_xlate(struct mbox_controller *mbox, static struct mbox_chan * imx_mu_xlate(struct mbox_controller *mbox,
const struct of_phandle_args *sp) const struct of_phandle_args *sp)
{ {
struct mbox_chan *p_chan;
u32 type, idx, chan; u32 type, idx, chan;
if (sp->args_count != 2) { if (sp->args_count != 2) {
...@@ -680,14 +695,25 @@ static struct mbox_chan * imx_mu_xlate(struct mbox_controller *mbox, ...@@ -680,14 +695,25 @@ static struct mbox_chan * imx_mu_xlate(struct mbox_controller *mbox,
type = sp->args[0]; /* channel type */ type = sp->args[0]; /* channel type */
idx = sp->args[1]; /* index */ idx = sp->args[1]; /* index */
chan = type * 4 + idx;
/* RST only supports 1 channel */
if ((type == IMX_MU_TYPE_RST) && idx) {
dev_err(mbox->dev, "Invalid RST channel %d\n", idx);
return ERR_PTR(-EINVAL);
}
chan = type * 4 + idx;
if (chan >= mbox->num_chans) { if (chan >= mbox->num_chans) {
dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx); dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
return &mbox->chans[chan]; p_chan = &mbox->chans[chan];
if (type == IMX_MU_TYPE_TXDB_V2)
p_chan->txdone_method = TXDONE_BY_ACK;
return p_chan;
} }
static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox, static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#include <linux/mailbox_controller.h> #include <linux/mailbox_controller.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "mailbox.h" #include "mailbox.h"
...@@ -403,7 +403,6 @@ MODULE_DEVICE_TABLE(of, sti_mailbox_match); ...@@ -403,7 +403,6 @@ MODULE_DEVICE_TABLE(of, sti_mailbox_match);
static int sti_mbox_probe(struct platform_device *pdev) static int sti_mbox_probe(struct platform_device *pdev)
{ {
const struct of_device_id *match;
struct mbox_controller *mbox; struct mbox_controller *mbox;
struct sti_mbox_device *mdev; struct sti_mbox_device *mdev;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
...@@ -411,12 +410,11 @@ static int sti_mbox_probe(struct platform_device *pdev) ...@@ -411,12 +410,11 @@ static int sti_mbox_probe(struct platform_device *pdev)
int irq; int irq;
int ret; int ret;
match = of_match_device(sti_mailbox_match, &pdev->dev); pdev->dev.platform_data = (struct sti_mbox_pdata *)device_get_match_data(&pdev->dev);
if (!match) { if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "No configuration found\n"); dev_err(&pdev->dev, "No configuration found\n");
return -ENODEV; return -ENODEV;
} }
pdev->dev.platform_data = (struct sti_mbox_pdata *) match->data;
mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL); mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL);
if (!mdev) if (!mdev)
......
...@@ -13,10 +13,13 @@ ...@@ -13,10 +13,13 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/mailbox_controller.h> #include <linux/mailbox_controller.h>
#include <linux/mailbox/mtk-cmdq-mailbox.h> #include <linux/mailbox/mtk-cmdq-mailbox.h>
#include <linux/of.h> #include <linux/of.h>
#define CMDQ_MBOX_AUTOSUSPEND_DELAY_MS 100
#define CMDQ_OP_CODE_MASK (0xff << CMDQ_OP_CODE_SHIFT) #define CMDQ_OP_CODE_MASK (0xff << CMDQ_OP_CODE_SHIFT)
#define CMDQ_NUM_CMD(t) (t->cmd_buf_size / CMDQ_INST_SIZE) #define CMDQ_NUM_CMD(t) (t->cmd_buf_size / CMDQ_INST_SIZE)
#define CMDQ_GCE_NUM_MAX (2) #define CMDQ_GCE_NUM_MAX (2)
...@@ -283,10 +286,8 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq, ...@@ -283,10 +286,8 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
break; break;
} }
if (list_empty(&thread->task_busy_list)) { if (list_empty(&thread->task_busy_list))
cmdq_thread_disable(cmdq, thread); cmdq_thread_disable(cmdq, thread);
clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
}
} }
static irqreturn_t cmdq_irq_handler(int irq, void *dev) static irqreturn_t cmdq_irq_handler(int irq, void *dev)
...@@ -307,9 +308,26 @@ static irqreturn_t cmdq_irq_handler(int irq, void *dev) ...@@ -307,9 +308,26 @@ static irqreturn_t cmdq_irq_handler(int irq, void *dev)
spin_unlock_irqrestore(&thread->chan->lock, flags); spin_unlock_irqrestore(&thread->chan->lock, flags);
} }
pm_runtime_mark_last_busy(cmdq->mbox.dev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int cmdq_runtime_resume(struct device *dev)
{
struct cmdq *cmdq = dev_get_drvdata(dev);
return clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks);
}
static int cmdq_runtime_suspend(struct device *dev)
{
struct cmdq *cmdq = dev_get_drvdata(dev);
clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
return 0;
}
static int cmdq_suspend(struct device *dev) static int cmdq_suspend(struct device *dev)
{ {
struct cmdq *cmdq = dev_get_drvdata(dev); struct cmdq *cmdq = dev_get_drvdata(dev);
...@@ -333,16 +351,14 @@ static int cmdq_suspend(struct device *dev) ...@@ -333,16 +351,14 @@ static int cmdq_suspend(struct device *dev)
if (cmdq->pdata->sw_ddr_en) if (cmdq->pdata->sw_ddr_en)
cmdq_sw_ddr_enable(cmdq, false); cmdq_sw_ddr_enable(cmdq, false);
clk_bulk_unprepare(cmdq->pdata->gce_num, cmdq->clocks); return pm_runtime_force_suspend(dev);
return 0;
} }
static int cmdq_resume(struct device *dev) static int cmdq_resume(struct device *dev)
{ {
struct cmdq *cmdq = dev_get_drvdata(dev); struct cmdq *cmdq = dev_get_drvdata(dev);
WARN_ON(clk_bulk_prepare(cmdq->pdata->gce_num, cmdq->clocks)); WARN_ON(pm_runtime_force_resume(dev));
cmdq->suspended = false; cmdq->suspended = false;
if (cmdq->pdata->sw_ddr_en) if (cmdq->pdata->sw_ddr_en)
...@@ -358,6 +374,9 @@ static int cmdq_remove(struct platform_device *pdev) ...@@ -358,6 +374,9 @@ static int cmdq_remove(struct platform_device *pdev)
if (cmdq->pdata->sw_ddr_en) if (cmdq->pdata->sw_ddr_en)
cmdq_sw_ddr_enable(cmdq, false); cmdq_sw_ddr_enable(cmdq, false);
if (!IS_ENABLED(CONFIG_PM))
cmdq_runtime_suspend(&pdev->dev);
clk_bulk_unprepare(cmdq->pdata->gce_num, cmdq->clocks); clk_bulk_unprepare(cmdq->pdata->gce_num, cmdq->clocks);
return 0; return 0;
} }
...@@ -369,13 +388,20 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) ...@@ -369,13 +388,20 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev); struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev);
struct cmdq_task *task; struct cmdq_task *task;
unsigned long curr_pa, end_pa; unsigned long curr_pa, end_pa;
int ret;
/* Client should not flush new tasks if suspended. */ /* Client should not flush new tasks if suspended. */
WARN_ON(cmdq->suspended); WARN_ON(cmdq->suspended);
ret = pm_runtime_get_sync(cmdq->mbox.dev);
if (ret < 0)
return ret;
task = kzalloc(sizeof(*task), GFP_ATOMIC); task = kzalloc(sizeof(*task), GFP_ATOMIC);
if (!task) if (!task) {
pm_runtime_put_autosuspend(cmdq->mbox.dev);
return -ENOMEM; return -ENOMEM;
}
task->cmdq = cmdq; task->cmdq = cmdq;
INIT_LIST_HEAD(&task->list_entry); INIT_LIST_HEAD(&task->list_entry);
...@@ -384,8 +410,6 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) ...@@ -384,8 +410,6 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
task->pkt = pkt; task->pkt = pkt;
if (list_empty(&thread->task_busy_list)) { if (list_empty(&thread->task_busy_list)) {
WARN_ON(clk_bulk_enable(cmdq->pdata->gce_num, cmdq->clocks));
/* /*
* The thread reset will clear thread related register to 0, * The thread reset will clear thread related register to 0,
* including pc, end, priority, irq, suspend and enable. Thus * including pc, end, priority, irq, suspend and enable. Thus
...@@ -424,6 +448,9 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) ...@@ -424,6 +448,9 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
} }
list_move_tail(&task->list_entry, &thread->task_busy_list); list_move_tail(&task->list_entry, &thread->task_busy_list);
pm_runtime_mark_last_busy(cmdq->mbox.dev);
pm_runtime_put_autosuspend(cmdq->mbox.dev);
return 0; return 0;
} }
...@@ -439,6 +466,8 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan) ...@@ -439,6 +466,8 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
struct cmdq_task *task, *tmp; struct cmdq_task *task, *tmp;
unsigned long flags; unsigned long flags;
WARN_ON(pm_runtime_get_sync(cmdq->mbox.dev));
spin_lock_irqsave(&thread->chan->lock, flags); spin_lock_irqsave(&thread->chan->lock, flags);
if (list_empty(&thread->task_busy_list)) if (list_empty(&thread->task_busy_list))
goto done; goto done;
...@@ -457,7 +486,6 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan) ...@@ -457,7 +486,6 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
} }
cmdq_thread_disable(cmdq, thread); cmdq_thread_disable(cmdq, thread);
clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
done: done:
/* /*
...@@ -467,6 +495,9 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan) ...@@ -467,6 +495,9 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
* to do any operation here, only unlock and leave. * to do any operation here, only unlock and leave.
*/ */
spin_unlock_irqrestore(&thread->chan->lock, flags); spin_unlock_irqrestore(&thread->chan->lock, flags);
pm_runtime_mark_last_busy(cmdq->mbox.dev);
pm_runtime_put_autosuspend(cmdq->mbox.dev);
} }
static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout) static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
...@@ -477,6 +508,11 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout) ...@@ -477,6 +508,11 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
struct cmdq_task *task, *tmp; struct cmdq_task *task, *tmp;
unsigned long flags; unsigned long flags;
u32 enable; u32 enable;
int ret;
ret = pm_runtime_get_sync(cmdq->mbox.dev);
if (ret < 0)
return ret;
spin_lock_irqsave(&thread->chan->lock, flags); spin_lock_irqsave(&thread->chan->lock, flags);
if (list_empty(&thread->task_busy_list)) if (list_empty(&thread->task_busy_list))
...@@ -497,10 +533,12 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout) ...@@ -497,10 +533,12 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
cmdq_thread_resume(thread); cmdq_thread_resume(thread);
cmdq_thread_disable(cmdq, thread); cmdq_thread_disable(cmdq, thread);
clk_bulk_disable(cmdq->pdata->gce_num, cmdq->clocks);
out: out:
spin_unlock_irqrestore(&thread->chan->lock, flags); spin_unlock_irqrestore(&thread->chan->lock, flags);
pm_runtime_mark_last_busy(cmdq->mbox.dev);
pm_runtime_put_autosuspend(cmdq->mbox.dev);
return 0; return 0;
wait: wait:
...@@ -513,6 +551,8 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout) ...@@ -513,6 +551,8 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
return -EFAULT; return -EFAULT;
} }
pm_runtime_mark_last_busy(cmdq->mbox.dev);
pm_runtime_put_autosuspend(cmdq->mbox.dev);
return 0; return 0;
} }
...@@ -642,12 +682,28 @@ static int cmdq_probe(struct platform_device *pdev) ...@@ -642,12 +682,28 @@ static int cmdq_probe(struct platform_device *pdev)
return err; return err;
} }
/* If Runtime PM is not available enable the clocks now. */
if (!IS_ENABLED(CONFIG_PM)) {
err = cmdq_runtime_resume(dev);
if (err)
return err;
}
err = devm_pm_runtime_enable(dev);
if (err)
return err;
pm_runtime_set_autosuspend_delay(dev, CMDQ_MBOX_AUTOSUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(dev);
return 0; return 0;
} }
static const struct dev_pm_ops cmdq_pm_ops = { static const struct dev_pm_ops cmdq_pm_ops = {
.suspend = cmdq_suspend, .suspend = cmdq_suspend,
.resume = cmdq_resume, .resume = cmdq_resume,
SET_RUNTIME_PM_OPS(cmdq_runtime_suspend,
cmdq_runtime_resume, NULL)
}; };
static const struct gce_plat gce_plat_v2 = { static const struct gce_plat gce_plat_v2 = {
......
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mailbox_controller.h> #include <linux/mailbox_controller.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/soc/ti/ti-msgmgr.h> #include <linux/soc/ti/ti-msgmgr.h>
#define Q_DATA_OFFSET(proxy, queue, reg) \ #define Q_DATA_OFFSET(proxy, queue, reg) \
...@@ -810,7 +810,6 @@ MODULE_DEVICE_TABLE(of, ti_msgmgr_of_match); ...@@ -810,7 +810,6 @@ MODULE_DEVICE_TABLE(of, ti_msgmgr_of_match);
static int ti_msgmgr_probe(struct platform_device *pdev) static int ti_msgmgr_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const struct of_device_id *of_id;
struct device_node *np; struct device_node *np;
const struct ti_msgmgr_desc *desc; const struct ti_msgmgr_desc *desc;
struct ti_msgmgr_inst *inst; struct ti_msgmgr_inst *inst;
...@@ -828,19 +827,12 @@ static int ti_msgmgr_probe(struct platform_device *pdev) ...@@ -828,19 +827,12 @@ static int ti_msgmgr_probe(struct platform_device *pdev)
} }
np = dev->of_node; np = dev->of_node;
of_id = of_match_device(ti_msgmgr_of_match, dev);
if (!of_id) {
dev_err(dev, "OF data missing\n");
return -EINVAL;
}
desc = of_id->data;
inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL); inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL);
if (!inst) if (!inst)
return -ENOMEM; return -ENOMEM;
inst->dev = dev; inst->dev = dev;
inst->desc = desc; inst->desc = desc = device_get_match_data(dev);
inst->queue_proxy_region = inst->queue_proxy_region =
devm_platform_ioremap_resource_byname(pdev, desc->data_region_name); devm_platform_ioremap_resource_byname(pdev, desc->data_region_name);
......
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