提交 7d01c880 编写于 作者: S Stephen Rothwell

powerpc: iSeries has only 256 IRQs

The iSeries Hypervisor only allows us to specify IRQ numbers up to 255 (it
has a u8 field to pass it in).  This patch allows platforms to specify a
maximum to the virtual IRQ numbers we will use and has iSeries set that
to 255.  If not set, the maximum is NR_IRQS - 1 (as before).
Signed-off-by: NStephen Rothwell <sfr@canb.auug.org.au>
上级 6246b612
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -272,18 +272,26 @@ unsigned int virt_irq_to_real_map[NR_IRQS];
* Don't use virtual irqs 0, 1, 2 for devices.
* The pcnet32 driver considers interrupt numbers < 2 to be invalid,
* and 2 is the XICS IPI interrupt.
* We limit virtual irqs to 17 less than NR_IRQS so that when we
* offset them by 16 (to reserve the first 16 for ISA interrupts)
* we don't end up with an interrupt number >= NR_IRQS.
* We limit virtual irqs to __irq_offet_value less than virt_irq_max so
* that when we offset them we don't end up with an interrupt
* number >= virt_irq_max.
*/
#define MIN_VIRT_IRQ 3
#define MAX_VIRT_IRQ (NR_IRQS - NUM_ISA_INTERRUPTS - 1)
#define NR_VIRT_IRQS (MAX_VIRT_IRQ - MIN_VIRT_IRQ + 1)
unsigned int virt_irq_max;
static unsigned int max_virt_irq;
static unsigned int nr_virt_irqs;
void
virt_irq_init(void)
{
int i;
if ((virt_irq_max == 0) || (virt_irq_max > (NR_IRQS - 1)))
virt_irq_max = NR_IRQS - 1;
max_virt_irq = virt_irq_max - __irq_offset_value;
nr_virt_irqs = max_virt_irq - MIN_VIRT_IRQ + 1;
for (i = 0; i < NR_IRQS; i++)
virt_irq_to_real_map[i] = UNDEFINED_IRQ;
}
......@@ -308,17 +316,17 @@ int virt_irq_create_mapping(unsigned int real_irq)
return real_irq;
}
/* map to a number between MIN_VIRT_IRQ and MAX_VIRT_IRQ */
/* map to a number between MIN_VIRT_IRQ and max_virt_irq */
virq = real_irq;
if (virq > MAX_VIRT_IRQ)
virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ;
if (virq > max_virt_irq)
virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ;
/* search for this number or a free slot */
first_virq = virq;
while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) {
if (virt_irq_to_real_map[virq] == real_irq)
return virq;
if (++virq > MAX_VIRT_IRQ)
if (++virq > max_virt_irq)
virq = MIN_VIRT_IRQ;
if (virq == first_virq)
goto nospace; /* oops, no free slots */
......@@ -330,8 +338,8 @@ int virt_irq_create_mapping(unsigned int real_irq)
nospace:
if (!warned) {
printk(KERN_CRIT "Interrupt table is full\n");
printk(KERN_CRIT "Increase NR_IRQS (currently %d) "
"in your kernel sources and rebuild.\n", NR_IRQS);
printk(KERN_CRIT "Increase virt_irq_max (currently %d) "
"in your kernel sources and rebuild.\n", virt_irq_max);
warned = 1;
}
return NO_IRQ;
......@@ -349,8 +357,8 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
virq = real_irq;
if (virq > MAX_VIRT_IRQ)
virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ;
if (virq > max_virt_irq)
virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ;
first_virq = virq;
......@@ -360,7 +368,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
virq++;
if (virq >= MAX_VIRT_IRQ)
if (virq >= max_virt_irq)
virq = 0;
} while (first_virq != virq);
......
......@@ -54,6 +54,7 @@
#include <asm/iseries/hv_lp_event.h>
#include <asm/iseries/lpar_map.h>
#include <asm/udbg.h>
#include <asm/irq.h>
#include "naca.h"
#include "setup.h"
......@@ -684,6 +685,12 @@ static int __init iseries_probe(void)
powerpc_firmware_features |= FW_FEATURE_ISERIES;
powerpc_firmware_features |= FW_FEATURE_LPAR;
/*
* The Hypervisor only allows us up to 256 interrupt
* sources (the irq number is passed in a u8).
*/
virt_irq_max = 255;
return 1;
}
......
......@@ -54,6 +54,13 @@
*/
extern unsigned int virt_irq_to_real_map[NR_IRQS];
/* The maximum virtual IRQ number that we support. This
* can be set by the platform and will be reduced by the
* value of __irq_offset_value. It defaults to and is
* capped by (NR_IRQS - 1).
*/
extern unsigned int virt_irq_max;
/* Create a mapping for a real_irq if it doesn't already exist.
* Return the virtual irq as a convenience.
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部