Lines Matching full:qmp
57 struct qmp *qmp; member
63 * struct qmp - driver state for QMP implementation
65 * @dev: reference to QMP device
77 struct qmp { struct
97 static void qmp_kick(struct qmp *qmp) in qmp_kick() argument
99 mbox_send_message(qmp->mbox_chan, NULL); in qmp_kick()
100 mbox_client_txdone(qmp->mbox_chan, 0); in qmp_kick()
103 static bool qmp_magic_valid(struct qmp *qmp) in qmp_magic_valid() argument
105 return readl(qmp->msgram + QMP_DESC_MAGIC) == QMP_MAGIC; in qmp_magic_valid()
108 static bool qmp_link_acked(struct qmp *qmp) in qmp_link_acked() argument
110 return readl(qmp->msgram + QMP_DESC_MCORE_LINK_STATE_ACK) == QMP_STATE_UP; in qmp_link_acked()
113 static bool qmp_mcore_channel_acked(struct qmp *qmp) in qmp_mcore_channel_acked() argument
115 return readl(qmp->msgram + QMP_DESC_MCORE_CH_STATE_ACK) == QMP_STATE_UP; in qmp_mcore_channel_acked()
118 static bool qmp_ucore_channel_up(struct qmp *qmp) in qmp_ucore_channel_up() argument
120 return readl(qmp->msgram + QMP_DESC_UCORE_CH_STATE) == QMP_STATE_UP; in qmp_ucore_channel_up()
123 static int qmp_open(struct qmp *qmp) in qmp_open() argument
128 if (!qmp_magic_valid(qmp)) { in qmp_open()
129 dev_err(qmp->dev, "QMP magic doesn't match\n"); in qmp_open()
133 val = readl(qmp->msgram + QMP_DESC_VERSION); in qmp_open()
135 dev_err(qmp->dev, "unsupported QMP version %d\n", val); in qmp_open()
139 qmp->offset = readl(qmp->msgram + QMP_DESC_MCORE_MBOX_OFFSET); in qmp_open()
140 qmp->size = readl(qmp->msgram + QMP_DESC_MCORE_MBOX_SIZE); in qmp_open()
141 if (!qmp->size) { in qmp_open()
142 dev_err(qmp->dev, "invalid mailbox size\n"); in qmp_open()
147 val = readl(qmp->msgram + QMP_DESC_UCORE_LINK_STATE); in qmp_open()
148 writel(val, qmp->msgram + QMP_DESC_UCORE_LINK_STATE_ACK); in qmp_open()
151 writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); in qmp_open()
153 qmp_kick(qmp); in qmp_open()
155 ret = wait_event_timeout(qmp->event, qmp_link_acked(qmp), HZ); in qmp_open()
157 dev_err(qmp->dev, "ucore didn't ack link\n"); in qmp_open()
161 writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_MCORE_CH_STATE); in qmp_open()
163 qmp_kick(qmp); in qmp_open()
165 ret = wait_event_timeout(qmp->event, qmp_ucore_channel_up(qmp), HZ); in qmp_open()
167 dev_err(qmp->dev, "ucore didn't open channel\n"); in qmp_open()
172 writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_UCORE_CH_STATE_ACK); in qmp_open()
174 qmp_kick(qmp); in qmp_open()
176 ret = wait_event_timeout(qmp->event, qmp_mcore_channel_acked(qmp), HZ); in qmp_open()
178 dev_err(qmp->dev, "ucore didn't ack channel\n"); in qmp_open()
185 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_CH_STATE); in qmp_open()
188 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); in qmp_open()
189 qmp_kick(qmp); in qmp_open()
194 static void qmp_close(struct qmp *qmp) in qmp_close() argument
196 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_CH_STATE); in qmp_close()
197 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); in qmp_close()
198 qmp_kick(qmp); in qmp_close()
203 struct qmp *qmp = data; in qmp_intr() local
205 wake_up_all(&qmp->event); in qmp_intr()
210 static bool qmp_message_empty(struct qmp *qmp) in qmp_message_empty() argument
212 return readl(qmp->msgram + qmp->offset) == 0; in qmp_message_empty()
217 * @qmp: qmp context
227 int __printf(2, 3) qmp_send(struct qmp *qmp, const char *fmt, ...) in qmp_send() argument
235 if (WARN_ON(IS_ERR_OR_NULL(qmp) || !fmt)) in qmp_send()
246 mutex_lock(&qmp->tx_lock); in qmp_send()
251 __iowrite32_copy(qmp->msgram + qmp->offset + sizeof(u32), in qmp_send()
253 writel(sizeof(buf), qmp->msgram + qmp->offset); in qmp_send()
256 readl(qmp->msgram + qmp->offset); in qmp_send()
257 qmp_kick(qmp); in qmp_send()
259 time_left = wait_event_interruptible_timeout(qmp->event, in qmp_send()
260 qmp_message_empty(qmp), HZ); in qmp_send()
262 dev_err(qmp->dev, "ucore did not ack channel\n"); in qmp_send()
266 writel(0, qmp->msgram + qmp->offset); in qmp_send()
273 mutex_unlock(&qmp->tx_lock); in qmp_send()
282 struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); in qmp_qdss_clk_prepare() local
284 return qmp_send(qmp, buf); in qmp_qdss_clk_prepare()
290 struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); in qmp_qdss_clk_unprepare() local
292 qmp_send(qmp, buf); in qmp_qdss_clk_unprepare()
300 static int qmp_qdss_clk_add(struct qmp *qmp) in qmp_qdss_clk_add() argument
308 qmp->qdss_clk.init = &qdss_init; in qmp_qdss_clk_add()
309 ret = clk_hw_register(qmp->dev, &qmp->qdss_clk); in qmp_qdss_clk_add()
311 dev_err(qmp->dev, "failed to register qdss clock\n"); in qmp_qdss_clk_add()
315 ret = of_clk_add_hw_provider(qmp->dev->of_node, of_clk_hw_simple_get, in qmp_qdss_clk_add()
316 &qmp->qdss_clk); in qmp_qdss_clk_add()
318 dev_err(qmp->dev, "unable to register of clk hw provider\n"); in qmp_qdss_clk_add()
319 clk_hw_unregister(&qmp->qdss_clk); in qmp_qdss_clk_add()
325 static void qmp_qdss_clk_remove(struct qmp *qmp) in qmp_qdss_clk_remove() argument
327 of_clk_del_provider(qmp->dev->of_node); in qmp_qdss_clk_remove()
328 clk_hw_unregister(&qmp->qdss_clk); in qmp_qdss_clk_remove()
360 ret = qmp_send(qmp_cdev->qmp, "{class: volt_flr, event:zero_temp, res:%s, value:%s}", in qmp_cdev_set_cur_state()
374 static int qmp_cooling_device_add(struct qmp *qmp, in qmp_cooling_device_add() argument
380 qmp_cdev->qmp = qmp; in qmp_cooling_device_add()
384 (qmp->dev, node, in qmp_cooling_device_add()
389 dev_err(qmp->dev, "unable to register %s cooling device\n", in qmp_cooling_device_add()
395 static int qmp_cooling_devices_register(struct qmp *qmp) in qmp_cooling_devices_register() argument
401 np = qmp->dev->of_node; in qmp_cooling_devices_register()
403 qmp->cooling_devs = devm_kcalloc(qmp->dev, QMP_NUM_COOLING_RESOURCES, in qmp_cooling_devices_register()
404 sizeof(*qmp->cooling_devs), in qmp_cooling_devices_register()
407 if (!qmp->cooling_devs) in qmp_cooling_devices_register()
413 ret = qmp_cooling_device_add(qmp, &qmp->cooling_devs[count++], in qmp_cooling_devices_register()
420 devm_kfree(qmp->dev, qmp->cooling_devs); in qmp_cooling_devices_register()
427 (qmp->cooling_devs[count].cdev); in qmp_cooling_devices_register()
428 devm_kfree(qmp->dev, qmp->cooling_devs); in qmp_cooling_devices_register()
433 static void qmp_cooling_devices_remove(struct qmp *qmp) in qmp_cooling_devices_remove() argument
438 thermal_cooling_device_unregister(qmp->cooling_devs[i].cdev); in qmp_cooling_devices_remove()
442 * qmp_get() - get a qmp handle from a device
445 * Return: handle to qmp device on success, ERR_PTR() on failure
447 struct qmp *qmp_get(struct device *dev) in qmp_get()
451 struct qmp *qmp; in qmp_get() local
456 np = of_parse_phandle(dev->of_node, "qcom,qmp", 0); in qmp_get()
465 qmp = platform_get_drvdata(pdev); in qmp_get()
467 if (!qmp) { in qmp_get()
471 return qmp; in qmp_get()
476 * qmp_put() - release a qmp handle
477 * @qmp: qmp handle obtained from qmp_get()
479 void qmp_put(struct qmp *qmp) in qmp_put() argument
485 if (!IS_ERR_OR_NULL(qmp)) in qmp_put()
486 put_device(qmp->dev); in qmp_put()
509 struct qmp *qmp = file->private_data; in qmp_debugfs_write() local
517 for (i = 0; i < ARRAY_SIZE(qmp->debugfs_files); i++) { in qmp_debugfs_write()
518 if (qmp->debugfs_files[i] == file->f_path.dentry) { in qmp_debugfs_write()
546 ret = qmp_send(qmp, buf); in qmp_debugfs_write()
558 static void qmp_debugfs_create(struct qmp *qmp) in qmp_debugfs_create() argument
563 qmp->debugfs_root = debugfs_create_dir("qcom_aoss", NULL); in qmp_debugfs_create()
565 for (i = 0; i < ARRAY_SIZE(qmp->debugfs_files); i++) { in qmp_debugfs_create()
568 qmp->debugfs_files[i] = debugfs_create_file(entry->name, 0200, in qmp_debugfs_create()
569 qmp->debugfs_root, in qmp_debugfs_create()
570 qmp, in qmp_debugfs_create()
577 struct qmp *qmp; in qmp_probe() local
581 qmp = devm_kzalloc(&pdev->dev, sizeof(*qmp), GFP_KERNEL); in qmp_probe()
582 if (!qmp) in qmp_probe()
585 qmp->dev = &pdev->dev; in qmp_probe()
586 init_waitqueue_head(&qmp->event); in qmp_probe()
587 mutex_init(&qmp->tx_lock); in qmp_probe()
589 qmp->msgram = devm_platform_ioremap_resource(pdev, 0); in qmp_probe()
590 if (IS_ERR(qmp->msgram)) in qmp_probe()
591 return PTR_ERR(qmp->msgram); in qmp_probe()
593 qmp->mbox_client.dev = &pdev->dev; in qmp_probe()
594 qmp->mbox_client.knows_txdone = true; in qmp_probe()
595 qmp->mbox_chan = mbox_request_channel(&qmp->mbox_client, 0); in qmp_probe()
596 if (IS_ERR(qmp->mbox_chan)) { in qmp_probe()
598 return PTR_ERR(qmp->mbox_chan); in qmp_probe()
603 "aoss-qmp", qmp); in qmp_probe()
609 ret = qmp_open(qmp); in qmp_probe()
613 ret = qmp_qdss_clk_add(qmp); in qmp_probe()
617 ret = qmp_cooling_devices_register(qmp); in qmp_probe()
621 platform_set_drvdata(pdev, qmp); in qmp_probe()
623 qmp_debugfs_create(qmp); in qmp_probe()
628 qmp_close(qmp); in qmp_probe()
630 mbox_free_channel(qmp->mbox_chan); in qmp_probe()
637 struct qmp *qmp = platform_get_drvdata(pdev); in qmp_remove() local
639 debugfs_remove_recursive(qmp->debugfs_root); in qmp_remove()
641 qmp_qdss_clk_remove(qmp); in qmp_remove()
642 qmp_cooling_devices_remove(qmp); in qmp_remove()
644 qmp_close(qmp); in qmp_remove()
645 mbox_free_channel(qmp->mbox_chan); in qmp_remove()
649 { .compatible = "qcom,sc7180-aoss-qmp", },
650 { .compatible = "qcom,sc7280-aoss-qmp", },
651 { .compatible = "qcom,sdm845-aoss-qmp", },
652 { .compatible = "qcom,sm8150-aoss-qmp", },
653 { .compatible = "qcom,sm8250-aoss-qmp", },
654 { .compatible = "qcom,sm8350-aoss-qmp", },
655 { .compatible = "qcom,aoss-qmp", },
671 MODULE_DESCRIPTION("Qualcomm AOSS QMP driver");