|
8 | 8 |
|
9 | 9 | #include <linux/debugfs.h> |
10 | 10 | #include <linux/delay.h> |
| 11 | +#include <linux/dcache.h> |
11 | 12 | #include <linux/kernel.h> |
12 | 13 | #include <linux/math64.h> |
13 | 14 | #include <linux/module.h> |
@@ -99,7 +100,6 @@ struct pmbus_data { |
99 | 100 | int num_attributes; |
100 | 101 | struct attribute_group group; |
101 | 102 | const struct attribute_group **groups; |
102 | | - struct dentry *debugfs; /* debugfs device directory */ |
103 | 103 |
|
104 | 104 | struct pmbus_sensor *sensors; |
105 | 105 |
|
@@ -3496,34 +3496,49 @@ static const struct file_operations pmbus_debugfs_ops_mfr = { |
3496 | 3496 | .open = simple_open, |
3497 | 3497 | }; |
3498 | 3498 |
|
3499 | | -static void pmbus_remove_debugfs(void *data) |
| 3499 | +static void pmbus_remove_symlink(void *symlink) |
3500 | 3500 | { |
3501 | | - struct dentry *entry = data; |
3502 | | - |
3503 | | - debugfs_remove_recursive(entry); |
| 3501 | + debugfs_remove(symlink); |
3504 | 3502 | } |
3505 | 3503 |
|
3506 | 3504 | static int pmbus_init_debugfs(struct i2c_client *client, |
3507 | 3505 | struct pmbus_data *data) |
3508 | 3506 | { |
3509 | | - struct dentry *debugfs; |
3510 | | - int i, idx = 0; |
3511 | | - char name[PMBUS_NAME_SIZE]; |
| 3507 | + struct dentry *symlink_d, *debugfs = client->debugfs; |
3512 | 3508 | struct pmbus_debugfs_entry *entries; |
| 3509 | + const char *pathname, *symlink; |
| 3510 | + char name[PMBUS_NAME_SIZE]; |
| 3511 | + int i, idx = 0; |
3513 | 3512 |
|
3514 | | - if (!pmbus_debugfs_dir) |
| 3513 | + /* |
| 3514 | + * client->debugfs may be NULL or an ERR_PTR(). dentry_path_raw() |
| 3515 | + * does not check if its parameters are valid, so validate |
| 3516 | + * client->debugfs before using it. |
| 3517 | + */ |
| 3518 | + if (!pmbus_debugfs_dir || IS_ERR_OR_NULL(debugfs)) |
3515 | 3519 | return -ENODEV; |
3516 | 3520 |
|
3517 | 3521 | /* |
3518 | | - * Create the debugfs directory for this device. Use the hwmon device |
3519 | | - * name to avoid conflicts (hwmon numbers are globally unique). |
| 3522 | + * Backwards compatibility: Create symlink from /pmbus/<hwmon_device> |
| 3523 | + * to i2c debugfs directory. |
3520 | 3524 | */ |
3521 | | - debugfs = debugfs_create_dir(dev_name(data->hwmon_dev), |
3522 | | - pmbus_debugfs_dir); |
3523 | | - if (IS_ERR_OR_NULL(debugfs)) |
3524 | | - return -ENODEV; |
| 3525 | + pathname = dentry_path_raw(debugfs, name, sizeof(name)); |
| 3526 | + if (IS_ERR(pathname)) |
| 3527 | + return PTR_ERR(pathname); |
| 3528 | + |
| 3529 | + /* |
| 3530 | + * The path returned by dentry_path_raw() starts with '/'. Prepend it |
| 3531 | + * with ".." to get the symlink relative to the pmbus root directory. |
| 3532 | + */ |
| 3533 | + symlink = kasprintf(GFP_KERNEL, "..%s", pathname); |
| 3534 | + if (!symlink) |
| 3535 | + return -ENOMEM; |
| 3536 | + |
| 3537 | + symlink_d = debugfs_create_symlink(dev_name(data->hwmon_dev), |
| 3538 | + pmbus_debugfs_dir, symlink); |
| 3539 | + kfree(symlink); |
3525 | 3540 |
|
3526 | | - data->debugfs = debugfs; |
| 3541 | + devm_add_action_or_reset(data->dev, pmbus_remove_symlink, symlink_d); |
3527 | 3542 |
|
3528 | 3543 | /* |
3529 | 3544 | * Allocate the max possible entries we need. |
@@ -3711,9 +3726,7 @@ static int pmbus_init_debugfs(struct i2c_client *client, |
3711 | 3726 | &pmbus_debugfs_ops); |
3712 | 3727 | } |
3713 | 3728 | } |
3714 | | - |
3715 | | - return devm_add_action_or_reset(data->dev, pmbus_remove_debugfs, |
3716 | | - debugfs); |
| 3729 | + return 0; |
3717 | 3730 | } |
3718 | 3731 | #else |
3719 | 3732 | static int pmbus_init_debugfs(struct i2c_client *client, |
@@ -3818,9 +3831,15 @@ EXPORT_SYMBOL_NS_GPL(pmbus_do_probe, "PMBUS"); |
3818 | 3831 |
|
3819 | 3832 | struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client) |
3820 | 3833 | { |
3821 | | - struct pmbus_data *data = i2c_get_clientdata(client); |
3822 | | - |
3823 | | - return data->debugfs; |
| 3834 | + /* |
| 3835 | + * client->debugfs may be an ERR_PTR(). Returning that to |
| 3836 | + * the calling code would potentially require additional |
| 3837 | + * complexity in the calling code and otherwise add no |
| 3838 | + * value. Return NULL in that case. |
| 3839 | + */ |
| 3840 | + if (IS_ERR_OR_NULL(client->debugfs)) |
| 3841 | + return NULL; |
| 3842 | + return client->debugfs; |
3824 | 3843 | } |
3825 | 3844 | EXPORT_SYMBOL_NS_GPL(pmbus_get_debugfs_dir, "PMBUS"); |
3826 | 3845 |
|
|
0 commit comments