@@ -103,6 +103,7 @@ struct plic_stats {
103103};
104104
105105struct plic_data {
106+ struct k_spinlock lock ;
106107
107108#ifdef CONFIG_PLIC_SHELL_IRQ_COUNT
108109 struct plic_stats stats ;
@@ -279,11 +280,13 @@ static void plic_irq_enable_set_state(uint32_t irq, bool enable)
279280 */
280281void riscv_plic_irq_enable (uint32_t irq )
281282{
282- uint32_t key = irq_lock ();
283+ const struct device * dev = get_plic_dev_from_irq (irq );
284+ struct plic_data * data = dev -> data ;
285+ k_spinlock_key_t key = k_spin_lock (& data -> lock );
283286
284287 plic_irq_enable_set_state (irq , true);
285288
286- irq_unlock ( key );
289+ k_spin_unlock ( & data -> lock , key );
287290}
288291
289292/**
@@ -298,47 +301,58 @@ void riscv_plic_irq_enable(uint32_t irq)
298301 */
299302void riscv_plic_irq_disable (uint32_t irq )
300303{
301- uint32_t key = irq_lock ();
304+ const struct device * dev = get_plic_dev_from_irq (irq );
305+ struct plic_data * data = dev -> data ;
306+ k_spinlock_key_t key = k_spin_lock (& data -> lock );
302307
303308 plic_irq_enable_set_state (irq , false);
304309
305- irq_unlock ( key );
310+ k_spin_unlock ( & data -> lock , key );
306311}
307312
308- /**
309- * @brief Check if a riscv PLIC-specific interrupt line is enabled
310- *
311- * This routine checks if a RISCV PLIC-specific interrupt line is enabled.
312- * @param irq IRQ number to check
313- *
314- * @return 1 or 0
315- */
316- int riscv_plic_irq_is_enabled (uint32_t irq )
313+ /* Check if the local IRQ of a PLIC instance is enabled */
314+ static int local_irq_is_enabled (const struct device * dev , uint32_t local_irq )
317315{
318- const struct device * dev = get_plic_dev_from_irq (irq );
319- const uint32_t local_irq = irq_from_level_2 (irq );
320316 uint32_t bit_position = local_irq & PLIC_REG_MASK ;
321- uint32_t en_value ;
322317 int is_enabled = IS_ENABLED (CONFIG_PLIC_IRQ_AFFINITY ) ? 0 : 1 ;
323- uint32_t key = irq_lock ();
324318
325319 for (uint32_t cpu_num = 0 ; cpu_num < arch_num_cpus (); cpu_num ++ ) {
326320 mem_addr_t en_addr =
327321 get_context_en_addr (dev , cpu_num ) + local_irq_to_reg_offset (local_irq );
322+ uint32_t en_value = sys_read32 (en_addr );
328323
329- en_value = sys_read32 (en_addr );
330324 if (IS_ENABLED (CONFIG_PLIC_IRQ_AFFINITY )) {
331325 is_enabled |= !!(en_value & BIT (bit_position ));
332326 } else {
333327 is_enabled &= !!(en_value & BIT (bit_position ));
334328 }
335329 }
336330
337- irq_unlock (key );
338-
339331 return is_enabled ;
340332}
341333
334+ /**
335+ * @brief Check if a riscv PLIC-specific interrupt line is enabled
336+ *
337+ * This routine checks if a RISCV PLIC-specific interrupt line is enabled.
338+ * @param irq IRQ number to check
339+ *
340+ * @return 1 or 0
341+ */
342+ int riscv_plic_irq_is_enabled (uint32_t irq )
343+ {
344+ const struct device * dev = get_plic_dev_from_irq (irq );
345+ struct plic_data * data = dev -> data ;
346+ const uint32_t local_irq = irq_from_level_2 (irq );
347+ int ret = 0 ;
348+
349+ K_SPINLOCK (& data -> lock ) {
350+ ret = local_irq_is_enabled (dev , local_irq );
351+ }
352+
353+ return ret ;
354+ }
355+
342356/**
343357 * @brief Set priority of a riscv PLIC-specific interrupt line
344358 *
@@ -413,9 +427,10 @@ const struct device *riscv_plic_get_dev(void)
413427int riscv_plic_irq_set_affinity (uint32_t irq , uint32_t cpumask )
414428{
415429 const struct device * dev = get_plic_dev_from_irq (irq );
416- const struct plic_data * data = dev -> data ;
430+ struct plic_data * data = dev -> data ;
417431 __maybe_unused const struct plic_config * config = dev -> config ;
418432 const uint32_t local_irq = irq_from_level_2 (irq );
433+ k_spinlock_key_t key ;
419434
420435 if (local_irq >= config -> nr_irqs ) {
421436 __ASSERT (false, "overflow: irq %d, local_irq %d" , irq , local_irq );
@@ -427,17 +442,15 @@ int riscv_plic_irq_set_affinity(uint32_t irq, uint32_t cpumask)
427442 return - EINVAL ;
428443 }
429444
430- uint32_t key = irq_lock ();
431-
445+ key = k_spin_lock (& data -> lock );
432446 /* Updated irq_cpumask for next time setting plic enable register */
433447 data -> irq_cpumask [local_irq ] = (plic_cpumask_t )cpumask ;
434448
435449 /* If irq is enabled, apply the new irq affinity */
436- if (riscv_plic_irq_is_enabled ( irq )) {
437- riscv_plic_irq_enable (irq );
450+ if (local_irq_is_enabled ( dev , local_irq )) {
451+ plic_irq_enable_set_state (irq , true );
438452 }
439-
440- irq_unlock (key );
453+ k_spin_unlock (& data -> lock , key );
441454
442455 return 0 ;
443456}
0 commit comments