Skip to content

Commit 23fe811

Browse files
LiHuiSong1joyxu
authored andcommitted
soc: hisilicon: kunpeng_hccs: Add used HCCS types sysfs
Kunpeng_hccs driver supports multiple HCCS types used on one platform at the same time. In this case, to find which HCCS types are used on the platform the user needs to scan the type attribute of all ports, which is unfriendly to the user. In addition, the aggregated information is also useful for global control like the low power feature. So add the sysfs to show all HCCS types used on the platform. Signed-off-by: Huisong Li <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Signed-off-by: Wei Xu <[email protected]>
1 parent b518783 commit 23fe811

File tree

3 files changed

+124
-1
lines changed

3 files changed

+124
-1
lines changed

Documentation/ABI/testing/sysfs-devices-platform-kunpeng_hccs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,11 @@ Description:
7979
indicates a lane.
8080
crc_err_cnt: (RO) CRC err count on this port.
8181
============= ==== =============================================
82+
83+
What: /sys/devices/platform/HISI04Bx:00/used_types
84+
Date: August 2024
85+
KernelVersion: 6.12
86+
Contact: Huisong Li <[email protected]>
87+
Description:
88+
This interface is used to show all HCCS types used on the
89+
platform, like, HCCS-v1, HCCS-v2 and so on.

drivers/soc/hisilicon/kunpeng_hccs.c

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@
2121
* - if all enabled ports are in linked
2222
* - if all linked ports are in full lane
2323
* - CRC error count sum
24+
*
25+
* - Retrieve all HCCS types used on the platform.
2426
*/
2527
#include <linux/acpi.h>
2628
#include <linux/iopoll.h>
2729
#include <linux/platform_device.h>
2830
#include <linux/sysfs.h>
31+
#include <linux/types.h>
2932

3033
#include <acpi/pcc.h>
3134

@@ -53,6 +56,15 @@ static struct hccs_chip_info *kobj_to_chip_info(struct kobject *k)
5356
return container_of(k, struct hccs_chip_info, kobj);
5457
}
5558

59+
static struct hccs_dev *device_kobj_to_hccs_dev(struct kobject *k)
60+
{
61+
struct device *dev = container_of(k, struct device, kobj);
62+
struct platform_device *pdev =
63+
container_of(dev, struct platform_device, dev);
64+
65+
return platform_get_drvdata(pdev);
66+
}
67+
5668
struct hccs_register_ctx {
5769
struct device *dev;
5870
u8 chan_id;
@@ -670,6 +682,55 @@ static int hccs_get_hw_info(struct hccs_dev *hdev)
670682
return 0;
671683
}
672684

685+
static u16 hccs_calc_used_type_num(struct hccs_dev *hdev,
686+
unsigned long *hccs_ver)
687+
{
688+
struct hccs_chip_info *chip;
689+
struct hccs_port_info *port;
690+
struct hccs_die_info *die;
691+
u16 used_type_num = 0;
692+
u16 i, j, k;
693+
694+
for (i = 0; i < hdev->chip_num; i++) {
695+
chip = &hdev->chips[i];
696+
for (j = 0; j < chip->die_num; j++) {
697+
die = &chip->dies[j];
698+
for (k = 0; k < die->port_num; k++) {
699+
port = &die->ports[k];
700+
set_bit(port->port_type, hccs_ver);
701+
}
702+
}
703+
}
704+
705+
for_each_set_bit(i, hccs_ver, HCCS_IP_MAX + 1)
706+
used_type_num++;
707+
708+
return used_type_num;
709+
}
710+
711+
static int hccs_init_type_name_maps(struct hccs_dev *hdev)
712+
{
713+
DECLARE_BITMAP(hccs_ver, HCCS_IP_MAX + 1) = {};
714+
unsigned int i;
715+
u16 idx = 0;
716+
717+
hdev->used_type_num = hccs_calc_used_type_num(hdev, hccs_ver);
718+
hdev->type_name_maps = devm_kcalloc(hdev->dev, hdev->used_type_num,
719+
sizeof(struct hccs_type_name_map),
720+
GFP_KERNEL);
721+
if (!hdev->type_name_maps)
722+
return -ENOMEM;
723+
724+
for_each_set_bit(i, hccs_ver, HCCS_IP_MAX + 1) {
725+
hdev->type_name_maps[idx].type = i;
726+
sprintf(hdev->type_name_maps[idx].name,
727+
"%s%u", HCCS_IP_PREFIX, i);
728+
idx++;
729+
}
730+
731+
return 0;
732+
}
733+
673734
static int hccs_query_port_link_status(struct hccs_dev *hdev,
674735
const struct hccs_port_info *port,
675736
struct hccs_link_status *link_status)
@@ -830,7 +891,7 @@ static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr,
830891
{
831892
const struct hccs_port_info *port = kobj_to_port_info(kobj);
832893

833-
return sysfs_emit(buf, "HCCS-v%u\n", port->port_type);
894+
return sysfs_emit(buf, "%s%u\n", HCCS_IP_PREFIX, port->port_type);
834895
}
835896
static struct kobj_attribute hccs_type_attr = __ATTR_RO(type);
836897

