.. | .. |
---|
197 | 197 | void __user *ip = (void __user *)arg; |
---|
198 | 198 | struct gpiohandle_data ghd; |
---|
199 | 199 | DECLARE_BITMAP(vals, GPIOHANDLES_MAX); |
---|
200 | | - int i; |
---|
| 200 | + unsigned int i; |
---|
| 201 | + int ret; |
---|
201 | 202 | |
---|
202 | | - if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { |
---|
203 | | - /* NOTE: It's ok to read values of output lines. */ |
---|
204 | | - int ret = gpiod_get_array_value_complex(false, |
---|
205 | | - true, |
---|
206 | | - lh->num_descs, |
---|
207 | | - lh->descs, |
---|
208 | | - NULL, |
---|
209 | | - vals); |
---|
| 203 | + if (!lh->gdev->chip) |
---|
| 204 | + return -ENODEV; |
---|
| 205 | + |
---|
| 206 | + switch (cmd) { |
---|
| 207 | + case GPIOHANDLE_GET_LINE_VALUES_IOCTL: |
---|
| 208 | + /* NOTE: It's okay to read values of output lines */ |
---|
| 209 | + ret = gpiod_get_array_value_complex(false, true, |
---|
| 210 | + lh->num_descs, lh->descs, |
---|
| 211 | + NULL, vals); |
---|
210 | 212 | if (ret) |
---|
211 | 213 | return ret; |
---|
212 | 214 | |
---|
.. | .. |
---|
218 | 220 | return -EFAULT; |
---|
219 | 221 | |
---|
220 | 222 | return 0; |
---|
221 | | - } else if (cmd == GPIOHANDLE_SET_LINE_VALUES_IOCTL) { |
---|
| 223 | + case GPIOHANDLE_SET_LINE_VALUES_IOCTL: |
---|
222 | 224 | /* |
---|
223 | 225 | * All line descriptors were created at once with the same |
---|
224 | 226 | * flags so just check if the first one is really output. |
---|
.. | .. |
---|
240 | 242 | lh->descs, |
---|
241 | 243 | NULL, |
---|
242 | 244 | vals); |
---|
243 | | - } else if (cmd == GPIOHANDLE_SET_CONFIG_IOCTL) { |
---|
| 245 | + case GPIOHANDLE_SET_CONFIG_IOCTL: |
---|
244 | 246 | return linehandle_set_config(lh, ip); |
---|
| 247 | + default: |
---|
| 248 | + return -EINVAL; |
---|
245 | 249 | } |
---|
246 | | - return -EINVAL; |
---|
247 | 250 | } |
---|
248 | 251 | |
---|
249 | 252 | #ifdef CONFIG_COMPAT |
---|
.. | .. |
---|
1165 | 1168 | struct linereq *lr = file->private_data; |
---|
1166 | 1169 | void __user *ip = (void __user *)arg; |
---|
1167 | 1170 | |
---|
1168 | | - if (cmd == GPIO_V2_LINE_GET_VALUES_IOCTL) |
---|
1169 | | - return linereq_get_values(lr, ip); |
---|
1170 | | - else if (cmd == GPIO_V2_LINE_SET_VALUES_IOCTL) |
---|
1171 | | - return linereq_set_values(lr, ip); |
---|
1172 | | - else if (cmd == GPIO_V2_LINE_SET_CONFIG_IOCTL) |
---|
1173 | | - return linereq_set_config(lr, ip); |
---|
| 1171 | + if (!lr->gdev->chip) |
---|
| 1172 | + return -ENODEV; |
---|
1174 | 1173 | |
---|
1175 | | - return -EINVAL; |
---|
| 1174 | + switch (cmd) { |
---|
| 1175 | + case GPIO_V2_LINE_GET_VALUES_IOCTL: |
---|
| 1176 | + return linereq_get_values(lr, ip); |
---|
| 1177 | + case GPIO_V2_LINE_SET_VALUES_IOCTL: |
---|
| 1178 | + return linereq_set_values(lr, ip); |
---|
| 1179 | + case GPIO_V2_LINE_SET_CONFIG_IOCTL: |
---|
| 1180 | + return linereq_set_config(lr, ip); |
---|
| 1181 | + default: |
---|
| 1182 | + return -EINVAL; |
---|
| 1183 | + } |
---|
1176 | 1184 | } |
---|
1177 | 1185 | |
---|
1178 | 1186 | #ifdef CONFIG_COMPAT |
---|
.. | .. |
---|
1188 | 1196 | { |
---|
1189 | 1197 | struct linereq *lr = file->private_data; |
---|
1190 | 1198 | __poll_t events = 0; |
---|
| 1199 | + |
---|
| 1200 | + if (!lr->gdev->chip) |
---|
| 1201 | + return EPOLLHUP | EPOLLERR; |
---|
1191 | 1202 | |
---|
1192 | 1203 | poll_wait(file, &lr->wait, wait); |
---|
1193 | 1204 | |
---|
.. | .. |
---|
1207 | 1218 | struct gpio_v2_line_event le; |
---|
1208 | 1219 | ssize_t bytes_read = 0; |
---|
1209 | 1220 | int ret; |
---|
| 1221 | + |
---|
| 1222 | + if (!lr->gdev->chip) |
---|
| 1223 | + return -ENODEV; |
---|
1210 | 1224 | |
---|
1211 | 1225 | if (count < sizeof(le)) |
---|
1212 | 1226 | return -EINVAL; |
---|
.. | .. |
---|
1473 | 1487 | struct lineevent_state *le = file->private_data; |
---|
1474 | 1488 | __poll_t events = 0; |
---|
1475 | 1489 | |
---|
| 1490 | + if (!le->gdev->chip) |
---|
| 1491 | + return EPOLLHUP | EPOLLERR; |
---|
| 1492 | + |
---|
1476 | 1493 | poll_wait(file, &le->wait, wait); |
---|
1477 | 1494 | |
---|
1478 | 1495 | if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock)) |
---|
.. | .. |
---|
1507 | 1524 | ssize_t bytes_read = 0; |
---|
1508 | 1525 | ssize_t ge_size; |
---|
1509 | 1526 | int ret; |
---|
| 1527 | + |
---|
| 1528 | + if (!le->gdev->chip) |
---|
| 1529 | + return -ENODEV; |
---|
1510 | 1530 | |
---|
1511 | 1531 | /* |
---|
1512 | 1532 | * When compatible system call is being used the struct gpioevent_data, |
---|
.. | .. |
---|
1585 | 1605 | struct lineevent_state *le = file->private_data; |
---|
1586 | 1606 | void __user *ip = (void __user *)arg; |
---|
1587 | 1607 | struct gpiohandle_data ghd; |
---|
| 1608 | + |
---|
| 1609 | + if (!le->gdev->chip) |
---|
| 1610 | + return -ENODEV; |
---|
1588 | 1611 | |
---|
1589 | 1612 | /* |
---|
1590 | 1613 | * We can get the value for an event line but not set it, |
---|
.. | .. |
---|
2095 | 2118 | return -ENODEV; |
---|
2096 | 2119 | |
---|
2097 | 2120 | /* Fill in the struct and pass to userspace */ |
---|
2098 | | - if (cmd == GPIO_GET_CHIPINFO_IOCTL) { |
---|
| 2121 | + switch (cmd) { |
---|
| 2122 | + case GPIO_GET_CHIPINFO_IOCTL: |
---|
2099 | 2123 | return chipinfo_get(cdev, ip); |
---|
2100 | 2124 | #ifdef CONFIG_GPIO_CDEV_V1 |
---|
2101 | | - } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) { |
---|
| 2125 | + case GPIO_GET_LINEHANDLE_IOCTL: |
---|
2102 | 2126 | return linehandle_create(gdev, ip); |
---|
2103 | | - } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) { |
---|
| 2127 | + case GPIO_GET_LINEEVENT_IOCTL: |
---|
2104 | 2128 | return lineevent_create(gdev, ip); |
---|
2105 | | - } else if (cmd == GPIO_GET_LINEINFO_IOCTL || |
---|
2106 | | - cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) { |
---|
2107 | | - return lineinfo_get_v1(cdev, ip, |
---|
2108 | | - cmd == GPIO_GET_LINEINFO_WATCH_IOCTL); |
---|
| 2129 | + case GPIO_GET_LINEINFO_IOCTL: |
---|
| 2130 | + return lineinfo_get_v1(cdev, ip, false); |
---|
| 2131 | + case GPIO_GET_LINEINFO_WATCH_IOCTL: |
---|
| 2132 | + return lineinfo_get_v1(cdev, ip, true); |
---|
2109 | 2133 | #endif /* CONFIG_GPIO_CDEV_V1 */ |
---|
2110 | | - } else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL || |
---|
2111 | | - cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) { |
---|
2112 | | - return lineinfo_get(cdev, ip, |
---|
2113 | | - cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL); |
---|
2114 | | - } else if (cmd == GPIO_V2_GET_LINE_IOCTL) { |
---|
| 2134 | + case GPIO_V2_GET_LINEINFO_IOCTL: |
---|
| 2135 | + return lineinfo_get(cdev, ip, false); |
---|
| 2136 | + case GPIO_V2_GET_LINEINFO_WATCH_IOCTL: |
---|
| 2137 | + return lineinfo_get(cdev, ip, true); |
---|
| 2138 | + case GPIO_V2_GET_LINE_IOCTL: |
---|
2115 | 2139 | return linereq_create(gdev, ip); |
---|
2116 | | - } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) { |
---|
| 2140 | + case GPIO_GET_LINEINFO_UNWATCH_IOCTL: |
---|
2117 | 2141 | return lineinfo_unwatch(cdev, ip); |
---|
| 2142 | + default: |
---|
| 2143 | + return -EINVAL; |
---|
2118 | 2144 | } |
---|
2119 | | - return -EINVAL; |
---|
2120 | 2145 | } |
---|
2121 | 2146 | |
---|
2122 | 2147 | #ifdef CONFIG_COMPAT |
---|
.. | .. |
---|
2164 | 2189 | struct gpio_chardev_data *cdev = file->private_data; |
---|
2165 | 2190 | __poll_t events = 0; |
---|
2166 | 2191 | |
---|
| 2192 | + if (!cdev->gdev->chip) |
---|
| 2193 | + return EPOLLHUP | EPOLLERR; |
---|
| 2194 | + |
---|
2167 | 2195 | poll_wait(file, &cdev->wait, pollt); |
---|
2168 | 2196 | |
---|
2169 | 2197 | if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events, |
---|
.. | .. |
---|
2182 | 2210 | int ret; |
---|
2183 | 2211 | size_t event_size; |
---|
2184 | 2212 | |
---|
| 2213 | + if (!cdev->gdev->chip) |
---|
| 2214 | + return -ENODEV; |
---|
| 2215 | + |
---|
2185 | 2216 | #ifndef CONFIG_GPIO_CDEV_V1 |
---|
2186 | 2217 | event_size = sizeof(struct gpio_v2_line_info_changed); |
---|
2187 | 2218 | if (count < event_size) |
---|