Skip to content

Commit 82c3a0b

Browse files
lsun100jwrdegoede
authored andcommitted
mlxbf-bootctl: Add sysfs file for BlueField boot fifo
This commit adds sysfs file for BlueField boot fifo. The boot fifo is usually used to push boot stream via USB or PCIe. Once OS is up, it can be reused by applications to read data or configuration from external host. Signed-off-by: Liming Sun <limings@nvidia.com> Reviewed-by: David Thompson <davthompson@nvidia.com> Link: https://lore.kernel.org/r/52b0b00dacbc4aad3169dd3667d79c85e334783b.1680657571.git.limings@nvidia.com Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
1 parent 5b309e8 commit 82c3a0b

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

Documentation/ABI/testing/sysfs-platform-mellanox-bootctl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,10 @@ Description:
6868
Wasted burnt and invalid
6969
Invalid not burnt but marked as valid (error state).
7070
======= ===============================================
71+
72+
What: /sys/bus/platform/devices/MLNXBF04:00/bootfifo
73+
Date: Apr 2023
74+
KernelVersion: 6.4
75+
Contact: "Liming Sun <limings@nvidia.com>"
76+
Description:
77+
The file used to access the BlueField boot fifo.

drivers/platform/mellanox/mlxbf-bootctl.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/acpi.h>
1212
#include <linux/arm-smccc.h>
13+
#include <linux/delay.h>
1314
#include <linux/module.h>
1415
#include <linux/platform_device.h>
1516

@@ -44,6 +45,10 @@ static const char * const mlxbf_bootctl_lifecycle_states[] = {
4445
[3] = "RMA",
4546
};
4647

48+
/* Mapped pointer for RSH_BOOT_FIFO_DATA and RSH_BOOT_FIFO_COUNT register. */
49+
static void __iomem *mlxbf_rsh_boot_data;
50+
static void __iomem *mlxbf_rsh_boot_cnt;
51+
4752
/* ARM SMC call which is atomic and no need for lock. */
4853
static int mlxbf_bootctl_smc(unsigned int smc_op, int smc_arg)
4954
{
@@ -287,6 +292,45 @@ static const struct acpi_device_id mlxbf_bootctl_acpi_ids[] = {
287292

288293
MODULE_DEVICE_TABLE(acpi, mlxbf_bootctl_acpi_ids);
289294

295+
static ssize_t mlxbf_bootctl_bootfifo_read(struct file *filp,
296+
struct kobject *kobj,
297+
struct bin_attribute *bin_attr,
298+
char *buf, loff_t pos,
299+
size_t count)
300+
{
301+
unsigned long timeout = msecs_to_jiffies(500);
302+
unsigned long expire = jiffies + timeout;
303+
u64 data, cnt = 0;
304+
char *p = buf;
305+
306+
while (count >= sizeof(data)) {
307+
/* Give up reading if no more data within 500ms. */
308+
if (!cnt) {
309+
cnt = readq(mlxbf_rsh_boot_cnt);
310+
if (!cnt) {
311+
if (time_after(jiffies, expire))
312+
break;
313+
usleep_range(10, 50);
314+
continue;
315+
}
316+
}
317+
318+
data = readq(mlxbf_rsh_boot_data);
319+
memcpy(p, &data, sizeof(data));
320+
count -= sizeof(data);
321+
p += sizeof(data);
322+
cnt--;
323+
expire = jiffies + timeout;
324+
}
325+
326+
return p - buf;
327+
}
328+
329+
static struct bin_attribute mlxbf_bootctl_bootfifo_sysfs_attr = {
330+
.attr = { .name = "bootfifo", .mode = 0400 },
331+
.read = mlxbf_bootctl_bootfifo_read,
332+
};
333+
290334
static bool mlxbf_bootctl_guid_match(const guid_t *guid,
291335
const struct arm_smccc_res *res)
292336
{
@@ -304,6 +348,16 @@ static int mlxbf_bootctl_probe(struct platform_device *pdev)
304348
guid_t guid;
305349
int ret;
306350

351+
/* Get the resource of the bootfifo data register. */
352+
mlxbf_rsh_boot_data = devm_platform_ioremap_resource(pdev, 0);
353+
if (IS_ERR(mlxbf_rsh_boot_data))
354+
return PTR_ERR(mlxbf_rsh_boot_data);
355+
356+
/* Get the resource of the bootfifo counter register. */
357+
mlxbf_rsh_boot_cnt = devm_platform_ioremap_resource(pdev, 1);
358+
if (IS_ERR(mlxbf_rsh_boot_cnt))
359+
return PTR_ERR(mlxbf_rsh_boot_cnt);
360+
307361
/* Ensure we have the UUID we expect for this service. */
308362
arm_smccc_smc(MLXBF_BOOTCTL_SIP_SVC_UID, 0, 0, 0, 0, 0, 0, 0, &res);
309363
guid_parse(mlxbf_bootctl_svc_uuid_str, &guid);
@@ -321,11 +375,25 @@ static int mlxbf_bootctl_probe(struct platform_device *pdev)
321375
if (ret < 0)
322376
dev_warn(&pdev->dev, "Unable to reset the EMMC boot mode\n");
323377

378+
ret = sysfs_create_bin_file(&pdev->dev.kobj,
379+
&mlxbf_bootctl_bootfifo_sysfs_attr);
380+
if (ret)
381+
pr_err("Unable to create bootfifo sysfs file, error %d\n", ret);
382+
383+
return ret;
384+
}
385+
386+
static int mlxbf_bootctl_remove(struct platform_device *pdev)
387+
{
388+
sysfs_remove_bin_file(&pdev->dev.kobj,
389+
&mlxbf_bootctl_bootfifo_sysfs_attr);
390+
324391
return 0;
325392
}
326393

327394
static struct platform_driver mlxbf_bootctl_driver = {
328395
.probe = mlxbf_bootctl_probe,
396+
.remove = mlxbf_bootctl_remove,
329397
.driver = {
330398
.name = "mlxbf-bootctl",
331399
.dev_groups = mlxbf_bootctl_groups,

0 commit comments

Comments
 (0)