xref: /OK3568_Linux_fs/kernel/drivers/misc/habanalabs/common/sysfs.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun 
3*4882a593Smuzhiyun /*
4*4882a593Smuzhiyun  * Copyright 2016-2019 HabanaLabs, Ltd.
5*4882a593Smuzhiyun  * All Rights Reserved.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include "habanalabs.h"
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/pci.h>
11*4882a593Smuzhiyun 
hl_get_frequency(struct hl_device * hdev,u32 pll_index,bool curr)12*4882a593Smuzhiyun long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr)
13*4882a593Smuzhiyun {
14*4882a593Smuzhiyun 	struct cpucp_packet pkt;
15*4882a593Smuzhiyun 	long result;
16*4882a593Smuzhiyun 	int rc;
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun 	memset(&pkt, 0, sizeof(pkt));
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun 	if (curr)
21*4882a593Smuzhiyun 		pkt.ctl = cpu_to_le32(CPUCP_PACKET_FREQUENCY_CURR_GET <<
22*4882a593Smuzhiyun 						CPUCP_PKT_CTL_OPCODE_SHIFT);
23*4882a593Smuzhiyun 	else
24*4882a593Smuzhiyun 		pkt.ctl = cpu_to_le32(CPUCP_PACKET_FREQUENCY_GET <<
25*4882a593Smuzhiyun 						CPUCP_PKT_CTL_OPCODE_SHIFT);
26*4882a593Smuzhiyun 	pkt.pll_index = cpu_to_le32(pll_index);
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
29*4882a593Smuzhiyun 						0, &result);
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	if (rc) {
32*4882a593Smuzhiyun 		dev_err(hdev->dev,
33*4882a593Smuzhiyun 			"Failed to get frequency of PLL %d, error %d\n",
34*4882a593Smuzhiyun 			pll_index, rc);
35*4882a593Smuzhiyun 		result = rc;
36*4882a593Smuzhiyun 	}
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	return result;
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun 
hl_set_frequency(struct hl_device * hdev,u32 pll_index,u64 freq)41*4882a593Smuzhiyun void hl_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	struct cpucp_packet pkt;
44*4882a593Smuzhiyun 	int rc;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	memset(&pkt, 0, sizeof(pkt));
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_FREQUENCY_SET <<
49*4882a593Smuzhiyun 					CPUCP_PKT_CTL_OPCODE_SHIFT);
50*4882a593Smuzhiyun 	pkt.pll_index = cpu_to_le32(pll_index);
51*4882a593Smuzhiyun 	pkt.value = cpu_to_le64(freq);
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
54*4882a593Smuzhiyun 						0, NULL);
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	if (rc)
57*4882a593Smuzhiyun 		dev_err(hdev->dev,
58*4882a593Smuzhiyun 			"Failed to set frequency to PLL %d, error %d\n",
59*4882a593Smuzhiyun 			pll_index, rc);
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun 
hl_get_max_power(struct hl_device * hdev)62*4882a593Smuzhiyun u64 hl_get_max_power(struct hl_device *hdev)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	struct cpucp_packet pkt;
65*4882a593Smuzhiyun 	long result;
66*4882a593Smuzhiyun 	int rc;
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	memset(&pkt, 0, sizeof(pkt));
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_MAX_POWER_GET <<
71*4882a593Smuzhiyun 				CPUCP_PKT_CTL_OPCODE_SHIFT);
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
74*4882a593Smuzhiyun 						0, &result);
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	if (rc) {
77*4882a593Smuzhiyun 		dev_err(hdev->dev, "Failed to get max power, error %d\n", rc);
78*4882a593Smuzhiyun 		result = rc;
79*4882a593Smuzhiyun 	}
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	return result;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
hl_set_max_power(struct hl_device * hdev)84*4882a593Smuzhiyun void hl_set_max_power(struct hl_device *hdev)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	struct cpucp_packet pkt;
87*4882a593Smuzhiyun 	int rc;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	memset(&pkt, 0, sizeof(pkt));
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_MAX_POWER_SET <<
92*4882a593Smuzhiyun 				CPUCP_PKT_CTL_OPCODE_SHIFT);
93*4882a593Smuzhiyun 	pkt.value = cpu_to_le64(hdev->max_power);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
96*4882a593Smuzhiyun 						0, NULL);
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	if (rc)
99*4882a593Smuzhiyun 		dev_err(hdev->dev, "Failed to set max power, error %d\n", rc);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
uboot_ver_show(struct device * dev,struct device_attribute * attr,char * buf)102*4882a593Smuzhiyun static ssize_t uboot_ver_show(struct device *dev, struct device_attribute *attr,
103*4882a593Smuzhiyun 				char *buf)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	return sprintf(buf, "%s\n", hdev->asic_prop.uboot_ver);
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
armcp_kernel_ver_show(struct device * dev,struct device_attribute * attr,char * buf)110*4882a593Smuzhiyun static ssize_t armcp_kernel_ver_show(struct device *dev,
111*4882a593Smuzhiyun 				struct device_attribute *attr, char *buf)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.kernel_version);
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
armcp_ver_show(struct device * dev,struct device_attribute * attr,char * buf)118*4882a593Smuzhiyun static ssize_t armcp_ver_show(struct device *dev, struct device_attribute *attr,
119*4882a593Smuzhiyun 				char *buf)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.cpucp_version);
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun 
cpld_ver_show(struct device * dev,struct device_attribute * attr,char * buf)126*4882a593Smuzhiyun static ssize_t cpld_ver_show(struct device *dev, struct device_attribute *attr,
127*4882a593Smuzhiyun 				char *buf)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	return sprintf(buf, "0x%08x\n",
132*4882a593Smuzhiyun 			hdev->asic_prop.cpucp_info.cpld_version);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
cpucp_kernel_ver_show(struct device * dev,struct device_attribute * attr,char * buf)135*4882a593Smuzhiyun static ssize_t cpucp_kernel_ver_show(struct device *dev,
136*4882a593Smuzhiyun 				struct device_attribute *attr, char *buf)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.kernel_version);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
cpucp_ver_show(struct device * dev,struct device_attribute * attr,char * buf)143*4882a593Smuzhiyun static ssize_t cpucp_ver_show(struct device *dev, struct device_attribute *attr,
144*4882a593Smuzhiyun 				char *buf)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.cpucp_version);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun 
infineon_ver_show(struct device * dev,struct device_attribute * attr,char * buf)151*4882a593Smuzhiyun static ssize_t infineon_ver_show(struct device *dev,
152*4882a593Smuzhiyun 				struct device_attribute *attr, char *buf)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	return sprintf(buf, "0x%04x\n",
157*4882a593Smuzhiyun 			hdev->asic_prop.cpucp_info.infineon_version);
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
fuse_ver_show(struct device * dev,struct device_attribute * attr,char * buf)160*4882a593Smuzhiyun static ssize_t fuse_ver_show(struct device *dev, struct device_attribute *attr,
161*4882a593Smuzhiyun 				char *buf)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.fuse_version);
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun 
thermal_ver_show(struct device * dev,struct device_attribute * attr,char * buf)168*4882a593Smuzhiyun static ssize_t thermal_ver_show(struct device *dev,
169*4882a593Smuzhiyun 				struct device_attribute *attr, char *buf)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.thermal_version);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun 
preboot_btl_ver_show(struct device * dev,struct device_attribute * attr,char * buf)176*4882a593Smuzhiyun static ssize_t preboot_btl_ver_show(struct device *dev,
177*4882a593Smuzhiyun 				struct device_attribute *attr, char *buf)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	return sprintf(buf, "%s\n", hdev->asic_prop.preboot_ver);
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun 
soft_reset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)184*4882a593Smuzhiyun static ssize_t soft_reset_store(struct device *dev,
185*4882a593Smuzhiyun 				struct device_attribute *attr, const char *buf,
186*4882a593Smuzhiyun 				size_t count)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
189*4882a593Smuzhiyun 	long value;
190*4882a593Smuzhiyun 	int rc;
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	rc = kstrtoul(buf, 0, &value);
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	if (rc) {
195*4882a593Smuzhiyun 		count = -EINVAL;
196*4882a593Smuzhiyun 		goto out;
197*4882a593Smuzhiyun 	}
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	if (!hdev->supports_soft_reset) {
200*4882a593Smuzhiyun 		dev_err(hdev->dev, "Device does not support soft-reset\n");
201*4882a593Smuzhiyun 		goto out;
202*4882a593Smuzhiyun 	}
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	dev_warn(hdev->dev, "Soft-Reset requested through sysfs\n");
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	hl_device_reset(hdev, false, false);
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun out:
209*4882a593Smuzhiyun 	return count;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun 
hard_reset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)212*4882a593Smuzhiyun static ssize_t hard_reset_store(struct device *dev,
213*4882a593Smuzhiyun 				struct device_attribute *attr,
214*4882a593Smuzhiyun 				const char *buf, size_t count)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
217*4882a593Smuzhiyun 	long value;
218*4882a593Smuzhiyun 	int rc;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	rc = kstrtoul(buf, 0, &value);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	if (rc) {
223*4882a593Smuzhiyun 		count = -EINVAL;
224*4882a593Smuzhiyun 		goto out;
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	dev_warn(hdev->dev, "Hard-Reset requested through sysfs\n");
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	hl_device_reset(hdev, true, false);
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun out:
232*4882a593Smuzhiyun 	return count;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun 
device_type_show(struct device * dev,struct device_attribute * attr,char * buf)235*4882a593Smuzhiyun static ssize_t device_type_show(struct device *dev,
236*4882a593Smuzhiyun 		struct device_attribute *attr, char *buf)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
239*4882a593Smuzhiyun 	char *str;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	switch (hdev->asic_type) {
242*4882a593Smuzhiyun 	case ASIC_GOYA:
243*4882a593Smuzhiyun 		str = "GOYA";
244*4882a593Smuzhiyun 		break;
245*4882a593Smuzhiyun 	case ASIC_GAUDI:
246*4882a593Smuzhiyun 		str = "GAUDI";
247*4882a593Smuzhiyun 		break;
248*4882a593Smuzhiyun 	default:
249*4882a593Smuzhiyun 		dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
250*4882a593Smuzhiyun 				hdev->asic_type);
251*4882a593Smuzhiyun 		return -EINVAL;
252*4882a593Smuzhiyun 	}
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	return sprintf(buf, "%s\n", str);
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun 
pci_addr_show(struct device * dev,struct device_attribute * attr,char * buf)257*4882a593Smuzhiyun static ssize_t pci_addr_show(struct device *dev, struct device_attribute *attr,
258*4882a593Smuzhiyun 				char *buf)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	return sprintf(buf, "%04x:%02x:%02x.%x\n",
263*4882a593Smuzhiyun 			pci_domain_nr(hdev->pdev->bus),
264*4882a593Smuzhiyun 			hdev->pdev->bus->number,
265*4882a593Smuzhiyun 			PCI_SLOT(hdev->pdev->devfn),
266*4882a593Smuzhiyun 			PCI_FUNC(hdev->pdev->devfn));
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun 
status_show(struct device * dev,struct device_attribute * attr,char * buf)269*4882a593Smuzhiyun static ssize_t status_show(struct device *dev, struct device_attribute *attr,
270*4882a593Smuzhiyun 				char *buf)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
273*4882a593Smuzhiyun 	char *str;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	if (atomic_read(&hdev->in_reset))
276*4882a593Smuzhiyun 		str = "In reset";
277*4882a593Smuzhiyun 	else if (hdev->disabled)
278*4882a593Smuzhiyun 		str = "Malfunction";
279*4882a593Smuzhiyun 	else
280*4882a593Smuzhiyun 		str = "Operational";
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	return sprintf(buf, "%s\n", str);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun 
soft_reset_cnt_show(struct device * dev,struct device_attribute * attr,char * buf)285*4882a593Smuzhiyun static ssize_t soft_reset_cnt_show(struct device *dev,
286*4882a593Smuzhiyun 		struct device_attribute *attr, char *buf)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", hdev->soft_reset_cnt);
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun 
hard_reset_cnt_show(struct device * dev,struct device_attribute * attr,char * buf)293*4882a593Smuzhiyun static ssize_t hard_reset_cnt_show(struct device *dev,
294*4882a593Smuzhiyun 		struct device_attribute *attr, char *buf)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", hdev->hard_reset_cnt);
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun 
max_power_show(struct device * dev,struct device_attribute * attr,char * buf)301*4882a593Smuzhiyun static ssize_t max_power_show(struct device *dev, struct device_attribute *attr,
302*4882a593Smuzhiyun 				char *buf)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
305*4882a593Smuzhiyun 	long val;
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	if (hl_device_disabled_or_in_reset(hdev))
308*4882a593Smuzhiyun 		return -ENODEV;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	val = hl_get_max_power(hdev);
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	return sprintf(buf, "%lu\n", val);
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun 
max_power_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)315*4882a593Smuzhiyun static ssize_t max_power_store(struct device *dev,
316*4882a593Smuzhiyun 		struct device_attribute *attr, const char *buf, size_t count)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
319*4882a593Smuzhiyun 	unsigned long value;
320*4882a593Smuzhiyun 	int rc;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	if (hl_device_disabled_or_in_reset(hdev)) {
323*4882a593Smuzhiyun 		count = -ENODEV;
324*4882a593Smuzhiyun 		goto out;
325*4882a593Smuzhiyun 	}
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	rc = kstrtoul(buf, 0, &value);
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	if (rc) {
330*4882a593Smuzhiyun 		count = -EINVAL;
331*4882a593Smuzhiyun 		goto out;
332*4882a593Smuzhiyun 	}
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	hdev->max_power = value;
335*4882a593Smuzhiyun 	hl_set_max_power(hdev);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun out:
338*4882a593Smuzhiyun 	return count;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun 
eeprom_read_handler(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t max_size)341*4882a593Smuzhiyun static ssize_t eeprom_read_handler(struct file *filp, struct kobject *kobj,
342*4882a593Smuzhiyun 			struct bin_attribute *attr, char *buf, loff_t offset,
343*4882a593Smuzhiyun 			size_t max_size)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun 	struct device *dev = container_of(kobj, struct device, kobj);
346*4882a593Smuzhiyun 	struct hl_device *hdev = dev_get_drvdata(dev);
347*4882a593Smuzhiyun 	char *data;
348*4882a593Smuzhiyun 	int rc;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	if (hl_device_disabled_or_in_reset(hdev))
351*4882a593Smuzhiyun 		return -ENODEV;
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	if (!max_size)
354*4882a593Smuzhiyun 		return -EINVAL;
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	data = kzalloc(max_size, GFP_KERNEL);
357*4882a593Smuzhiyun 	if (!data)
358*4882a593Smuzhiyun 		return -ENOMEM;
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	rc = hdev->asic_funcs->get_eeprom_data(hdev, data, max_size);
361*4882a593Smuzhiyun 	if (rc)
362*4882a593Smuzhiyun 		goto out;
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	memcpy(buf, data, max_size);
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun out:
367*4882a593Smuzhiyun 	kfree(data);
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	return max_size;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun static DEVICE_ATTR_RO(armcp_kernel_ver);
373*4882a593Smuzhiyun static DEVICE_ATTR_RO(armcp_ver);
374*4882a593Smuzhiyun static DEVICE_ATTR_RO(cpld_ver);
375*4882a593Smuzhiyun static DEVICE_ATTR_RO(cpucp_kernel_ver);
376*4882a593Smuzhiyun static DEVICE_ATTR_RO(cpucp_ver);
377*4882a593Smuzhiyun static DEVICE_ATTR_RO(device_type);
378*4882a593Smuzhiyun static DEVICE_ATTR_RO(fuse_ver);
379*4882a593Smuzhiyun static DEVICE_ATTR_WO(hard_reset);
380*4882a593Smuzhiyun static DEVICE_ATTR_RO(hard_reset_cnt);
381*4882a593Smuzhiyun static DEVICE_ATTR_RO(infineon_ver);
382*4882a593Smuzhiyun static DEVICE_ATTR_RW(max_power);
383*4882a593Smuzhiyun static DEVICE_ATTR_RO(pci_addr);
384*4882a593Smuzhiyun static DEVICE_ATTR_RO(preboot_btl_ver);
385*4882a593Smuzhiyun static DEVICE_ATTR_WO(soft_reset);
386*4882a593Smuzhiyun static DEVICE_ATTR_RO(soft_reset_cnt);
387*4882a593Smuzhiyun static DEVICE_ATTR_RO(status);
388*4882a593Smuzhiyun static DEVICE_ATTR_RO(thermal_ver);
389*4882a593Smuzhiyun static DEVICE_ATTR_RO(uboot_ver);
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun static struct bin_attribute bin_attr_eeprom = {
392*4882a593Smuzhiyun 	.attr = {.name = "eeprom", .mode = (0444)},
393*4882a593Smuzhiyun 	.size = PAGE_SIZE,
394*4882a593Smuzhiyun 	.read = eeprom_read_handler
395*4882a593Smuzhiyun };
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun static struct attribute *hl_dev_attrs[] = {
398*4882a593Smuzhiyun 	&dev_attr_armcp_kernel_ver.attr,
399*4882a593Smuzhiyun 	&dev_attr_armcp_ver.attr,
400*4882a593Smuzhiyun 	&dev_attr_cpld_ver.attr,
401*4882a593Smuzhiyun 	&dev_attr_cpucp_kernel_ver.attr,
402*4882a593Smuzhiyun 	&dev_attr_cpucp_ver.attr,
403*4882a593Smuzhiyun 	&dev_attr_device_type.attr,
404*4882a593Smuzhiyun 	&dev_attr_fuse_ver.attr,
405*4882a593Smuzhiyun 	&dev_attr_hard_reset.attr,
406*4882a593Smuzhiyun 	&dev_attr_hard_reset_cnt.attr,
407*4882a593Smuzhiyun 	&dev_attr_infineon_ver.attr,
408*4882a593Smuzhiyun 	&dev_attr_max_power.attr,
409*4882a593Smuzhiyun 	&dev_attr_pci_addr.attr,
410*4882a593Smuzhiyun 	&dev_attr_preboot_btl_ver.attr,
411*4882a593Smuzhiyun 	&dev_attr_soft_reset.attr,
412*4882a593Smuzhiyun 	&dev_attr_soft_reset_cnt.attr,
413*4882a593Smuzhiyun 	&dev_attr_status.attr,
414*4882a593Smuzhiyun 	&dev_attr_thermal_ver.attr,
415*4882a593Smuzhiyun 	&dev_attr_uboot_ver.attr,
416*4882a593Smuzhiyun 	NULL,
417*4882a593Smuzhiyun };
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun static struct bin_attribute *hl_dev_bin_attrs[] = {
420*4882a593Smuzhiyun 	&bin_attr_eeprom,
421*4882a593Smuzhiyun 	NULL
422*4882a593Smuzhiyun };
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun static struct attribute_group hl_dev_attr_group = {
425*4882a593Smuzhiyun 	.attrs = hl_dev_attrs,
426*4882a593Smuzhiyun 	.bin_attrs = hl_dev_bin_attrs,
427*4882a593Smuzhiyun };
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun static struct attribute_group hl_dev_clks_attr_group;
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun static const struct attribute_group *hl_dev_attr_groups[] = {
432*4882a593Smuzhiyun 	&hl_dev_attr_group,
433*4882a593Smuzhiyun 	&hl_dev_clks_attr_group,
434*4882a593Smuzhiyun 	NULL,
435*4882a593Smuzhiyun };
436*4882a593Smuzhiyun 
hl_sysfs_init(struct hl_device * hdev)437*4882a593Smuzhiyun int hl_sysfs_init(struct hl_device *hdev)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun 	int rc;
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	if (hdev->asic_type == ASIC_GOYA)
442*4882a593Smuzhiyun 		hdev->pm_mng_profile = PM_AUTO;
443*4882a593Smuzhiyun 	else
444*4882a593Smuzhiyun 		hdev->pm_mng_profile = PM_MANUAL;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	hdev->max_power = hdev->asic_prop.max_power_default;
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	hdev->asic_funcs->add_device_attr(hdev, &hl_dev_clks_attr_group);
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	rc = device_add_groups(hdev->dev, hl_dev_attr_groups);
451*4882a593Smuzhiyun 	if (rc) {
452*4882a593Smuzhiyun 		dev_err(hdev->dev,
453*4882a593Smuzhiyun 			"Failed to add groups to device, error %d\n", rc);
454*4882a593Smuzhiyun 		return rc;
455*4882a593Smuzhiyun 	}
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	return 0;
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun 
hl_sysfs_fini(struct hl_device * hdev)460*4882a593Smuzhiyun void hl_sysfs_fini(struct hl_device *hdev)
461*4882a593Smuzhiyun {
462*4882a593Smuzhiyun 	device_remove_groups(hdev->dev, hl_dev_attr_groups);
463*4882a593Smuzhiyun }
464