diff options
author | Jarod Wilson <jarod@redhat.com> | 2010-04-23 01:27:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:58:24 -0400 |
commit | 6718e8ad950f73fc895b98a413a63cb2add3b4d2 (patch) | |
tree | 45ef313730c83d671131957f6a3eb7dba07a8c61 /drivers/media/IR/imon.c | |
parent | 0a4f8d0798c834472b9d8d50df32b62c733009fd (diff) |
V4L/DVB: IR/imon: convert to ir-core protocol change handling
Drop the imon driver's internal protocol definitions in favor of using
those provided by ir-core. Should make ir-keytable Just Work for
switching protocol on the fly on the imon devices that support both the
native imon remotes and mce remotes.
The imon-no-pad-stabilize pseudo-protocol was dropped as a protocol, and
converted to a separate modprobe option (which it probably should have
been in the first place). On the TODO list is to convert this to an as yet
unwritten protocol-specific options framework.
While the mce remotes obviously map to IR_TYPE_RC6, I've yet to look at
what the actual ir signals from the native imon remotes are, so for the
moment, imon native ir is mapped to IR_TYPE_OTHER. Nailing it down more
accurately is also on the TODO list.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/IR/imon.c')
-rw-r--r-- | drivers/media/IR/imon.c | 151 |
1 files changed, 65 insertions, 86 deletions
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c index d941b98eed3e..b65c31ab4a4f 100644 --- a/drivers/media/IR/imon.c +++ b/drivers/media/IR/imon.c | |||
@@ -127,8 +127,7 @@ struct imon_context { | |||
127 | 127 | ||
128 | u32 kc; /* current input keycode */ | 128 | u32 kc; /* current input keycode */ |
129 | u32 last_keycode; /* last reported input keycode */ | 129 | u32 last_keycode; /* last reported input keycode */ |
130 | u8 ir_protocol; /* iMON or MCE (RC6) IR protocol? */ | 130 | u64 ir_type; /* iMON or MCE (RC6) IR protocol? */ |
131 | u8 ir_proto_mask; /* supported IR protocol mask */ | ||
132 | u8 mce_toggle_bit; /* last mce toggle bit */ | 131 | u8 mce_toggle_bit; /* last mce toggle bit */ |
133 | bool release_code; /* some keys send a release code */ | 132 | bool release_code; /* some keys send a release code */ |
134 | 133 | ||
@@ -174,20 +173,6 @@ enum { | |||
174 | }; | 173 | }; |
175 | 174 | ||
176 | enum { | 175 | enum { |
177 | IMON_IR_PROTOCOL_AUTO = 0x0, | ||
178 | IMON_IR_PROTOCOL_MCE = 0x1, | ||
179 | IMON_IR_PROTOCOL_IMON = 0x2, | ||
180 | IMON_IR_PROTOCOL_IMON_NOPAD = 0x4, | ||
181 | }; | ||
182 | |||
183 | enum { | ||
184 | IMON_IR_PROTO_MASK_NONE = 0x0, | ||
185 | IMON_IR_PROTO_MASK_MCE = IMON_IR_PROTOCOL_MCE, | ||
186 | IMON_IR_PROTO_MASK_IMON = IMON_IR_PROTOCOL_IMON | | ||
187 | IMON_IR_PROTOCOL_IMON_NOPAD, | ||
188 | }; | ||
189 | |||
190 | enum { | ||
191 | IMON_KEY_IMON = 0, | 176 | IMON_KEY_IMON = 0, |
192 | IMON_KEY_MCE = 1, | 177 | IMON_KEY_MCE = 1, |
193 | IMON_KEY_PANEL = 2, | 178 | IMON_KEY_PANEL = 2, |
@@ -330,12 +315,10 @@ module_param(display_type, int, S_IRUGO); | |||
330 | MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, " | 315 | MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, " |
331 | "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)"); | 316 | "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)"); |
332 | 317 | ||
333 | /* IR protocol: native iMON, Windows MCE (RC-6), or iMON w/o PAD stabilize */ | 318 | static int pad_stabilize = 1; |
334 | static int ir_protocol; | 319 | module_param(pad_stabilize, int, S_IRUGO | S_IWUSR); |
335 | module_param(ir_protocol, int, S_IRUGO | S_IWUSR); | 320 | MODULE_PARM_DESC(pad_stabilize, "Apply stabilization algorithm to iMON PAD " |
336 | MODULE_PARM_DESC(ir_protocol, "Which IR protocol to use. 0=auto-detect, " | 321 | "presses in arrow key mode. 0=disable, 1=enable (default)."); |
337 | "1=Windows Media Center Ed. (RC-6), 2=iMON native, " | ||
338 | "4=iMON w/o PAD stabilize (default: auto-detect)"); | ||
339 | 322 | ||
340 | /* | 323 | /* |
341 | * In certain use cases, mouse mode isn't really helpful, and could actually | 324 | * In certain use cases, mouse mode isn't really helpful, and could actually |
@@ -1007,72 +990,67 @@ static void imon_touch_display_timeout(unsigned long data) | |||
1007 | * really just RC-6), but only one or the other at a time, as the signals | 990 | * really just RC-6), but only one or the other at a time, as the signals |
1008 | * are decoded onboard the receiver. | 991 | * are decoded onboard the receiver. |
1009 | */ | 992 | */ |
1010 | static void imon_set_ir_protocol(struct imon_context *ictx) | 993 | int imon_ir_change_protocol(void *priv, u64 ir_type) |
1011 | { | 994 | { |
1012 | int retval; | 995 | int retval; |
996 | struct imon_context *ictx = priv; | ||
1013 | struct device *dev = ictx->dev; | 997 | struct device *dev = ictx->dev; |
998 | bool pad_mouse; | ||
1014 | unsigned char ir_proto_packet[] = { | 999 | unsigned char ir_proto_packet[] = { |
1015 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; | 1000 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; |
1016 | 1001 | ||
1017 | if (ir_protocol && !(ir_protocol & ictx->ir_proto_mask)) | 1002 | if (!(ir_type & ictx->props->allowed_protos)) |
1018 | dev_warn(dev, "Looks like you're trying to use an IR protocol " | 1003 | dev_warn(dev, "Looks like you're trying to use an IR protocol " |
1019 | "this device does not support\n"); | 1004 | "this device does not support\n"); |
1020 | 1005 | ||
1021 | switch (ir_protocol) { | 1006 | switch (ir_type) { |
1022 | case IMON_IR_PROTOCOL_AUTO: | 1007 | case IR_TYPE_RC6: |
1023 | if (ictx->product == 0xffdc) { | ||
1024 | if (ictx->ir_proto_mask & IMON_IR_PROTO_MASK_MCE) { | ||
1025 | ir_proto_packet[0] = 0x01; | ||
1026 | ictx->ir_protocol = IMON_IR_PROTOCOL_MCE; | ||
1027 | ictx->pad_mouse = 0; | ||
1028 | init_timer(&ictx->itimer); | ||
1029 | ictx->itimer.data = (unsigned long)ictx; | ||
1030 | ictx->itimer.function = imon_mce_timeout; | ||
1031 | } else { | ||
1032 | ictx->ir_protocol = IMON_IR_PROTOCOL_IMON; | ||
1033 | ictx->pad_mouse = 1; | ||
1034 | } | ||
1035 | } | ||
1036 | break; | ||
1037 | case IMON_IR_PROTOCOL_MCE: | ||
1038 | dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); | 1008 | dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); |
1039 | ir_proto_packet[0] = 0x01; | 1009 | ir_proto_packet[0] = 0x01; |
1040 | ictx->ir_protocol = IMON_IR_PROTOCOL_MCE; | 1010 | pad_mouse = false; |
1041 | ictx->pad_mouse = 0; | ||
1042 | init_timer(&ictx->itimer); | 1011 | init_timer(&ictx->itimer); |
1043 | ictx->itimer.data = (unsigned long)ictx; | 1012 | ictx->itimer.data = (unsigned long)ictx; |
1044 | ictx->itimer.function = imon_mce_timeout; | 1013 | ictx->itimer.function = imon_mce_timeout; |
1045 | break; | 1014 | break; |
1046 | case IMON_IR_PROTOCOL_IMON: | 1015 | case IR_TYPE_UNKNOWN: |
1047 | dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); | 1016 | case IR_TYPE_OTHER: |
1048 | /* ir_proto_packet[0] = 0x00; // already the default */ | 1017 | dev_dbg(dev, "Configuring IR receiver for iMON protocol"); |
1049 | ictx->ir_protocol = IMON_IR_PROTOCOL_IMON; | 1018 | if (pad_stabilize) { |
1050 | ictx->pad_mouse = 1; | 1019 | printk(KERN_CONT "\n"); |
1051 | break; | 1020 | pad_mouse = true; |
1052 | case IMON_IR_PROTOCOL_IMON_NOPAD: | 1021 | } else { |
1053 | dev_dbg(dev, "Configuring IR receiver for iMON protocol " | 1022 | printk(KERN_CONT " (without PAD stabilization)\n"); |
1054 | "without PAD stabilize function enabled\n"); | 1023 | pad_mouse = false; |
1024 | } | ||
1055 | /* ir_proto_packet[0] = 0x00; // already the default */ | 1025 | /* ir_proto_packet[0] = 0x00; // already the default */ |
1056 | ictx->ir_protocol = IMON_IR_PROTOCOL_IMON_NOPAD; | 1026 | ir_type = IR_TYPE_OTHER; |
1057 | ictx->pad_mouse = 0; | ||
1058 | break; | 1027 | break; |
1059 | default: | 1028 | default: |
1060 | dev_info(dev, "%s: unknown IR protocol specified, will " | 1029 | dev_warn(dev, "Unsupported IR protocol specified, overriding " |
1061 | "just default to iMON protocol\n", __func__); | 1030 | "to iMON IR protocol"); |
1062 | ictx->ir_protocol = IMON_IR_PROTOCOL_IMON; | 1031 | if (pad_stabilize) { |
1063 | ictx->pad_mouse = 1; | 1032 | printk(KERN_CONT "\n"); |
1033 | pad_mouse = true; | ||
1034 | } else { | ||
1035 | printk(KERN_CONT " (without PAD stabilization)\n"); | ||
1036 | pad_mouse = false; | ||
1037 | } | ||
1038 | /* ir_proto_packet[0] = 0x00; // already the default */ | ||
1039 | ir_type = IR_TYPE_OTHER; | ||
1064 | break; | 1040 | break; |
1065 | } | 1041 | } |
1066 | 1042 | ||
1067 | memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); | 1043 | memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); |
1068 | 1044 | ||
1069 | retval = send_packet(ictx); | 1045 | retval = send_packet(ictx); |
1070 | if (retval) { | 1046 | if (retval) |
1071 | dev_info(dev, "%s: failed to set IR protocol, falling back " | 1047 | goto out; |
1072 | "to standard iMON protocol mode\n", __func__); | 1048 | |
1073 | ir_protocol = IMON_IR_PROTOCOL_IMON; | 1049 | ictx->ir_type = ir_type; |
1074 | ictx->ir_protocol = IMON_IR_PROTOCOL_IMON; | 1050 | ictx->pad_mouse = pad_mouse; |
1075 | } | 1051 | |
1052 | out: | ||
1053 | return retval; | ||
1076 | } | 1054 | } |
1077 | 1055 | ||
1078 | static inline int tv2int(const struct timeval *a, const struct timeval *b) | 1056 | static inline int tv2int(const struct timeval *a, const struct timeval *b) |
@@ -1329,7 +1307,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) | |||
1329 | rel_x = buf[2]; | 1307 | rel_x = buf[2]; |
1330 | rel_y = buf[3]; | 1308 | rel_y = buf[3]; |
1331 | 1309 | ||
1332 | if (ictx->ir_protocol == IMON_IR_PROTOCOL_IMON) { | 1310 | if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) { |
1333 | if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { | 1311 | if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { |
1334 | dir = stabilize((int)rel_x, (int)rel_y, | 1312 | dir = stabilize((int)rel_x, (int)rel_y, |
1335 | timeout, threshold); | 1313 | timeout, threshold); |
@@ -1386,7 +1364,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) | |||
1386 | buf[0] = 0x01; | 1364 | buf[0] = 0x01; |
1387 | buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; | 1365 | buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; |
1388 | 1366 | ||
1389 | if (ictx->ir_protocol == IMON_IR_PROTOCOL_IMON) { | 1367 | if (ictx->ir_type == IR_TYPE_OTHER && pad_stabilize) { |
1390 | dir = stabilize((int)rel_x, (int)rel_y, | 1368 | dir = stabilize((int)rel_x, (int)rel_y, |
1391 | timeout, threshold); | 1369 | timeout, threshold); |
1392 | if (!dir) { | 1370 | if (!dir) { |
@@ -1499,7 +1477,7 @@ static void imon_incoming_packet(struct imon_context *ictx, | |||
1499 | kc = imon_panel_key_lookup(panel_key); | 1477 | kc = imon_panel_key_lookup(panel_key); |
1500 | } else { | 1478 | } else { |
1501 | remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff); | 1479 | remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff); |
1502 | if (ictx->ir_protocol == IMON_IR_PROTOCOL_MCE) { | 1480 | if (ictx->ir_type == IR_TYPE_RC6) { |
1503 | if (buf[0] == 0x80) | 1481 | if (buf[0] == 0x80) |
1504 | ktype = IMON_KEY_MCE; | 1482 | ktype = IMON_KEY_MCE; |
1505 | kc = imon_mce_key_lookup(ictx, remote_key); | 1483 | kc = imon_mce_key_lookup(ictx, remote_key); |
@@ -1680,12 +1658,6 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx) | |||
1680 | struct ir_dev_props *props; | 1658 | struct ir_dev_props *props; |
1681 | struct ir_input_dev *ir; | 1659 | struct ir_input_dev *ir; |
1682 | int ret, i; | 1660 | int ret, i; |
1683 | char *ir_codes = NULL; | ||
1684 | |||
1685 | if (ir_protocol == IMON_IR_PROTOCOL_MCE) | ||
1686 | ir_codes = RC_MAP_IMON_MCE; | ||
1687 | else | ||
1688 | ir_codes = RC_MAP_IMON_PAD; | ||
1689 | 1661 | ||
1690 | idev = input_allocate_device(); | 1662 | idev = input_allocate_device(); |
1691 | if (!idev) { | 1663 | if (!idev) { |
@@ -1727,8 +1699,12 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx) | |||
1727 | __set_bit(kc, idev->keybit); | 1699 | __set_bit(kc, idev->keybit); |
1728 | } | 1700 | } |
1729 | 1701 | ||
1702 | props->priv = ictx; | ||
1730 | props->driver_type = RC_DRIVER_SCANCODE; | 1703 | props->driver_type = RC_DRIVER_SCANCODE; |
1731 | props->allowed_protos = IR_TYPE_UNKNOWN; | 1704 | /* IR_TYPE_OTHER maps to iMON PAD remote, IR_TYPE_RC6 to MCE remote */ |
1705 | props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; | ||
1706 | props->change_protocol = imon_ir_change_protocol; | ||
1707 | ictx->props = props; | ||
1732 | 1708 | ||
1733 | ictx->ir = ir; | 1709 | ictx->ir = ir; |
1734 | memcpy(&ir->dev, ictx->dev, sizeof(struct device)); | 1710 | memcpy(&ir->dev, ictx->dev, sizeof(struct device)); |
@@ -1738,7 +1714,7 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx) | |||
1738 | 1714 | ||
1739 | input_set_drvdata(idev, ir); | 1715 | input_set_drvdata(idev, ir); |
1740 | 1716 | ||
1741 | ret = ir_input_register(idev, ir_codes, props, MOD_NAME); | 1717 | ret = ir_input_register(idev, RC_MAP_IMON_PAD, props, MOD_NAME); |
1742 | if (ret < 0) { | 1718 | if (ret < 0) { |
1743 | dev_err(ictx->dev, "remote input dev register failed\n"); | 1719 | dev_err(ictx->dev, "remote input dev register failed\n"); |
1744 | goto idev_register_failed; | 1720 | goto idev_register_failed; |
@@ -2058,13 +2034,14 @@ rx_urb_alloc_failed: | |||
2058 | * is no actual data to report. However, byte 6 of this buffer looks like | 2034 | * is no actual data to report. However, byte 6 of this buffer looks like |
2059 | * its unique across device variants, so we're trying to key off that to | 2035 | * its unique across device variants, so we're trying to key off that to |
2060 | * figure out which display type (if any) and what IR protocol the device | 2036 | * figure out which display type (if any) and what IR protocol the device |
2061 | * actually supports. | 2037 | * actually supports. These devices have their IR protocol hard-coded into |
2038 | * their firmware, they can't be changed on the fly like the newer hardware. | ||
2062 | */ | 2039 | */ |
2063 | static void imon_get_ffdc_type(struct imon_context *ictx) | 2040 | static void imon_get_ffdc_type(struct imon_context *ictx) |
2064 | { | 2041 | { |
2065 | u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; | 2042 | u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; |
2066 | u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; | 2043 | u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; |
2067 | u8 ir_proto_mask = IMON_IR_PROTO_MASK_IMON; | 2044 | u64 allowed_protos = IR_TYPE_OTHER; |
2068 | 2045 | ||
2069 | switch (ffdc_cfg_byte) { | 2046 | switch (ffdc_cfg_byte) { |
2070 | /* iMON Knob, no display, iMON IR + vol knob */ | 2047 | /* iMON Knob, no display, iMON IR + vol knob */ |
@@ -2076,7 +2053,6 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
2076 | case 0x35: | 2053 | case 0x35: |
2077 | dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR"); | 2054 | dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR"); |
2078 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | 2055 | detected_display_type = IMON_DISPLAY_TYPE_VFD; |
2079 | ir_proto_mask = IMON_IR_PROTO_MASK_NONE; | ||
2080 | break; | 2056 | break; |
2081 | /* iMON VFD, iMON IR */ | 2057 | /* iMON VFD, iMON IR */ |
2082 | case 0x24: | 2058 | case 0x24: |
@@ -2088,7 +2064,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
2088 | case 0x9f: | 2064 | case 0x9f: |
2089 | dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR"); | 2065 | dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR"); |
2090 | detected_display_type = IMON_DISPLAY_TYPE_LCD; | 2066 | detected_display_type = IMON_DISPLAY_TYPE_LCD; |
2091 | ir_proto_mask = IMON_IR_PROTO_MASK_MCE; | 2067 | allowed_protos = IR_TYPE_RC6; |
2092 | break; | 2068 | break; |
2093 | default: | 2069 | default: |
2094 | dev_info(ictx->dev, "Unknown 0xffdc device, " | 2070 | dev_info(ictx->dev, "Unknown 0xffdc device, " |
@@ -2097,10 +2073,11 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
2097 | break; | 2073 | break; |
2098 | } | 2074 | } |
2099 | 2075 | ||
2100 | printk(" (id 0x%02x)\n", ffdc_cfg_byte); | 2076 | printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte); |
2101 | 2077 | ||
2102 | ictx->display_type = detected_display_type; | 2078 | ictx->display_type = detected_display_type; |
2103 | ictx->ir_proto_mask = ir_proto_mask; | 2079 | ictx->props->allowed_protos = allowed_protos; |
2080 | ictx->ir_type = allowed_protos; | ||
2104 | } | 2081 | } |
2105 | 2082 | ||
2106 | static void imon_set_display_type(struct imon_context *ictx, | 2083 | static void imon_set_display_type(struct imon_context *ictx, |
@@ -2255,9 +2232,6 @@ static int __devinit imon_probe(struct usb_interface *interface, | |||
2255 | 2232 | ||
2256 | if (product == 0xffdc) | 2233 | if (product == 0xffdc) |
2257 | imon_get_ffdc_type(ictx); | 2234 | imon_get_ffdc_type(ictx); |
2258 | else | ||
2259 | ictx->ir_proto_mask = IMON_IR_PROTO_MASK_MCE | | ||
2260 | IMON_IR_PROTO_MASK_IMON; | ||
2261 | 2235 | ||
2262 | imon_set_display_type(ictx, interface); | 2236 | imon_set_display_type(ictx, interface); |
2263 | 2237 | ||
@@ -2266,7 +2240,12 @@ static int __devinit imon_probe(struct usb_interface *interface, | |||
2266 | } | 2240 | } |
2267 | 2241 | ||
2268 | /* set IR protocol/remote type */ | 2242 | /* set IR protocol/remote type */ |
2269 | imon_set_ir_protocol(ictx); | 2243 | ret = imon_ir_change_protocol(ictx, ictx->ir_type); |
2244 | if (ret) { | ||
2245 | dev_warn(dev, "%s: failed to set IR protocol, falling back " | ||
2246 | "to standard iMON protocol mode\n", __func__); | ||
2247 | ictx->ir_type = IR_TYPE_OTHER; | ||
2248 | } | ||
2270 | 2249 | ||
2271 | dev_info(dev, "iMON device (%04x:%04x, intf%d) on " | 2250 | dev_info(dev, "iMON device (%04x:%04x, intf%d) on " |
2272 | "usb<%d:%d> initialized\n", vendor, product, ifnum, | 2251 | "usb<%d:%d> initialized\n", vendor, product, ifnum, |
@@ -2343,7 +2322,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface) | |||
2343 | if (!ictx->display_isopen) | 2322 | if (!ictx->display_isopen) |
2344 | free_imon_context(ictx); | 2323 | free_imon_context(ictx); |
2345 | } else { | 2324 | } else { |
2346 | if (ictx->ir_protocol == IMON_IR_PROTOCOL_MCE) | 2325 | if (ictx->ir_type == IR_TYPE_RC6) |
2347 | del_timer_sync(&ictx->itimer); | 2326 | del_timer_sync(&ictx->itimer); |
2348 | mutex_unlock(&ictx->lock); | 2327 | mutex_unlock(&ictx->lock); |
2349 | } | 2328 | } |