Merge tag 'acpi-6.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[platform/kernel/linux-rpi.git] / drivers / soundwire / irq.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2023 Cirrus Logic, Inc. and
3 //                    Cirrus Logic International Semiconductor Ltd.
4
5 #include <linux/device.h>
6 #include <linux/fwnode.h>
7 #include <linux/irq.h>
8 #include <linux/irqdomain.h>
9 #include <linux/soundwire/sdw.h>
10 #include "irq.h"
11
12 static int sdw_irq_map(struct irq_domain *h, unsigned int virq,
13                        irq_hw_number_t hw)
14 {
15         struct sdw_bus *bus = h->host_data;
16
17         irq_set_chip_data(virq, bus);
18         irq_set_chip(virq, &bus->irq_chip);
19         irq_set_nested_thread(virq, 1);
20         irq_set_noprobe(virq);
21
22         return 0;
23 }
24
25 static const struct irq_domain_ops sdw_domain_ops = {
26         .map    = sdw_irq_map,
27 };
28
29 int sdw_irq_create(struct sdw_bus *bus,
30                    struct fwnode_handle *fwnode)
31 {
32         bus->irq_chip.name = dev_name(bus->dev);
33
34         bus->domain = irq_domain_create_linear(fwnode, SDW_MAX_DEVICES,
35                                                &sdw_domain_ops, bus);
36         if (!bus->domain) {
37                 dev_err(bus->dev, "Failed to add IRQ domain\n");
38                 return -EINVAL;
39         }
40
41         return 0;
42 }
43
44 void sdw_irq_delete(struct sdw_bus *bus)
45 {
46         irq_domain_remove(bus->domain);
47 }
48
49 void sdw_irq_create_mapping(struct sdw_slave *slave)
50 {
51         slave->irq = irq_create_mapping(slave->bus->domain, slave->dev_num);
52         if (!slave->irq)
53                 dev_warn(&slave->dev, "Failed to map IRQ\n");
54 }
55
56 void sdw_irq_dispose_mapping(struct sdw_slave *slave)
57 {
58         irq_dispose_mapping(irq_find_mapping(slave->bus->domain, slave->dev_num));
59 }