/* * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2022-08-24 GuEe-GUI first version */ #ifndef __PIC_H__ #define __PIC_H__ #include #include #include #include struct rt_pci_msi_desc; struct rt_pci_msi_msg; struct rt_pic_ops; struct rt_pic_irq; struct rt_pic { /* * Other IC is not implemented with PIC but rt_device/object, we need to * identify with this object: * * struct rt_ic_XYZ_device * { * struct rt_device parent; * struct rt_pic pic; * ... * }; */ struct rt_object parent; rt_list_t list; struct rt_pic_ops *ops; void *priv_data; void *user_data; int irq_start; rt_size_t irq_nr; struct rt_pic_irq *pirqs; }; struct rt_pic_ops { const char *name; rt_err_t (*irq_init)(struct rt_pic *pic); rt_err_t (*irq_finit)(struct rt_pic *pic); void (*irq_enable)(struct rt_pic_irq *pirq); void (*irq_disable)(struct rt_pic_irq *pirq); void (*irq_ack)(struct rt_pic_irq *pirq); void (*irq_mask)(struct rt_pic_irq *pirq); void (*irq_unmask)(struct rt_pic_irq *pirq); void (*irq_eoi)(struct rt_pic_irq *pirq); rt_err_t (*irq_set_priority)(struct rt_pic_irq *pirq, rt_uint32_t priority); rt_err_t (*irq_set_affinity)(struct rt_pic_irq *pirq, rt_bitmap_t *affinity); rt_err_t (*irq_set_triger_mode)(struct rt_pic_irq *pirq, rt_uint32_t mode); void (*irq_send_ipi)(struct rt_pic_irq *pirq, rt_bitmap_t *cpumask); void (*irq_compose_msi_msg)(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg); void (*irq_write_msi_msg)(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg); int (*irq_alloc_msi)(struct rt_pic *pic, struct rt_pci_msi_desc *msi_desc); void (*irq_free_msi)(struct rt_pic *pic, int irq); int (*irq_map)(struct rt_pic *pic, int hwirq, rt_uint32_t mode); rt_err_t (*irq_parse)(struct rt_pic *pic, struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq); #define RT_PIC_F_IRQ_ROUTING RT_BIT(0) /* Routing ISR when cascade */ rt_ubase_t flags; }; struct rt_pic_isr { rt_list_t list; #define RT_IRQ_F_NONE 0 int flags; struct rt_irq_desc action; }; struct rt_pic_irq { int irq; int hwirq; #define RT_IRQ_MODE_NONE 0 #define RT_IRQ_MODE_EDGE_RISING 1 #define RT_IRQ_MODE_EDGE_FALLING 2 #define RT_IRQ_MODE_EDGE_BOTH (RT_IRQ_MODE_EDGE_FALLING | RT_IRQ_MODE_EDGE_RISING) #define RT_IRQ_MODE_LEVEL_HIGH 4 #define RT_IRQ_MODE_LEVEL_LOW 8 #define RT_IRQ_MODE_LEVEL_MASK (RT_IRQ_MODE_LEVEL_LOW | RT_IRQ_MODE_LEVEL_HIGH) #define RT_IRQ_MODE_MASK 0xf rt_uint32_t mode; rt_uint32_t priority; RT_BITMAP_DECLARE(affinity, RT_CPUS_NR); rt_list_t list; rt_list_t children_nodes; struct rt_pci_msi_desc *msi_desc; struct rt_pic_isr isr; struct rt_spinlock rw_lock; struct rt_pic *pic; struct rt_pic_irq *parent; }; void rt_pic_default_name(struct rt_pic *pic); struct rt_pic *rt_pic_dynamic_cast(void *ptr); rt_err_t rt_pic_linear_irq(struct rt_pic *pic, rt_size_t irq_nr); int rt_pic_config_ipi(struct rt_pic *pic, int ipi_index, int hwirq); int rt_pic_config_irq(struct rt_pic *pic, int irq_index, int hwirq); rt_inline struct rt_pic_irq *rt_pic_find_irq(struct rt_pic *pic, int irq_index) { /* This is a quickly interface */ RT_ASSERT(pic != RT_NULL); RT_ASSERT(pic->pirqs != RT_NULL); RT_ASSERT(irq_index < pic->irq_nr); return &pic->pirqs[irq_index]; } struct rt_pic_irq *rt_pic_find_ipi(struct rt_pic *pic, int ipi_index); struct rt_pic_irq *rt_pic_find_pirq(struct rt_pic *pic, int irq); rt_err_t rt_pic_cascade(struct rt_pic_irq *pirq, int parent_irq); rt_err_t rt_pic_uncascade(struct rt_pic_irq *pirq); rt_err_t rt_pic_attach_irq(int irq, rt_isr_handler_t handler, void *uid, const char *name, int flags); rt_err_t rt_pic_detach_irq(int irq, void *uid); rt_err_t rt_pic_add_traps(rt_bool_t (*handler)(void *), void *data); rt_err_t rt_pic_do_traps(void); rt_err_t rt_pic_handle_isr(struct rt_pic_irq *pirq); /* User-implemented extensions */ rt_err_t rt_pic_user_extends(struct rt_pic *pic); rt_err_t rt_pic_irq_init(void); rt_err_t rt_pic_irq_finit(void); void rt_pic_irq_enable(int irq); void rt_pic_irq_disable(int irq); void rt_pic_irq_ack(int irq); void rt_pic_irq_mask(int irq); void rt_pic_irq_unmask(int irq); void rt_pic_irq_eoi(int irq); rt_err_t rt_pic_irq_set_priority(int irq, rt_uint32_t priority); rt_uint32_t rt_pic_irq_get_priority(int irq); rt_err_t rt_pic_irq_set_affinity(int irq, rt_bitmap_t *affinity); rt_err_t rt_pic_irq_get_affinity(int irq, rt_bitmap_t *out_affinity); rt_err_t rt_pic_irq_set_triger_mode(int irq, rt_uint32_t mode); rt_uint32_t rt_pic_irq_get_triger_mode(int irq); void rt_pic_irq_send_ipi(int irq, rt_bitmap_t *cpumask); void rt_pic_irq_parent_enable(struct rt_pic_irq *pirq); void rt_pic_irq_parent_disable(struct rt_pic_irq *pirq); void rt_pic_irq_parent_ack(struct rt_pic_irq *pirq); void rt_pic_irq_parent_mask(struct rt_pic_irq *pirq); void rt_pic_irq_parent_unmask(struct rt_pic_irq *pirq); void rt_pic_irq_parent_eoi(struct rt_pic_irq *pirq); rt_err_t rt_pic_irq_parent_set_priority(struct rt_pic_irq *pirq, rt_uint32_t priority); rt_err_t rt_pic_irq_parent_set_affinity(struct rt_pic_irq *pirq, rt_bitmap_t *affinity); rt_err_t rt_pic_irq_parent_set_triger_mode(struct rt_pic_irq *pirq, rt_uint32_t mode); #define RT_PIC_OFW_DECLARE(name, ids, handler) RT_OFW_STUB_EXPORT(name, ids, pic, handler) rt_err_t rt_pic_init(void); #endif /* __PIC_H__ */