~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sparc/kernel/irq_64.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/sparc/kernel/irq_64.c (Architecture m68k) and /arch/ppc/kernel/irq_64.c (Architecture ppc)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /* irq.c: UltraSparc IRQ handling/init/registr    
  3  *                                                
  4  * Copyright (C) 1997, 2007, 2008 David S. Mil    
  5  * Copyright (C) 1998  Eddie C. Dost    (ecd@s    
  6  * Copyright (C) 1998  Jakub Jelinek    (jj@ul    
  7  */                                               
  8                                                   
  9 #include <linux/sched.h>                          
 10 #include <linux/linkage.h>                        
 11 #include <linux/ptrace.h>                         
 12 #include <linux/errno.h>                          
 13 #include <linux/kernel_stat.h>                    
 14 #include <linux/signal.h>                         
 15 #include <linux/mm.h>                             
 16 #include <linux/interrupt.h>                      
 17 #include <linux/slab.h>                           
 18 #include <linux/random.h>                         
 19 #include <linux/init.h>                           
 20 #include <linux/delay.h>                          
 21 #include <linux/proc_fs.h>                        
 22 #include <linux/seq_file.h>                       
 23 #include <linux/ftrace.h>                         
 24 #include <linux/irq.h>                            
 25                                                   
 26 #include <asm/ptrace.h>                           
 27 #include <asm/processor.h>                        
 28 #include <linux/atomic.h>                         
 29 #include <asm/irq.h>                              
 30 #include <asm/io.h>                               
 31 #include <asm/iommu.h>                            
 32 #include <asm/upa.h>                              
 33 #include <asm/oplib.h>                            
 34 #include <asm/prom.h>                             
 35 #include <asm/timer.h>                            
 36 #include <asm/smp.h>                              
 37 #include <asm/starfire.h>                         
 38 #include <linux/uaccess.h>                        
 39 #include <asm/cache.h>                            
 40 #include <asm/cpudata.h>                          
 41 #include <asm/auxio.h>                            
 42 #include <asm/head.h>                             
 43 #include <asm/hypervisor.h>                       
 44 #include <asm/cacheflush.h>                       
 45 #include <asm/softirq_stack.h>                    
 46                                                   
 47 #include "entry.h"                                
 48 #include "cpumap.h"                               
 49 #include "kstack.h"                               
 50                                                   
 51 struct ino_bucket *ivector_table;                 
 52 unsigned long ivector_table_pa;                   
 53                                                   
 54 /* On several sun4u processors, it is illegal     
 55  * non-bypass accesses.  Therefore we access a    
 56  * using bypass accesses only.                    
 57  */                                               
 58 static unsigned long bucket_get_chain_pa(unsig    
 59 {                                                 
 60         unsigned long ret;                        
 61                                                   
 62         __asm__ __volatile__("ldxa      [%1] %    
 63                              : "=&r" (ret)        
 64                              : "r" (bucket_pa     
 65                                     offsetof(s    
 66                                              _    
 67                                "i" (ASI_PHYS_U    
 68                                                   
 69         return ret;                               
 70 }                                                 
 71                                                   
 72 static void bucket_clear_chain_pa(unsigned lon    
 73 {                                                 
 74         __asm__ __volatile__("stxa      %%g0,     
 75                              : /* no outputs *    
 76                              : "r" (bucket_pa     
 77                                     offsetof(s    
 78                                              _    
 79                                "i" (ASI_PHYS_U    
 80 }                                                 
 81                                                   
 82 static unsigned int bucket_get_irq(unsigned lo    
 83 {                                                 
 84         unsigned int ret;                         
 85                                                   
 86         __asm__ __volatile__("lduwa     [%1] %    
 87                              : "=&r" (ret)        
 88                              : "r" (bucket_pa     
 89                                     offsetof(s    
 90                                              _    
 91                                "i" (ASI_PHYS_U    
 92                                                   
 93         return ret;                               
 94 }                                                 
 95                                                   
 96 static void bucket_set_irq(unsigned long bucke    
 97 {                                                 
 98         __asm__ __volatile__("stwa      %0, [%    
 99                              : /* no outputs *    
100                              : "r" (irq),         
101                                "r" (bucket_pa     
102                                     offsetof(s    
103                                              _    
104                                "i" (ASI_PHYS_U    
105 }                                                 
106                                                   
107 #define irq_work_pa(__cpu)      &(trap_block[(    
108                                                   
109 static unsigned long hvirq_major __initdata;      
110 static int __init early_hvirq_major(char *p)      
111 {                                                 
112         int rc = kstrtoul(p, 10, &hvirq_major)    
113                                                   
114         return rc;                                
115 }                                                 
116 early_param("hvirq", early_hvirq_major);          
117                                                   
118 static int hv_irq_version;                        
119                                                   
120 /* Major version 2.0 of HV_GRP_INTR added supp    
121  * based interfaces, but:                         
122  *                                                
123  * 1) Several OSs, Solaris and Linux included,    
124  *    negotiating version 1.0 (or failing to n    
125  *    hypervisor has a workaround that provide    
126  *    when only verion 1.0 of the API is in us    
127  *                                                
128  * 2) Second, and more importantly, with major    
129  *    interfaces only were actually hooked up     
130  *    though the Hypervisor specification clea    
131  *                                                
132  *      The new interrupt API functions will b    
133  *      when it negotiates version 2.0 in the     
134  *      a guest negotiates version 2.0, all in    
135  *      support using the cookie interface, an    
136  *      version 1.0 interrupt APIs numbered 0x    
137  *      ENOTSUPPORTED error being returned.       
138  *                                                
139  *   with an emphasis on "all interrupt source    
140  *                                                
141  * To correct this, major version 3.0 was crea    
142  * support VIRQs for all interrupt sources (no    
143  * if we want to move completely over the cook    
144  * negotiate major version 3.0 or later of HV_    
145  */                                               
146 static bool sun4v_cookie_only_virqs(void)         
147 {                                                 
148         if (hv_irq_version >= 3)                  
149                 return true;                      
150         return false;                             
151 }                                                 
152                                                   
153 static void __init irq_init_hv(void)              
154 {                                                 
155         unsigned long hv_error, major, minor =    
156                                                   
157         if (tlb_type != hypervisor)               
158                 return;                           
159                                                   
160         if (hvirq_major)                          
161                 major = hvirq_major;              
162         else                                      
163                 major = 3;                        
164                                                   
165         hv_error = sun4v_hvapi_register(HV_GRP    
166         if (!hv_error)                            
167                 hv_irq_version = major;           
168         else                                      
169                 hv_irq_version = 1;               
170                                                   
171         pr_info("SUN4V: Using IRQ API major %d    
172                 hv_irq_version,                   
173                 sun4v_cookie_only_virqs() ? "e    
174 }                                                 
175                                                   
176 /* This function is for the timer interrupt.*/    
177 int __init arch_probe_nr_irqs(void)               
178 {                                                 
179         return 1;                                 
180 }                                                 
181                                                   
182 #define DEFAULT_NUM_IVECS       (0xfffU)          
183 static unsigned int nr_ivec = DEFAULT_NUM_IVEC    
184 #define NUM_IVECS (nr_ivec)                       
185                                                   
186 static unsigned int __init size_nr_ivec(void)     
187 {                                                 
188         if (tlb_type == hypervisor) {             
189                 switch (sun4v_chip_type) {        
190                 /* Athena's devhandle|devino i    
191                 case SUN4V_CHIP_SPARC64X:         
192                         nr_ivec = 0xffff;         
193                         break;                    
194                 }                                 
195         }                                         
196         return nr_ivec;                           
197 }                                                 
198                                                   
199 struct irq_handler_data {                         
200         union {                                   
201                 struct {                          
202                         unsigned int dev_handl    
203                         unsigned int dev_ino;     
204                 };                                
205                 unsigned long sysino;             
206         };                                        
207         struct ino_bucket bucket;                 
208         unsigned long   iclr;                     
209         unsigned long   imap;                     
210 };                                                
211                                                   
212 static inline unsigned int irq_data_to_handle(    
213 {                                                 
214         struct irq_handler_data *ihd = irq_dat    
215                                                   
216         return ihd->dev_handle;                   
217 }                                                 
218                                                   
219 static inline unsigned int irq_data_to_ino(str    
220 {                                                 
221         struct irq_handler_data *ihd = irq_dat    
222                                                   
223         return ihd->dev_ino;                      
224 }                                                 
225                                                   
226 static inline unsigned long irq_data_to_sysino    
227 {                                                 
228         struct irq_handler_data *ihd = irq_dat    
229                                                   
230         return ihd->sysino;                       
231 }                                                 
232                                                   
233 void irq_free(unsigned int irq)                   
234 {                                                 
235         void *data = irq_get_handler_data(irq)    
236                                                   
237         kfree(data);                              
238         irq_set_handler_data(irq, NULL);          
239         irq_free_descs(irq, 1);                   
240 }                                                 
241                                                   
242 unsigned int irq_alloc(unsigned int dev_handle    
243 {                                                 
244         int irq;                                  
245                                                   
246         irq = __irq_alloc_descs(-1, 1, 1, numa    
247         if (irq <= 0)                             
248                 goto out;                         
249                                                   
250         return irq;                               
251 out:                                              
252         return 0;                                 
253 }                                                 
254                                                   
255 static unsigned int cookie_exists(u32 devhandl    
256 {                                                 
257         unsigned long hv_err, cookie;             
258         struct ino_bucket *bucket;                
259         unsigned int irq = 0U;                    
260                                                   
261         hv_err = sun4v_vintr_get_cookie(devhan    
262         if (hv_err) {                             
263                 pr_err("HV get cookie failed h    
264                 goto out;                         
265         }                                         
266                                                   
267         if (cookie & ((1UL << 63UL))) {           
268                 cookie = ~cookie;                 
269                 bucket = (struct ino_bucket *)    
270                 irq = bucket->__irq;              
271         }                                         
272 out:                                              
273         return irq;                               
274 }                                                 
275                                                   
276 static unsigned int sysino_exists(u32 devhandl    
277 {                                                 
278         unsigned long sysino = sun4v_devino_to    
279         struct ino_bucket *bucket;                
280         unsigned int irq;                         
281                                                   
282         bucket = &ivector_table[sysino];          
283         irq = bucket_get_irq(__pa(bucket));       
284                                                   
285         return irq;                               
286 }                                                 
287                                                   
288 void ack_bad_irq(unsigned int irq)                
289 {                                                 
290         pr_crit("BAD IRQ ack %d\n", irq);         
291 }                                                 
292                                                   
293 void irq_install_pre_handler(int irq,             
294                              void (*func)(unsi    
295                              void *arg1, void     
296 {                                                 
297         pr_warn("IRQ pre handler NOT supported    
298 }                                                 
299                                                   
300 /*                                                
301  * /proc/interrupts printing:                     
302  */                                               
303 int arch_show_interrupts(struct seq_file *p, i    
304 {                                                 
305         int j;                                    
306                                                   
307         seq_printf(p, "NMI: ");                   
308         for_each_online_cpu(j)                    
309                 seq_printf(p, "%10u ", cpu_dat    
310         seq_printf(p, "     Non-maskable inter    
311         return 0;                                 
312 }                                                 
313                                                   
314 static unsigned int sun4u_compute_tid(unsigned    
315 {                                                 
316         unsigned int tid;                         
317                                                   
318         if (this_is_starfire) {                   
319                 tid = starfire_translate(imap,    
320                 tid <<= IMAP_TID_SHIFT;           
321                 tid &= IMAP_TID_UPA;              
322         } else {                                  
323                 if (tlb_type == cheetah || tlb    
324                         unsigned long ver;        
325                                                   
326                         __asm__ ("rdpr %%ver,     
327                         if ((ver >> 32UL) == _    
328                             (ver >> 32UL) == _    
329                                 tid = cpuid <<    
330                                 tid &= IMAP_TI    
331                         } else {                  
332                                 unsigned int a    
333                                 unsigned int n    
334                                                   
335                                 tid = ((a << I    
336                                        (n << I    
337                                 tid &= (IMAP_A    
338                                         IMAP_N    
339                         }                         
340                 } else {                          
341                         tid = cpuid << IMAP_TI    
342                         tid &= IMAP_TID_UPA;      
343                 }                                 
344         }                                         
345                                                   
346         return tid;                               
347 }                                                 
348                                                   
349 #ifdef CONFIG_SMP                                 
350 static int irq_choose_cpu(unsigned int irq, co    
351 {                                                 
352         int cpuid;                                
353                                                   
354         if (cpumask_equal(affinity, cpu_online    
355                 cpuid = map_to_cpu(irq);          
356         } else {                                  
357                 cpuid = cpumask_first_and(affi    
358                 cpuid = cpuid < nr_cpu_ids ? c    
359         }                                         
360                                                   
361         return cpuid;                             
362 }                                                 
363 #else                                             
364 #define irq_choose_cpu(irq, affinity)   \         
365         real_hard_smp_processor_id()              
366 #endif                                            
367                                                   
368 static void sun4u_irq_enable(struct irq_data *    
369 {                                                 
370         struct irq_handler_data *handler_data;    
371                                                   
372         handler_data = irq_data_get_irq_handle    
373         if (likely(handler_data)) {               
374                 unsigned long cpuid, imap, val    
375                 unsigned int tid;                 
376                                                   
377                 cpuid = irq_choose_cpu(data->i    
378                                        irq_dat    
379                 imap = handler_data->imap;        
380                                                   
381                 tid = sun4u_compute_tid(imap,     
382                                                   
383                 val = upa_readq(imap);            
384                 val &= ~(IMAP_TID_UPA | IMAP_T    
385                          IMAP_AID_SAFARI | IMA    
386                 val |= tid | IMAP_VALID;          
387                 upa_writeq(val, imap);            
388                 upa_writeq(ICLR_IDLE, handler_    
389         }                                         
390 }                                                 
391                                                   
392 static int sun4u_set_affinity(struct irq_data     
393                                const struct cp    
394 {                                                 
395         struct irq_handler_data *handler_data;    
396                                                   
397         handler_data = irq_data_get_irq_handle    
398         if (likely(handler_data)) {               
399                 unsigned long cpuid, imap, val    
400                 unsigned int tid;                 
401                                                   
402                 cpuid = irq_choose_cpu(data->i    
403                 imap = handler_data->imap;        
404                                                   
405                 tid = sun4u_compute_tid(imap,     
406                                                   
407                 val = upa_readq(imap);            
408                 val &= ~(IMAP_TID_UPA | IMAP_T    
409                          IMAP_AID_SAFARI | IMA    
410                 val |= tid | IMAP_VALID;          
411                 upa_writeq(val, imap);            
412                 upa_writeq(ICLR_IDLE, handler_    
413         }                                         
414                                                   
415         return 0;                                 
416 }                                                 
417                                                   
418 /* Don't do anything.  The desc->status check     
419  * handler_irq() will skip the handler call an    
420  * interrupt in the sent state.  The next ->en    
421  * ICLR register to reset the state machine.      
422  *                                                
423  * This scheme is necessary, instead of cleari    
424  * IMAP register, to handle the case of IMAP r    
425  * multiple INOs (and thus ICLR registers).  S    
426  * virtual IRQ for each shared IMAP instance,     
427  * there is only one user so it prematurely ca    
428  * free_irq().                                    
429  *                                                
430  * We have to provide an explicit ->disable()     
431  * NULL to get the default.  The reason is tha    
432  * sees that, it also hooks up a default ->shu    
433  * invokes ->mask() which we do not want.  See    
434  */                                               
435 static void sun4u_irq_disable(struct irq_data     
436 {                                                 
437 }                                                 
438                                                   
439 static void sun4u_irq_eoi(struct irq_data *dat    
440 {                                                 
441         struct irq_handler_data *handler_data;    
442                                                   
443         handler_data = irq_data_get_irq_handle    
444         if (likely(handler_data))                 
445                 upa_writeq(ICLR_IDLE, handler_    
446 }                                                 
447                                                   
448 static void sun4v_irq_enable(struct irq_data *    
449 {                                                 
450         unsigned long cpuid = irq_choose_cpu(d    
451                                              i    
452         unsigned int ino = irq_data_to_sysino(    
453         int err;                                  
454                                                   
455         err = sun4v_intr_settarget(ino, cpuid)    
456         if (err != HV_EOK)                        
457                 printk(KERN_ERR "sun4v_intr_se    
458                        "err(%d)\n", ino, cpuid    
459         err = sun4v_intr_setstate(ino, HV_INTR    
460         if (err != HV_EOK)                        
461                 printk(KERN_ERR "sun4v_intr_se    
462                        "err(%d)\n", ino, err);    
463         err = sun4v_intr_setenabled(ino, HV_IN    
464         if (err != HV_EOK)                        
465                 printk(KERN_ERR "sun4v_intr_se    
466                        ino, err);                 
467 }                                                 
468                                                   
469 static int sun4v_set_affinity(struct irq_data     
470                                const struct cp    
471 {                                                 
472         unsigned long cpuid = irq_choose_cpu(d    
473         unsigned int ino = irq_data_to_sysino(    
474         int err;                                  
475                                                   
476         err = sun4v_intr_settarget(ino, cpuid)    
477         if (err != HV_EOK)                        
478                 printk(KERN_ERR "sun4v_intr_se    
479                        "err(%d)\n", ino, cpuid    
480                                                   
481         return 0;                                 
482 }                                                 
483                                                   
484 static void sun4v_irq_disable(struct irq_data     
485 {                                                 
486         unsigned int ino = irq_data_to_sysino(    
487         int err;                                  
488                                                   
489         err = sun4v_intr_setenabled(ino, HV_IN    
490         if (err != HV_EOK)                        
491                 printk(KERN_ERR "sun4v_intr_se    
492                        "err(%d)\n", ino, err);    
493 }                                                 
494                                                   
495 static void sun4v_irq_eoi(struct irq_data *dat    
496 {                                                 
497         unsigned int ino = irq_data_to_sysino(    
498         int err;                                  
499                                                   
500         err = sun4v_intr_setstate(ino, HV_INTR    
501         if (err != HV_EOK)                        
502                 printk(KERN_ERR "sun4v_intr_se    
503                        "err(%d)\n", ino, err);    
504 }                                                 
505                                                   
506 static void sun4v_virq_enable(struct irq_data     
507 {                                                 
508         unsigned long dev_handle = irq_data_to    
509         unsigned long dev_ino = irq_data_to_in    
510         unsigned long cpuid;                      
511         int err;                                  
512                                                   
513         cpuid = irq_choose_cpu(data->irq, irq_    
514                                                   
515         err = sun4v_vintr_set_target(dev_handl    
516         if (err != HV_EOK)                        
517                 printk(KERN_ERR "sun4v_vintr_s    
518                        "err(%d)\n",               
519                        dev_handle, dev_ino, cp    
520         err = sun4v_vintr_set_state(dev_handle    
521                                     HV_INTR_ST    
522         if (err != HV_EOK)                        
523                 printk(KERN_ERR "sun4v_vintr_s    
524                        "HV_INTR_STATE_IDLE): e    
525                        dev_handle, dev_ino, er    
526         err = sun4v_vintr_set_valid(dev_handle    
527                                     HV_INTR_EN    
528         if (err != HV_EOK)                        
529                 printk(KERN_ERR "sun4v_vintr_s    
530                        "HV_INTR_ENABLED): err(    
531                        dev_handle, dev_ino, er    
532 }                                                 
533                                                   
534 static int sun4v_virt_set_affinity(struct irq_    
535                                     const stru    
536 {                                                 
537         unsigned long dev_handle = irq_data_to    
538         unsigned long dev_ino = irq_data_to_in    
539         unsigned long cpuid;                      
540         int err;                                  
541                                                   
542         cpuid = irq_choose_cpu(data->irq, mask    
543                                                   
544         err = sun4v_vintr_set_target(dev_handl    
545         if (err != HV_EOK)                        
546                 printk(KERN_ERR "sun4v_vintr_s    
547                        "err(%d)\n",               
548                        dev_handle, dev_ino, cp    
549                                                   
550         return 0;                                 
551 }                                                 
552                                                   
553 static void sun4v_virq_disable(struct irq_data    
554 {                                                 
555         unsigned long dev_handle = irq_data_to    
556         unsigned long dev_ino = irq_data_to_in    
557         int err;                                  
558                                                   
559                                                   
560         err = sun4v_vintr_set_valid(dev_handle    
561                                     HV_INTR_DI    
562         if (err != HV_EOK)                        
563                 printk(KERN_ERR "sun4v_vintr_s    
564                        "HV_INTR_DISABLED): err    
565                        dev_handle, dev_ino, er    
566 }                                                 
567                                                   
568 static void sun4v_virq_eoi(struct irq_data *da    
569 {                                                 
570         unsigned long dev_handle = irq_data_to    
571         unsigned long dev_ino = irq_data_to_in    
572         int err;                                  
573                                                   
574         err = sun4v_vintr_set_state(dev_handle    
575                                     HV_INTR_ST    
576         if (err != HV_EOK)                        
577                 printk(KERN_ERR "sun4v_vintr_s    
578                        "HV_INTR_STATE_IDLE): e    
579                        dev_handle, dev_ino, er    
580 }                                                 
581                                                   
582 static struct irq_chip sun4u_irq = {              
583         .name                   = "sun4u",        
584         .irq_enable             = sun4u_irq_en    
585         .irq_disable            = sun4u_irq_di    
586         .irq_eoi                = sun4u_irq_eo    
587         .irq_set_affinity       = sun4u_set_af    
588         .flags                  = IRQCHIP_EOI_    
589 };                                                
590                                                   
591 static struct irq_chip sun4v_irq = {              
592         .name                   = "sun4v",        
593         .irq_enable             = sun4v_irq_en    
594         .irq_disable            = sun4v_irq_di    
595         .irq_eoi                = sun4v_irq_eo    
596         .irq_set_affinity       = sun4v_set_af    
597         .flags                  = IRQCHIP_EOI_    
598 };                                                
599                                                   
600 static struct irq_chip sun4v_virq = {             
601         .name                   = "vsun4v",       
602         .irq_enable             = sun4v_virq_e    
603         .irq_disable            = sun4v_virq_d    
604         .irq_eoi                = sun4v_virq_e    
605         .irq_set_affinity       = sun4v_virt_s    
606         .flags                  = IRQCHIP_EOI_    
607 };                                                
608                                                   
609 unsigned int build_irq(int inofixup, unsigned     
610 {                                                 
611         struct irq_handler_data *handler_data;    
612         struct ino_bucket *bucket;                
613         unsigned int irq;                         
614         int ino;                                  
615                                                   
616         BUG_ON(tlb_type == hypervisor);           
617                                                   
618         ino = (upa_readq(imap) & (IMAP_IGN | I    
619         bucket = &ivector_table[ino];             
620         irq = bucket_get_irq(__pa(bucket));       
621         if (!irq) {                               
622                 irq = irq_alloc(0, ino);          
623                 bucket_set_irq(__pa(bucket), i    
624                 irq_set_chip_and_handler_name(    
625                                                   
626         }                                         
627                                                   
628         handler_data = irq_get_handler_data(ir    
629         if (unlikely(handler_data))               
630                 goto out;                         
631                                                   
632         handler_data = kzalloc(sizeof(struct i    
633         if (unlikely(!handler_data)) {            
634                 prom_printf("IRQ: kzalloc(irq_    
635                 prom_halt();                      
636         }                                         
637         irq_set_handler_data(irq, handler_data    
638                                                   
639         handler_data->imap  = imap;               
640         handler_data->iclr  = iclr;               
641                                                   
642 out:                                              
643         return irq;                               
644 }                                                 
645                                                   
646 static unsigned int sun4v_build_common(u32 dev    
647                 void (*handler_data_init)(stru    
648                 u32 devhandle, unsigned int de    
649                 struct irq_chip *chip)            
650 {                                                 
651         struct irq_handler_data *data;            
652         unsigned int irq;                         
653                                                   
654         irq = irq_alloc(devhandle, devino);       
655         if (!irq)                                 
656                 goto out;                         
657                                                   
658         data = kzalloc(sizeof(struct irq_handl    
659         if (unlikely(!data)) {                    
660                 pr_err("IRQ handler data alloc    
661                 irq_free(irq);                    
662                 irq = 0;                          
663                 goto out;                         
664         }                                         
665                                                   
666         irq_set_handler_data(irq, data);          
667         handler_data_init(data, devhandle, dev    
668         irq_set_chip_and_handler_name(irq, chi    
669         data->imap = ~0UL;                        
670         data->iclr = ~0UL;                        
671 out:                                              
672         return irq;                               
673 }                                                 
674                                                   
675 static unsigned long cookie_assign(unsigned in    
676                 unsigned int devino)              
677 {                                                 
678         struct irq_handler_data *ihd = irq_get    
679         unsigned long hv_error, cookie;           
680                                                   
681         /* handler_irq needs to find the irq.     
682          * sun4v_dev_mondo and treated as a no    
683          */                                       
684         ihd->bucket.__irq = irq;                  
685         cookie = ~__pa(&ihd->bucket);             
686                                                   
687         hv_error = sun4v_vintr_set_cookie(devh    
688         if (hv_error)                             
689                 pr_err("HV vintr set cookie fa    
690                                                   
691         return hv_error;                          
692 }                                                 
693                                                   
694 static void cookie_handler_data(struct irq_han    
695                                 u32 devhandle,    
696 {                                                 
697         data->dev_handle = devhandle;             
698         data->dev_ino = devino;                   
699 }                                                 
700                                                   
701 static unsigned int cookie_build_irq(u32 devha    
702                                      struct ir    
703 {                                                 
704         unsigned long hv_error;                   
705         unsigned int irq;                         
706                                                   
707         irq = sun4v_build_common(devhandle, de    
708                                                   
709         hv_error = cookie_assign(irq, devhandl    
710         if (hv_error) {                           
711                 irq_free(irq);                    
712                 irq = 0;                          
713         }                                         
714                                                   
715         return irq;                               
716 }                                                 
717                                                   
718 static unsigned int sun4v_build_cookie(u32 dev    
719 {                                                 
720         unsigned int irq;                         
721                                                   
722         irq = cookie_exists(devhandle, devino)    
723         if (irq)                                  
724                 goto out;                         
725                                                   
726         irq = cookie_build_irq(devhandle, devi    
727                                                   
728 out:                                              
729         return irq;                               
730 }                                                 
731                                                   
732 static void sysino_set_bucket(unsigned int irq    
733 {                                                 
734         struct irq_handler_data *ihd = irq_get    
735         struct ino_bucket *bucket;                
736         unsigned long sysino;                     
737                                                   
738         sysino = sun4v_devino_to_sysino(ihd->d    
739         BUG_ON(sysino >= nr_ivec);                
740         bucket = &ivector_table[sysino];          
741         bucket_set_irq(__pa(bucket), irq);        
742 }                                                 
743                                                   
744 static void sysino_handler_data(struct irq_han    
745                                 u32 devhandle,    
746 {                                                 
747         unsigned long sysino;                     
748                                                   
749         sysino = sun4v_devino_to_sysino(devhan    
750         data->sysino = sysino;                    
751 }                                                 
752                                                   
753 static unsigned int sysino_build_irq(u32 devha    
754                                      struct ir    
755 {                                                 
756         unsigned int irq;                         
757                                                   
758         irq = sun4v_build_common(devhandle, de    
759         if (!irq)                                 
760                 goto out;                         
761                                                   
762         sysino_set_bucket(irq);                   
763 out:                                              
764         return irq;                               
765 }                                                 
766                                                   
767 static int sun4v_build_sysino(u32 devhandle, u    
768 {                                                 
769         int irq;                                  
770                                                   
771         irq = sysino_exists(devhandle, devino)    
772         if (irq)                                  
773                 goto out;                         
774                                                   
775         irq = sysino_build_irq(devhandle, devi    
776 out:                                              
777         return irq;                               
778 }                                                 
779                                                   
780 unsigned int sun4v_build_irq(u32 devhandle, un    
781 {                                                 
782         unsigned int irq;                         
783                                                   
784         if (sun4v_cookie_only_virqs())            
785                 irq = sun4v_build_cookie(devha    
786         else                                      
787                 irq = sun4v_build_sysino(devha    
788                                                   
789         return irq;                               
790 }                                                 
791                                                   
792 unsigned int sun4v_build_virq(u32 devhandle, u    
793 {                                                 
794         int irq;                                  
795                                                   
796         irq = cookie_build_irq(devhandle, devi    
797         if (!irq)                                 
798                 goto out;                         
799                                                   
800         /* This is borrowed from the original     
801          */                                       
802         irq_set_status_flags(irq, IRQ_NOAUTOEN    
803                                                   
804 out:                                              
805         return irq;                               
806 }                                                 
807                                                   
808 void *hardirq_stack[NR_CPUS];                     
809 void *softirq_stack[NR_CPUS];                     
810                                                   
811 void __irq_entry handler_irq(int pil, struct p    
812 {                                                 
813         unsigned long pstate, bucket_pa;          
814         struct pt_regs *old_regs;                 
815         void *orig_sp;                            
816                                                   
817         clear_softint(1 << pil);                  
818                                                   
819         old_regs = set_irq_regs(regs);            
820         irq_enter();                              
821                                                   
822         /* Grab an atomic snapshot of the pend    
823         __asm__ __volatile__("rdpr      %%psta    
824                              "wrpr      %0, %3    
825                              "ldx       [%2],     
826                              "stx       %%g0,     
827                              "wrpr      %0, 0x    
828                              : "=&r" (pstate),    
829                              : "r" (irq_work_p    
830                                "i" (PSTATE_IE)    
831                              : "memory");         
832                                                   
833         orig_sp = set_hardirq_stack();            
834                                                   
835         while (bucket_pa) {                       
836                 unsigned long next_pa;            
837                 unsigned int irq;                 
838                                                   
839                 next_pa = bucket_get_chain_pa(    
840                 irq = bucket_get_irq(bucket_pa    
841                 bucket_clear_chain_pa(bucket_p    
842                                                   
843                 generic_handle_irq(irq);          
844                                                   
845                 bucket_pa = next_pa;              
846         }                                         
847                                                   
848         restore_hardirq_stack(orig_sp);           
849                                                   
850         irq_exit();                               
851         set_irq_regs(old_regs);                   
852 }                                                 
853                                                   
854 #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK                
855 void do_softirq_own_stack(void)                   
856 {                                                 
857         void *orig_sp, *sp = softirq_stack[smp    
858                                                   
859         sp += THREAD_SIZE - 192 - STACK_BIAS;     
860                                                   
861         __asm__ __volatile__("mov %%sp, %0\n\t    
862                              "mov %1, %%sp"       
863                              : "=&r" (orig_sp)    
864                              : "r" (sp));         
865         __do_softirq();                           
866         __asm__ __volatile__("mov %0, %%sp"       
867                              : : "r" (orig_sp)    
868 }                                                 
869 #endif                                            
870                                                   
871 #ifdef CONFIG_HOTPLUG_CPU                         
872 void fixup_irqs(void)                             
873 {                                                 
874         unsigned int irq;                         
875                                                   
876         for (irq = 0; irq < NR_IRQS; irq++) {     
877                 struct irq_desc *desc = irq_to    
878                 struct irq_data *data;            
879                 unsigned long flags;              
880                                                   
881                 if (!desc)                        
882                         continue;                 
883                 data = irq_desc_get_irq_data(d    
884                 raw_spin_lock_irqsave(&desc->l    
885                 if (desc->action && !irqd_is_p    
886                         if (data->chip->irq_se    
887                                 data->chip->ir    
888                                         irq_da    
889                                         false)    
890                 }                                 
891                 raw_spin_unlock_irqrestore(&de    
892         }                                         
893                                                   
894         tick_ops->disable_irq();                  
895 }                                                 
896 #endif                                            
897                                                   
898 struct sun5_timer {                               
899         u64     count0;                           
900         u64     limit0;                           
901         u64     count1;                           
902         u64     limit1;                           
903 };                                                
904                                                   
905 static struct sun5_timer *prom_timers;            
906 static u64 prom_limit0, prom_limit1;              
907                                                   
908 static void map_prom_timers(void)                 
909 {                                                 
910         struct device_node *dp;                   
911         const unsigned int *addr;                 
912                                                   
913         /* PROM timer node hangs out in the to    
914         dp = of_find_node_by_path("/");           
915         dp = dp->child;                           
916         while (dp) {                              
917                 if (of_node_name_eq(dp, "count    
918                         break;                    
919                 dp = dp->sibling;                 
920         }                                         
921                                                   
922         /* Assume if node is not present, PROM    
923          * which we should not care about.        
924          */                                       
925         if (!dp) {                                
926                 prom_timers = (struct sun5_tim    
927                 return;                           
928         }                                         
929                                                   
930         /* If PROM is really using this, it mu    
931         addr = of_get_property(dp, "address",     
932         if (!addr) {                              
933                 prom_printf("PROM does not hav    
934                 prom_timers = (struct sun5_tim    
935                 return;                           
936         }                                         
937         prom_timers = (struct sun5_timer *) ((    
938 }                                                 
939                                                   
940 static void kill_prom_timer(void)                 
941 {                                                 
942         if (!prom_timers)                         
943                 return;                           
944                                                   
945         /* Save them away for later. */           
946         prom_limit0 = prom_timers->limit0;        
947         prom_limit1 = prom_timers->limit1;        
948                                                   
949         /* Just as in sun4c PROM uses timer wh    
950          * We turn both off here just to be pa    
951          */                                       
952         prom_timers->limit0 = 0;                  
953         prom_timers->limit1 = 0;                  
954                                                   
955         /* Wheee, eat the interrupt packet too    
956         __asm__ __volatile__(                     
957 "       mov     0x40, %%g2\n"                     
958 "       ldxa    [%%g0] %0, %%g1\n"                
959 "       ldxa    [%%g2] %1, %%g1\n"                
960 "       stxa    %%g0, [%%g0] %0\n"                
961 "       membar  #Sync\n"                          
962         : /* no outputs */                        
963         : "i" (ASI_INTR_RECEIVE), "i" (ASI_INT    
964         : "g1", "g2");                            
965 }                                                 
966                                                   
967 void notrace init_irqwork_curcpu(void)            
968 {                                                 
969         int cpu = hard_smp_processor_id();        
970                                                   
971         trap_block[cpu].irq_worklist_pa = 0UL;    
972 }                                                 
973                                                   
974 /* Please be very careful with register_one_mo    
975  * sun4v_register_mondo_queues().                 
976  *                                                
977  * On SMP this gets invoked from the CPU tramp    
978  * the cpu has fully taken over the trap table    
979  * and its kernel stack + %g6 thread register     
980  * not fully cooked yet.                          
981  *                                                
982  * Therefore you cannot make any OBP calls, no    
983  * from these two routines.                       
984  */                                               
985 static void notrace register_one_mondo(unsigne    
986                                        unsigne    
987 {                                                 
988         unsigned long num_entries = (qmask + 1    
989         unsigned long status;                     
990                                                   
991         status = sun4v_cpu_qconf(type, paddr,     
992         if (status != HV_EOK) {                   
993                 prom_printf("SUN4V: sun4v_cpu_    
994                             "err %lu\n", type,    
995                 prom_halt();                      
996         }                                         
997 }                                                 
998                                                   
999 void notrace sun4v_register_mondo_queues(int t    
1000 {                                                
1001         struct trap_per_cpu *tb = &trap_block    
1002                                                  
1003         register_one_mondo(tb->cpu_mondo_pa,     
1004                            tb->cpu_mondo_qmas    
1005         register_one_mondo(tb->dev_mondo_pa,     
1006                            tb->dev_mondo_qmas    
1007         register_one_mondo(tb->resum_mondo_pa    
1008                            tb->resum_qmask);     
1009         register_one_mondo(tb->nonresum_mondo    
1010                            tb->nonresum_qmask    
1011 }                                                
1012                                                  
1013 /* Each queue region must be a power of 2 mul    
1014  * size.  The base real address must be align    
1015  * region.  Thus, an 8KB queue must be 8KB al    
1016  */                                              
1017 static void __init alloc_one_queue(unsigned l    
1018 {                                                
1019         unsigned long size = PAGE_ALIGN(qmask    
1020         unsigned long order = get_order(size)    
1021         unsigned long p;                         
1022                                                  
1023         p = __get_free_pages(GFP_KERNEL | __G    
1024         if (!p) {                                
1025                 prom_printf("SUN4V: Error, ca    
1026                 prom_halt();                     
1027         }                                        
1028                                                  
1029         *pa_ptr = __pa(p);                       
1030 }                                                
1031                                                  
1032 static void __init init_cpu_send_mondo_info(s    
1033 {                                                
1034 #ifdef CONFIG_SMP                                
1035         unsigned long page;                      
1036         void *mondo, *p;                         
1037                                                  
1038         BUILD_BUG_ON((NR_CPUS * sizeof(u16))     
1039                                                  
1040         /* Make sure mondo block is 64byte al    
1041         p = kzalloc(127, GFP_KERNEL);            
1042         if (!p) {                                
1043                 prom_printf("SUN4V: Error, ca    
1044                 prom_halt();                     
1045         }                                        
1046         mondo = (void *)(((unsigned long)p +     
1047         tb->cpu_mondo_block_pa = __pa(mondo);    
1048                                                  
1049         page = get_zeroed_page(GFP_KERNEL);      
1050         if (!page) {                             
1051                 prom_printf("SUN4V: Error, ca    
1052                 prom_halt();                     
1053         }                                        
1054                                                  
1055         tb->cpu_list_pa = __pa(page);            
1056 #endif                                           
1057 }                                                
1058                                                  
1059 /* Allocate mondo and error queues for all po    
1060 static void __init sun4v_init_mondo_queues(vo    
1061 {                                                
1062         int cpu;                                 
1063                                                  
1064         for_each_possible_cpu(cpu) {             
1065                 struct trap_per_cpu *tb = &tr    
1066                                                  
1067                 alloc_one_queue(&tb->cpu_mond    
1068                 alloc_one_queue(&tb->dev_mond    
1069                 alloc_one_queue(&tb->resum_mo    
1070                 alloc_one_queue(&tb->resum_ke    
1071                 alloc_one_queue(&tb->nonresum    
1072                 alloc_one_queue(&tb->nonresum    
1073                                 tb->nonresum_    
1074         }                                        
1075 }                                                
1076                                                  
1077 static void __init init_send_mondo_info(void)    
1078 {                                                
1079         int cpu;                                 
1080                                                  
1081         for_each_possible_cpu(cpu) {             
1082                 struct trap_per_cpu *tb = &tr    
1083                                                  
1084                 init_cpu_send_mondo_info(tb);    
1085         }                                        
1086 }                                                
1087                                                  
1088 static struct irqaction timer_irq_action = {     
1089         .name = "timer",                         
1090 };                                               
1091                                                  
1092 static void __init irq_ivector_init(void)        
1093 {                                                
1094         unsigned long size, order;               
1095         unsigned int ivecs;                      
1096                                                  
1097         /* If we are doing cookie only VIRQs     
1098          * table to process interrupts.          
1099          */                                      
1100         if (sun4v_cookie_only_virqs())           
1101                 return;                          
1102                                                  
1103         ivecs = size_nr_ivec();                  
1104         size = sizeof(struct ino_bucket) * iv    
1105         order = get_order(size);                 
1106         ivector_table = (struct ino_bucket *)    
1107                 __get_free_pages(GFP_KERNEL |    
1108         if (!ivector_table) {                    
1109                 prom_printf("Fatal error, can    
1110                 prom_halt();                     
1111         }                                        
1112         __flush_dcache_range((unsigned long)     
1113                              ((unsigned long)    
1114                                                  
1115         ivector_table_pa = __pa(ivector_table    
1116 }                                                
1117                                                  
1118 /* Only invoked on boot processor.*/             
1119 void __init init_IRQ(void)                       
1120 {                                                
1121         irq_init_hv();                           
1122         irq_ivector_init();                      
1123         map_prom_timers();                       
1124         kill_prom_timer();                       
1125                                                  
1126         if (tlb_type == hypervisor)              
1127                 sun4v_init_mondo_queues();       
1128                                                  
1129         init_send_mondo_info();                  
1130                                                  
1131         if (tlb_type == hypervisor) {            
1132                 /* Load up the boot cpu's ent    
1133                 sun4v_register_mondo_queues(h    
1134         }                                        
1135                                                  
1136         /* We need to clear any IRQ's pending    
1137          * registers, a spurious one could be    
1138          * PROM timer which we just disabled.    
1139          */                                      
1140         clear_softint(get_softint());            
1141                                                  
1142         /* Now that ivector table is initiali    
1143          * to receive IRQ vector traps.  We w    
1144          * one or two right now, in case some    
1145          * to boot us wants to speak to us.      
1146          */                                      
1147         __asm__ __volatile__("rdpr      %%pst    
1148                              "or        %%g1,    
1149                              "wrpr      %%g1,    
1150                              : /* No outputs     
1151                              : "i" (PSTATE_IE    
1152                              : "g1");            
1153                                                  
1154         irq_to_desc(0)->action = &timer_irq_a    
1155 }                                                
1156                                                  

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php