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
12static 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(irq: virq, data: bus);
18 irq_set_chip(irq: virq, chip: &bus->irq_chip);
19 irq_set_nested_thread(irq: virq, nest: 1);
20 irq_set_noprobe(irq: virq);
21
22 return 0;
23}
24
25static const struct irq_domain_ops sdw_domain_ops = {
26 .map = sdw_irq_map,
27};
28
29int sdw_irq_create(struct sdw_bus *bus,
30 struct fwnode_handle *fwnode)
31{
32 bus->irq_chip.name = dev_name(dev: bus->dev);
33
34 bus->domain = irq_domain_create_linear(fwnode, SDW_MAX_DEVICES,
35 ops: &sdw_domain_ops, host_data: 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
44void sdw_irq_delete(struct sdw_bus *bus)
45{
46 irq_domain_remove(host: bus->domain);
47}
48
49void sdw_irq_create_mapping(struct sdw_slave *slave)
50{
51 slave->irq = irq_create_mapping(host: slave->bus->domain, hwirq: slave->dev_num);
52 if (!slave->irq)
53 dev_warn(&slave->dev, "Failed to map IRQ\n");
54}
55
56void sdw_irq_dispose_mapping(struct sdw_slave *slave)
57{
58 irq_dispose_mapping(virq: irq_find_mapping(domain: slave->bus->domain, hwirq: slave->dev_num));
59}
60

source code of linux/drivers/soundwire/irq.c