diff options
Diffstat (limited to 'SOURCES/steam-deck.patch')
-rw-r--r-- | SOURCES/steam-deck.patch | 224 |
1 files changed, 112 insertions, 112 deletions
diff --git a/SOURCES/steam-deck.patch b/SOURCES/steam-deck.patch index 395cdd3..9eba750 100644 --- a/SOURCES/steam-deck.patch +++ b/SOURCES/steam-deck.patch @@ -24,7 +24,7 @@ index 8b93856de432..af335d9150e9 100644 @@ -2260,5 +2260,16 @@ config MFD_RSMU_SPI Additional drivers must be enabled in order to use the functionality of the device. - + +config MFD_STEAMDECK + tristate "Valve Steam Deck" + select MFD_CORE @@ -206,7 +206,7 @@ index 7ac3daaf59ce..d784c78417cf 100644 @@ -1900,6 +1900,17 @@ config SENSORS_SCH5636 This driver can also be built as a module. If so, the module will be called sch5636. - + +config SENSORS_STEAMDECK + tristate "Steam Deck EC sensors" + depends on MFD_STEAMDECK @@ -486,7 +486,7 @@ index 499d0f215a8b..d1d761695cd6 100644 @@ -864,6 +864,13 @@ config LEDS_ACER_A500 This option enables support for the Power Button LED of Acer Iconia Tab A500. - + +config LEDS_STEAMDECK + tristate "LED support for Steam Deck" + depends on LEDS_CLASS && MFD_STEAMDECK @@ -495,7 +495,7 @@ index 499d0f215a8b..d1d761695cd6 100644 + power button) on Steam Deck + source "drivers/leds/blink/Kconfig" - + comment "Flash and Torch LED drivers" diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 4fd2f92cd198..130a1c175dde 100644 @@ -612,7 +612,7 @@ index 290186e44e6b..4d444a9e2c1f 100644 @@ -189,4 +189,11 @@ config EXTCON_USBC_TUSB320 Say Y here to enable support for USB Type C cable detection extcon support using a TUSB320. - + +config EXTCON_STEAMDECK + tristate "Steam Deck extcon support" + depends on MFD_STEAMDECK @@ -840,7 +840,7 @@ index fab9e9460bd4..9d0a5471b181 100644 @@ -180,6 +180,76 @@ static const struct hwmon_chip_info steamdeck_hwmon_chip_info = { .info = steamdeck_hwmon_info, }; - + + +static ssize_t +steamdeck_hwmon_simple_store(struct device *dev, const char *buf, size_t count, @@ -948,7 +948,7 @@ index 0e504b3c2796..a60fa7db9141 100644 @@ -41,9 +41,29 @@ struct steamdeck { STEAMDECK_ATTR_RO(firmware_version, "PDFW"); STEAMDECK_ATTR_RO(board_id, "BOID"); - + +static ssize_t controller_board_power_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) @@ -1010,13 +1010,13 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 #include <linux/sched.h> #include <linux/usb/g_hid.h> +#include <uapi/linux/usb/g_hid.h> - + #include "u_f.h" #include "u_hid.h" @@ -75,6 +76,13 @@ struct f_hidg { wait_queue_head_t write_queue; struct usb_request *req; - + + /* get report */ + struct usb_request *get_req; + struct usb_hidg_report get_report; @@ -1030,7 +1030,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 @@ -523,6 +531,64 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer, return status; } - + + +static int f_hidg_get_report(struct file *file, struct usb_hidg_report __user *buffer) +{ @@ -1097,13 +1097,13 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 #undef READ_COND_SSREPORT #undef READ_COND_INTOUT +#undef GET_REPORT_COND - + static int f_hidg_release(struct inode *inode, struct file *fd) { @@ -640,6 +707,10 @@ static void hidg_ssreport_complete(struct usb_ep *ep, struct usb_request *req) wake_up(&hidg->read_queue); } - + +static void hidg_get_report_complete(struct usb_ep *ep, struct usb_request *req) +{ +} @@ -1118,7 +1118,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 + unsigned long flags; + bool do_wake = false; __u16 value, length; - + value = __le16_to_cpu(ctrl->wValue); @@ -659,14 +732,29 @@ static int hidg_setup(struct usb_function *f, switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { @@ -1126,7 +1126,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 | HID_REQ_GET_REPORT): - VDBG(cdev, "get_report\n"); + VDBG(cdev, "get_report | wLength=%d\n", ctrl->wLength); - + - /* send an empty report */ - length = min_t(unsigned, length, hidg->report_length); - memset(req->buf, 0x0, length); @@ -1137,7 +1137,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 + if (status < 0) { + ERROR(cdev, "usb_ep_queue error on get_report %d\n", + status); - + - goto respond; - break; + spin_lock_irqsave(&hidg->get_spinlock, flags); @@ -1153,11 +1153,11 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 + } + + return status; - + case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_GET_PROTOCOL): @@ -800,6 +888,14 @@ static void hidg_disable(struct usb_function *f) - + hidg->req = NULL; spin_unlock_irqrestore(&hidg->write_spinlock, flags); + @@ -1169,7 +1169,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 + hidg->get_req = NULL; + spin_unlock_irqrestore(&hidg->get_spinlock, flags); } - + static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) @@ -908,6 +1004,7 @@ static const struct file_operations f_hidg_fops = { .write = f_hidg_write, @@ -1178,11 +1178,11 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 + .unlocked_ioctl = f_hidg_ioctl, .llseek = noop_llseek, }; - + @@ -918,6 +1015,14 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) struct usb_string *us; int status; - + + hidg->get_req = usb_ep_alloc_request(c->cdev->gadget->ep0, GFP_ATOMIC); + if (!hidg->get_req) + return -ENOMEM; @@ -1203,17 +1203,17 @@ index ea85e2c701a15..6fec92b5a0bd9 100644 init_waitqueue_head(&hidg->read_queue); + init_waitqueue_head(&hidg->get_queue); INIT_LIST_HEAD(&hidg->completed_out_req); - + /* create char device */ @@ -1021,6 +1128,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) if (hidg->req != NULL) free_ep_req(hidg->in_ep, hidg->req); - + + usb_ep_free_request(c->cdev->gadget->ep0, hidg->get_req); + return status; } - + diff --git a/include/uapi/linux/usb/g_hid.h b/include/uapi/linux/usb/g_hid.h new file mode 100644 index 0000000000000..c6068b4863543 @@ -1264,14 +1264,14 @@ index 835473910a498..9754822b2a409 100644 +++ b/include/uapi/linux/usb/gadgetfs.h @@ -62,7 +62,7 @@ struct usb_gadgetfs_event { }; - - + + -/* The 'g' code is also used by printer gadget ioctl requests. +/* The 'g' code is also used by printer and hid gadget ioctl requests. * Don't add any colliding codes to either driver, and keep * them in unique ranges (size 0x20 for now). */ --- +-- 2.41.0 @@ -1306,7 +1306,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644 @@ -76,6 +76,11 @@ struct f_hidg { wait_queue_head_t write_queue; struct usb_request *req; - + + /* set report */ + struct list_head completed_set_req; + spinlock_t set_spinlock; @@ -1318,7 +1318,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644 @@ -531,6 +536,54 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer, return status; } - + +static int f_hidg_set_report(struct file *file, struct usb_hidg_report __user *buffer) +{ + struct f_hidg *hidg = file->private_data; @@ -1367,7 +1367,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644 + free_ep_req(hidg->func.config->cdev->gadget->ep0, req); + return status; +} - + static int f_hidg_get_report(struct file *file, struct usb_hidg_report __user *buffer) { @@ -582,6 +635,8 @@ static int f_hidg_get_report(struct file *file, struct usb_hidg_report __user *b @@ -1380,34 +1380,34 @@ index 6fec92b5a0bd9..172cba91aded1 100644 return f_hidg_get_report(file, (struct usb_hidg_report __user *)arg); default: @@ -596,6 +651,7 @@ static __poll_t f_hidg_poll(struct file *file, poll_table *wait) - + poll_wait(file, &hidg->read_queue, wait); poll_wait(file, &hidg->write_queue, wait); + poll_wait(file, &hidg->set_queue, wait); - + if (WRITE_COND) ret |= EPOLLOUT | EPOLLWRNORM; @@ -608,12 +664,16 @@ static __poll_t f_hidg_poll(struct file *file, poll_table *wait) ret |= EPOLLIN | EPOLLRDNORM; } - + + if (SET_REPORT_COND) + ret |= EPOLLPRI; + return ret; } - + #undef WRITE_COND #undef READ_COND_SSREPORT #undef READ_COND_INTOUT +#undef SET_REPORT_COND #undef GET_REPORT_COND - + static int f_hidg_release(struct inode *inode, struct file *fd) @@ -658,11 +718,19 @@ static void hidg_intout_complete(struct usb_ep *ep, struct usb_request *req) - + req_list->req = req; - + - spin_lock_irqsave(&hidg->read_spinlock, flags); - list_add_tail(&req_list->list, &hidg->completed_out_req); - spin_unlock_irqrestore(&hidg->read_spinlock, flags); @@ -1415,7 +1415,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644 + spin_lock_irqsave(&hidg->set_spinlock, flags); + list_add_tail(&req_list->list, &hidg->completed_set_req); + spin_unlock_irqrestore(&hidg->set_spinlock, flags); - + - wake_up(&hidg->read_queue); + wake_up(&hidg->set_queue); + } else { @@ -1457,13 +1457,13 @@ index 6fec92b5a0bd9..172cba91aded1 100644 + } + + return status; - + case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_SET_PROTOCOL): @@ -880,6 +963,14 @@ static void hidg_disable(struct usb_function *f) spin_unlock_irqrestore(&hidg->read_spinlock, flags); } - + + spin_lock_irqsave(&hidg->set_spinlock, flags); + list_for_each_entry_safe(list, next, &hidg->completed_set_req, list) { + free_ep_req(f->config->cdev->gadget->ep0, list->req); @@ -1487,7 +1487,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644 init_waitqueue_head(&hidg->get_queue); INIT_LIST_HEAD(&hidg->completed_out_req); + INIT_LIST_HEAD(&hidg->completed_set_req); - + /* create char device */ cdev_init(&hidg->cdev, &f_hidg_fops); diff --git a/include/uapi/linux/usb/g_hid.h b/include/uapi/linux/usb/g_hid.h @@ -1515,12 +1515,12 @@ index c6068b4863543..54814c2c68d60 100644 - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - + #ifndef __UAPI_LINUX_USB_G_HID_H #define __UAPI_LINUX_USB_G_HID_H - + #include <linux/types.h> - + +#define HIDG_REPORT_SIZE_MAX 64 + struct usb_hidg_report { @@ -1528,16 +1528,16 @@ index c6068b4863543..54814c2c68d60 100644 - __u8 data[512]; + __u8 data[HIDG_REPORT_SIZE_MAX]; }; - + /* The 'g' code is also used by gadgetfs and hid gadget ioctl requests. * Don't add any colliding codes to either driver, and keep * them in unique ranges (size 0x20 for now). */ +#define GADGET_HID_READ_SET_REPORT _IOR('g', 0x41, struct usb_hidg_report) #define GADGET_HID_WRITE_GET_REPORT _IOW('g', 0x42, struct usb_hidg_report) - + #endif /* __UAPI_LINUX_USB_G_HID_H */ --- +-- 2.41.0 @@ -1562,7 +1562,7 @@ index b110818fc9458..39a9bf3b7f77d 100644 --- a/drivers/hid/hid-steam.c +++ b/drivers/hid/hid-steam.c @@ -71,7 +71,7 @@ static LIST_HEAD(steam_devices); - + /* * Commands that can be sent in a feature report. - * Thanks to Valve for some valuable hints. @@ -1618,7 +1618,7 @@ index b110818fc9458..39a9bf3b7f77d 100644 +#define STEAM_CMD_DONGLE_GET_CONN_SLOTS 0xc4 +#define STEAM_CMD_HAPTIC_CMD 0xea #define STEAM_CMD_HAPTIC_RUMBLE 0xeb - + /* Some useful register ids */ -#define STEAM_REG_LPAD_MODE 0x07 -#define STEAM_REG_RPAD_MODE 0x08 @@ -1679,13 +1679,13 @@ index b110818fc9458..39a9bf3b7f77d 100644 +#define STEAM_REG_SLEEP_INACTIVITY_TIMEOUT 0x32 +#define STEAM_REG_LEFT_TRACKPAD_CLICK_PRESSURE 0x34 +#define STEAM_REG_RIGHT_TRACKPAD_CLICK_PRESSURE 0x35 - + /* Raw event identifiers */ #define STEAM_EV_INPUT_DATA 0x01 @@ -108,13 +179,28 @@ static LIST_HEAD(steam_devices); #define STEAM_EV_BATTERY 0x04 #define STEAM_EV_DECK_INPUT_DATA 0x09 - + +/* String attribute idenitifiers */ +#define STEAM_ATTRIB_STR_BOARD_SERIAL 0x00 +#define STEAM_ATTRIB_STR_UNIT_SERIAL 0x01 @@ -1714,7 +1714,7 @@ index b110818fc9458..39a9bf3b7f77d 100644 +#define STEAM_TRACKPAD_ABSOLUTE_DPAD 0x06 +#define STEAM_TRACKPAD_NONE 0x07 +#define STEAM_TRACKPAD_GESTURE_KEYBOARD 0x08 - + /* Other random constants */ #define STEAM_SERIAL_LEN 10 @@ -232,7 +318,7 @@ static int steam_write_registers(struct steam_device *steam, @@ -1725,7 +1725,7 @@ index b110818fc9458..39a9bf3b7f77d 100644 + u8 cmd[64] = {STEAM_CMD_SET_REGISTER, 0x00}; int ret; va_list args; - + @@ -268,7 +354,7 @@ static int steam_get_serial(struct steam_device *steam) * Recv: 0xae 0x15 0x01 serialnumber (10 chars) */ @@ -1733,7 +1733,7 @@ index b110818fc9458..39a9bf3b7f77d 100644 - u8 cmd[] = {STEAM_CMD_GET_SERIAL, 0x15, 0x01}; + u8 cmd[] = {STEAM_CMD_GET_STRING_ATTRIB, 0x15, STEAM_ATTRIB_STR_UNIT_SERIAL}; u8 reply[3 + STEAM_SERIAL_LEN + 1]; - + ret = steam_send_report(steam, cmd, sizeof(cmd)); @@ -277,7 +363,7 @@ static int steam_get_serial(struct steam_device *steam) ret = steam_recv_report(steam, reply, sizeof(reply)); @@ -1751,7 +1751,7 @@ index b110818fc9458..39a9bf3b7f77d 100644 - return steam_send_report_byte(steam, STEAM_CMD_REQUEST_COMM_STATUS); + return steam_send_report_byte(steam, STEAM_CMD_DONGLE_GET_STATE); } - + static inline int steam_haptic_rumble(struct steam_device *steam, @@ -339,9 +425,9 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable) /* enable esc, enter, cursors */ @@ -1763,10 +1763,10 @@ index b110818fc9458..39a9bf3b7f77d 100644 - STEAM_REG_RPAD_MARGIN, 0x01, /* enable margin */ + STEAM_REG_SMOOTH_ABSOLUTE_MOUSE, 0x01, /* enable smooth */ 0); - + cancel_delayed_work_sync(&steam->heartbeat); @@ -351,11 +437,11 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable) - + if (steam->quirks & STEAM_QUIRK_DECK) { steam_write_registers(steam, - STEAM_REG_RPAD_MARGIN, 0x00, /* disable margin */ @@ -1804,7 +1804,7 @@ index b110818fc9458..39a9bf3b7f77d 100644 0); schedule_delayed_work(&steam->heartbeat, 5 * HZ); } --- +-- 2.41.0 @@ -1826,7 +1826,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644 @@ -202,6 +202,11 @@ static LIST_HEAD(steam_devices); #define STEAM_TRACKPAD_NONE 0x07 #define STEAM_TRACKPAD_GESTURE_KEYBOARD 0x08 - + +/* Pad identifiers for the deck */ +#define STEAM_PAD_LEFT 0 +#define STEAM_PAD_RIGHT 1 @@ -1834,7 +1834,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644 + /* Other random constants */ #define STEAM_SERIAL_LEN 10 - + @@ -221,6 +226,9 @@ struct steam_device { u8 battery_charge; u16 voltage; @@ -1848,7 +1848,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644 @@ -380,6 +388,33 @@ static inline int steam_request_conn_status(struct steam_device *steam) return steam_send_report_byte(steam, STEAM_CMD_DONGLE_GET_STATE); } - + +/* + * Send a haptic pulse to the trackpads + * Duration and interval are measured in microseconds, count is the number @@ -1880,7 +1880,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644 u16 intensity, u16 left_speed, u16 right_speed, u8 left_gain, u8 right_gain) @@ -421,6 +456,9 @@ static int steam_play_effect(struct input_dev *dev, void *data, - + static void steam_set_lizard_mode(struct steam_device *steam, bool enable) { + if (steam->gamepad_mode) @@ -1892,7 +1892,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644 @@ -805,6 +843,29 @@ static void steam_work_connect_cb(struct work_struct *work) } } - + +static void steam_mode_switch_cb(struct work_struct *work) +{ + struct steam_device *steam = container_of(to_delayed_work(work), @@ -1945,7 +1945,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644 } @@ -1393,6 +1457,14 @@ static void steam_do_deck_input_event(struct steam_device *steam, input_event(input, EV_KEY, BTN_BASE, !!(b14 & BIT(2))); - + input_sync(input); + + if (!(b9 & BIT(6)) && steam->did_mode_switch) { @@ -1956,9 +1956,9 @@ index 39a9bf3b7f77d..0620046b142ef 100644 + schedule_delayed_work(&steam->mode_switch, 45 * HZ / 100); + } } - + /* --- +-- 2.41.0 @@ -2000,7 +2000,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 + int ret = 0; u8 cmd[] = {STEAM_CMD_GET_STRING_ATTRIB, 0x15, STEAM_ATTRIB_STR_UNIT_SERIAL}; u8 reply[3 + STEAM_SERIAL_LEN + 1]; - + + mutex_lock(&steam->report_mutex); ret = steam_send_report(steam, cmd, sizeof(cmd)); if (ret < 0) @@ -2023,7 +2023,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 + mutex_unlock(&steam->report_mutex); + return ret; } - + /* @@ -385,7 +390,11 @@ static int steam_get_serial(struct steam_device *steam) */ @@ -2036,7 +2036,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 + mutex_unlock(&steam->report_mutex); + return ret; } - + /* @@ -397,6 +406,7 @@ static inline int steam_request_conn_status(struct steam_device *steam) static inline int steam_haptic_pulse(struct steam_device *steam, u8 pad, @@ -2044,42 +2044,42 @@ index 0620046b142ef..845ca71b8bd3a 100644 { + int ret; u8 report[10] = {STEAM_CMD_HAPTIC_PULSE, 8}; - + /* Left and right are swapped on this report for legacy reasons */ @@ -412,13 +422,17 @@ static inline int steam_haptic_pulse(struct steam_device *steam, u8 pad, report[8] = count >> 8; report[9] = gain; - + - return steam_send_report(steam, report, sizeof(report)); + mutex_lock(&steam->report_mutex); + ret = steam_send_report(steam, report, sizeof(report)); + mutex_unlock(&steam->report_mutex); + return ret; } - + static inline int steam_haptic_rumble(struct steam_device *steam, u16 intensity, u16 left_speed, u16 right_speed, u8 left_gain, u8 right_gain) { + int ret; u8 report[11] = {STEAM_CMD_HAPTIC_RUMBLE, 9}; - + report[3] = intensity & 0xFF; @@ -430,7 +444,10 @@ static inline int steam_haptic_rumble(struct steam_device *steam, report[9] = left_gain; report[10] = right_gain; - + - return steam_send_report(steam, report, sizeof(report)); + mutex_lock(&steam->report_mutex); + ret = steam_send_report(steam, report, sizeof(report)); + mutex_unlock(&steam->report_mutex); + return ret; } - + static void steam_haptic_rumble_cb(struct work_struct *work) @@ -460,6 +477,7 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable) enable = false; - + if (enable) { + mutex_lock(&steam->report_mutex); /* enable esc, enter, cursors */ @@ -2090,13 +2090,13 @@ index 0620046b142ef..845ca71b8bd3a 100644 STEAM_REG_SMOOTH_ABSOLUTE_MOUSE, 0x01, /* enable smooth */ 0); + mutex_unlock(&steam->report_mutex); - + cancel_delayed_work_sync(&steam->heartbeat); } else { + mutex_lock(&steam->report_mutex); /* disable esc, enter, cursor */ steam_send_report_byte(steam, STEAM_CMD_CLEAR_MAPPINGS); - + @@ -481,18 +501,19 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable) STEAM_REG_LEFT_TRACKPAD_CLICK_PRESSURE, 0xFFFF, /* disable clicky pad */ STEAM_REG_RIGHT_TRACKPAD_CLICK_PRESSURE, 0xFFFF, /* disable clicky pad */ @@ -2125,7 +2125,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 struct steam_device *steam = input_get_drvdata(dev); + unsigned long flags; + bool set_lizard_mode; - + - mutex_lock(&steam->mutex); - if (!steam->client_opened && lizard_mode) + spin_lock_irqsave(&steam->lock, flags); @@ -2137,13 +2137,13 @@ index 0620046b142ef..845ca71b8bd3a 100644 + return 0; } - + static void steam_input_close(struct input_dev *dev) { struct steam_device *steam = input_get_drvdata(dev); + unsigned long flags; + bool set_lizard_mode; - + - mutex_lock(&steam->mutex); - if (!steam->client_opened && lizard_mode) + spin_lock_irqsave(&steam->lock, flags); @@ -2153,14 +2153,14 @@ index 0620046b142ef..845ca71b8bd3a 100644 steam_set_lizard_mode(steam, true); - mutex_unlock(&steam->mutex); } - + static enum power_supply_property steam_battery_props[] = { @@ -760,6 +788,7 @@ static int steam_register(struct steam_device *steam) { int ret; bool client_opened; + unsigned long flags; - + /* * This function can be called several times in a row with the @@ -772,11 +801,9 @@ static int steam_register(struct steam_device *steam) @@ -2172,13 +2172,13 @@ index 0620046b142ef..845ca71b8bd3a 100644 strscpy(steam->serial_no, "XXXXXXXXXX", sizeof(steam->serial_no)); - mutex_unlock(&steam->mutex); - + hid_info(steam->hdev, "Steam Controller '%s' connected", steam->serial_no); @@ -791,11 +818,11 @@ static int steam_register(struct steam_device *steam) mutex_unlock(&steam_devices_lock); } - + - mutex_lock(&steam->mutex); + spin_lock_irqsave(&steam->lock, flags); client_opened = steam->client_opened; @@ -2186,7 +2186,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 if (!client_opened) steam_set_lizard_mode(steam, lizard_mode); - mutex_unlock(&steam->mutex); - + if (!client_opened) ret = steam_input_register(steam); @@ -847,16 +874,21 @@ static void steam_mode_switch_cb(struct work_struct *work) @@ -2198,7 +2198,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 steam->gamepad_mode = !steam->gamepad_mode; if (!lizard_mode) return; - + - mutex_lock(&steam->mutex); if (steam->gamepad_mode) steam_set_lizard_mode(steam, false); @@ -2212,7 +2212,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 + if (!client_opened) + steam_set_lizard_mode(steam, lizard_mode); + } - + steam_haptic_pulse(steam, STEAM_PAD_RIGHT, 0x190, 0, 1, 0); if (steam->gamepad_mode) { @@ -889,16 +921,21 @@ static void steam_lizard_mode_heartbeat(struct work_struct *work) @@ -2221,7 +2221,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 heartbeat.work); + bool client_opened; + unsigned long flags; - + - mutex_lock(&steam->mutex); - if (!steam->client_opened && steam->client_hdev) { + spin_lock_irqsave(&steam->lock, flags); @@ -2238,37 +2238,37 @@ index 0620046b142ef..845ca71b8bd3a 100644 } - mutex_unlock(&steam->mutex); } - + static int steam_client_ll_parse(struct hid_device *hdev) @@ -921,10 +958,11 @@ static void steam_client_ll_stop(struct hid_device *hdev) static int steam_client_ll_open(struct hid_device *hdev) { struct steam_device *steam = hdev->driver_data; + unsigned long flags; - + - mutex_lock(&steam->mutex); + spin_lock_irqsave(&steam->lock, flags); steam->client_opened = true; - mutex_unlock(&steam->mutex); + spin_unlock_irqrestore(&steam->lock, flags); - + steam_input_unregister(steam); - + @@ -939,14 +977,12 @@ static void steam_client_ll_close(struct hid_device *hdev) bool connected; - + spin_lock_irqsave(&steam->lock, flags); - connected = steam->connected; + steam->client_opened = false; + connected = steam->connected && !steam->client_opened; spin_unlock_irqrestore(&steam->lock, flags); - + - mutex_lock(&steam->mutex); - steam->client_opened = false; if (connected) steam_set_lizard_mode(steam, lizard_mode); - mutex_unlock(&steam->mutex); - + if (connected) steam_input_register(steam); @@ -1035,7 +1071,7 @@ static int steam_probe(struct hid_device *hdev, @@ -2283,7 +2283,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 @@ -1043,13 +1079,6 @@ static int steam_probe(struct hid_device *hdev, INIT_DEFERRABLE_WORK(&steam->heartbeat, steam_lizard_mode_heartbeat); INIT_WORK(&steam->rumble_work, steam_haptic_rumble_cb); - + - steam->client_hdev = steam_create_client_hid(hdev); - if (IS_ERR(steam->client_hdev)) { - ret = PTR_ERR(steam->client_hdev); @@ -2297,7 +2297,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 @@ -1058,10 +1087,6 @@ static int steam_probe(struct hid_device *hdev, if (ret) goto hid_hw_start_fail; - + - ret = hid_add_device(steam->client_hdev); - if (ret) - goto client_hdev_add_fail; @@ -2308,7 +2308,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 @@ -1087,15 +1112,26 @@ static int steam_probe(struct hid_device *hdev, } } - + + steam->client_hdev = steam_create_client_hid(hdev); + if (IS_ERR(steam->client_hdev)) { + ret = PTR_ERR(steam->client_hdev); @@ -2321,7 +2321,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 + goto client_hdev_add_fail; + return 0; - + -input_register_fail: -hid_hw_open_fail: client_hdev_add_fail: @@ -2339,7 +2339,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 @@ -1115,14 +1151,12 @@ static void steam_remove(struct hid_device *hdev) return; } - + + cancel_delayed_work_sync(&steam->heartbeat); + cancel_delayed_work_sync(&steam->mode_switch); + cancel_work_sync(&steam->work_connect); @@ -2355,7 +2355,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 hid_info(hdev, "Steam wireless receiver disconnected"); } @@ -1597,10 +1631,8 @@ static int steam_param_set_lizard_mode(const char *val, - + mutex_lock(&steam_devices_lock); list_for_each_entry(steam, &steam_devices, list) { - mutex_lock(&steam->mutex); @@ -2365,7 +2365,7 @@ index 0620046b142ef..845ca71b8bd3a 100644 } mutex_unlock(&steam_devices_lock); return 0; --- +-- 2.41.0 @@ -2405,26 +2405,26 @@ index 845ca71b8bd3a..0c2fe51b29bc1 100644 - bool client_opened; + unsigned long client_opened; unsigned long flags; - + /* @@ -961,7 +961,7 @@ static int steam_client_ll_open(struct hid_device *hdev) unsigned long flags; - + spin_lock_irqsave(&steam->lock, flags); - steam->client_opened = true; + steam->client_opened++; spin_unlock_irqrestore(&steam->lock, flags); - + steam_input_unregister(steam); @@ -977,7 +977,7 @@ static void steam_client_ll_close(struct hid_device *hdev) bool connected; - + spin_lock_irqsave(&steam->lock, flags); - steam->client_opened = false; + steam->client_opened--; connected = steam->connected && !steam->client_opened; spin_unlock_irqrestore(&steam->lock, flags); - + @@ -1156,7 +1156,7 @@ static void steam_remove(struct hid_device *hdev) cancel_work_sync(&steam->work_connect); hid_destroy_device(steam->client_hdev); @@ -2434,7 +2434,7 @@ index 845ca71b8bd3a..0c2fe51b29bc1 100644 if (steam->quirks & STEAM_QUIRK_WIRELESS) { hid_info(hdev, "Steam wireless receiver disconnected"); } --- +-- 2.41.0 @@ -2458,11 +2458,11 @@ index 0c2fe51b29bc1..92e3e1052fa42 100644 +++ b/drivers/hid/hid-steam.c @@ -208,7 +208,7 @@ static LIST_HEAD(steam_devices); #define STEAM_PAD_BOTH 2 - + /* Other random constants */ -#define STEAM_SERIAL_LEN 10 +#define STEAM_SERIAL_LEN 0x15 - + struct steam_device { struct list_head list; @@ -359,10 +359,10 @@ static int steam_get_serial(struct steam_device *steam) @@ -2476,7 +2476,7 @@ index 0c2fe51b29bc1..92e3e1052fa42 100644 - u8 cmd[] = {STEAM_CMD_GET_STRING_ATTRIB, 0x15, STEAM_ATTRIB_STR_UNIT_SERIAL}; + u8 cmd[] = {STEAM_CMD_GET_STRING_ATTRIB, sizeof(steam->serial_no), STEAM_ATTRIB_STR_UNIT_SERIAL}; u8 reply[3 + STEAM_SERIAL_LEN + 1]; - + mutex_lock(&steam->report_mutex); @@ -372,12 +372,12 @@ static int steam_get_serial(struct steam_device *steam) ret = steam_recv_report(steam, reply, sizeof(reply)); @@ -2493,5 +2493,5 @@ index 0c2fe51b29bc1..92e3e1052fa42 100644 out: mutex_unlock(&steam->report_mutex); return ret; --- +-- 2.41.0 |