Skip to content

Commit e989424

Browse files
committed
genirq/msi: Remove platform MSI leftovers
No more users! Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Anna-Maria Behnsen <[email protected]> Signed-off-by: Shivamurthy Shastri <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Greg Kroah-Hartman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent ce44d1f commit e989424

File tree

3 files changed

+5
-450
lines changed

3 files changed

+5
-450
lines changed

drivers/base/platform-msi.c

Lines changed: 3 additions & 347 deletions
Original file line numberDiff line numberDiff line change
@@ -4,346 +4,12 @@
44
*
55
* Copyright (C) 2015 ARM Limited, All Rights Reserved.
66
* Author: Marc Zyngier <[email protected]>
7+
* Copyright (C) 2022 Linutronix GmbH
78
*/
89

910
#include <linux/device.h>
10-
#include <linux/idr.h>
11-
#include <linux/irq.h>
1211
#include <linux/irqdomain.h>
1312
#include <linux/msi.h>
14-
#include <linux/slab.h>
15-
16-
/* Begin of removal area. Once everything is converted over. Cleanup the includes too! */
17-
18-
#define DEV_ID_SHIFT 21
19-
#define MAX_DEV_MSIS (1 << (32 - DEV_ID_SHIFT))
20-
21-
/*
22-
* Internal data structure containing a (made up, but unique) devid
23-
* and the callback to write the MSI message.
24-
*/
25-
struct platform_msi_priv_data {
26-
struct device *dev;
27-
void *host_data;
28-
msi_alloc_info_t arg;
29-
irq_write_msi_msg_t write_msg;
30-
int devid;
31-
};
32-
33-
/* The devid allocator */
34-
static DEFINE_IDA(platform_msi_devid_ida);
35-
36-
#ifdef GENERIC_MSI_DOMAIN_OPS
37-
/*
38-
* Convert an msi_desc to a globaly unique identifier (per-device
39-
* devid + msi_desc position in the msi_list).
40-
*/
41-
static irq_hw_number_t platform_msi_calc_hwirq(struct msi_desc *desc)
42-
{
43-
u32 devid = desc->dev->msi.data->platform_data->devid;
44-
45-
return (devid << (32 - DEV_ID_SHIFT)) | desc->msi_index;
46-
}
47-
48-
static void platform_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
49-
{
50-
arg->desc = desc;
51-
arg->hwirq = platform_msi_calc_hwirq(desc);
52-
}
53-
54-
static int platform_msi_init(struct irq_domain *domain,
55-
struct msi_domain_info *info,
56-
unsigned int virq, irq_hw_number_t hwirq,
57-
msi_alloc_info_t *arg)
58-
{
59-
return irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
60-
info->chip, info->chip_data);
61-
}
62-
63-
static void platform_msi_set_proxy_dev(msi_alloc_info_t *arg)
64-
{
65-
arg->flags |= MSI_ALLOC_FLAGS_PROXY_DEVICE;
66-
}
67-
#else
68-
#define platform_msi_set_desc NULL
69-
#define platform_msi_init NULL
70-
#define platform_msi_set_proxy_dev(x) do {} while(0)
71-
#endif
72-
73-
static void platform_msi_update_dom_ops(struct msi_domain_info *info)
74-
{
75-
struct msi_domain_ops *ops = info->ops;
76-
77-
BUG_ON(!ops);
78-
79-
if (ops->msi_init == NULL)
80-
ops->msi_init = platform_msi_init;
81-
if (ops->set_desc == NULL)
82-
ops->set_desc = platform_msi_set_desc;
83-
}
84-
85-
static void platform_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
86-
{
87-
struct msi_desc *desc = irq_data_get_msi_desc(data);
88-
89-
desc->dev->msi.data->platform_data->write_msg(desc, msg);
90-
}
91-
92-
static void platform_msi_update_chip_ops(struct msi_domain_info *info)
93-
{
94-
struct irq_chip *chip = info->chip;
95-
96-
BUG_ON(!chip);
97-
if (!chip->irq_mask)
98-
chip->irq_mask = irq_chip_mask_parent;
99-
if (!chip->irq_unmask)
100-
chip->irq_unmask = irq_chip_unmask_parent;
101-
if (!chip->irq_eoi)
102-
chip->irq_eoi = irq_chip_eoi_parent;
103-
if (!chip->irq_set_affinity)
104-
chip->irq_set_affinity = msi_domain_set_affinity;
105-
if (!chip->irq_write_msi_msg)
106-
chip->irq_write_msi_msg = platform_msi_write_msg;
107-
if (WARN_ON((info->flags & MSI_FLAG_LEVEL_CAPABLE) &&
108-
!(chip->flags & IRQCHIP_SUPPORTS_LEVEL_MSI)))
109-
info->flags &= ~MSI_FLAG_LEVEL_CAPABLE;
110-
}
111-
112-
/**
113-
* platform_msi_create_irq_domain - Create a platform MSI interrupt domain
114-
* @fwnode: Optional fwnode of the interrupt controller
115-
* @info: MSI domain info
116-
* @parent: Parent irq domain
117-
*
118-
* Updates the domain and chip ops and creates a platform MSI
119-
* interrupt domain.
120-
*
121-
* Returns:
122-
* A domain pointer or NULL in case of failure.
123-
*/
124-
struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode,
125-
struct msi_domain_info *info,
126-
struct irq_domain *parent)
127-
{
128-
struct irq_domain *domain;
129-
130-
if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)
131-
platform_msi_update_dom_ops(info);
132-
if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
133-
platform_msi_update_chip_ops(info);
134-
info->flags |= MSI_FLAG_DEV_SYSFS | MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS |
135-
MSI_FLAG_FREE_MSI_DESCS;
136-
137-
domain = msi_create_irq_domain(fwnode, info, parent);
138-
if (domain)
139-
irq_domain_update_bus_token(domain, DOMAIN_BUS_PLATFORM_MSI);
140-
141-
return domain;
142-
}
143-
EXPORT_SYMBOL_GPL(platform_msi_create_irq_domain);
144-
145-
static int platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec,
146-
irq_write_msi_msg_t write_msi_msg)
147-
{
148-
struct platform_msi_priv_data *datap;
149-
int err;
150-
151-
/*
152-
* Limit the number of interrupts to 2048 per device. Should we
153-
* need to bump this up, DEV_ID_SHIFT should be adjusted
154-
* accordingly (which would impact the max number of MSI
155-
* capable devices).
156-
*/
157-
if (!dev->msi.domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
158-
return -EINVAL;
159-
160-
if (dev->msi.domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
161-
dev_err(dev, "Incompatible msi_domain, giving up\n");
162-
return -EINVAL;
163-
}
164-
165-
err = msi_setup_device_data(dev);
166-
if (err)
167-
return err;
168-
169-
/* Already initialized? */
170-
if (dev->msi.data->platform_data)
171-
return -EBUSY;
172-
173-
datap = kzalloc(sizeof(*datap), GFP_KERNEL);
174-
if (!datap)
175-
return -ENOMEM;
176-
177-
datap->devid = ida_alloc_max(&platform_msi_devid_ida,
178-
(1 << DEV_ID_SHIFT) - 1, GFP_KERNEL);
179-
if (datap->devid < 0) {
180-
err = datap->devid;
181-
kfree(datap);
182-
return err;
183-
}
184-
185-
datap->write_msg = write_msi_msg;
186-
datap->dev = dev;
187-
dev->msi.data->platform_data = datap;
188-
return 0;
189-
}
190-
191-
static void platform_msi_free_priv_data(struct device *dev)
192-
{
193-
struct platform_msi_priv_data *data = dev->msi.data->platform_data;
194-
195-
dev->msi.data->platform_data = NULL;
196-
ida_free(&platform_msi_devid_ida, data->devid);
197-
kfree(data);
198-
}
199-
200-
/**
201-
* platform_msi_domain_alloc_irqs - Allocate MSI interrupts for @dev
202-
* @dev: The device for which to allocate interrupts
203-
* @nvec: The number of interrupts to allocate
204-
* @write_msi_msg: Callback to write an interrupt message for @dev
205-
*
206-
* Returns:
207-
* Zero for success, or an error code in case of failure
208-
*/
209-
static int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
210-
irq_write_msi_msg_t write_msi_msg)
211-
{
212-
int err;
213-
214-
err = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
215-
if (err)
216-
return err;
217-
218-
err = msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, nvec - 1);
219-
if (err)
220-
platform_msi_free_priv_data(dev);
221-
222-
return err;
223-
}
224-
225-
/**
226-
* platform_msi_get_host_data - Query the private data associated with
227-
* a platform-msi domain
228-
* @domain: The platform-msi domain
229-
*
230-
* Return: The private data provided when calling
231-
* platform_msi_create_device_domain().
232-
*/
233-
void *platform_msi_get_host_data(struct irq_domain *domain)
234-
{
235-
struct platform_msi_priv_data *data = domain->host_data;
236-
237-
return data->host_data;
238-
}
239-
240-
static struct lock_class_key platform_device_msi_lock_class;
241-
242-
/**
243-
* __platform_msi_create_device_domain - Create a platform-msi device domain
244-
*
245-
* @dev: The device generating the MSIs
246-
* @nvec: The number of MSIs that need to be allocated
247-
* @is_tree: flag to indicate tree hierarchy
248-
* @write_msi_msg: Callback to write an interrupt message for @dev
249-
* @ops: The hierarchy domain operations to use
250-
* @host_data: Private data associated to this domain
251-
*
252-
* Return: An irqdomain for @nvec interrupts on success, NULL in case of error.
253-
*
254-
* This is for interrupt domains which stack on a platform-msi domain
255-
* created by platform_msi_create_irq_domain(). @dev->msi.domain points to
256-
* that platform-msi domain which is the parent for the new domain.
257-
*/
258-
struct irq_domain *
259-
__platform_msi_create_device_domain(struct device *dev,
260-
unsigned int nvec,
261-
bool is_tree,
262-
irq_write_msi_msg_t write_msi_msg,
263-
const struct irq_domain_ops *ops,
264-
void *host_data)
265-
{
266-
struct platform_msi_priv_data *data;
267-
struct irq_domain *domain;
268-
int err;
269-
270-
err = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
271-
if (err)
272-
return NULL;
273-
274-
/*
275-
* Use a separate lock class for the MSI descriptor mutex on
276-
* platform MSI device domains because the descriptor mutex nests
277-
* into the domain mutex. See alloc/free below.
278-
*/
279-
lockdep_set_class(&dev->msi.data->mutex, &platform_device_msi_lock_class);
280-
281-
data = dev->msi.data->platform_data;
282-
data->host_data = host_data;
283-
domain = irq_domain_create_hierarchy(dev->msi.domain, 0,
284-
is_tree ? 0 : nvec,
285-
dev->fwnode, ops, data);
286-
if (!domain)
287-
goto free_priv;
288-
289-
platform_msi_set_proxy_dev(&data->arg);
290-
err = msi_domain_prepare_irqs(domain->parent, dev, nvec, &data->arg);
291-
if (err)
292-
goto free_domain;
293-
294-
return domain;
295-
296-
free_domain:
297-
irq_domain_remove(domain);
298-
free_priv:
299-
platform_msi_free_priv_data(dev);
300-
return NULL;
301-
}
302-
303-
/**
304-
* platform_msi_device_domain_free - Free interrupts associated with a platform-msi
305-
* device domain
306-
*
307-
* @domain: The platform-msi device domain
308-
* @virq: The base irq from which to perform the free operation
309-
* @nr_irqs: How many interrupts to free from @virq
310-
*/
311-
void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int virq,
312-
unsigned int nr_irqs)
313-
{
314-
struct platform_msi_priv_data *data = domain->host_data;
315-
316-
msi_lock_descs(data->dev);
317-
msi_domain_depopulate_descs(data->dev, virq, nr_irqs);
318-
irq_domain_free_irqs_common(domain, virq, nr_irqs);
319-
msi_free_msi_descs_range(data->dev, virq, virq + nr_irqs - 1);
320-
msi_unlock_descs(data->dev);
321-
}
322-
323-
/**
324-
* platform_msi_device_domain_alloc - Allocate interrupts associated with
325-
* a platform-msi device domain
326-
*
327-
* @domain: The platform-msi device domain
328-
* @virq: The base irq from which to perform the allocate operation
329-
* @nr_irqs: How many interrupts to allocate from @virq
330-
*
331-
* Return 0 on success, or an error code on failure. Must be called
332-
* with irq_domain_mutex held (which can only be done as part of a
333-
* top-level interrupt allocation).
334-
*/
335-
int platform_msi_device_domain_alloc(struct irq_domain *domain, unsigned int virq,
336-
unsigned int nr_irqs)
337-
{
338-
struct platform_msi_priv_data *data = domain->host_data;
339-
struct device *dev = data->dev;
340-
341-
return msi_domain_populate_irqs(domain->parent, dev, virq, nr_irqs, &data->arg);
342-
}
343-
344-
/* End of removal area */
345-
346-
/* Real per device domain interfaces */
34713

