Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 175855
b: refs/heads/master
c: 49bd364
h: refs/heads/master
i:
  175853: 3dc6bde
  175851: a7d9c0a
  175847: 0f8b269
  175839: 31de0ed
v: v3
  • Loading branch information
Mark Nelson authored and Benjamin Herrenschmidt committed Dec 9, 2009
1 parent 63762b0 commit 7d15891
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 275a64f6040073254fa15eaf6e4e720f77d531d6
refs/heads/master: 49bd3647134ea47420067aea8d1401e722bf2aac
56 changes: 51 additions & 5 deletions trunk/arch/powerpc/platforms/pseries/xics.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/cpu.h>
#include <linux/msi.h>
#include <linux/of.h>
#include <linux/percpu.h>

#include <asm/firmware.h>
#include <asm/io.h>
Expand All @@ -46,6 +47,12 @@ static struct irq_host *xics_host;
*/
#define IPI_PRIORITY 4

/* The least favored priority */
#define LOWEST_PRIORITY 0xFF

/* The number of priorities defined above */
#define MAX_NUM_PRIORITIES 3

static unsigned int default_server = 0xFF;
static unsigned int default_distrib_server = 0;
static unsigned int interrupt_server_size = 8;
Expand All @@ -56,6 +63,12 @@ static int ibm_set_xive;
static int ibm_int_on;
static int ibm_int_off;

struct xics_cppr {
unsigned char stack[MAX_NUM_PRIORITIES];
int index;
};

static DEFINE_PER_CPU(struct xics_cppr, xics_cppr);

/* Direct hardware low level accessors */

Expand Down Expand Up @@ -284,6 +297,19 @@ static inline unsigned int xics_xirr_vector(unsigned int xirr)
return xirr & 0x00ffffff;
}

static void push_cppr(unsigned int vec)
{
struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);

if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
return;

if (vec == XICS_IPI)
os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
else
os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
}

static unsigned int xics_get_irq_direct(void)
{
unsigned int xirr = direct_xirr_info_get();
Expand All @@ -294,8 +320,10 @@ static unsigned int xics_get_irq_direct(void)
return NO_IRQ;

irq = irq_radix_revmap_lookup(xics_host, vec);
if (likely(irq != NO_IRQ))
if (likely(irq != NO_IRQ)) {
push_cppr(vec);
return irq;
}

/* We don't have a linux mapping, so have rtas mask it. */
xics_mask_unknown_vec(vec);
Expand All @@ -315,8 +343,10 @@ static unsigned int xics_get_irq_lpar(void)
return NO_IRQ;

irq = irq_radix_revmap_lookup(xics_host, vec);
if (likely(irq != NO_IRQ))
if (likely(irq != NO_IRQ)) {
push_cppr(vec);
return irq;
}

/* We don't have a linux mapping, so have RTAS mask it. */
xics_mask_unknown_vec(vec);
Expand All @@ -326,20 +356,30 @@ static unsigned int xics_get_irq_lpar(void)
return NO_IRQ;
}

static unsigned char pop_cppr(void)
{
struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);

if (WARN_ON(os_cppr->index < 1))
return LOWEST_PRIORITY;

return os_cppr->stack[--os_cppr->index];
}

static void xics_eoi_direct(unsigned int virq)
{
unsigned int irq = (unsigned int)irq_map[virq].hwirq;

iosync();
direct_xirr_info_set((0xff << 24) | irq);
direct_xirr_info_set((pop_cppr() << 24) | irq);
}

static void xics_eoi_lpar(unsigned int virq)
{
unsigned int irq = (unsigned int)irq_map[virq].hwirq;

iosync();
lpar_xirr_info_set((0xff << 24) | irq);
lpar_xirr_info_set((pop_cppr() << 24) | irq);
}

static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
Expand Down Expand Up @@ -746,6 +786,12 @@ void __init xics_init_IRQ(void)

static void xics_set_cpu_priority(unsigned char cppr)
{
struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);

BUG_ON(os_cppr->index != 0);

os_cppr->stack[os_cppr->index] = cppr;

if (firmware_has_feature(FW_FEATURE_LPAR))
lpar_cppr_info(cppr);
else
Expand All @@ -772,7 +818,7 @@ static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)

void xics_setup_cpu(void)
{
xics_set_cpu_priority(0xff);
xics_set_cpu_priority(LOWEST_PRIORITY);

xics_set_cpu_giq(default_distrib_server, 1);
}
Expand Down

0 comments on commit 7d15891

Please sign in to comment.