This source file includes following definitions.
- io7_device_interrupt
- io7_get_irq_ctl
- io7_enable_irq
- io7_disable_irq
- marvel_irq_noop
- io7_redirect_irq
- io7_redirect_one_lsi
- io7_redirect_one_msi
- init_one_io7_lsi
- init_one_io7_msi
- init_io7_irqs
- marvel_init_irq
- marvel_map_irq
- marvel_init_pci
- marvel_init_rtc
- marvel_smp_callin
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/types.h>
  10 #include <linux/mm.h>
  11 #include <linux/sched.h>
  12 #include <linux/pci.h>
  13 #include <linux/init.h>
  14 #include <linux/bitops.h>
  15 
  16 #include <asm/ptrace.h>
  17 #include <asm/dma.h>
  18 #include <asm/irq.h>
  19 #include <asm/mmu_context.h>
  20 #include <asm/io.h>
  21 #include <asm/pgtable.h>
  22 #include <asm/core_marvel.h>
  23 #include <asm/hwrpb.h>
  24 #include <asm/tlbflush.h>
  25 #include <asm/vga.h>
  26 
  27 #include "proto.h"
  28 #include "err_impl.h"
  29 #include "irq_impl.h"
  30 #include "pci_impl.h"
  31 #include "machvec_impl.h"
  32 
  33 #if NR_IRQS < MARVEL_NR_IRQS
  34 # error NR_IRQS < MARVEL_NR_IRQS !!!
  35 #endif
  36 
  37 
  38 
  39 
  40 
  41 static void 
  42 io7_device_interrupt(unsigned long vector)
  43 {
  44         unsigned int pid;
  45         unsigned int irq;
  46 
  47         
  48 
  49 
  50 
  51 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 
  61         pid = vector >> 16;
  62         irq = ((vector & 0xffff) - 0x800) >> 4;
  63 
  64         irq += 16;                              
  65         irq &= MARVEL_IRQ_VEC_IRQ_MASK;         
  66         irq |= pid << MARVEL_IRQ_VEC_PE_SHIFT;  
  67 
  68         handle_irq(irq);
  69 }
  70 
  71 static volatile unsigned long *
  72 io7_get_irq_ctl(unsigned int irq, struct io7 **pio7)
  73 {
  74         volatile unsigned long *ctl;
  75         unsigned int pid;
  76         struct io7 *io7;
  77 
  78         pid = irq >> MARVEL_IRQ_VEC_PE_SHIFT;
  79 
  80         if (!(io7 = marvel_find_io7(pid))) {
  81                 printk(KERN_ERR 
  82                        "%s for nonexistent io7 -- vec %x, pid %d\n",
  83                        __func__, irq, pid);
  84                 return NULL;
  85         }
  86 
  87         irq &= MARVEL_IRQ_VEC_IRQ_MASK; 
  88         irq -= 16;                      
  89 
  90         if (irq >= 0x180) {
  91                 printk(KERN_ERR 
  92                        "%s for invalid irq -- pid %d adjusted irq %x\n",
  93                        __func__, pid, irq);
  94                 return NULL;
  95         }
  96 
  97         ctl = &io7->csrs->PO7_LSI_CTL[irq & 0xff].csr; 
  98         if (irq >= 0x80)                
  99                 ctl = &io7->csrs->PO7_MSI_CTL[((irq - 0x80) >> 5) & 0x0f].csr;
 100 
 101         if (pio7) *pio7 = io7;
 102         return ctl;
 103 }
 104 
 105 static void
 106 io7_enable_irq(struct irq_data *d)
 107 {
 108         volatile unsigned long *ctl;
 109         unsigned int irq = d->irq;
 110         struct io7 *io7;
 111 
 112         ctl = io7_get_irq_ctl(irq, &io7);
 113         if (!ctl || !io7) {
 114                 printk(KERN_ERR "%s: get_ctl failed for irq %x\n",
 115                        __func__, irq);
 116                 return;
 117         }
 118 
 119         raw_spin_lock(&io7->irq_lock);
 120         *ctl |= 1UL << 24;
 121         mb();
 122         *ctl;
 123         raw_spin_unlock(&io7->irq_lock);
 124 }
 125 
 126 static void
 127 io7_disable_irq(struct irq_data *d)
 128 {
 129         volatile unsigned long *ctl;
 130         unsigned int irq = d->irq;
 131         struct io7 *io7;
 132 
 133         ctl = io7_get_irq_ctl(irq, &io7);
 134         if (!ctl || !io7) {
 135                 printk(KERN_ERR "%s: get_ctl failed for irq %x\n",
 136                        __func__, irq);
 137                 return;
 138         }
 139 
 140         raw_spin_lock(&io7->irq_lock);
 141         *ctl &= ~(1UL << 24);
 142         mb();
 143         *ctl;
 144         raw_spin_unlock(&io7->irq_lock);
 145 }
 146 
 147 static void
 148 marvel_irq_noop(struct irq_data *d)
 149 {
 150         return;
 151 }
 152 
 153 static struct irq_chip marvel_legacy_irq_type = {
 154         .name           = "LEGACY",
 155         .irq_mask       = marvel_irq_noop,
 156         .irq_unmask     = marvel_irq_noop,
 157 };
 158 
 159 static struct irq_chip io7_lsi_irq_type = {
 160         .name           = "LSI",
 161         .irq_unmask     = io7_enable_irq,
 162         .irq_mask       = io7_disable_irq,
 163         .irq_mask_ack   = io7_disable_irq,
 164 };
 165 
 166 static struct irq_chip io7_msi_irq_type = {
 167         .name           = "MSI",
 168         .irq_unmask     = io7_enable_irq,
 169         .irq_mask       = io7_disable_irq,
 170         .irq_ack        = marvel_irq_noop,
 171 };
 172 
 173 static void
 174 io7_redirect_irq(struct io7 *io7, 
 175                  volatile unsigned long *csr, 
 176                  unsigned int where)
 177 {
 178         unsigned long val;
 179         
 180         val = *csr;
 181         val &= ~(0x1ffUL << 24);                
 182         val |= ((unsigned long)where << 24);    
 183         
 184         *csr = val;
 185         mb();
 186         *csr;
 187 }
 188 
 189 static void 
 190 io7_redirect_one_lsi(struct io7 *io7, unsigned int which, unsigned int where)
 191 {
 192         unsigned long val;
 193 
 194         
 195 
 196 
 197         val = io7->csrs->PO7_LSI_CTL[which].csr;
 198         val &= ~(0x1ffUL << 14);                
 199         val |= ((unsigned long)where << 14);    
 200 
 201         io7->csrs->PO7_LSI_CTL[which].csr = val;
 202         mb();
 203         io7->csrs->PO7_LSI_CTL[which].csr;
 204 }
 205 
 206 static void 
 207 io7_redirect_one_msi(struct io7 *io7, unsigned int which, unsigned int where)
 208 {
 209         unsigned long val;
 210 
 211         
 212 
 213 
 214         val = io7->csrs->PO7_MSI_CTL[which].csr;
 215         val &= ~(0x1ffUL << 14);                
 216         val |= ((unsigned long)where << 14);    
 217 
 218         io7->csrs->PO7_MSI_CTL[which].csr = val;
 219         mb();
 220         io7->csrs->PO7_MSI_CTL[which].csr;
 221 }
 222 
 223 static void __init
 224 init_one_io7_lsi(struct io7 *io7, unsigned int which, unsigned int where)
 225 {
 226         
 227 
 228 
 229         io7->csrs->PO7_LSI_CTL[which].csr = ((unsigned long)where << 14);
 230         mb();
 231         io7->csrs->PO7_LSI_CTL[which].csr;
 232 }
 233 
 234 static void __init
 235 init_one_io7_msi(struct io7 *io7, unsigned int which, unsigned int where)
 236 {
 237         
 238 
 239 
 240         io7->csrs->PO7_MSI_CTL[which].csr = ((unsigned long)where << 14);
 241         mb();
 242         io7->csrs->PO7_MSI_CTL[which].csr;
 243 }
 244 
 245 static void __init
 246 init_io7_irqs(struct io7 *io7, 
 247               struct irq_chip *lsi_ops,
 248               struct irq_chip *msi_ops)
 249 {
 250         long base = (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT) + 16;
 251         long i;
 252 
 253         printk("Initializing interrupts for IO7 at PE %u - base %lx\n",
 254                 io7->pe, base);
 255 
 256         
 257 
 258 
 259 
 260 
 261 
 262 
 263 
 264 
 265         printk("  Interrupts reported to CPU at PE %u\n", boot_cpuid);
 266 
 267         raw_spin_lock(&io7->irq_lock);
 268 
 269         
 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);
 275 
 276         
 277         for (i = 0; i < 128; ++i) {
 278                 irq_set_chip_and_handler(base + i, lsi_ops, handle_level_irq);
 279                 irq_set_status_flags(i, IRQ_LEVEL);
 280         }
 281 
 282         
 283         for (i = 0; i < 0x60; ++i) 
 284                 init_one_io7_lsi(io7, i, boot_cpuid);
 285 
 286         init_one_io7_lsi(io7, 0x74, boot_cpuid);
 287         init_one_io7_lsi(io7, 0x75, boot_cpuid);
 288 
 289 
 290         
 291         for (i = 128; i < (128 + 512); ++i) {
 292                 irq_set_chip_and_handler(base + i, msi_ops, handle_level_irq);
 293                 irq_set_status_flags(i, IRQ_LEVEL);
 294         }
 295 
 296         for (i = 0; i < 16; ++i)
 297                 init_one_io7_msi(io7, i, boot_cpuid);
 298 
 299         raw_spin_unlock(&io7->irq_lock);
 300 }
 301 
 302 static void __init
 303 marvel_init_irq(void)
 304 {
 305         int i;
 306         struct io7 *io7 = NULL;
 307 
 308         
 309         for (i = 0; i < 16; ++i) {
 310                 irq_set_chip_and_handler(i, &marvel_legacy_irq_type,
 311                                          handle_level_irq);
 312         }
 313 
 314         
 315         for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; )
 316                 init_io7_irqs(io7, &io7_lsi_irq_type, &io7_msi_irq_type);
 317 }
 318 
 319 static int 
 320 marvel_map_irq(const struct pci_dev *cdev, u8 slot, u8 pin)
 321 {
 322         struct pci_dev *dev = (struct pci_dev *)cdev;
 323         struct pci_controller *hose = dev->sysdata;
 324         struct io7_port *io7_port = hose->sysdata;
 325         struct io7 *io7 = io7_port->io7;
 326         int msi_loc, msi_data_off;
 327         u16 msg_ctl;
 328         u16 msg_dat;
 329         u8 intline; 
 330         int irq;
 331 
 332         pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline);
 333         irq = intline;
 334 
 335         msi_loc = dev->msi_cap;
 336         msg_ctl = 0;
 337         if (msi_loc) 
 338                 pci_read_config_word(dev, msi_loc + PCI_MSI_FLAGS, &msg_ctl);
 339 
 340         if (msg_ctl & PCI_MSI_FLAGS_ENABLE) {
 341                 msi_data_off = PCI_MSI_DATA_32;
 342                 if (msg_ctl & PCI_MSI_FLAGS_64BIT) 
 343                         msi_data_off = PCI_MSI_DATA_64;
 344                 pci_read_config_word(dev, msi_loc + msi_data_off, &msg_dat);
 345 
 346                 irq = msg_dat & 0x1ff;          
 347                 irq += 0x80;                    
 348 
 349 #if 1
 350                 printk("PCI:%d:%d:%d (hose %d) is using MSI\n",
 351                        dev->bus->number, 
 352                        PCI_SLOT(dev->devfn), 
 353                        PCI_FUNC(dev->devfn),
 354                        hose->index);
 355                 printk("  %d message(s) from 0x%04x\n", 
 356                        1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4),
 357                        msg_dat);
 358                 printk("  reporting on %d IRQ(s) from %d (0x%x)\n", 
 359                        1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4),
 360                        (irq + 16) | (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT),
 361                        (irq + 16) | (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT));
 362 #endif
 363 
 364 #if 0
 365                 pci_write_config_word(dev, msi_loc + PCI_MSI_FLAGS,
 366                                       msg_ctl & ~PCI_MSI_FLAGS_ENABLE);
 367                 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline);
 368                 irq = intline;
 369 
 370                 printk("  forcing LSI interrupt on irq %d [0x%x]\n", irq, irq);
 371 #endif
 372         }
 373 
 374         irq += 16;                                      
 375         irq |= io7->pe << MARVEL_IRQ_VEC_PE_SHIFT;      
 376 
 377         return irq; 
 378 }
 379 
 380 static void __init
 381 marvel_init_pci(void)
 382 {
 383         struct io7 *io7;
 384 
 385         marvel_register_error_handlers();
 386 
 387         
 388         pci_set_flags(PCI_PROBE_ONLY);
 389         common_init_pci();
 390         locate_and_init_vga(NULL);
 391 
 392         
 393         for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) 
 394                 io7_clear_errors(io7);
 395 }
 396 
 397 static void __init
 398 marvel_init_rtc(void)
 399 {
 400         init_rtc_irq();
 401 }
 402 
 403 static void
 404 marvel_smp_callin(void)
 405 {
 406         int cpuid = hard_smp_processor_id();
 407         struct io7 *io7 = marvel_find_io7(cpuid);
 408         unsigned int i;
 409 
 410         if (!io7)
 411                 return;
 412 
 413         
 414 
 415 
 416         printk("Redirecting IO7 interrupts to local CPU at PE %u\n", cpuid);
 417 
 418         
 419         io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr, cpuid);
 420         io7_redirect_irq(io7, &io7->csrs->HPI_CTL.csr, cpuid);
 421         io7_redirect_irq(io7, &io7->csrs->CRD_CTL.csr, cpuid);
 422         io7_redirect_irq(io7, &io7->csrs->STV_CTL.csr, cpuid);
 423         io7_redirect_irq(io7, &io7->csrs->HEI_CTL.csr, cpuid);
 424 
 425         
 426         for (i = 0; i < 0x60; ++i) 
 427                 io7_redirect_one_lsi(io7, i, cpuid);
 428 
 429         io7_redirect_one_lsi(io7, 0x74, cpuid);
 430         io7_redirect_one_lsi(io7, 0x75, cpuid);
 431 
 432         
 433         for (i = 0; i < 16; ++i)
 434                 io7_redirect_one_msi(io7, i, cpuid);
 435 }
 436 
 437 
 438 
 439 
 440 struct alpha_machine_vector marvel_ev7_mv __initmv = {
 441         .vector_name            = "MARVEL/EV7",
 442         DO_EV7_MMU,
 443         .rtc_port               = 0x70,
 444         .rtc_boot_cpu_only      = 1,
 445         DO_MARVEL_IO,
 446         .machine_check          = marvel_machine_check,
 447         .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
 448         .min_io_address         = DEFAULT_IO_BASE,
 449         .min_mem_address        = DEFAULT_MEM_BASE,
 450         .pci_dac_offset         = IO7_DAC_OFFSET,
 451 
 452         .nr_irqs                = MARVEL_NR_IRQS,
 453         .device_interrupt       = io7_device_interrupt,
 454 
 455         .agp_info               = marvel_agp_info,
 456 
 457         .smp_callin             = marvel_smp_callin,
 458         .init_arch              = marvel_init_arch,
 459         .init_irq               = marvel_init_irq,
 460         .init_rtc               = marvel_init_rtc,
 461         .init_pci               = marvel_init_pci,
 462         .kill_arch              = marvel_kill_arch,
 463         .pci_map_irq            = marvel_map_irq,
 464         .pci_swizzle            = common_swizzle,
 465 
 466         .pa_to_nid              = marvel_pa_to_nid,
 467         .cpuid_to_nid           = marvel_cpuid_to_nid,
 468         .node_mem_start         = marvel_node_mem_start,
 469         .node_mem_size          = marvel_node_mem_size,
 470 };
 471 ALIAS_MV(marvel_ev7)