lkml.org 
[lkml]   [2023]   [Feb]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 5/5] apple-gmux: add debugfs interface
    Date
    Allow reading and writing gmux ports from userspace.

    For example:

    echo 4 > /sys/kernel/debug/apple_gmux/selected_port
    cat /sys/kernel/debug/apple_gmux/selected_port_data | xxd -p

    Will show the gmux version information (00000005 in this case)

    Signed-off-by: Orlando Chamberlain <orlandoch.dev@gmail.com>
    ---
    v2->v3: don't check if the folder failed to be created
    drivers/platform/x86/apple-gmux.c | 82 +++++++++++++++++++++++++++++++
    1 file changed, 82 insertions(+)

    diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c
    index 01e7b1939916..4cbdc9f9bd10 100644
    --- a/drivers/platform/x86/apple-gmux.c
    +++ b/drivers/platform/x86/apple-gmux.c
    @@ -22,6 +22,7 @@
    #include <linux/delay.h>
    #include <linux/pci.h>
    #include <linux/vga_switcheroo.h>
    +#include <linux/debugfs.h>
    #include <asm/io.h>

    /**
    @@ -66,6 +67,10 @@ struct apple_gmux_data {
    enum vga_switcheroo_client_id switch_state_external;
    enum vga_switcheroo_state power_state;
    struct completion powerchange_done;
    +
    + /* debugfs data */
    + u8 selected_port;
    + struct dentry *debug_dentry;
    };

    static struct apple_gmux_data *apple_gmux_data;
    @@ -672,6 +677,81 @@ static void gmux_notify_handler(acpi_handle device, u32 value, void *context)
    complete(&gmux_data->powerchange_done);
    }

    +/**
    + * DOC: Debugfs Interface
    + *
    + * gmux ports can be accessed from userspace as a debugfs interface. For example:
    + *
    + * # echo 4 > /sys/kernel/debug/apple_gmux/selected_port
    + * # cat /sys/kernel/debug/apple_gmux/selected_port_data | xxd -p
    + * 00000005
    + *
    + * Reads 4 bytes from port 4 (GMUX_PORT_VERSION_MAJOR).
    + *
    + * 1 and 4 byte writes are also allowed.
    + */
    +
    +static ssize_t gmux_selected_port_data_write(struct file *file,
    + const char __user *userbuf, size_t count, loff_t *ppos)
    +{
    + struct apple_gmux_data *gmux_data = file->private_data;
    + int ret;
    +
    + if (*ppos)
    + return -EINVAL;
    +
    + if (count == 1) {
    + u8 data;
    +
    + ret = copy_from_user(&data, userbuf, 1);
    + if (ret)
    + return ret;
    + gmux_write8(gmux_data, gmux_data->selected_port, data);
    + } else if (count == 4) {
    + u32 data;
    +
    + ret = copy_from_user(&data, userbuf, 4);
    + if (ret)
    + return ret;
    + gmux_write32(gmux_data, gmux_data->selected_port, data);
    + } else
    + return -EINVAL;
    +
    + return count;
    +}
    +
    +static ssize_t gmux_selected_port_data_read(struct file *file,
    + char __user *userbuf, size_t count, loff_t *ppos)
    +{
    + struct apple_gmux_data *gmux_data = file->private_data;
    + u32 data;
    +
    + data = gmux_read32(gmux_data, gmux_data->selected_port);
    +
    + return simple_read_from_buffer(userbuf, count, ppos, &data, sizeof(data));
    +}
    +
    +static const struct file_operations gmux_port_data_ops = {
    + .open = simple_open,
    + .write = gmux_selected_port_data_write,
    + .read = gmux_selected_port_data_read
    +};
    +
    +static void gmux_init_debugfs(struct apple_gmux_data *gmux_data)
    +{
    + gmux_data->debug_dentry = debugfs_create_dir(KBUILD_MODNAME, NULL);
    +
    + debugfs_create_u8("selected_port", 0644, gmux_data->debug_dentry,
    + &gmux_data->selected_port);
    + debugfs_create_file("selected_port_data", 0644, gmux_data->debug_dentry,
    + gmux_data, &gmux_port_data_ops);
    +}
    +
    +static void gmux_fini_debugfs(struct apple_gmux_data *gmux_data)
    +{
    + debugfs_remove_recursive(gmux_data->debug_dentry);
    +}
    +
    static int gmux_suspend(struct device *dev)
    {
    struct pnp_dev *pnp = to_pnp_dev(dev);
    @@ -872,6 +952,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
    goto err_register_handler;
    }

    + gmux_init_debugfs(gmux_data);
    return 0;

    err_register_handler:
    @@ -903,6 +984,7 @@ static void gmux_remove(struct pnp_dev *pnp)
    {
    struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);

    + gmux_fini_debugfs(gmux_data);
    vga_switcheroo_unregister_handler();
    gmux_disable_interrupts(gmux_data);
    if (gmux_data->gpe >= 0) {
    --
    2.39.1
    \
     
     \ /
      Last update: 2023-03-27 00:27    [W:4.612 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site