irq-riscv-imsic-state.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2021 Western Digital Corporation or its affiliates.
  4. * Copyright (C) 2022 Ventana Micro Systems Inc.
  5. */
  6. #ifndef _IRQ_RISCV_IMSIC_STATE_H
  7. #define _IRQ_RISCV_IMSIC_STATE_H
  8. #include <linux/irqchip/riscv-imsic.h>
  9. #include <linux/irqdomain.h>
  10. #include <linux/fwnode.h>
  11. #include <linux/timer.h>
  12. #define IMSIC_IPI_ID 1
  13. #define IMSIC_NR_IPI 8
  14. struct imsic_vector {
  15. /* Fixed details of the vector */
  16. unsigned int cpu;
  17. unsigned int local_id;
  18. /* Details saved by driver in the vector */
  19. unsigned int hwirq;
  20. /* Details accessed using local lock held */
  21. bool enable;
  22. struct imsic_vector *move_next;
  23. struct imsic_vector *move_prev;
  24. };
  25. struct imsic_local_priv {
  26. /* Local lock to protect vector enable/move variables and dirty bitmap */
  27. raw_spinlock_t lock;
  28. /* Local dirty bitmap for synchronization */
  29. unsigned long *dirty_bitmap;
  30. #ifdef CONFIG_SMP
  31. /* Local timer for synchronization */
  32. struct timer_list timer;
  33. #endif
  34. /* Local vector table */
  35. struct imsic_vector *vectors;
  36. };
  37. struct imsic_priv {
  38. /* Device details */
  39. struct fwnode_handle *fwnode;
  40. /* Global configuration common for all HARTs */
  41. struct imsic_global_config global;
  42. /* Per-CPU state */
  43. struct imsic_local_priv __percpu *lpriv;
  44. /* State of IRQ matrix allocator */
  45. raw_spinlock_t matrix_lock;
  46. struct irq_matrix *matrix;
  47. /* IRQ domains (created by platform driver) */
  48. struct irq_domain *base_domain;
  49. };
  50. extern struct imsic_priv *imsic;
  51. void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val);
  52. static inline void __imsic_id_set_enable(unsigned long id)
  53. {
  54. __imsic_eix_update(id, 1, false, true);
  55. }
  56. static inline void __imsic_id_clear_enable(unsigned long id)
  57. {
  58. __imsic_eix_update(id, 1, false, false);
  59. }
  60. void imsic_local_sync_all(bool force_all);
  61. void imsic_local_delivery(bool enable);
  62. void imsic_vector_mask(struct imsic_vector *vec);
  63. void imsic_vector_unmask(struct imsic_vector *vec);
  64. static inline bool imsic_vector_isenabled(struct imsic_vector *vec)
  65. {
  66. return READ_ONCE(vec->enable);
  67. }
  68. static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec)
  69. {
  70. return READ_ONCE(vec->move_prev);
  71. }
  72. void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec);
  73. struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id);
  74. struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask);
  75. void imsic_vector_free(struct imsic_vector *vector);
  76. void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind);
  77. void imsic_vector_debug_show_summary(struct seq_file *m, int ind);
  78. void imsic_state_online(void);
  79. void imsic_state_offline(void);
  80. int imsic_setup_state(struct fwnode_handle *fwnode, void *opaque);
  81. int imsic_irqdomain_init(void);
  82. #endif