@@ -1134,6 +1195,33 @@ static const struct kobj_type hccs_chip_type = {
11341195
.default_groups = hccs_chip_default_groups,
11351196
};
11361197

1198+
1199+
static ssize_t used_types_show(struct kobject *kobj,
1200+
struct kobj_attribute *attr, char *buf)
1201+
{
1202+
struct hccs_dev *hdev = device_kobj_to_hccs_dev(kobj);
1203+
int len = 0;
1204+
u16 i;
1205+
1206+
for (i = 0; i < hdev->used_type_num - 1; i++)
1207+
len += sysfs_emit(&buf[len], "%s ", hdev->type_name_maps[i].name);
1208+
len += sysfs_emit(&buf[len], "%s\n", hdev->type_name_maps[i].name);
1209+
1210+
return len;
1211+
}
1212+
static struct kobj_attribute used_types_attr =
1213+
__ATTR(used_types, 0444, used_types_show, NULL);
1214+
1215+
static void hccs_remove_misc_sysfs(struct hccs_dev *hdev)
1216+
{
1217+
sysfs_remove_file(&hdev->dev->kobj, &used_types_attr.attr);
1218+
}
1219+
1220+
static int hccs_add_misc_sysfs(struct hccs_dev *hdev)
1221+
{
1222+
return sysfs_create_file(&hdev->dev->kobj, &used_types_attr.attr);
1223+
}
1224+
11371225
static void hccs_remove_die_dir(struct hccs_die_info *die)
11381226
{
11391227
struct hccs_port_info *port;
@@ -1168,6 +1256,8 @@ static void hccs_remove_topo_dirs(struct hccs_dev *hdev)
11681256

11691257
for (i = 0; i < hdev->chip_num; i++)
11701258
hccs_remove_chip_dir(&hdev->chips[i]);
1259+
1260+
hccs_remove_misc_sysfs(hdev);
11711261
}
11721262

11731263
static int hccs_create_hccs_dir(struct hccs_dev *hdev,
@@ -1263,6 +1353,12 @@ static int hccs_create_topo_dirs(struct hccs_dev *hdev)
12631353
}
12641354
}
12651355

1356+
ret = hccs_add_misc_sysfs(hdev);
1357+
if (ret) {
1358+
dev_err(hdev->dev, "create misc sysfs interface failed, ret = %d\n", ret);
1359+
goto err;
1360+
}
1361+
12661362
return 0;
12671363
err:
12681364
for (k = 0; k < id; k++)
@@ -1313,6 +1409,10 @@ static int hccs_probe(struct platform_device *pdev)
13131409
if (rc)
13141410
goto unregister_pcc_chan;
13151411

1412+
rc = hccs_init_type_name_maps(hdev);
1413+
if (rc)
1414+
goto unregister_pcc_chan;
1415+
13161416
rc = hccs_create_topo_dirs(hdev);
13171417
if (rc)
13181418
goto unregister_pcc_chan;

drivers/soc/hisilicon/kunpeng_hccs.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@
1010
* | P0 | P1 | P2 | P3 | P0 | P1 | P2 | P3 | P0 | P1 | P2 | P3 |P0 | P1 | P2 | P3 |
1111
*/
1212

13+
enum hccs_port_type {
14+
HCCS_V1 = 1,
15+
HCCS_V2,
16+
};
17+
18+
#define HCCS_IP_PREFIX "HCCS-v"
19+
#define HCCS_IP_MAX 255
20+
#define HCCS_NAME_MAX_LEN 9
21+
struct hccs_type_name_map {
22+
u8 type;
23+
char name[HCCS_NAME_MAX_LEN + 1];
24+
};
25+
1326
/*
1427
* This value cannot be 255, otherwise the loop of the multi-BD communication
1528
* case cannot end.
@@ -74,6 +87,8 @@ struct hccs_dev {
7487
u64 caps;
7588
u8 chip_num;
7689
struct hccs_chip_info *chips;
90+
u16 used_type_num;
91+
struct hccs_type_name_map *type_name_maps;
7792
u8 chan_id;
7893
struct mutex lock;
7994
struct hccs_mbox_client_info cl_info;

0 commit comments

Comments
 (0)