Lines Matching +full:level +full:- +full:high
1 // SPDX-License-Identifier: GPL-2.0
11 /* update the isr according to irq level and route irq to eiointc */
12 static void pch_pic_update_irq(struct loongarch_pch_pic *s, int irq, int level) in pch_pic_update_irq() argument
20 if (level) { in pch_pic_update_irq()
21 if (mask & s->irr & ~s->mask) { in pch_pic_update_irq()
22 s->isr |= mask; in pch_pic_update_irq()
23 irq = s->htmsi_vector[irq]; in pch_pic_update_irq()
24 eiointc_set_irq(s->kvm->arch.eiointc, irq, level); in pch_pic_update_irq()
27 if (mask & s->isr & ~s->irr) { in pch_pic_update_irq()
28 s->isr &= ~mask; in pch_pic_update_irq()
29 irq = s->htmsi_vector[irq]; in pch_pic_update_irq()
30 eiointc_set_irq(s->kvm->arch.eiointc, irq, level); in pch_pic_update_irq()
36 static void pch_pic_update_batch_irqs(struct loongarch_pch_pic *s, u64 irq_mask, int level) in pch_pic_update_batch_irqs() argument
44 pch_pic_update_irq(s, irq, level); in pch_pic_update_batch_irqs()
51 void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level) in pch_pic_set_irq() argument
55 spin_lock(&s->lock); in pch_pic_set_irq()
56 if (level) in pch_pic_set_irq()
57 s->irr |= mask; /* set irr */ in pch_pic_set_irq()
64 if (s->edge & mask) { in pch_pic_set_irq()
65 spin_unlock(&s->lock); in pch_pic_set_irq()
68 s->irr &= ~mask; in pch_pic_set_irq()
70 pch_pic_update_irq(s, irq, level); in pch_pic_set_irq()
71 spin_unlock(&s->lock); in pch_pic_set_irq()
75 void pch_msi_set_irq(struct kvm *kvm, int irq, int level) in pch_msi_set_irq() argument
77 eiointc_set_irq(kvm->arch.eiointc, irq, level); in pch_msi_set_irq()
81 * pch pic register is 64-bit, but it is accessed by 32-bit,
82 * so we use high to get whether low or high 32 bits we want
85 static u32 pch_pic_read_reg(u64 *s, int high) in pch_pic_read_reg() argument
89 /* read the high 32 bits when high is 1 */ in pch_pic_read_reg()
90 return high ? (u32)(val >> 32) : (u32)val; in pch_pic_read_reg()
94 * pch pic register is 64-bit, but it is accessed by 32-bit,
95 * so we use high to get whether low or high 32 bits we want
98 static u32 pch_pic_write_reg(u64 *s, int high, u32 v) in pch_pic_write_reg() argument
102 if (high) { in pch_pic_write_reg()
104 * Clear val high 32 bits in pch_pic_write_reg()
105 * Write the high 32 bits when the high is 1 in pch_pic_write_reg()
112 * Write the low 32 bits when the high is 0 in pch_pic_write_reg()
125 offset = addr - s->pch_pic_base; in loongarch_pch_pic_read()
127 spin_lock(&s->lock); in loongarch_pch_pic_read()
139 offset -= PCH_PIC_MASK_START; in loongarch_pch_pic_read()
142 data = pch_pic_read_reg(&s->mask, index); in loongarch_pch_pic_read()
146 offset -= PCH_PIC_HTMSI_EN_START; in loongarch_pch_pic_read()
149 data = pch_pic_read_reg(&s->htmsi_en, index); in loongarch_pch_pic_read()
153 offset -= PCH_PIC_EDGE_START; in loongarch_pch_pic_read()
156 data = pch_pic_read_reg(&s->edge, index); in loongarch_pch_pic_read()
169 offset -= PCH_PIC_HTMSI_VEC_START; in loongarch_pch_pic_read()
171 data = s->htmsi_vector[offset]; in loongarch_pch_pic_read()
175 /* we only use defalut value 0: high level triggered */ in loongarch_pch_pic_read()
179 ret = -EINVAL; in loongarch_pch_pic_read()
181 spin_unlock(&s->lock); in loongarch_pch_pic_read()
191 struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic; in kvm_pch_pic_read()
195 return -EINVAL; in kvm_pch_pic_read()
199 vcpu->kvm->stat.pch_pic_read_exits++; in kvm_pch_pic_read()
214 offset = addr - s->pch_pic_base; in loongarch_pch_pic_write()
216 spin_lock(&s->lock); in loongarch_pch_pic_write()
219 offset -= PCH_PIC_MASK_START; in loongarch_pch_pic_write()
220 /* get whether high or low 32 bits we want to write */ in loongarch_pch_pic_write()
222 old = pch_pic_write_reg(&s->mask, index, data); in loongarch_pch_pic_write()
231 offset -= PCH_PIC_HTMSI_EN_START; in loongarch_pch_pic_write()
233 pch_pic_write_reg(&s->htmsi_en, index, data); in loongarch_pch_pic_write()
236 offset -= PCH_PIC_EDGE_START; in loongarch_pch_pic_write()
238 /* 1: edge triggered, 0: level triggered */ in loongarch_pch_pic_write()
239 pch_pic_write_reg(&s->edge, index, data); in loongarch_pch_pic_write()
242 offset -= PCH_PIC_CLEAR_START; in loongarch_pch_pic_write()
245 old = pch_pic_read_reg(&s->irr, index); in loongarch_pch_pic_write()
250 irq = old & pch_pic_read_reg(&s->edge, index) & data; in loongarch_pch_pic_write()
252 pch_pic_write_reg(&s->irr, index, old & ~irq); in loongarch_pch_pic_write()
257 offset -= PCH_PIC_AUTO_CTRL0_START; in loongarch_pch_pic_write()
260 pch_pic_write_reg(&s->auto_ctrl0, index, 0); in loongarch_pch_pic_write()
263 offset -= PCH_PIC_AUTO_CTRL1_START; in loongarch_pch_pic_write()
266 pch_pic_write_reg(&s->auto_ctrl1, index, 0); in loongarch_pch_pic_write()
269 offset -= PCH_PIC_ROUTE_ENTRY_START; in loongarch_pch_pic_write()
271 s->route_entry[offset] = 1; in loongarch_pch_pic_write()
275 offset -= PCH_PIC_HTMSI_VEC_START; in loongarch_pch_pic_write()
276 s->htmsi_vector[offset] = (u8)data; in loongarch_pch_pic_write()
279 offset -= PCH_PIC_POLARITY_START; in loongarch_pch_pic_write()
281 /* we only use defalut value 0: high level triggered */ in loongarch_pch_pic_write()
282 pch_pic_write_reg(&s->polarity, index, 0); in loongarch_pch_pic_write()
285 ret = -EINVAL; in loongarch_pch_pic_write()
288 spin_unlock(&s->lock); in loongarch_pch_pic_write()
298 struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic; in kvm_pch_pic_write()
302 return -EINVAL; in kvm_pch_pic_write()
306 vcpu->kvm->stat.pch_pic_write_exits++; in kvm_pch_pic_write()
320 struct kvm *kvm = dev->kvm; in kvm_pch_pic_init()
322 struct loongarch_pch_pic *s = dev->kvm->arch.pch_pic; in kvm_pch_pic_init()
324 s->pch_pic_base = addr; in kvm_pch_pic_init()
325 device = &s->device; in kvm_pch_pic_init()
328 mutex_lock(&kvm->slots_lock); in kvm_pch_pic_init()
331 mutex_unlock(&kvm->slots_lock); in kvm_pch_pic_init()
333 return (ret < 0) ? -EFAULT : 0; in kvm_pch_pic_init()
346 s = dev->kvm->arch.pch_pic; in kvm_pch_pic_regs_access()
347 addr = attr->attr; in kvm_pch_pic_regs_access()
348 data = (void __user *)attr->addr; in kvm_pch_pic_regs_access()
353 p = &s->mask; in kvm_pch_pic_regs_access()
356 p = &s->htmsi_en; in kvm_pch_pic_regs_access()
359 p = &s->edge; in kvm_pch_pic_regs_access()
362 p = &s->auto_ctrl0; in kvm_pch_pic_regs_access()
365 p = &s->auto_ctrl1; in kvm_pch_pic_regs_access()
368 offset = addr - PCH_PIC_ROUTE_ENTRY_START; in kvm_pch_pic_regs_access()
369 p = &s->route_entry[offset]; in kvm_pch_pic_regs_access()
373 offset = addr - PCH_PIC_HTMSI_VEC_START; in kvm_pch_pic_regs_access()
374 p = &s->htmsi_vector[offset]; in kvm_pch_pic_regs_access()
378 p = &s->irr; in kvm_pch_pic_regs_access()
381 p = &s->isr; in kvm_pch_pic_regs_access()
384 p = &s->polarity; in kvm_pch_pic_regs_access()
387 return -EINVAL; in kvm_pch_pic_regs_access()
390 spin_lock(&s->lock); in kvm_pch_pic_regs_access()
394 ret = -EFAULT; in kvm_pch_pic_regs_access()
397 ret = -EFAULT; in kvm_pch_pic_regs_access()
399 spin_unlock(&s->lock); in kvm_pch_pic_regs_access()
407 switch (attr->group) { in kvm_pch_pic_get_attr()
411 return -EINVAL; in kvm_pch_pic_get_attr()
419 void __user *uaddr = (void __user *)(long)attr->addr; in kvm_pch_pic_set_attr()
421 switch (attr->group) { in kvm_pch_pic_set_attr()
423 switch (attr->attr) { in kvm_pch_pic_set_attr()
426 return -EFAULT; in kvm_pch_pic_set_attr()
428 if (!dev->kvm->arch.pch_pic) { in kvm_pch_pic_set_attr()
430 return -ENODEV; in kvm_pch_pic_set_attr()
435 kvm_err("%s: unknown group (%d) attr (%lld)\n", __func__, attr->group, in kvm_pch_pic_set_attr()
436 attr->attr); in kvm_pch_pic_set_attr()
437 return -EINVAL; in kvm_pch_pic_set_attr()
442 return -EINVAL; in kvm_pch_pic_set_attr()
454 return -ENOMEM; in kvm_setup_default_irq_routing()
471 struct kvm *kvm = dev->kvm; in kvm_pch_pic_create()
475 if (kvm->arch.pch_pic) in kvm_pch_pic_create()
476 return -EINVAL; in kvm_pch_pic_create()
480 return -ENOMEM; in kvm_pch_pic_create()
484 return -ENOMEM; in kvm_pch_pic_create()
486 spin_lock_init(&s->lock); in kvm_pch_pic_create()
487 s->kvm = kvm; in kvm_pch_pic_create()
488 kvm->arch.pch_pic = s; in kvm_pch_pic_create()
498 if (!dev || !dev->kvm || !dev->kvm->arch.pch_pic) in kvm_pch_pic_destroy()
501 kvm = dev->kvm; in kvm_pch_pic_destroy()
502 s = kvm->arch.pch_pic; in kvm_pch_pic_destroy()
504 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &s->device); in kvm_pch_pic_destroy()
509 .name = "kvm-loongarch-pch-pic",