Contents of /trunk/kernel-alx/patches-5.4/0274-5.4.175-all-fixes.patch
Parent Directory | Revision Log
Revision 3635 -
(show annotations)
(download)
Mon Oct 24 12:34:12 2022 UTC (18 months, 3 weeks ago) by niro
File size: 27341 byte(s)
Mon Oct 24 12:34:12 2022 UTC (18 months, 3 weeks ago) by niro
File size: 27341 byte(s)
-sync kernel patches
1 | diff --git a/Makefile b/Makefile |
2 | index 3075f06f77131..2f6c51097d003 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,7 +1,7 @@ |
6 | # SPDX-License-Identifier: GPL-2.0 |
7 | VERSION = 5 |
8 | PATCHLEVEL = 4 |
9 | -SUBLEVEL = 174 |
10 | +SUBLEVEL = 175 |
11 | EXTRAVERSION = |
12 | NAME = Kleptomaniac Octopus |
13 | |
14 | diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi |
15 | index 50c64146d4926..af81f386793ca 100644 |
16 | --- a/arch/arm/boot/dts/bcm283x.dtsi |
17 | +++ b/arch/arm/boot/dts/bcm283x.dtsi |
18 | @@ -183,6 +183,7 @@ |
19 | |
20 | interrupt-controller; |
21 | #interrupt-cells = <2>; |
22 | + gpio-ranges = <&gpio 0 0 54>; |
23 | |
24 | /* Defines pin muxing groups according to |
25 | * BCM2835-ARM-Peripherals.pdf page 102. |
26 | diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h |
27 | index 08b35587bc6dc..352c102f3459c 100644 |
28 | --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h |
29 | +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h |
30 | @@ -118,6 +118,9 @@ struct drm_i915_gem_object { |
31 | |
32 | I915_SELFTEST_DECLARE(struct list_head st_link); |
33 | |
34 | + unsigned long flags; |
35 | +#define I915_BO_WAS_BOUND_BIT 0 |
36 | + |
37 | /* |
38 | * Is the object to be mapped as read-only to the GPU |
39 | * Only honoured if hardware has relevant pte bit |
40 | diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c |
41 | index 18f0ce0135c17..aa63fa0ab575e 100644 |
42 | --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c |
43 | +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c |
44 | @@ -8,6 +8,8 @@ |
45 | #include "i915_gem_object.h" |
46 | #include "i915_scatterlist.h" |
47 | |
48 | +#include "gt/intel_gt.h" |
49 | + |
50 | void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, |
51 | struct sg_table *pages, |
52 | unsigned int sg_page_sizes) |
53 | @@ -176,6 +178,14 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) |
54 | __i915_gem_object_reset_page_iter(obj); |
55 | obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0; |
56 | |
57 | + if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) { |
58 | + struct drm_i915_private *i915 = to_i915(obj->base.dev); |
59 | + intel_wakeref_t wakeref; |
60 | + |
61 | + with_intel_runtime_pm_if_in_use(&i915->runtime_pm, wakeref) |
62 | + intel_gt_invalidate_tlbs(&i915->gt); |
63 | + } |
64 | + |
65 | return pages; |
66 | } |
67 | |
68 | diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c |
69 | index d48ec9a76ed16..c8c070375d298 100644 |
70 | --- a/drivers/gpu/drm/i915/gt/intel_gt.c |
71 | +++ b/drivers/gpu/drm/i915/gt/intel_gt.c |
72 | @@ -15,6 +15,8 @@ void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) |
73 | |
74 | spin_lock_init(>->irq_lock); |
75 | |
76 | + mutex_init(>->tlb_invalidate_lock); |
77 | + |
78 | INIT_LIST_HEAD(>->closed_vma); |
79 | spin_lock_init(>->closed_lock); |
80 | |
81 | @@ -266,3 +268,100 @@ void intel_gt_driver_late_release(struct intel_gt *gt) |
82 | intel_uc_driver_late_release(>->uc); |
83 | intel_gt_fini_reset(gt); |
84 | } |
85 | + |
86 | +struct reg_and_bit { |
87 | + i915_reg_t reg; |
88 | + u32 bit; |
89 | +}; |
90 | + |
91 | +static struct reg_and_bit |
92 | +get_reg_and_bit(const struct intel_engine_cs *engine, const bool gen8, |
93 | + const i915_reg_t *regs, const unsigned int num) |
94 | +{ |
95 | + const unsigned int class = engine->class; |
96 | + struct reg_and_bit rb = { }; |
97 | + |
98 | + if (WARN_ON_ONCE(class >= num || !regs[class].reg)) |
99 | + return rb; |
100 | + |
101 | + rb.reg = regs[class]; |
102 | + if (gen8 && class == VIDEO_DECODE_CLASS) |
103 | + rb.reg.reg += 4 * engine->instance; /* GEN8_M2TCR */ |
104 | + else |
105 | + rb.bit = engine->instance; |
106 | + |
107 | + rb.bit = BIT(rb.bit); |
108 | + |
109 | + return rb; |
110 | +} |
111 | + |
112 | +void intel_gt_invalidate_tlbs(struct intel_gt *gt) |
113 | +{ |
114 | + static const i915_reg_t gen8_regs[] = { |
115 | + [RENDER_CLASS] = GEN8_RTCR, |
116 | + [VIDEO_DECODE_CLASS] = GEN8_M1TCR, /* , GEN8_M2TCR */ |
117 | + [VIDEO_ENHANCEMENT_CLASS] = GEN8_VTCR, |
118 | + [COPY_ENGINE_CLASS] = GEN8_BTCR, |
119 | + }; |
120 | + static const i915_reg_t gen12_regs[] = { |
121 | + [RENDER_CLASS] = GEN12_GFX_TLB_INV_CR, |
122 | + [VIDEO_DECODE_CLASS] = GEN12_VD_TLB_INV_CR, |
123 | + [VIDEO_ENHANCEMENT_CLASS] = GEN12_VE_TLB_INV_CR, |
124 | + [COPY_ENGINE_CLASS] = GEN12_BLT_TLB_INV_CR, |
125 | + }; |
126 | + struct drm_i915_private *i915 = gt->i915; |
127 | + struct intel_uncore *uncore = gt->uncore; |
128 | + struct intel_engine_cs *engine; |
129 | + enum intel_engine_id id; |
130 | + const i915_reg_t *regs; |
131 | + unsigned int num = 0; |
132 | + |
133 | + if (I915_SELFTEST_ONLY(gt->awake == -ENODEV)) |
134 | + return; |
135 | + |
136 | + if (INTEL_GEN(i915) == 12) { |
137 | + regs = gen12_regs; |
138 | + num = ARRAY_SIZE(gen12_regs); |
139 | + } else if (INTEL_GEN(i915) >= 8 && INTEL_GEN(i915) <= 11) { |
140 | + regs = gen8_regs; |
141 | + num = ARRAY_SIZE(gen8_regs); |
142 | + } else if (INTEL_GEN(i915) < 8) { |
143 | + return; |
144 | + } |
145 | + |
146 | + if (WARN_ONCE(!num, "Platform does not implement TLB invalidation!")) |
147 | + return; |
148 | + |
149 | + GEM_TRACE("\n"); |
150 | + |
151 | + assert_rpm_wakelock_held(&i915->runtime_pm); |
152 | + |
153 | + mutex_lock(>->tlb_invalidate_lock); |
154 | + intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); |
155 | + |
156 | + for_each_engine(engine, gt, id) { |
157 | + /* |
158 | + * HW architecture suggest typical invalidation time at 40us, |
159 | + * with pessimistic cases up to 100us and a recommendation to |
160 | + * cap at 1ms. We go a bit higher just in case. |
161 | + */ |
162 | + const unsigned int timeout_us = 100; |
163 | + const unsigned int timeout_ms = 4; |
164 | + struct reg_and_bit rb; |
165 | + |
166 | + rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num); |
167 | + if (!i915_mmio_reg_offset(rb.reg)) |
168 | + continue; |
169 | + |
170 | + intel_uncore_write_fw(uncore, rb.reg, rb.bit); |
171 | + if (__intel_wait_for_register_fw(uncore, |
172 | + rb.reg, rb.bit, 0, |
173 | + timeout_us, timeout_ms, |
174 | + NULL)) |
175 | + DRM_ERROR_RATELIMITED("%s TLB invalidation did not complete in %ums!\n", |
176 | + engine->name, timeout_ms); |
177 | + } |
178 | + |
179 | + intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL); |
180 | + mutex_unlock(>->tlb_invalidate_lock); |
181 | +} |
182 | diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h |
183 | index 4920cb351f109..4eab15bdcd97b 100644 |
184 | --- a/drivers/gpu/drm/i915/gt/intel_gt.h |
185 | +++ b/drivers/gpu/drm/i915/gt/intel_gt.h |
186 | @@ -57,4 +57,6 @@ static inline bool intel_gt_is_wedged(struct intel_gt *gt) |
187 | |
188 | void intel_gt_queue_hangcheck(struct intel_gt *gt); |
189 | |
190 | +void intel_gt_invalidate_tlbs(struct intel_gt *gt); |
191 | + |
192 | #endif /* __INTEL_GT_H__ */ |
193 | diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h |
194 | index dc295c196d11c..82a78719b32d5 100644 |
195 | --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h |
196 | +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h |
197 | @@ -40,6 +40,8 @@ struct intel_gt { |
198 | |
199 | struct intel_uc uc; |
200 | |
201 | + struct mutex tlb_invalidate_lock; |
202 | + |
203 | struct intel_gt_timelines { |
204 | spinlock_t lock; /* protects active_list */ |
205 | struct list_head active_list; |
206 | diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h |
207 | index 7b6e68f082f8c..1386d0f5eac63 100644 |
208 | --- a/drivers/gpu/drm/i915/i915_reg.h |
209 | +++ b/drivers/gpu/drm/i915/i915_reg.h |
210 | @@ -2519,6 +2519,12 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) |
211 | #define GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING (1 << 28) |
212 | #define GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT (1 << 24) |
213 | |
214 | +#define GEN8_RTCR _MMIO(0x4260) |
215 | +#define GEN8_M1TCR _MMIO(0x4264) |
216 | +#define GEN8_M2TCR _MMIO(0x4268) |
217 | +#define GEN8_BTCR _MMIO(0x426c) |
218 | +#define GEN8_VTCR _MMIO(0x4270) |
219 | + |
220 | #if 0 |
221 | #define PRB0_TAIL _MMIO(0x2030) |
222 | #define PRB0_HEAD _MMIO(0x2034) |
223 | @@ -2602,6 +2608,11 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) |
224 | #define FAULT_VA_HIGH_BITS (0xf << 0) |
225 | #define FAULT_GTT_SEL (1 << 4) |
226 | |
227 | +#define GEN12_GFX_TLB_INV_CR _MMIO(0xced8) |
228 | +#define GEN12_VD_TLB_INV_CR _MMIO(0xcedc) |
229 | +#define GEN12_VE_TLB_INV_CR _MMIO(0xcee0) |
230 | +#define GEN12_BLT_TLB_INV_CR _MMIO(0xcee4) |
231 | + |
232 | #define FPGA_DBG _MMIO(0x42300) |
233 | #define FPGA_DBG_RM_NOCLAIM (1 << 31) |
234 | |
235 | diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c |
236 | index e0e677b2a3a94..c24f49ee10d73 100644 |
237 | --- a/drivers/gpu/drm/i915/i915_vma.c |
238 | +++ b/drivers/gpu/drm/i915/i915_vma.c |
239 | @@ -341,6 +341,10 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, |
240 | return ret; |
241 | |
242 | vma->flags |= bind_flags; |
243 | + |
244 | + if (vma->obj) |
245 | + set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags); |
246 | + |
247 | return 0; |
248 | } |
249 | |
250 | diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |
251 | index 5eb73ded8e07a..765f7a62870db 100644 |
252 | --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |
253 | +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |
254 | @@ -1002,15 +1002,14 @@ extern int vmw_execbuf_fence_commands(struct drm_file *file_priv, |
255 | struct vmw_private *dev_priv, |
256 | struct vmw_fence_obj **p_fence, |
257 | uint32_t *p_handle); |
258 | -extern void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, |
259 | +extern int vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, |
260 | struct vmw_fpriv *vmw_fp, |
261 | int ret, |
262 | struct drm_vmw_fence_rep __user |
263 | *user_fence_rep, |
264 | struct vmw_fence_obj *fence, |
265 | uint32_t fence_handle, |
266 | - int32_t out_fence_fd, |
267 | - struct sync_file *sync_file); |
268 | + int32_t out_fence_fd); |
269 | bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd); |
270 | |
271 | /** |
272 | diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c |
273 | index ff86d49dc5e8a..e3d20048075bf 100644 |
274 | --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c |
275 | +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c |
276 | @@ -3413,17 +3413,17 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv, |
277 | * Also if copying fails, user-space will be unable to signal the fence object |
278 | * so we wait for it immediately, and then unreference the user-space reference. |
279 | */ |
280 | -void |
281 | +int |
282 | vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, |
283 | struct vmw_fpriv *vmw_fp, int ret, |
284 | struct drm_vmw_fence_rep __user *user_fence_rep, |
285 | struct vmw_fence_obj *fence, uint32_t fence_handle, |
286 | - int32_t out_fence_fd, struct sync_file *sync_file) |
287 | + int32_t out_fence_fd) |
288 | { |
289 | struct drm_vmw_fence_rep fence_rep; |
290 | |
291 | if (user_fence_rep == NULL) |
292 | - return; |
293 | + return 0; |
294 | |
295 | memset(&fence_rep, 0, sizeof(fence_rep)); |
296 | |
297 | @@ -3451,20 +3451,14 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, |
298 | * handle. |
299 | */ |
300 | if (unlikely(ret != 0) && (fence_rep.error == 0)) { |
301 | - if (sync_file) |
302 | - fput(sync_file->file); |
303 | - |
304 | - if (fence_rep.fd != -1) { |
305 | - put_unused_fd(fence_rep.fd); |
306 | - fence_rep.fd = -1; |
307 | - } |
308 | - |
309 | ttm_ref_object_base_unref(vmw_fp->tfile, fence_handle, |
310 | TTM_REF_USAGE); |
311 | VMW_DEBUG_USER("Fence copy error. Syncing.\n"); |
312 | (void) vmw_fence_obj_wait(fence, false, false, |
313 | VMW_FENCE_WAIT_TIMEOUT); |
314 | } |
315 | + |
316 | + return ret ? -EFAULT : 0; |
317 | } |
318 | |
319 | /** |
320 | @@ -3806,16 +3800,23 @@ int vmw_execbuf_process(struct drm_file *file_priv, |
321 | |
322 | (void) vmw_fence_obj_wait(fence, false, false, |
323 | VMW_FENCE_WAIT_TIMEOUT); |
324 | + } |
325 | + } |
326 | + |
327 | + ret = vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, |
328 | + user_fence_rep, fence, handle, out_fence_fd); |
329 | + |
330 | + if (sync_file) { |
331 | + if (ret) { |
332 | + /* usercopy of fence failed, put the file object */ |
333 | + fput(sync_file->file); |
334 | + put_unused_fd(out_fence_fd); |
335 | } else { |
336 | /* Link the fence with the FD created earlier */ |
337 | fd_install(out_fence_fd, sync_file->file); |
338 | } |
339 | } |
340 | |
341 | - vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, |
342 | - user_fence_rep, fence, handle, out_fence_fd, |
343 | - sync_file); |
344 | - |
345 | /* Don't unreference when handing fence out */ |
346 | if (unlikely(out_fence != NULL)) { |
347 | *out_fence = fence; |
348 | @@ -3833,7 +3834,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, |
349 | */ |
350 | vmw_validation_unref_lists(&val_ctx); |
351 | |
352 | - return 0; |
353 | + return ret; |
354 | |
355 | out_unlock_binding: |
356 | mutex_unlock(&dev_priv->binding_mutex); |
357 | diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |
358 | index 178a6cd1a06fe..874093a0b04f0 100644 |
359 | --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |
360 | +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |
361 | @@ -1171,7 +1171,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, |
362 | } |
363 | |
364 | vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence, |
365 | - handle, -1, NULL); |
366 | + handle, -1); |
367 | vmw_fence_obj_unreference(&fence); |
368 | return 0; |
369 | out_no_create: |
370 | diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |
371 | index 33b1519887474..0b800c3540492 100644 |
372 | --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |
373 | +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |
374 | @@ -2570,7 +2570,7 @@ void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv, |
375 | if (file_priv) |
376 | vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), |
377 | ret, user_fence_rep, fence, |
378 | - handle, -1, NULL); |
379 | + handle, -1); |
380 | if (out_fence) |
381 | *out_fence = fence; |
382 | else |
383 | diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c |
384 | index 2c01e2ebef7aa..d97c19ef75830 100644 |
385 | --- a/drivers/mmc/host/sdhci-esdhc-imx.c |
386 | +++ b/drivers/mmc/host/sdhci-esdhc-imx.c |
387 | @@ -218,8 +218,7 @@ static struct esdhc_soc_data usdhc_imx7ulp_data = { |
388 | static struct esdhc_soc_data usdhc_imx8qxp_data = { |
389 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
390 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
391 | - | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES |
392 | - | ESDHC_FLAG_CQHCI, |
393 | + | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES, |
394 | }; |
395 | |
396 | struct pltfm_imx_data { |
397 | diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c |
398 | index 0de1a3a96984c..fa742535f6791 100644 |
399 | --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c |
400 | +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c |
401 | @@ -19,6 +19,7 @@ |
402 | #include <linux/irq.h> |
403 | #include <linux/irqdesc.h> |
404 | #include <linux/init.h> |
405 | +#include <linux/interrupt.h> |
406 | #include <linux/of_address.h> |
407 | #include <linux/of.h> |
408 | #include <linux/of_irq.h> |
409 | @@ -37,12 +38,10 @@ |
410 | |
411 | #define MODULE_NAME "pinctrl-bcm2835" |
412 | #define BCM2835_NUM_GPIOS 54 |
413 | +#define BCM2711_NUM_GPIOS 58 |
414 | #define BCM2835_NUM_BANKS 2 |
415 | #define BCM2835_NUM_IRQS 3 |
416 | |
417 | -#define BCM2835_PIN_BITMAP_SZ \ |
418 | - DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8) |
419 | - |
420 | /* GPIO register offsets */ |
421 | #define GPFSEL0 0x0 /* Function Select */ |
422 | #define GPSET0 0x1c /* Pin Output Set */ |
423 | @@ -78,13 +77,15 @@ |
424 | struct bcm2835_pinctrl { |
425 | struct device *dev; |
426 | void __iomem *base; |
427 | + int *wake_irq; |
428 | |
429 | /* note: locking assumes each bank will have its own unsigned long */ |
430 | unsigned long enabled_irq_map[BCM2835_NUM_BANKS]; |
431 | - unsigned int irq_type[BCM2835_NUM_GPIOS]; |
432 | + unsigned int irq_type[BCM2711_NUM_GPIOS]; |
433 | |
434 | struct pinctrl_dev *pctl_dev; |
435 | struct gpio_chip gpio_chip; |
436 | + struct pinctrl_desc pctl_desc; |
437 | struct pinctrl_gpio_range gpio_range; |
438 | |
439 | raw_spinlock_t irq_lock[BCM2835_NUM_BANKS]; |
440 | @@ -147,6 +148,10 @@ static struct pinctrl_pin_desc bcm2835_gpio_pins[] = { |
441 | BCM2835_GPIO_PIN(51), |
442 | BCM2835_GPIO_PIN(52), |
443 | BCM2835_GPIO_PIN(53), |
444 | + BCM2835_GPIO_PIN(54), |
445 | + BCM2835_GPIO_PIN(55), |
446 | + BCM2835_GPIO_PIN(56), |
447 | + BCM2835_GPIO_PIN(57), |
448 | }; |
449 | |
450 | /* one pin per group */ |
451 | @@ -205,6 +210,10 @@ static const char * const bcm2835_gpio_groups[] = { |
452 | "gpio51", |
453 | "gpio52", |
454 | "gpio53", |
455 | + "gpio54", |
456 | + "gpio55", |
457 | + "gpio56", |
458 | + "gpio57", |
459 | }; |
460 | |
461 | enum bcm2835_fsel { |
462 | @@ -355,6 +364,22 @@ static const struct gpio_chip bcm2835_gpio_chip = { |
463 | .can_sleep = false, |
464 | }; |
465 | |
466 | +static const struct gpio_chip bcm2711_gpio_chip = { |
467 | + .label = "pinctrl-bcm2711", |
468 | + .owner = THIS_MODULE, |
469 | + .request = gpiochip_generic_request, |
470 | + .free = gpiochip_generic_free, |
471 | + .direction_input = bcm2835_gpio_direction_input, |
472 | + .direction_output = bcm2835_gpio_direction_output, |
473 | + .get_direction = bcm2835_gpio_get_direction, |
474 | + .get = bcm2835_gpio_get, |
475 | + .set = bcm2835_gpio_set, |
476 | + .set_config = gpiochip_generic_config, |
477 | + .base = -1, |
478 | + .ngpio = BCM2711_NUM_GPIOS, |
479 | + .can_sleep = false, |
480 | +}; |
481 | + |
482 | static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc, |
483 | unsigned int bank, u32 mask) |
484 | { |
485 | @@ -401,7 +426,7 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc) |
486 | bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000); |
487 | bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff); |
488 | break; |
489 | - case 2: /* IRQ2 covers GPIOs 46-53 */ |
490 | + case 2: /* IRQ2 covers GPIOs 46-57 */ |
491 | bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000); |
492 | break; |
493 | } |
494 | @@ -409,6 +434,11 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc) |
495 | chained_irq_exit(host_chip, desc); |
496 | } |
497 | |
498 | +static irqreturn_t bcm2835_gpio_wake_irq_handler(int irq, void *dev_id) |
499 | +{ |
500 | + return IRQ_HANDLED; |
501 | +} |
502 | + |
503 | static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, |
504 | unsigned reg, unsigned offset, bool enable) |
505 | { |
506 | @@ -608,6 +638,34 @@ static void bcm2835_gpio_irq_ack(struct irq_data *data) |
507 | bcm2835_gpio_set_bit(pc, GPEDS0, gpio); |
508 | } |
509 | |
510 | +static int bcm2835_gpio_irq_set_wake(struct irq_data *data, unsigned int on) |
511 | +{ |
512 | + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); |
513 | + struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); |
514 | + unsigned gpio = irqd_to_hwirq(data); |
515 | + unsigned int irqgroup; |
516 | + int ret = -EINVAL; |
517 | + |
518 | + if (!pc->wake_irq) |
519 | + return ret; |
520 | + |
521 | + if (gpio <= 27) |
522 | + irqgroup = 0; |
523 | + else if (gpio >= 28 && gpio <= 45) |
524 | + irqgroup = 1; |
525 | + else if (gpio >= 46 && gpio <= 57) |
526 | + irqgroup = 2; |
527 | + else |
528 | + return ret; |
529 | + |
530 | + if (on) |
531 | + ret = enable_irq_wake(pc->wake_irq[irqgroup]); |
532 | + else |
533 | + ret = disable_irq_wake(pc->wake_irq[irqgroup]); |
534 | + |
535 | + return ret; |
536 | +} |
537 | + |
538 | static struct irq_chip bcm2835_gpio_irq_chip = { |
539 | .name = MODULE_NAME, |
540 | .irq_enable = bcm2835_gpio_irq_enable, |
541 | @@ -616,11 +674,13 @@ static struct irq_chip bcm2835_gpio_irq_chip = { |
542 | .irq_ack = bcm2835_gpio_irq_ack, |
543 | .irq_mask = bcm2835_gpio_irq_disable, |
544 | .irq_unmask = bcm2835_gpio_irq_enable, |
545 | + .irq_set_wake = bcm2835_gpio_irq_set_wake, |
546 | + .flags = IRQCHIP_MASK_ON_SUSPEND, |
547 | }; |
548 | |
549 | static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev) |
550 | { |
551 | - return ARRAY_SIZE(bcm2835_gpio_groups); |
552 | + return BCM2835_NUM_GPIOS; |
553 | } |
554 | |
555 | static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev, |
556 | @@ -778,7 +838,7 @@ static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, |
557 | err = of_property_read_u32_index(np, "brcm,pins", i, &pin); |
558 | if (err) |
559 | goto out; |
560 | - if (pin >= ARRAY_SIZE(bcm2835_gpio_pins)) { |
561 | + if (pin >= pc->pctl_desc.npins) { |
562 | dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n", |
563 | np, pin); |
564 | err = -EINVAL; |
565 | @@ -854,7 +914,7 @@ static int bcm2835_pmx_get_function_groups(struct pinctrl_dev *pctldev, |
566 | { |
567 | /* every pin can do every function */ |
568 | *groups = bcm2835_gpio_groups; |
569 | - *num_groups = ARRAY_SIZE(bcm2835_gpio_groups); |
570 | + *num_groups = BCM2835_NUM_GPIOS; |
571 | |
572 | return 0; |
573 | } |
574 | @@ -1054,29 +1114,66 @@ static const struct pinconf_ops bcm2711_pinconf_ops = { |
575 | .pin_config_set = bcm2711_pinconf_set, |
576 | }; |
577 | |
578 | -static struct pinctrl_desc bcm2835_pinctrl_desc = { |
579 | +static const struct pinctrl_desc bcm2835_pinctrl_desc = { |
580 | .name = MODULE_NAME, |
581 | .pins = bcm2835_gpio_pins, |
582 | - .npins = ARRAY_SIZE(bcm2835_gpio_pins), |
583 | + .npins = BCM2835_NUM_GPIOS, |
584 | .pctlops = &bcm2835_pctl_ops, |
585 | .pmxops = &bcm2835_pmx_ops, |
586 | .confops = &bcm2835_pinconf_ops, |
587 | .owner = THIS_MODULE, |
588 | }; |
589 | |
590 | -static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = { |
591 | +static const struct pinctrl_desc bcm2711_pinctrl_desc = { |
592 | + .name = "pinctrl-bcm2711", |
593 | + .pins = bcm2835_gpio_pins, |
594 | + .npins = BCM2711_NUM_GPIOS, |
595 | + .pctlops = &bcm2835_pctl_ops, |
596 | + .pmxops = &bcm2835_pmx_ops, |
597 | + .confops = &bcm2711_pinconf_ops, |
598 | + .owner = THIS_MODULE, |
599 | +}; |
600 | + |
601 | +static const struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = { |
602 | .name = MODULE_NAME, |
603 | .npins = BCM2835_NUM_GPIOS, |
604 | }; |
605 | |
606 | +static const struct pinctrl_gpio_range bcm2711_pinctrl_gpio_range = { |
607 | + .name = "pinctrl-bcm2711", |
608 | + .npins = BCM2711_NUM_GPIOS, |
609 | +}; |
610 | + |
611 | +struct bcm_plat_data { |
612 | + const struct gpio_chip *gpio_chip; |
613 | + const struct pinctrl_desc *pctl_desc; |
614 | + const struct pinctrl_gpio_range *gpio_range; |
615 | +}; |
616 | + |
617 | +static const struct bcm_plat_data bcm2835_plat_data = { |
618 | + .gpio_chip = &bcm2835_gpio_chip, |
619 | + .pctl_desc = &bcm2835_pinctrl_desc, |
620 | + .gpio_range = &bcm2835_pinctrl_gpio_range, |
621 | +}; |
622 | + |
623 | +static const struct bcm_plat_data bcm2711_plat_data = { |
624 | + .gpio_chip = &bcm2711_gpio_chip, |
625 | + .pctl_desc = &bcm2711_pinctrl_desc, |
626 | + .gpio_range = &bcm2711_pinctrl_gpio_range, |
627 | +}; |
628 | + |
629 | static const struct of_device_id bcm2835_pinctrl_match[] = { |
630 | { |
631 | .compatible = "brcm,bcm2835-gpio", |
632 | - .data = &bcm2835_pinconf_ops, |
633 | + .data = &bcm2835_plat_data, |
634 | }, |
635 | { |
636 | .compatible = "brcm,bcm2711-gpio", |
637 | - .data = &bcm2711_pinconf_ops, |
638 | + .data = &bcm2711_plat_data, |
639 | + }, |
640 | + { |
641 | + .compatible = "brcm,bcm7211-gpio", |
642 | + .data = &bcm2711_plat_data, |
643 | }, |
644 | {} |
645 | }; |
646 | @@ -1085,14 +1182,16 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) |
647 | { |
648 | struct device *dev = &pdev->dev; |
649 | struct device_node *np = dev->of_node; |
650 | + const struct bcm_plat_data *pdata; |
651 | struct bcm2835_pinctrl *pc; |
652 | struct gpio_irq_chip *girq; |
653 | struct resource iomem; |
654 | int err, i; |
655 | const struct of_device_id *match; |
656 | + int is_7211 = 0; |
657 | |
658 | - BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS); |
659 | - BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS); |
660 | + BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS); |
661 | + BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS); |
662 | |
663 | pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); |
664 | if (!pc) |
665 | @@ -1111,7 +1210,14 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) |
666 | if (IS_ERR(pc->base)) |
667 | return PTR_ERR(pc->base); |
668 | |
669 | - pc->gpio_chip = bcm2835_gpio_chip; |
670 | + match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node); |
671 | + if (!match) |
672 | + return -EINVAL; |
673 | + |
674 | + pdata = match->data; |
675 | + is_7211 = of_device_is_compatible(np, "brcm,bcm7211-gpio"); |
676 | + |
677 | + pc->gpio_chip = *pdata->gpio_chip; |
678 | pc->gpio_chip.parent = dev; |
679 | pc->gpio_chip.of_node = np; |
680 | |
681 | @@ -1135,6 +1241,18 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) |
682 | raw_spin_lock_init(&pc->irq_lock[i]); |
683 | } |
684 | |
685 | + pc->pctl_desc = *pdata->pctl_desc; |
686 | + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); |
687 | + if (IS_ERR(pc->pctl_dev)) { |
688 | + gpiochip_remove(&pc->gpio_chip); |
689 | + return PTR_ERR(pc->pctl_dev); |
690 | + } |
691 | + |
692 | + pc->gpio_range = *pdata->gpio_range; |
693 | + pc->gpio_range.base = pc->gpio_chip.base; |
694 | + pc->gpio_range.gc = &pc->gpio_chip; |
695 | + pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); |
696 | + |
697 | girq = &pc->gpio_chip.irq; |
698 | girq->chip = &bcm2835_gpio_irq_chip; |
699 | girq->parent_handler = bcm2835_gpio_irq_handler; |
700 | @@ -1142,8 +1260,19 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) |
701 | girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS, |
702 | sizeof(*girq->parents), |
703 | GFP_KERNEL); |
704 | - if (!girq->parents) |
705 | + if (!girq->parents) { |
706 | + pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range); |
707 | return -ENOMEM; |
708 | + } |
709 | + |
710 | + if (is_7211) { |
711 | + pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS, |
712 | + sizeof(*pc->wake_irq), |
713 | + GFP_KERNEL); |
714 | + if (!pc->wake_irq) |
715 | + return -ENOMEM; |
716 | + } |
717 | + |
718 | /* |
719 | * Use the same handler for all groups: this is necessary |
720 | * since we use one gpiochip to cover all lines - the |
721 | @@ -1151,34 +1280,44 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) |
722 | * bank that was firing the IRQ and look up the per-group |
723 | * and bank data. |
724 | */ |
725 | - for (i = 0; i < BCM2835_NUM_IRQS; i++) |
726 | + for (i = 0; i < BCM2835_NUM_IRQS; i++) { |
727 | + int len; |
728 | + char *name; |
729 | + |
730 | girq->parents[i] = irq_of_parse_and_map(np, i); |
731 | + if (!is_7211) |
732 | + continue; |
733 | + |
734 | + /* Skip over the all banks interrupts */ |
735 | + pc->wake_irq[i] = irq_of_parse_and_map(np, i + |
736 | + BCM2835_NUM_IRQS + 1); |
737 | + |
738 | + len = strlen(dev_name(pc->dev)) + 16; |
739 | + name = devm_kzalloc(pc->dev, len, GFP_KERNEL); |
740 | + if (!name) |
741 | + return -ENOMEM; |
742 | + |
743 | + snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i); |
744 | + |
745 | + /* These are optional interrupts */ |
746 | + err = devm_request_irq(dev, pc->wake_irq[i], |
747 | + bcm2835_gpio_wake_irq_handler, |
748 | + IRQF_SHARED, name, pc); |
749 | + if (err) |
750 | + dev_warn(dev, "unable to request wake IRQ %d\n", |
751 | + pc->wake_irq[i]); |
752 | + } |
753 | + |
754 | girq->default_type = IRQ_TYPE_NONE; |
755 | girq->handler = handle_level_irq; |
756 | |
757 | err = gpiochip_add_data(&pc->gpio_chip, pc); |
758 | if (err) { |
759 | dev_err(dev, "could not add GPIO chip\n"); |
760 | + pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range); |
761 | return err; |
762 | } |
763 | |
764 | - match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node); |
765 | - if (match) { |
766 | - bcm2835_pinctrl_desc.confops = |
767 | - (const struct pinconf_ops *)match->data; |
768 | - } |
769 | - |
770 | - pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc); |
771 | - if (IS_ERR(pc->pctl_dev)) { |
772 | - gpiochip_remove(&pc->gpio_chip); |
773 | - return PTR_ERR(pc->pctl_dev); |
774 | - } |
775 | - |
776 | - pc->gpio_range = bcm2835_pinctrl_gpio_range; |
777 | - pc->gpio_range.base = pc->gpio_chip.base; |
778 | - pc->gpio_range.gc = &pc->gpio_chip; |
779 | - pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); |
780 | - |
781 | return 0; |
782 | } |
783 | |
784 | diff --git a/fs/select.c b/fs/select.c |
785 | index e51796063cb6e..7716d9d5be1e8 100644 |
786 | --- a/fs/select.c |
787 | +++ b/fs/select.c |
788 | @@ -458,9 +458,11 @@ get_max: |
789 | return max; |
790 | } |
791 | |
792 | -#define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR) |
793 | -#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR) |
794 | -#define POLLEX_SET (EPOLLPRI) |
795 | +#define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR |\ |
796 | + EPOLLNVAL) |
797 | +#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR |\ |
798 | + EPOLLNVAL) |
799 | +#define POLLEX_SET (EPOLLPRI | EPOLLNVAL) |
800 | |
801 | static inline void wait_key_set(poll_table *wait, unsigned long in, |
802 | unsigned long out, unsigned long bit, |
803 | @@ -527,6 +529,7 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) |
804 | break; |
805 | if (!(bit & all_bits)) |
806 | continue; |
807 | + mask = EPOLLNVAL; |
808 | f = fdget(i); |
809 | if (f.file) { |
810 | wait_key_set(wait, in, out, bit, |
811 | @@ -534,34 +537,34 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) |
812 | mask = vfs_poll(f.file, wait); |
813 | |
814 | fdput(f); |
815 | - if ((mask & POLLIN_SET) && (in & bit)) { |
816 | - res_in |= bit; |
817 | - retval++; |
818 | - wait->_qproc = NULL; |
819 | - } |
820 | - if ((mask & POLLOUT_SET) && (out & bit)) { |
821 | - res_out |= bit; |
822 | - retval++; |
823 | - wait->_qproc = NULL; |
824 | - } |
825 | - if ((mask & POLLEX_SET) && (ex & bit)) { |
826 | - res_ex |= bit; |
827 | - retval++; |
828 | - wait->_qproc = NULL; |
829 | - } |
830 | - /* got something, stop busy polling */ |
831 | - if (retval) { |
832 | - can_busy_loop = false; |
833 | - busy_flag = 0; |
834 | - |
835 | - /* |
836 | - * only remember a returned |
837 | - * POLL_BUSY_LOOP if we asked for it |
838 | - */ |
839 | - } else if (busy_flag & mask) |
840 | - can_busy_loop = true; |
841 | - |
842 | } |
843 | + if ((mask & POLLIN_SET) && (in & bit)) { |
844 | + res_in |= bit; |
845 | + retval++; |
846 | + wait->_qproc = NULL; |
847 | + } |
848 | + if ((mask & POLLOUT_SET) && (out & bit)) { |
849 | + res_out |= bit; |
850 | + retval++; |
851 | + wait->_qproc = NULL; |
852 | + } |
853 | + if ((mask & POLLEX_SET) && (ex & bit)) { |
854 | + res_ex |= bit; |
855 | + retval++; |
856 | + wait->_qproc = NULL; |
857 | + } |
858 | + /* got something, stop busy polling */ |
859 | + if (retval) { |
860 | + can_busy_loop = false; |
861 | + busy_flag = 0; |
862 | + |
863 | + /* |
864 | + * only remember a returned |
865 | + * POLL_BUSY_LOOP if we asked for it |
866 | + */ |
867 | + } else if (busy_flag & mask) |
868 | + can_busy_loop = true; |
869 | + |
870 | } |
871 | if (res_in) |
872 | *rinp = res_in; |
873 | diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c |
874 | index 7777c35e0a171..5797cf2909b00 100644 |
875 | --- a/kernel/rcu/tree.c |
876 | +++ b/kernel/rcu/tree.c |
877 | @@ -1358,10 +1358,11 @@ static void __maybe_unused rcu_advance_cbs_nowake(struct rcu_node *rnp, |
878 | struct rcu_data *rdp) |
879 | { |
880 | rcu_lockdep_assert_cblist_protected(rdp); |
881 | - if (!rcu_seq_state(rcu_seq_current(&rnp->gp_seq)) || |
882 | - !raw_spin_trylock_rcu_node(rnp)) |
883 | + if (!rcu_seq_state(rcu_seq_current(&rnp->gp_seq)) || !raw_spin_trylock_rcu_node(rnp)) |
884 | return; |
885 | - WARN_ON_ONCE(rcu_advance_cbs(rnp, rdp)); |
886 | + // The grace period cannot end while we hold the rcu_node lock. |
887 | + if (rcu_seq_state(rcu_seq_current(&rnp->gp_seq))) |
888 | + WARN_ON_ONCE(rcu_advance_cbs(rnp, rdp)); |
889 | raw_spin_unlock_rcu_node(rnp); |
890 | } |
891 |