Lines Matching full:qmp

58 	struct qmp *qmp;  member
64 * struct qmp - driver state for QMP implementation
66 * @dev: reference to QMP device
78 struct qmp { struct
98 static void qmp_kick(struct qmp *qmp) in qmp_kick() argument
100 mbox_send_message(qmp->mbox_chan, NULL); in qmp_kick()
101 mbox_client_txdone(qmp->mbox_chan, 0); in qmp_kick()
104 static bool qmp_magic_valid(struct qmp *qmp) in qmp_magic_valid() argument
106 return readl(qmp->msgram + QMP_DESC_MAGIC) == QMP_MAGIC; in qmp_magic_valid()
109 static bool qmp_link_acked(struct qmp *qmp) in qmp_link_acked() argument
111 return readl(qmp->msgram + QMP_DESC_MCORE_LINK_STATE_ACK) == QMP_STATE_UP; in qmp_link_acked()
114 static bool qmp_mcore_channel_acked(struct qmp *qmp) in qmp_mcore_channel_acked() argument
116 return readl(qmp->msgram + QMP_DESC_MCORE_CH_STATE_ACK) == QMP_STATE_UP; in qmp_mcore_channel_acked()
119 static bool qmp_ucore_channel_up(struct qmp *qmp) in qmp_ucore_channel_up() argument
121 return readl(qmp->msgram + QMP_DESC_UCORE_CH_STATE) == QMP_STATE_UP; in qmp_ucore_channel_up()
124 static int qmp_open(struct qmp *qmp) in qmp_open() argument
129 if (!qmp_magic_valid(qmp)) { in qmp_open()
130 dev_err(qmp->dev, "QMP magic doesn't match\n"); in qmp_open()
134 val = readl(qmp->msgram + QMP_DESC_VERSION); in qmp_open()
136 dev_err(qmp->dev, "unsupported QMP version %d\n", val); in qmp_open()
140 qmp->offset = readl(qmp->msgram + QMP_DESC_MCORE_MBOX_OFFSET); in qmp_open()
141 qmp->size = readl(qmp->msgram + QMP_DESC_MCORE_MBOX_SIZE); in qmp_open()
142 if (!qmp->size) { in qmp_open()
143 dev_err(qmp->dev, "invalid mailbox size\n"); in qmp_open()
148 val = readl(qmp->msgram + QMP_DESC_UCORE_LINK_STATE); in qmp_open()
149 writel(val, qmp->msgram + QMP_DESC_UCORE_LINK_STATE_ACK); in qmp_open()
152 writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); in qmp_open()
154 qmp_kick(qmp); in qmp_open()
156 ret = wait_event_timeout(qmp->event, qmp_link_acked(qmp), HZ); in qmp_open()
158 dev_err(qmp->dev, "ucore didn't ack link\n"); in qmp_open()
162 writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_MCORE_CH_STATE); in qmp_open()
164 qmp_kick(qmp); in qmp_open()
166 ret = wait_event_timeout(qmp->event, qmp_ucore_channel_up(qmp), HZ); in qmp_open()
168 dev_err(qmp->dev, "ucore didn't open channel\n"); in qmp_open()
173 writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_UCORE_CH_STATE_ACK); in qmp_open()
175 qmp_kick(qmp); in qmp_open()
177 ret = wait_event_timeout(qmp->event, qmp_mcore_channel_acked(qmp), HZ); in qmp_open()
179 dev_err(qmp->dev, "ucore didn't ack channel\n"); in qmp_open()
186 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_CH_STATE); in qmp_open()
189 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); in qmp_open()
190 qmp_kick(qmp); in qmp_open()
195 static void qmp_close(struct qmp *qmp) in qmp_close() argument
197 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_CH_STATE); in qmp_close()
198 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); in qmp_close()
199 qmp_kick(qmp); in qmp_close()
204 struct qmp *qmp = data; in qmp_intr() local
206 wake_up_all(&qmp->event); in qmp_intr()
211 static bool qmp_message_empty(struct qmp *qmp) in qmp_message_empty() argument
213 return readl(qmp->msgram + qmp->offset) == 0; in qmp_message_empty()
218 * @qmp: qmp context
228 int __printf(2, 3) qmp_send(struct qmp *qmp, const char *fmt, ...) in qmp_send() argument
236 if (WARN_ON(IS_ERR_OR_NULL(qmp) || !fmt)) in qmp_send()
247 mutex_lock(&qmp->tx_lock); in qmp_send()
252 __iowrite32_copy(qmp->msgram + qmp->offset + sizeof(u32), in qmp_send()
254 writel(sizeof(buf), qmp->msgram + qmp->offset); in qmp_send()
257 readl(qmp->msgram + qmp->offset); in qmp_send()
258 qmp_kick(qmp); in qmp_send()
260 time_left = wait_event_interruptible_timeout(qmp->event, in qmp_send()
261 qmp_message_empty(qmp), HZ); in qmp_send()
263 dev_err(qmp->dev, "ucore did not ack channel\n"); in qmp_send()
267 writel(0, qmp->msgram + qmp->offset); in qmp_send()
274 mutex_unlock(&qmp->tx_lock); in qmp_send()
283 struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); in qmp_qdss_clk_prepare() local
285 return qmp_send(qmp, buf); in qmp_qdss_clk_prepare()
291 struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); in qmp_qdss_clk_unprepare() local
293 qmp_send(qmp, buf); in qmp_qdss_clk_unprepare()
301 static int qmp_qdss_clk_add(struct qmp *qmp) in qmp_qdss_clk_add() argument
309 qmp->qdss_clk.init = &qdss_init; in qmp_qdss_clk_add()
310 ret = clk_hw_register(qmp->dev, &qmp->qdss_clk); in qmp_qdss_clk_add()
312 dev_err(qmp->dev, "failed to register qdss clock\n"); in qmp_qdss_clk_add()
316 ret = of_clk_add_hw_provider(qmp->dev->of_node, of_clk_hw_simple_get, in qmp_qdss_clk_add()
317 &qmp->qdss_clk); in qmp_qdss_clk_add()
319 dev_err(qmp->dev, "unable to register of clk hw provider\n"); in qmp_qdss_clk_add()
320 clk_hw_unregister(&qmp->qdss_clk); in qmp_qdss_clk_add()
326 static void qmp_qdss_clk_remove(struct qmp *qmp) in qmp_qdss_clk_remove() argument
328 of_clk_del_provider(qmp->dev->of_node); in qmp_qdss_clk_remove()
329 clk_hw_unregister(&qmp->qdss_clk); in qmp_qdss_clk_remove()
361 ret = qmp_send(qmp_cdev->qmp, "{class: volt_flr, event:zero_temp, res:%s, value:%s}", in qmp_cdev_set_cur_state()
375 static int qmp_cooling_device_add(struct qmp *qmp, in qmp_cooling_device_add() argument
381 qmp_cdev->qmp = qmp; in qmp_cooling_device_add()
385 (qmp->dev, node, in qmp_cooling_device_add()
390 dev_err(qmp->dev, "unable to register %s cooling device\n", in qmp_cooling_device_add()
396 static int qmp_cooling_devices_register(struct qmp *qmp) in qmp_cooling_devices_register() argument
402 np = qmp->dev->of_node; in qmp_cooling_devices_register()
404 qmp->cooling_devs = devm_kcalloc(qmp->dev, QMP_NUM_COOLING_RESOURCES, in qmp_cooling_devices_register()
405 sizeof(*qmp->cooling_devs), in qmp_cooling_devices_register()
408 if (!qmp->cooling_devs) in qmp_cooling_devices_register()
414 ret = qmp_cooling_device_add(qmp, &qmp->cooling_devs[count++], in qmp_cooling_devices_register()
421 devm_kfree(qmp->dev, qmp->cooling_devs); in qmp_cooling_devices_register()
428 (qmp->cooling_devs[count].cdev); in qmp_cooling_devices_register()
429 devm_kfree(qmp->dev, qmp->cooling_devs); in qmp_cooling_devices_register()
434 static void qmp_cooling_devices_remove(struct qmp *qmp) in qmp_cooling_devices_remove() argument
439 thermal_cooling_device_unregister(qmp->cooling_devs[i].cdev); in qmp_cooling_devices_remove()
443 * qmp_get() - get a qmp handle from a device
446 * Return: handle to qmp device on success, ERR_PTR() on failure
448 struct qmp *qmp_get(struct device *dev) in qmp_get()
452 struct qmp *qmp; in qmp_get() local
457 np = of_parse_phandle(dev->of_node, "qcom,qmp", 0); in qmp_get()
466 qmp = platform_get_drvdata(pdev); in qmp_get()
468 if (!qmp) { in qmp_get()
472 return qmp; in qmp_get()
477 * qmp_put() - release a qmp handle
478 * @qmp: qmp handle obtained from qmp_get()
480 void qmp_put(struct qmp *qmp) in qmp_put() argument
486 if (!IS_ERR_OR_NULL(qmp)) in qmp_put()
487 put_device(qmp->dev); in qmp_put()
510 struct qmp *qmp = file->private_data; in qmp_debugfs_write() local
518 for (i = 0; i < ARRAY_SIZE(qmp->debugfs_files); i++) { in qmp_debugfs_write()
519 if (qmp->debugfs_files[i] == file->f_path.dentry) { in qmp_debugfs_write()
547 ret = qmp_send(qmp, buf); in qmp_debugfs_write()
559 static void qmp_debugfs_create(struct qmp *qmp) in qmp_debugfs_create() argument
564 qmp->debugfs_root = debugfs_create_dir("qcom_aoss", NULL); in qmp_debugfs_create()
566 for (i = 0; i < ARRAY_SIZE(qmp->debugfs_files); i++) { in qmp_debugfs_create()
569 qmp->debugfs_files[i] = debugfs_create_file(entry->name, 0200, in qmp_debugfs_create()
570 qmp->debugfs_root, in qmp_debugfs_create()
571 qmp, in qmp_debugfs_create()
578 struct qmp *qmp; in qmp_probe() local
582 qmp = devm_kzalloc(&pdev->dev, sizeof(*qmp), GFP_KERNEL); in qmp_probe()
583 if (!qmp) in qmp_probe()
586 qmp->dev = &pdev->dev; in qmp_probe()
587 init_waitqueue_head(&qmp->event); in qmp_probe()
588 mutex_init(&qmp->tx_lock); in qmp_probe()
590 qmp->msgram = devm_platform_ioremap_resource(pdev, 0); in qmp_probe()
591 if (IS_ERR(qmp->msgram)) in qmp_probe()
592 return PTR_ERR(qmp->msgram); in qmp_probe()
594 qmp->mbox_client.dev = &pdev->dev; in qmp_probe()
595 qmp->mbox_client.knows_txdone = true; in qmp_probe()
596 qmp->mbox_chan = mbox_request_channel(&qmp->mbox_client, 0); in qmp_probe()
597 if (IS_ERR(qmp->mbox_chan)) { in qmp_probe()
599 return PTR_ERR(qmp->mbox_chan); in qmp_probe()
604 "aoss-qmp", qmp); in qmp_probe()
610 ret = qmp_open(qmp); in qmp_probe()
614 ret = qmp_qdss_clk_add(qmp); in qmp_probe()
618 ret = qmp_cooling_devices_register(qmp); in qmp_probe()
622 platform_set_drvdata(pdev, qmp); in qmp_probe()
624 qmp_debugfs_create(qmp); in qmp_probe()
629 qmp_close(qmp); in qmp_probe()
631 mbox_free_channel(qmp->mbox_chan); in qmp_probe()
638 struct qmp *qmp = platform_get_drvdata(pdev); in qmp_remove() local
640 debugfs_remove_recursive(qmp->debugfs_root); in qmp_remove()
642 qmp_qdss_clk_remove(qmp); in qmp_remove()
643 qmp_cooling_devices_remove(qmp); in qmp_remove()
645 qmp_close(qmp); in qmp_remove()
646 mbox_free_channel(qmp->mbox_chan); in qmp_remove()
650 { .compatible = "qcom,sc7180-aoss-qmp", },
651 { .compatible = "qcom,sc7280-aoss-qmp", },
652 { .compatible = "qcom,sdm845-aoss-qmp", },
653 { .compatible = "qcom,sm8150-aoss-qmp", },
654 { .compatible = "qcom,sm8250-aoss-qmp", },
655 { .compatible = "qcom,sm8350-aoss-qmp", },
656 { .compatible = "qcom,aoss-qmp", },
672 MODULE_DESCRIPTION("Qualcomm AOSS QMP driver");