diff options
Diffstat (limited to 'drivers/net/ipa/ipa_sysfs.c')
| -rw-r--r-- | drivers/net/ipa/ipa_sysfs.c | 90 |
1 files changed, 64 insertions, 26 deletions
diff --git a/drivers/net/ipa/ipa_sysfs.c b/drivers/net/ipa/ipa_sysfs.c index ff61dbdd70d8..a53e9e6f6cdf 100644 --- a/drivers/net/ipa/ipa_sysfs.c +++ b/drivers/net/ipa/ipa_sysfs.c @@ -1,15 +1,14 @@ // SPDX-License-Identifier: GPL-2.0 -/* Copyright (C) 2021 Linaro Ltd. */ +/* Copyright (C) 2021-2024 Linaro Ltd. */ -#include <linux/kernel.h> -#include <linux/types.h> #include <linux/device.h> #include <linux/sysfs.h> +#include <linux/types.h> #include "ipa.h" -#include "ipa_version.h" #include "ipa_sysfs.h" +#include "ipa_version.h" static const char *ipa_version_string(struct ipa *ipa) { @@ -36,8 +35,14 @@ static const char *ipa_version_string(struct ipa *ipa) return "4.9"; case IPA_VERSION_4_11: return "4.11"; + case IPA_VERSION_5_0: + return "5.0"; + case IPA_VERSION_5_1: + return "5.1"; + case IPA_VERSION_5_5: + return "5.5"; default: - return "0.0"; /* Won't happen (checked at probe time) */ + return "0.0"; /* Should not happen */ } } @@ -46,7 +51,7 @@ version_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ipa *ipa = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_version_string(ipa)); + return sysfs_emit(buf, "%s\n", ipa_version_string(ipa)); } static DEVICE_ATTR_RO(version); @@ -70,7 +75,7 @@ static ssize_t rx_offload_show(struct device *dev, { struct ipa *ipa = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa)); + return sysfs_emit(buf, "%s\n", ipa_offload_string(ipa)); } static DEVICE_ATTR_RO(rx_offload); @@ -80,7 +85,7 @@ static ssize_t tx_offload_show(struct device *dev, { struct ipa *ipa = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa)); + return sysfs_emit(buf, "%s\n", ipa_offload_string(ipa)); } static DEVICE_ATTR_RO(tx_offload); @@ -96,38 +101,71 @@ const struct attribute_group ipa_feature_attribute_group = { .attrs = ipa_feature_attrs, }; -static ssize_t -ipa_endpoint_id_show(struct ipa *ipa, char *buf, enum ipa_endpoint_name name) +static umode_t ipa_endpoint_id_is_visible(struct kobject *kobj, + struct attribute *attr, int n) { - u32 endpoint_id = ipa->name_map[name]->endpoint_id; + struct ipa *ipa = dev_get_drvdata(kobj_to_dev(kobj)); + struct device_attribute *dev_attr; + struct dev_ext_attribute *ea; + bool visible; - return scnprintf(buf, PAGE_SIZE, "%u\n", endpoint_id); + /* An endpoint id attribute is only visible if it's defined */ + dev_attr = container_of(attr, struct device_attribute, attr); + ea = container_of(dev_attr, struct dev_ext_attribute, attr); + + visible = !!ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var]; + + return visible ? attr->mode : 0; } -static ssize_t rx_endpoint_id_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t endpoint_id_attr_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct ipa *ipa = dev_get_drvdata(dev); + struct ipa_endpoint *endpoint; + struct dev_ext_attribute *ea; + + ea = container_of(attr, struct dev_ext_attribute, attr); + endpoint = ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var]; - return ipa_endpoint_id_show(ipa, buf, IPA_ENDPOINT_AP_MODEM_RX); + return sysfs_emit(buf, "%u\n", endpoint->endpoint_id); } -static DEVICE_ATTR_RO(rx_endpoint_id); +#define ENDPOINT_ID_ATTR(_n, _endpoint_name) \ + static struct dev_ext_attribute dev_attr_endpoint_id_ ## _n = { \ + .attr = __ATTR(_n, 0444, endpoint_id_attr_show, NULL), \ + .var = (void *)(_endpoint_name), \ + } -static ssize_t tx_endpoint_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ipa *ipa = dev_get_drvdata(dev); +ENDPOINT_ID_ATTR(modem_rx, IPA_ENDPOINT_AP_MODEM_RX); +ENDPOINT_ID_ATTR(modem_tx, IPA_ENDPOINT_AP_MODEM_TX); - return ipa_endpoint_id_show(ipa, buf, IPA_ENDPOINT_AP_MODEM_TX); -} +static struct attribute *ipa_endpoint_id_attrs[] = { + &dev_attr_endpoint_id_modem_rx.attr.attr, + &dev_attr_endpoint_id_modem_tx.attr.attr, + NULL +}; -static DEVICE_ATTR_RO(tx_endpoint_id); +const struct attribute_group ipa_endpoint_id_attribute_group = { + .name = "endpoint_id", + .is_visible = ipa_endpoint_id_is_visible, + .attrs = ipa_endpoint_id_attrs, +}; + +/* Reuse endpoint ID attributes for the legacy modem endpoint IDs */ +#define MODEM_ATTR(_n, _endpoint_name) \ + static struct dev_ext_attribute dev_attr_modem_ ## _n = { \ + .attr = __ATTR(_n, 0444, endpoint_id_attr_show, NULL), \ + .var = (void *)(_endpoint_name), \ + } + +MODEM_ATTR(rx_endpoint_id, IPA_ENDPOINT_AP_MODEM_RX); +MODEM_ATTR(tx_endpoint_id, IPA_ENDPOINT_AP_MODEM_TX); static struct attribute *ipa_modem_attrs[] = { - &dev_attr_rx_endpoint_id.attr, - &dev_attr_tx_endpoint_id.attr, - NULL + &dev_attr_modem_rx_endpoint_id.attr.attr, + &dev_attr_modem_tx_endpoint_id.attr.attr, + NULL, }; const struct attribute_group ipa_modem_attribute_group = { |
