Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Common definitions across all variants of ICP and ICS interrupt
0004  * controllers.
0005  */
0006 
0007 #ifndef _XICS_H
0008 #define _XICS_H
0009 
0010 #include <linux/interrupt.h>
0011 
0012 #define XICS_IPI        2
0013 #define XICS_IRQ_SPURIOUS   0
0014 
0015 /* Want a priority other than 0.  Various HW issues require this. */
0016 #define DEFAULT_PRIORITY    5
0017 
0018 /*
0019  * Mark IPIs as higher priority so we can take them inside interrupts
0020  * FIXME: still true now?
0021  */
0022 #define IPI_PRIORITY        4
0023 
0024 /* The least favored priority */
0025 #define LOWEST_PRIORITY     0xFF
0026 
0027 /* The number of priorities defined above */
0028 #define MAX_NUM_PRIORITIES  3
0029 
0030 /* Native ICP */
0031 #ifdef CONFIG_PPC_ICP_NATIVE
0032 extern int icp_native_init(void);
0033 extern void icp_native_flush_interrupt(void);
0034 extern void icp_native_cause_ipi_rm(int cpu);
0035 #else
0036 static inline int icp_native_init(void) { return -ENODEV; }
0037 #endif
0038 
0039 /* PAPR ICP */
0040 #ifdef CONFIG_PPC_ICP_HV
0041 int __init icp_hv_init(void);
0042 #else
0043 static inline int icp_hv_init(void) { return -ENODEV; }
0044 #endif
0045 
0046 #ifdef CONFIG_PPC_POWERNV
0047 int __init icp_opal_init(void);
0048 extern void icp_opal_flush_interrupt(void);
0049 #else
0050 static inline int icp_opal_init(void) { return -ENODEV; }
0051 #endif
0052 
0053 /* ICP ops */
0054 struct icp_ops {
0055     unsigned int (*get_irq)(void);
0056     void (*eoi)(struct irq_data *d);
0057     void (*set_priority)(unsigned char prio);
0058     void (*teardown_cpu)(void);
0059     void (*flush_ipi)(void);
0060 #ifdef CONFIG_SMP
0061     void (*cause_ipi)(int cpu);
0062     irq_handler_t ipi_action;
0063 #endif
0064 };
0065 
0066 extern const struct icp_ops *icp_ops;
0067 
0068 #ifdef CONFIG_PPC_ICS_NATIVE
0069 /* Native ICS */
0070 extern int ics_native_init(void);
0071 #else
0072 static inline int ics_native_init(void) { return -ENODEV; }
0073 #endif
0074 
0075 /* RTAS ICS */
0076 #ifdef CONFIG_PPC_ICS_RTAS
0077 extern int ics_rtas_init(void);
0078 #else
0079 static inline int ics_rtas_init(void) { return -ENODEV; }
0080 #endif
0081 
0082 /* HAL ICS */
0083 #ifdef CONFIG_PPC_POWERNV
0084 extern int ics_opal_init(void);
0085 #else
0086 static inline int ics_opal_init(void) { return -ENODEV; }
0087 #endif
0088 
0089 /* ICS instance, hooked up to chip_data of an irq */
0090 struct ics {
0091     struct list_head link;
0092     int (*check)(struct ics *ics, unsigned int hwirq);
0093     void (*mask_unknown)(struct ics *ics, unsigned long vec);
0094     long (*get_server)(struct ics *ics, unsigned long vec);
0095     int (*host_match)(struct ics *ics, struct device_node *node);
0096     struct irq_chip *chip;
0097     char data[];
0098 };
0099 
0100 /* Commons */
0101 extern unsigned int xics_default_server;
0102 extern unsigned int xics_default_distrib_server;
0103 extern unsigned int xics_interrupt_server_size;
0104 extern struct irq_domain *xics_host;
0105 
0106 struct xics_cppr {
0107     unsigned char stack[MAX_NUM_PRIORITIES];
0108     int index;
0109 };
0110 
0111 DECLARE_PER_CPU(struct xics_cppr, xics_cppr);
0112 
0113 static inline void xics_push_cppr(unsigned int vec)
0114 {
0115     struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
0116 
0117     if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
0118         return;
0119 
0120     if (vec == XICS_IPI)
0121         os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
0122     else
0123         os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
0124 }
0125 
0126 static inline unsigned char xics_pop_cppr(void)
0127 {
0128     struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
0129 
0130     if (WARN_ON(os_cppr->index < 1))
0131         return LOWEST_PRIORITY;
0132 
0133     return os_cppr->stack[--os_cppr->index];
0134 }
0135 
0136 static inline void xics_set_base_cppr(unsigned char cppr)
0137 {
0138     struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
0139 
0140     /* we only really want to set the priority when there's
0141      * just one cppr value on the stack
0142      */
0143     WARN_ON(os_cppr->index != 0);
0144 
0145     os_cppr->stack[0] = cppr;
0146 }
0147 
0148 static inline unsigned char xics_cppr_top(void)
0149 {
0150     struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
0151     
0152     return os_cppr->stack[os_cppr->index];
0153 }
0154 
0155 DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
0156 
0157 extern void xics_init(void);
0158 extern void xics_setup_cpu(void);
0159 extern void xics_update_irq_servers(void);
0160 extern void xics_set_cpu_giq(unsigned int gserver, unsigned int join);
0161 extern void xics_mask_unknown_vec(unsigned int vec);
0162 extern irqreturn_t xics_ipi_dispatch(int cpu);
0163 extern void xics_smp_probe(void);
0164 extern void xics_register_ics(struct ics *ics);
0165 extern void xics_teardown_cpu(void);
0166 extern void xics_kexec_teardown_cpu(int secondary);
0167 extern void xics_migrate_irqs_away(void);
0168 extern void icp_native_eoi(struct irq_data *d);
0169 extern int xics_set_irq_type(struct irq_data *d, unsigned int flow_type);
0170 extern int xics_retrigger(struct irq_data *data);
0171 #ifdef CONFIG_SMP
0172 extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
0173                    unsigned int strict_check);
0174 #else
0175 #define xics_get_irq_server(virq, cpumask, strict_check) (xics_default_server)
0176 #endif
0177 
0178 
0179 #endif /* _XICS_H */