# --- T2-COPYRIGHT-NOTE-BEGIN --- # T2 SDE: architecture/powerpc64/package/*/0060-ps3avmgr-char-device.patch # Copyright (C) 2019 - 2023 The T2 SDE Project # # This Copyright note is generated by scripts/Create-CopyPatch, # more information can be found in the files COPYING and README. # # This patch file is dual-licensed. It is available under the license the # patched project is licensed under, as long as it is an OpenSource license # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms # of the GNU General Public License version 2 as used by the T2 SDE. # --- T2-COPYRIGHT-NOTE-END --- --- ./drivers/ps3/ps3av.c.vanilla 2023-08-06 14:50:30.299167412 +0200 +++ ./drivers/ps3/ps3av.c 2023-08-06 14:50:40.239167596 +0200 @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #include #include @@ -23,6 +25,8 @@ #define BUFSIZE 4096 /* vuart buf size */ #define PS3AV_BUF_SIZE 512 /* max packet size */ +#define DEVICE_NAME "ps3avmngr" + static int safe_mode; static int timeout = 5000; /* in msec ( 5 sec ) */ @@ -47,6 +51,8 @@ static struct ps3av { struct ps3av_reply_hdr reply_hdr; u8 raw[PS3AV_BUF_SIZE]; } recv_buf; + struct miscdevice misc; + int misc_ok; } *ps3av; /* color space */ @@ -919,6 +925,68 @@ int ps3av_audio_mute(int mute) } EXPORT_SYMBOL_GPL(ps3av_audio_mute); +static ssize_t ps3av_misc_read(struct file *file, char __user *usrbuf, + size_t count, loff_t *pos) +{ + char *buf; + int result; + + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + result = ps3_vuart_read(ps3av->dev, buf, count); + if (result) + goto out; + + if (copy_to_user(usrbuf, buf, count)) { + result = -EFAULT; + goto out; + } + + result = count; + +out: + + kfree(buf); + + return result; +} + +static ssize_t ps3av_misc_write(struct file *file, const char __user *usrbuf, + size_t count, loff_t *pos) +{ + char *buf; + int result; + + buf = kmalloc(count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, usrbuf, count)) { + result = -EFAULT; + goto out; + } + + result = ps3_vuart_write(ps3av->dev, buf, count); + if (result) + goto out; + + result = count; + +out: + + kfree(buf); + + return result; +} + +static const struct file_operations ps3av_misc_fops = { + .owner = THIS_MODULE, + .read = ps3av_misc_read, + .write = ps3av_misc_write, +}; + static int ps3av_probe(struct ps3_system_bus_device *dev) { int res; @@ -985,11 +1053,34 @@ static int ps3av_probe(struct ps3_system_bus_device *dev) ps3av->ps3av_mode = id; mutex_unlock(&ps3av->mutex); + ps3av->misc.parent = &dev->core; + ps3av->misc.minor = MISC_DYNAMIC_MINOR, + ps3av->misc.name = DEVICE_NAME, + ps3av->misc.fops = &ps3av_misc_fops, + + res = misc_register(&ps3av->misc); + if (res) { + dev_err(&dev->core, "%s:%u: misc_register failed %d\n", + __func__, __LINE__, res); + goto skip_misc; + } + + ps3av->misc_ok = 1; + + dev_info(&dev->core, "%s:%u: registered misc device %d\n", + __func__, __LINE__, ps3av->misc.minor); + +skip_misc: + dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); return 0; fail: + + if (ps3av->misc_ok) + misc_deregister(&ps3av->misc); + kfree(ps3av); ps3av = NULL; return res; @@ -999,6 +1090,9 @@ static int ps3av_remove(struct ps3_system_bus_device *dev) { dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); if (ps3av) { + if (ps3av->misc_ok) + misc_deregister(&ps3av->misc); + ps3av_cmd_fin(); flush_work(&ps3av->work); kfree(ps3av);