root/drivers/soc/fsl/qe/qe_ic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qe_ic_read
  2. qe_ic_write
  3. qe_ic_from_irq
  4. qe_ic_from_irq_data
  5. qe_ic_unmask_irq
  6. qe_ic_mask_irq
  7. qe_ic_host_match
  8. qe_ic_host_map
  9. qe_ic_get_low_irq
  10. qe_ic_get_high_irq
  11. qe_ic_init
  12. qe_ic_set_highest_priority
  13. qe_ic_set_priority
  14. qe_ic_set_high_priority
  15. init_qe_ic_sysfs

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * arch/powerpc/sysdev/qe_lib/qe_ic.c
   4  *
   5  * Copyright (C) 2006 Freescale Semiconductor, Inc.  All rights reserved.
   6  *
   7  * Author: Li Yang <leoli@freescale.com>
   8  * Based on code from Shlomi Gridish <gridish@freescale.com>
   9  *
  10  * QUICC ENGINE Interrupt Controller
  11  */
  12 
  13 #include <linux/of_irq.h>
  14 #include <linux/of_address.h>
  15 #include <linux/kernel.h>
  16 #include <linux/init.h>
  17 #include <linux/errno.h>
  18 #include <linux/reboot.h>
  19 #include <linux/slab.h>
  20 #include <linux/stddef.h>
  21 #include <linux/sched.h>
  22 #include <linux/signal.h>
  23 #include <linux/device.h>
  24 #include <linux/spinlock.h>
  25 #include <asm/irq.h>
  26 #include <asm/io.h>
  27 #include <soc/fsl/qe/qe_ic.h>
  28 
  29 #include "qe_ic.h"
  30 
  31 static DEFINE_RAW_SPINLOCK(qe_ic_lock);
  32 
  33 static struct qe_ic_info qe_ic_info[] = {
  34         [1] = {
  35                .mask = 0x00008000,
  36                .mask_reg = QEIC_CIMR,
  37                .pri_code = 0,
  38                .pri_reg = QEIC_CIPWCC,
  39                },
  40         [2] = {
  41                .mask = 0x00004000,
  42                .mask_reg = QEIC_CIMR,
  43                .pri_code = 1,
  44                .pri_reg = QEIC_CIPWCC,
  45                },
  46         [3] = {
  47                .mask = 0x00002000,
  48                .mask_reg = QEIC_CIMR,
  49                .pri_code = 2,
  50                .pri_reg = QEIC_CIPWCC,
  51                },
  52         [10] = {
  53                 .mask = 0x00000040,
  54                 .mask_reg = QEIC_CIMR,
  55                 .pri_code = 1,
  56                 .pri_reg = QEIC_CIPZCC,
  57                 },
  58         [11] = {
  59                 .mask = 0x00000020,
  60                 .mask_reg = QEIC_CIMR,
  61                 .pri_code = 2,
  62                 .pri_reg = QEIC_CIPZCC,
  63                 },
  64         [12] = {
  65                 .mask = 0x00000010,
  66                 .mask_reg = QEIC_CIMR,
  67                 .pri_code = 3,
  68                 .pri_reg = QEIC_CIPZCC,
  69                 },
  70         [13] = {
  71                 .mask = 0x00000008,
  72                 .mask_reg = QEIC_CIMR,
  73                 .pri_code = 4,
  74                 .pri_reg = QEIC_CIPZCC,
  75                 },
  76         [14] = {
  77                 .mask = 0x00000004,
  78                 .mask_reg = QEIC_CIMR,
  79                 .pri_code = 5,
  80                 .pri_reg = QEIC_CIPZCC,
  81                 },
  82         [15] = {
  83                 .mask = 0x00000002,
  84                 .mask_reg = QEIC_CIMR,
  85                 .pri_code = 6,
  86                 .pri_reg = QEIC_CIPZCC,
  87                 },
  88         [20] = {
  89                 .mask = 0x10000000,
  90                 .mask_reg = QEIC_CRIMR,
  91                 .pri_code = 3,
  92                 .pri_reg = QEIC_CIPRTA,
  93                 },
  94         [25] = {
  95                 .mask = 0x00800000,
  96                 .mask_reg = QEIC_CRIMR,
  97                 .pri_code = 0,
  98                 .pri_reg = QEIC_CIPRTB,
  99                 },
 100         [26] = {
 101                 .mask = 0x00400000,
 102                 .mask_reg = QEIC_CRIMR,
 103                 .pri_code = 1,
 104                 .pri_reg = QEIC_CIPRTB,
 105                 },
 106         [27] = {
 107                 .mask = 0x00200000,
 108                 .mask_reg = QEIC_CRIMR,
 109                 .pri_code = 2,
 110                 .pri_reg = QEIC_CIPRTB,
 111                 },
 112         [28] = {
 113                 .mask = 0x00100000,
 114                 .mask_reg = QEIC_CRIMR,
 115                 .pri_code = 3,
 116                 .pri_reg = QEIC_CIPRTB,
 117                 },
 118         [32] = {
 119                 .mask = 0x80000000,
 120                 .mask_reg = QEIC_CIMR,
 121                 .pri_code = 0,
 122                 .pri_reg = QEIC_CIPXCC,
 123                 },
 124         [33] = {
 125                 .mask = 0x40000000,
 126                 .mask_reg = QEIC_CIMR,
 127                 .pri_code = 1,
 128                 .pri_reg = QEIC_CIPXCC,
 129                 },
 130         [34] = {
 131                 .mask = 0x20000000,
 132                 .mask_reg = QEIC_CIMR,
 133                 .pri_code = 2,
 134                 .pri_reg = QEIC_CIPXCC,
 135                 },
 136         [35] = {
 137                 .mask = 0x10000000,
 138                 .mask_reg = QEIC_CIMR,
 139                 .pri_code = 3,
 140                 .pri_reg = QEIC_CIPXCC,
 141                 },
 142         [36] = {
 143                 .mask = 0x08000000,
 144                 .mask_reg = QEIC_CIMR,
 145                 .pri_code = 4,
 146                 .pri_reg = QEIC_CIPXCC,
 147                 },
 148         [40] = {
 149                 .mask = 0x00800000,
 150                 .mask_reg = QEIC_CIMR,
 151                 .pri_code = 0,
 152                 .pri_reg = QEIC_CIPYCC,
 153                 },
 154         [41] = {
 155                 .mask = 0x00400000,
 156                 .mask_reg = QEIC_CIMR,
 157                 .pri_code = 1,
 158                 .pri_reg = QEIC_CIPYCC,
 159                 },
 160         [42] = {
 161                 .mask = 0x00200000,
 162                 .mask_reg = QEIC_CIMR,
 163                 .pri_code = 2,
 164                 .pri_reg = QEIC_CIPYCC,
 165                 },
 166         [43] = {
 167                 .mask = 0x00100000,
 168                 .mask_reg = QEIC_CIMR,
 169                 .pri_code = 3,
 170                 .pri_reg = QEIC_CIPYCC,
 171                 },
 172 };
 173 
 174 static inline u32 qe_ic_read(volatile __be32  __iomem * base, unsigned int reg)
 175 {
 176         return in_be32(base + (reg >> 2));
 177 }
 178 
 179 static inline void qe_ic_write(volatile __be32  __iomem * base, unsigned int reg,
 180                                u32 value)
 181 {
 182         out_be32(base + (reg >> 2), value);
 183 }
 184 
 185 static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
 186 {
 187         return irq_get_chip_data(virq);
 188 }
 189 
 190 static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
 191 {
 192         return irq_data_get_irq_chip_data(d);
 193 }
 194 
 195 static void qe_ic_unmask_irq(struct irq_data *d)
 196 {
 197         struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
 198         unsigned int src = irqd_to_hwirq(d);
 199         unsigned long flags;
 200         u32 temp;
 201 
 202         raw_spin_lock_irqsave(&qe_ic_lock, flags);
 203 
 204         temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
 205         qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
 206                     temp | qe_ic_info[src].mask);
 207 
 208         raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
 209 }
 210 
 211 static void qe_ic_mask_irq(struct irq_data *d)
 212 {
 213         struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
 214         unsigned int src = irqd_to_hwirq(d);
 215         unsigned long flags;
 216         u32 temp;
 217 
 218         raw_spin_lock_irqsave(&qe_ic_lock, flags);
 219 
 220         temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
 221         qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
 222                     temp & ~qe_ic_info[src].mask);
 223 
 224         /* Flush the above write before enabling interrupts; otherwise,
 225          * spurious interrupts will sometimes happen.  To be 100% sure
 226          * that the write has reached the device before interrupts are
 227          * enabled, the mask register would have to be read back; however,
 228          * this is not required for correctness, only to avoid wasting
 229          * time on a large number of spurious interrupts.  In testing,
 230          * a sync reduced the observed spurious interrupts to zero.
 231          */
 232         mb();
 233 
 234         raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
 235 }
 236 
 237 static struct irq_chip qe_ic_irq_chip = {
 238         .name = "QEIC",
 239         .irq_unmask = qe_ic_unmask_irq,
 240         .irq_mask = qe_ic_mask_irq,
 241         .irq_mask_ack = qe_ic_mask_irq,
 242 };
 243 
 244 static int qe_ic_host_match(struct irq_domain *h, struct device_node *node,
 245                             enum irq_domain_bus_token bus_token)
 246 {
 247         /* Exact match, unless qe_ic node is NULL */
 248         struct device_node *of_node = irq_domain_get_of_node(h);
 249         return of_node == NULL || of_node == node;
 250 }
 251 
 252 static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
 253                           irq_hw_number_t hw)
 254 {
 255         struct qe_ic *qe_ic = h->host_data;
 256         struct irq_chip *chip;
 257 
 258         if (hw >= ARRAY_SIZE(qe_ic_info)) {
 259                 pr_err("%s: Invalid hw irq number for QEIC\n", __func__);
 260                 return -EINVAL;
 261         }
 262 
 263         if (qe_ic_info[hw].mask == 0) {
 264                 printk(KERN_ERR "Can't map reserved IRQ\n");
 265                 return -EINVAL;
 266         }
 267         /* Default chip */
 268         chip = &qe_ic->hc_irq;
 269 
 270         irq_set_chip_data(virq, qe_ic);
 271         irq_set_status_flags(virq, IRQ_LEVEL);
 272 
 273         irq_set_chip_and_handler(virq, chip, handle_level_irq);
 274 
 275         return 0;
 276 }
 277 
 278 static const struct irq_domain_ops qe_ic_host_ops = {
 279         .match = qe_ic_host_match,
 280         .map = qe_ic_host_map,
 281         .xlate = irq_domain_xlate_onetwocell,
 282 };
 283 
 284 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
 285 unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
 286 {
 287         int irq;
 288 
 289         BUG_ON(qe_ic == NULL);
 290 
 291         /* get the interrupt source vector. */
 292         irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
 293 
 294         if (irq == 0)
 295                 return NO_IRQ;
 296 
 297         return irq_linear_revmap(qe_ic->irqhost, irq);
 298 }
 299 
 300 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
 301 unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
 302 {
 303         int irq;
 304 
 305         BUG_ON(qe_ic == NULL);
 306 
 307         /* get the interrupt source vector. */
 308         irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
 309 
 310         if (irq == 0)
 311                 return NO_IRQ;
 312 
 313         return irq_linear_revmap(qe_ic->irqhost, irq);
 314 }
 315 
 316 void __init qe_ic_init(struct device_node *node, unsigned int flags,
 317                        void (*low_handler)(struct irq_desc *desc),
 318                        void (*high_handler)(struct irq_desc *desc))
 319 {
 320         struct qe_ic *qe_ic;
 321         struct resource res;
 322         u32 temp = 0, ret, high_active = 0;
 323 
 324         ret = of_address_to_resource(node, 0, &res);
 325         if (ret)
 326                 return;
 327 
 328         qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
 329         if (qe_ic == NULL)
 330                 return;
 331 
 332         qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
 333                                                &qe_ic_host_ops, qe_ic);
 334         if (qe_ic->irqhost == NULL) {
 335                 kfree(qe_ic);
 336                 return;
 337         }
 338 
 339         qe_ic->regs = ioremap(res.start, resource_size(&res));
 340 
 341         qe_ic->hc_irq = qe_ic_irq_chip;
 342 
 343         qe_ic->virq_high = irq_of_parse_and_map(node, 0);
 344         qe_ic->virq_low = irq_of_parse_and_map(node, 1);
 345 
 346         if (qe_ic->virq_low == NO_IRQ) {
 347                 printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
 348                 kfree(qe_ic);
 349                 return;
 350         }
 351 
 352         /* default priority scheme is grouped. If spread mode is    */
 353         /* required, configure cicr accordingly.                    */
 354         if (flags & QE_IC_SPREADMODE_GRP_W)
 355                 temp |= CICR_GWCC;
 356         if (flags & QE_IC_SPREADMODE_GRP_X)
 357                 temp |= CICR_GXCC;
 358         if (flags & QE_IC_SPREADMODE_GRP_Y)
 359                 temp |= CICR_GYCC;
 360         if (flags & QE_IC_SPREADMODE_GRP_Z)
 361                 temp |= CICR_GZCC;
 362         if (flags & QE_IC_SPREADMODE_GRP_RISCA)
 363                 temp |= CICR_GRTA;
 364         if (flags & QE_IC_SPREADMODE_GRP_RISCB)
 365                 temp |= CICR_GRTB;
 366 
 367         /* choose destination signal for highest priority interrupt */
 368         if (flags & QE_IC_HIGH_SIGNAL) {
 369                 temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
 370                 high_active = 1;
 371         }
 372 
 373         qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
 374 
 375         irq_set_handler_data(qe_ic->virq_low, qe_ic);
 376         irq_set_chained_handler(qe_ic->virq_low, low_handler);
 377 
 378         if (qe_ic->virq_high != NO_IRQ &&
 379                         qe_ic->virq_high != qe_ic->virq_low) {
 380                 irq_set_handler_data(qe_ic->virq_high, qe_ic);
 381                 irq_set_chained_handler(qe_ic->virq_high, high_handler);
 382         }
 383 }
 384 
 385 void qe_ic_set_highest_priority(unsigned int virq, int high)
 386 {
 387         struct qe_ic *qe_ic = qe_ic_from_irq(virq);
 388         unsigned int src = virq_to_hw(virq);
 389         u32 temp = 0;
 390 
 391         temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
 392 
 393         temp &= ~CICR_HP_MASK;
 394         temp |= src << CICR_HP_SHIFT;
 395 
 396         temp &= ~CICR_HPIT_MASK;
 397         temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
 398 
 399         qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
 400 }
 401 
 402 /* Set Priority level within its group, from 1 to 8 */
 403 int qe_ic_set_priority(unsigned int virq, unsigned int priority)
 404 {
 405         struct qe_ic *qe_ic = qe_ic_from_irq(virq);
 406         unsigned int src = virq_to_hw(virq);
 407         u32 temp;
 408 
 409         if (priority > 8 || priority == 0)
 410                 return -EINVAL;
 411         if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
 412                       "%s: Invalid hw irq number for QEIC\n", __func__))
 413                 return -EINVAL;
 414         if (qe_ic_info[src].pri_reg == 0)
 415                 return -EINVAL;
 416 
 417         temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
 418 
 419         if (priority < 4) {
 420                 temp &= ~(0x7 << (32 - priority * 3));
 421                 temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
 422         } else {
 423                 temp &= ~(0x7 << (24 - priority * 3));
 424                 temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
 425         }
 426 
 427         qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
 428 
 429         return 0;
 430 }
 431 
 432 /* Set a QE priority to use high irq, only priority 1~2 can use high irq */
 433 int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
 434 {
 435         struct qe_ic *qe_ic = qe_ic_from_irq(virq);
 436         unsigned int src = virq_to_hw(virq);
 437         u32 temp, control_reg = QEIC_CICNR, shift = 0;
 438 
 439         if (priority > 2 || priority == 0)
 440                 return -EINVAL;
 441         if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
 442                       "%s: Invalid hw irq number for QEIC\n", __func__))
 443                 return -EINVAL;
 444 
 445         switch (qe_ic_info[src].pri_reg) {
 446         case QEIC_CIPZCC:
 447                 shift = CICNR_ZCC1T_SHIFT;
 448                 break;
 449         case QEIC_CIPWCC:
 450                 shift = CICNR_WCC1T_SHIFT;
 451                 break;
 452         case QEIC_CIPYCC:
 453                 shift = CICNR_YCC1T_SHIFT;
 454                 break;
 455         case QEIC_CIPXCC:
 456                 shift = CICNR_XCC1T_SHIFT;
 457                 break;
 458         case QEIC_CIPRTA:
 459                 shift = CRICR_RTA1T_SHIFT;
 460                 control_reg = QEIC_CRICR;
 461                 break;
 462         case QEIC_CIPRTB:
 463                 shift = CRICR_RTB1T_SHIFT;
 464                 control_reg = QEIC_CRICR;
 465                 break;
 466         default:
 467                 return -EINVAL;
 468         }
 469 
 470         shift += (2 - priority) * 2;
 471         temp = qe_ic_read(qe_ic->regs, control_reg);
 472         temp &= ~(SIGNAL_MASK << shift);
 473         temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
 474         qe_ic_write(qe_ic->regs, control_reg, temp);
 475 
 476         return 0;
 477 }
 478 
 479 static struct bus_type qe_ic_subsys = {
 480         .name = "qe_ic",
 481         .dev_name = "qe_ic",
 482 };
 483 
 484 static struct device device_qe_ic = {
 485         .id = 0,
 486         .bus = &qe_ic_subsys,
 487 };
 488 
 489 static int __init init_qe_ic_sysfs(void)
 490 {
 491         int rc;
 492 
 493         printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
 494 
 495         rc = subsys_system_register(&qe_ic_subsys, NULL);
 496         if (rc) {
 497                 printk(KERN_ERR "Failed registering qe_ic sys class\n");
 498                 return -ENODEV;
 499         }
 500         rc = device_register(&device_qe_ic);
 501         if (rc) {
 502                 printk(KERN_ERR "Failed registering qe_ic sys device\n");
 503                 return -ENODEV;
 504         }
 505         return 0;
 506 }
 507 
 508 subsys_initcall(init_qe_ic_sysfs);

/* [<][>][^][v][top][bottom][index][help] */