7 #include <linux/kernel.h>
8 #include <linux/types.h>
10 #include <linux/sched.h>
11 #include <linux/pci.h>
13 #include <linux/bitops.h>
15 #include <asm/ptrace.h>
18 #include <asm/mmu_context.h>
20 #include <asm/pgtable.h>
23 #include <asm/tlbflush.h>
33 #if NR_IRQS < MARVEL_NR_IRQS
34 # error NR_IRQS < MARVEL_NR_IRQS !!!
42 io7_device_interrupt(
unsigned long vector)
62 irq = ((vector & 0xffff) - 0x800) >> 4;
71 static volatile unsigned long *
72 io7_get_irq_ctl(
unsigned int irq,
struct io7 **pio7)
74 volatile unsigned long *
ctl;
82 "%s for nonexistent io7 -- vec %x, pid %d\n",
92 "%s for invalid irq -- pid %d adjusted irq %x\n",
97 ctl = &io7->csrs->PO7_LSI_CTL[irq & 0xff].csr;
99 ctl = &io7->csrs->PO7_MSI_CTL[((irq - 0x80) >> 5) & 0x0f].csr;
101 if (pio7) *pio7 = io7;
108 volatile unsigned long *
ctl;
109 unsigned int irq = d->
irq;
112 ctl = io7_get_irq_ctl(irq, &io7);
119 spin_lock(&io7->irq_lock);
123 spin_unlock(&io7->irq_lock);
129 volatile unsigned long *
ctl;
130 unsigned int irq = d->
irq;
133 ctl = io7_get_irq_ctl(irq, &io7);
140 spin_lock(&io7->irq_lock);
141 *ctl &= ~(1
UL << 24);
144 spin_unlock(&io7->irq_lock);
153 static struct irq_chip marvel_legacy_irq_type = {
155 .irq_mask = marvel_irq_noop,
156 .irq_unmask = marvel_irq_noop,
159 static struct irq_chip io7_lsi_irq_type = {
161 .irq_unmask = io7_enable_irq,
162 .irq_mask = io7_disable_irq,
163 .irq_mask_ack = io7_disable_irq,
166 static struct irq_chip io7_msi_irq_type = {
168 .irq_unmask = io7_enable_irq,
169 .irq_mask = io7_disable_irq,
170 .irq_ack = marvel_irq_noop,
174 io7_redirect_irq(
struct io7 *io7,
175 volatile unsigned long *
csr,
181 val &= ~(0x1ff
UL << 24);
182 val |= ((
unsigned long)where << 24);
190 io7_redirect_one_lsi(
struct io7 *io7,
unsigned int which,
unsigned int where)
197 val = io7->csrs->PO7_LSI_CTL[which].csr;
198 val &= ~(0x1ff
UL << 14);
199 val |= ((
unsigned long)where << 14);
201 io7->csrs->PO7_LSI_CTL[which].csr =
val;
203 io7->csrs->PO7_LSI_CTL[which].csr;
207 io7_redirect_one_msi(
struct io7 *io7,
unsigned int which,
unsigned int where)
214 val = io7->csrs->PO7_MSI_CTL[which].csr;
215 val &= ~(0x1ff
UL << 14);
216 val |= ((
unsigned long)where << 14);
218 io7->csrs->PO7_MSI_CTL[which].csr =
val;
220 io7->csrs->PO7_MSI_CTL[which].csr;
224 init_one_io7_lsi(
struct io7 *io7,
unsigned int which,
unsigned int where)
229 io7->csrs->PO7_LSI_CTL[which].csr = ((
unsigned long)where << 14);
231 io7->csrs->PO7_LSI_CTL[which].csr;
235 init_one_io7_msi(
struct io7 *io7,
unsigned int which,
unsigned int where)
240 io7->csrs->PO7_MSI_CTL[which].csr = ((
unsigned long)where << 14);
242 io7->csrs->PO7_MSI_CTL[which].csr;
246 init_io7_irqs(
struct io7 *io7,
253 printk(
"Initializing interrupts for IO7 at PE %u - base %lx\n",
267 spin_lock(&io7->irq_lock);
270 io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr,
boot_cpuid);
271 io7_redirect_irq(io7, &io7->csrs->HPI_CTL.csr,
boot_cpuid);
272 io7_redirect_irq(io7, &io7->csrs->CRD_CTL.csr,
boot_cpuid);
273 io7_redirect_irq(io7, &io7->csrs->STV_CTL.csr,
boot_cpuid);
274 io7_redirect_irq(io7, &io7->csrs->HEI_CTL.csr,
boot_cpuid);
277 for (i = 0; i < 128; ++
i) {
283 for (i = 0; i < 0x60; ++
i)
291 for (i = 128; i < (128 + 512); ++
i) {
296 for (i = 0; i < 16; ++
i)
299 spin_unlock(&io7->irq_lock);
303 marvel_init_irq(
void)
306 struct io7 *io7 =
NULL;
309 for (i = 0; i < 16; ++
i) {
310 irq_set_chip_and_handler(i, &marvel_legacy_irq_type,
316 init_io7_irqs(io7, &io7_lsi_irq_type, &io7_msi_irq_type);
323 struct io7_port *io7_port = hose->sysdata;
324 struct io7 *io7 = io7_port->io7;
325 int msi_loc, msi_data_off;
337 pci_read_config_word(dev, msi_loc +
PCI_MSI_FLAGS, &msg_ctl);
343 pci_read_config_word(dev, msi_loc + msi_data_off, &msg_dat);
345 irq = msg_dat & 0x1ff;
349 printk(
"PCI:%d:%d:%d (hose %d) is using MSI\n",
354 printk(
" %d message(s) from 0x%04x\n",
357 printk(
" reporting on %d IRQ(s) from %d (0x%x)\n",
359 (irq + 16) | (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT),
360 (irq + 16) | (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT));
365 msg_ctl & ~PCI_MSI_FLAGS_ENABLE);
369 printk(
" forcing LSI interrupt on irq %d [0x%x]\n", irq, irq);
380 marvel_init_pci(
void)
387 pci_set_flags(PCI_PROBE_ONLY);
389 locate_and_init_vga(
NULL);
397 marvel_init_rtc(
void)
409 smp_get_rtc_time(
void *
data)
416 smp_set_rtc_time(
void *
data)
435 return __get_rtc_time(time);
439 marvel_set_rtc_time(
struct rtc_time *time)
450 return __set_rtc_time(time);
454 marvel_smp_callin(
void)
466 printk(
"Redirecting IO7 interrupts to local CPU at PE %u\n", cpuid);
469 io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr, cpuid);
470 io7_redirect_irq(io7, &io7->csrs->HPI_CTL.csr, cpuid);
471 io7_redirect_irq(io7, &io7->csrs->CRD_CTL.csr, cpuid);
472 io7_redirect_irq(io7, &io7->csrs->STV_CTL.csr, cpuid);
473 io7_redirect_irq(io7, &io7->csrs->HEI_CTL.csr, cpuid);
476 for (i = 0; i < 0x60; ++
i)
477 io7_redirect_one_lsi(io7, i, cpuid);
479 io7_redirect_one_lsi(io7, 0x74, cpuid);
480 io7_redirect_one_lsi(io7, 0x75, cpuid);
483 for (i = 0; i < 16; ++
i)
484 io7_redirect_one_msi(io7, i, cpuid);
490 struct alpha_machine_vector marvel_ev7_mv
__initmv = {
491 .vector_name =
"MARVEL/EV7",
494 .rtc_get_time = marvel_get_rtc_time,
495 .rtc_set_time = marvel_set_rtc_time,
504 .device_interrupt = io7_device_interrupt,
508 .smp_callin = marvel_smp_callin,
510 .init_irq = marvel_init_irq,
511 .init_rtc = marvel_init_rtc,
512 .init_pci = marvel_init_pci,
514 .pci_map_irq = marvel_map_irq,