Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2)  * Support for hardware-managed IRQ auto-distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  * Copyright (C) 2010  Paul Mundt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "internals.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static unsigned long dist_handle[INTC_NR_IRQS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) void intc_balancing_enable(unsigned int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) 	struct intc_desc_int *d = get_intc_desc(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) 	unsigned long handle = dist_handle[irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 	if (irq_balancing_disabled(irq) || !handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 	addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 	intc_reg_fns[_INTC_FN(handle)](addr, handle, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) void intc_balancing_disable(unsigned int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 	struct intc_desc_int *d = get_intc_desc(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 	unsigned long handle = dist_handle[irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 	if (irq_balancing_disabled(irq) || !handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 	addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 	intc_reg_fns[_INTC_FN(handle)](addr, handle, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static unsigned int intc_dist_data(struct intc_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 				   struct intc_desc_int *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 				   intc_enum enum_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 	struct intc_mask_reg *mr = desc->hw.mask_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 	unsigned int i, j, fn, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	unsigned long reg_e, reg_d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 	for (i = 0; mr && enum_id && i < desc->hw.nr_mask_regs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 		mr = desc->hw.mask_regs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 		 * Skip this entry if there's no auto-distribution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 		 * register associated with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 		if (!mr->dist_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 		for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 			if (mr->enum_ids[j] != enum_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 			fn = REG_FN_MODIFY_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 			mode = MODE_ENABLE_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 			reg_e = mr->dist_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 			reg_d = mr->dist_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 			fn += (mr->reg_width >> 3) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 			return _INTC_MK(fn, mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 					intc_get_reg(d, reg_e),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 					intc_get_reg(d, reg_d),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 					1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 					(mr->reg_width - 1) - j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 	 * It's possible we've gotten here with no distribution options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 	 * available for the IRQ in question, so we just skip over those.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) void intc_set_dist_handle(unsigned int irq, struct intc_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 			  struct intc_desc_int *d, intc_enum id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 	 * Nothing to do for this IRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 	if (!desc->hw.mask_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) 	raw_spin_lock_irqsave(&intc_big_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 	dist_handle[irq] = intc_dist_data(desc, d, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 	raw_spin_unlock_irqrestore(&intc_big_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }