irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state

Allow the pending state of an LPI to be set or cleared via
irq_set_irqchip_state.

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

+78
+78
drivers/irqchip/irq-gic-v3-its.c
··· 167 167 struct { 168 168 struct its_device *dev; 169 169 u32 event_id; 170 + } its_clear_cmd; 171 + 172 + struct { 173 + struct its_device *dev; 174 + u32 event_id; 170 175 } its_int_cmd; 171 176 172 177 struct { ··· 385 380 return col; 386 381 } 387 382 383 + static struct its_collection *its_build_int_cmd(struct its_cmd_block *cmd, 384 + struct its_cmd_desc *desc) 385 + { 386 + struct its_collection *col; 387 + 388 + col = dev_event_to_col(desc->its_int_cmd.dev, 389 + desc->its_int_cmd.event_id); 390 + 391 + its_encode_cmd(cmd, GITS_CMD_INT); 392 + its_encode_devid(cmd, desc->its_int_cmd.dev->device_id); 393 + its_encode_event_id(cmd, desc->its_int_cmd.event_id); 394 + 395 + its_fixup_cmd(cmd); 396 + 397 + return col; 398 + } 399 + 400 + static struct its_collection *its_build_clear_cmd(struct its_cmd_block *cmd, 401 + struct its_cmd_desc *desc) 402 + { 403 + struct its_collection *col; 404 + 405 + col = dev_event_to_col(desc->its_clear_cmd.dev, 406 + desc->its_clear_cmd.event_id); 407 + 408 + its_encode_cmd(cmd, GITS_CMD_CLEAR); 409 + its_encode_devid(cmd, desc->its_clear_cmd.dev->device_id); 410 + its_encode_event_id(cmd, desc->its_clear_cmd.event_id); 411 + 412 + its_fixup_cmd(cmd); 413 + 414 + return col; 415 + } 416 + 388 417 static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd, 389 418 struct its_cmd_desc *desc) 390 419 { ··· 580 541 581 542 static BUILD_SINGLE_CMD_FUNC(its_send_single_command, its_cmd_builder_t, 582 543 struct its_collection, its_build_sync_cmd) 544 + 545 + static void its_send_int(struct its_device *dev, u32 event_id) 546 + { 547 + struct its_cmd_desc desc; 548 + 549 + desc.its_int_cmd.dev = dev; 550 + desc.its_int_cmd.event_id = event_id; 551 + 552 + its_send_single_command(dev->its, its_build_int_cmd, &desc); 553 + } 554 + 555 + static void its_send_clear(struct its_device *dev, u32 event_id) 556 + { 557 + struct its_cmd_desc desc; 558 + 559 + desc.its_clear_cmd.dev = dev; 560 + desc.its_clear_cmd.event_id = event_id; 561 + 562 + its_send_single_command(dev->its, its_build_clear_cmd, &desc); 563 + } 583 564 584 565 static void its_send_inv(struct its_device *dev, u32 event_id) 585 566 { ··· 767 708 iommu_dma_map_msi_msg(d->irq, msg); 768 709 } 769 710 711 + static int its_irq_set_irqchip_state(struct irq_data *d, 712 + enum irqchip_irq_state which, 713 + bool state) 714 + { 715 + struct its_device *its_dev = irq_data_get_irq_chip_data(d); 716 + u32 event = its_get_event_id(d); 717 + 718 + if (which != IRQCHIP_STATE_PENDING) 719 + return -EINVAL; 720 + 721 + if (state) 722 + its_send_int(its_dev, event); 723 + else 724 + its_send_clear(its_dev, event); 725 + 726 + return 0; 727 + } 728 + 770 729 static struct irq_chip its_irq_chip = { 771 730 .name = "ITS", 772 731 .irq_mask = its_mask_irq, ··· 792 715 .irq_eoi = irq_chip_eoi_parent, 793 716 .irq_set_affinity = its_set_affinity, 794 717 .irq_compose_msi_msg = its_irq_compose_msi_msg, 718 + .irq_set_irqchip_state = its_irq_set_irqchip_state, 795 719 }; 796 720 797 721 /*