aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/manage.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r--kernel/irq/manage.c73
1 files changed, 66 insertions, 7 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index ef0bc02c3a70..73a2b786b5e9 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -115,12 +115,12 @@ EXPORT_SYMBOL(synchronize_irq);
115#ifdef CONFIG_SMP 115#ifdef CONFIG_SMP
116cpumask_var_t irq_default_affinity; 116cpumask_var_t irq_default_affinity;
117 117
118static int __irq_can_set_affinity(struct irq_desc *desc) 118static bool __irq_can_set_affinity(struct irq_desc *desc)
119{ 119{
120 if (!desc || !irqd_can_balance(&desc->irq_data) || 120 if (!desc || !irqd_can_balance(&desc->irq_data) ||
121 !desc->irq_data.chip || !desc->irq_data.chip->irq_set_affinity) 121 !desc->irq_data.chip || !desc->irq_data.chip->irq_set_affinity)
122 return 0; 122 return false;
123 return 1; 123 return true;
124} 124}
125 125
126/** 126/**
@@ -134,6 +134,21 @@ int irq_can_set_affinity(unsigned int irq)
134} 134}
135 135
136/** 136/**
137 * irq_can_set_affinity_usr - Check if affinity of a irq can be set from user space
138 * @irq: Interrupt to check
139 *
140 * Like irq_can_set_affinity() above, but additionally checks for the
141 * AFFINITY_MANAGED flag.
142 */
143bool irq_can_set_affinity_usr(unsigned int irq)
144{
145 struct irq_desc *desc = irq_to_desc(irq);
146
147 return __irq_can_set_affinity(desc) &&
148 !irqd_affinity_is_managed(&desc->irq_data);
149}
150
151/**
137 * irq_set_thread_affinity - Notify irq threads to adjust affinity 152 * irq_set_thread_affinity - Notify irq threads to adjust affinity
138 * @desc: irq descriptor which has affitnity changed 153 * @desc: irq descriptor which has affitnity changed
139 * 154 *
@@ -338,10 +353,11 @@ static int setup_affinity(struct irq_desc *desc, struct cpumask *mask)
338 return 0; 353 return 0;
339 354
340 /* 355 /*
341 * Preserve an userspace affinity setup, but make sure that 356 * Preserve the managed affinity setting and an userspace affinity
342 * one of the targets is online. 357 * setup, but make sure that one of the targets is online.
343 */ 358 */
344 if (irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) { 359 if (irqd_affinity_is_managed(&desc->irq_data) ||
360 irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) {
345 if (cpumask_intersects(desc->irq_common_data.affinity, 361 if (cpumask_intersects(desc->irq_common_data.affinity,
346 cpu_online_mask)) 362 cpu_online_mask))
347 set = desc->irq_common_data.affinity; 363 set = desc->irq_common_data.affinity;
@@ -1117,6 +1133,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
1117 new->irq = irq; 1133 new->irq = irq;
1118 1134
1119 /* 1135 /*
1136 * If the trigger type is not specified by the caller,
1137 * then use the default for this interrupt.
1138 */
1139 if (!(new->flags & IRQF_TRIGGER_MASK))
1140 new->flags |= irqd_get_trigger_type(&desc->irq_data);
1141
1142 /*
1120 * Check whether the interrupt nests into another interrupt 1143 * Check whether the interrupt nests into another interrupt
1121 * thread. 1144 * thread.
1122 */ 1145 */
@@ -1409,10 +1432,18 @@ int setup_irq(unsigned int irq, struct irqaction *act)
1409 1432
1410 if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc))) 1433 if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
1411 return -EINVAL; 1434 return -EINVAL;
1435
1436 retval = irq_chip_pm_get(&desc->irq_data);
1437 if (retval < 0)
1438 return retval;
1439
1412 chip_bus_lock(desc); 1440 chip_bus_lock(desc);
1413 retval = __setup_irq(irq, desc, act); 1441 retval = __setup_irq(irq, desc, act);
1414 chip_bus_sync_unlock(desc); 1442 chip_bus_sync_unlock(desc);
1415 1443
1444 if (retval)
1445 irq_chip_pm_put(&desc->irq_data);
1446
1416 return retval; 1447 return retval;
1417} 1448}
1418EXPORT_SYMBOL_GPL(setup_irq); 1449EXPORT_SYMBOL_GPL(setup_irq);
@@ -1506,6 +1537,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
1506 } 1537 }
1507 } 1538 }
1508 1539
1540 irq_chip_pm_put(&desc->irq_data);
1509 module_put(desc->owner); 1541 module_put(desc->owner);
1510 kfree(action->secondary); 1542 kfree(action->secondary);
1511 return action; 1543 return action;
@@ -1648,11 +1680,16 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
1648 action->name = devname; 1680 action->name = devname;
1649 action->dev_id = dev_id; 1681 action->dev_id = dev_id;
1650 1682
1683 retval = irq_chip_pm_get(&desc->irq_data);
1684 if (retval < 0)
1685 return retval;
1686
1651 chip_bus_lock(desc); 1687 chip_bus_lock(desc);
1652 retval = __setup_irq(irq, desc, action); 1688 retval = __setup_irq(irq, desc, action);
1653 chip_bus_sync_unlock(desc); 1689 chip_bus_sync_unlock(desc);
1654 1690
1655 if (retval) { 1691 if (retval) {
1692 irq_chip_pm_put(&desc->irq_data);
1656 kfree(action->secondary); 1693 kfree(action->secondary);
1657 kfree(action); 1694 kfree(action);
1658 } 1695 }
@@ -1730,7 +1767,14 @@ void enable_percpu_irq(unsigned int irq, unsigned int type)
1730 if (!desc) 1767 if (!desc)
1731 return; 1768 return;
1732 1769
1770 /*
1771 * If the trigger type is not specified by the caller, then
1772 * use the default for this interrupt.
1773 */
1733 type &= IRQ_TYPE_SENSE_MASK; 1774 type &= IRQ_TYPE_SENSE_MASK;
1775 if (type == IRQ_TYPE_NONE)
1776 type = irqd_get_trigger_type(&desc->irq_data);
1777
1734 if (type != IRQ_TYPE_NONE) { 1778 if (type != IRQ_TYPE_NONE) {
1735 int ret; 1779 int ret;
1736 1780
@@ -1822,6 +1866,7 @@ static struct irqaction *__free_percpu_irq(unsigned int irq, void __percpu *dev_
1822 1866
1823 unregister_handler_proc(irq, action); 1867 unregister_handler_proc(irq, action);
1824 1868
1869 irq_chip_pm_put(&desc->irq_data);
1825 module_put(desc->owner); 1870 module_put(desc->owner);
1826 return action; 1871 return action;
1827 1872
@@ -1884,10 +1929,18 @@ int setup_percpu_irq(unsigned int irq, struct irqaction *act)
1884 1929
1885 if (!desc || !irq_settings_is_per_cpu_devid(desc)) 1930 if (!desc || !irq_settings_is_per_cpu_devid(desc))
1886 return -EINVAL; 1931 return -EINVAL;
1932
1933 retval = irq_chip_pm_get(&desc->irq_data);
1934 if (retval < 0)
1935 return retval;
1936
1887 chip_bus_lock(desc); 1937 chip_bus_lock(desc);
1888 retval = __setup_irq(irq, desc, act); 1938 retval = __setup_irq(irq, desc, act);
1889 chip_bus_sync_unlock(desc); 1939 chip_bus_sync_unlock(desc);
1890 1940
1941 if (retval)
1942 irq_chip_pm_put(&desc->irq_data);
1943
1891 return retval; 1944 return retval;
1892} 1945}
1893 1946
@@ -1931,12 +1984,18 @@ int request_percpu_irq(unsigned int irq, irq_handler_t handler,
1931 action->name = devname; 1984 action->name = devname;
1932 action->percpu_dev_id = dev_id; 1985 action->percpu_dev_id = dev_id;
1933 1986
1987 retval = irq_chip_pm_get(&desc->irq_data);
1988 if (retval < 0)
1989 return retval;
1990
1934 chip_bus_lock(desc); 1991 chip_bus_lock(desc);
1935 retval = __setup_irq(irq, desc, action); 1992 retval = __setup_irq(irq, desc, action);
1936 chip_bus_sync_unlock(desc); 1993 chip_bus_sync_unlock(desc);
1937 1994
1938 if (retval) 1995 if (retval) {
1996 irq_chip_pm_put(&desc->irq_data);
1939 kfree(action); 1997 kfree(action);
1998 }
1940 1999
1941 return retval; 2000 return retval;
1942} 2001}