blob: df41715c08ee1d5afe8fd5fb75bd54a223d337ae [file] [log] [blame]
developere5e687d2023-08-08 16:05:33 +08001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
4 *
5 * Author: Ren-Ting Wang <ren-ting.wang@mediatek.com>
6 */
7
8#include <linux/device.h>
9
developer0fb30d52023-12-04 09:51:36 +080010#include "tops/firmware.h"
11#include "tops/internal.h"
12#include "tops/mcu.h"
13#include "tops/trm.h"
14#include "tops/tunnel.h"
15#include "tops/wdt.h"
developere5e687d2023-08-08 16:05:33 +080016
17static int mtk_tops_trm_fetch_setting(const char *buf,
18 int *ofs,
19 char *name,
20 u32 *offset,
21 u32 *size,
22 u8 *enable)
23{
24 int nchar = 0;
25 int ret = 0;
26
27 ret = sscanf(buf + *ofs, "%31s %x %x %hhx %n",
28 name, offset, size, enable, &nchar);
29 if (ret != 4)
30 return -EPERM;
31
32 *ofs += nchar;
33
34 return nchar;
35}
36
37static ssize_t mtk_tops_trm_store(struct device *dev,
38 struct device_attribute *attr,
39 const char *buf,
40 size_t count)
41{
42 char name[TRM_CONFIG_NAME_MAX_LEN] = { 0 };
43 char cmd[21] = { 0 };
44 int nchar = 0;
45 int ret = 0;
46 u32 offset;
47 u8 enable;
48 u32 size;
49
50 ret = sscanf(buf, "%20s %n", cmd, &nchar);
51 if (ret != 1)
52 return -EPERM;
53
54 if (!strcmp(cmd, "trm_dump")) {
55 ret = mtk_trm_dump(TRM_RSN_NULL);
56 if (ret)
57 return ret;
58 } else if (!strcmp(cmd, "trm_cfg_setup")) {
59 ret = mtk_tops_trm_fetch_setting(buf, &nchar,
60 name, &offset, &size, &enable);
61 if (ret < 0)
62 return ret;
63
64 ret = mtk_trm_cfg_setup(name, offset, size, enable);
65 if (ret)
66 return ret;
67 }
68
69 return count;
70}
71
72static ssize_t mtk_tops_wdt_store(struct device *dev,
73 struct device_attribute *attr,
74 const char *buf,
75 size_t count)
76{
77 char cmd[21] = {0};
78 u32 core = 0;
79 u32 i;
80 int ret;
81
82 ret = sscanf(buf, "%20s %x", cmd, &core);
83 if (ret != 2)
84 return -EPERM;
85
86 core &= CORE_TOPS_MASK;
87 if (!strcmp(cmd, "WDT_TO")) {
88 for (i = 0; i < CORE_TOPS_NUM; i++) {
89 if (core & 0x1)
90 mtk_tops_wdt_trigger_timeout(i);
91 core >>= 1;
92 }
93 } else {
94 return -EINVAL;
95 }
96
97 return count;
98}
99
developere5e687d2023-08-08 16:05:33 +0800100static DEVICE_ATTR_WO(mtk_tops_trm);
101static DEVICE_ATTR_WO(mtk_tops_wdt);
102
103static struct attribute *mtk_tops_attributes[] = {
developere5e687d2023-08-08 16:05:33 +0800104 &dev_attr_mtk_tops_trm.attr,
105 &dev_attr_mtk_tops_wdt.attr,
106 NULL,
107};
108
109static const struct attribute_group mtk_tops_attr_group = {
110 .name = "mtk_tops",
111 .attrs = mtk_tops_attributes,
112};
113
114int mtk_tops_ctrl_init(struct platform_device *pdev)
115{
116 int ret = 0;
117
118 ret = sysfs_create_group(&pdev->dev.kobj, &mtk_tops_attr_group);
119 if (ret) {
120 TOPS_ERR("create sysfs failed\n");
121 return ret;
122 }
123
124 return ret;
125}
126
127void mtk_tops_ctrl_deinit(struct platform_device *pdev)
128{
129 sysfs_remove_group(&pdev->dev.kobj, &mtk_tops_attr_group);
130}