34814
/*
34915
* This indirection can go when platform_device_msi_init_and_alloc_irqs()
@@ -357,7 +23,7 @@ static void platform_msi_write_msi_msg(struct irq_data *d, struct msi_msg *msg)
35723
cb(irq_data_get_msi_desc(d), msg);
35824
}
35925

360-
static void platform_msi_set_desc_byindex(msi_alloc_info_t *arg, struct msi_desc *desc)
26+
static void platform_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
36127
{
36228
arg->desc = desc;
36329
arg->hwirq = desc->msi_index;
@@ -373,7 +39,7 @@ static const struct msi_domain_template platform_msi_template = {
37339
},
37440

37541
.ops = {
376-
.set_desc = platform_msi_set_desc_byindex,
42+
.set_desc = platform_msi_set_desc,
37743
},
37844

37945
.info = {
@@ -408,10 +74,6 @@ int platform_device_msi_init_and_alloc_irqs(struct device *dev, unsigned int nve
40874
if (!domain || !write_msi_msg)
40975
return -EINVAL;
41076

411-
/* Migration support. Will go away once everything is converted */
412-
if (!irq_domain_is_msi_parent(domain))
413-
return platform_msi_domain_alloc_irqs(dev, nvec, write_msi_msg);
414-
41577
/*
41678
* @write_msi_msg is stored in the resulting msi_domain_info::data.
41779
* The underlying domain creation mechanism will assign that
@@ -432,12 +94,6 @@ EXPORT_SYMBOL_GPL(platform_device_msi_init_and_alloc_irqs);
43294
*/
43395
void platform_device_msi_free_irqs_all(struct device *dev)
43496
{
435-
struct irq_domain *domain = dev->msi.domain;
436-
43797
msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN);
438-
439-
/* Migration support. Will go away once everything is converted */
440-
if (!irq_domain_is_msi_parent(domain))
441-
platform_msi_free_priv_data(dev);
44298
}
44399
EXPORT_SYMBOL_GPL(platform_device_msi_free_irqs_all);

0 commit comments

Comments
 (0)