linux/arch/powerpc/sysdev/qe_lib/qe_ic.c

534 lines
12 KiB
C
Raw Normal View History

[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
/*
* arch/powerpc/sysdev/qe_lib/qe_ic.c
*
* Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
*
* Author: Li Yang <leoli@freescale.com>
* Based on code from Shlomi Gridish <gridish@freescale.com>
*
* QUICC ENGINE Interrupt Controller
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/sysdev.h>
#include <linux/device.h>
#include <linux/bootmem.h>
#include <linux/spinlock.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/qe_ic.h>
#include "qe_ic.h"
static DEFINE_SPINLOCK(qe_ic_lock);
static struct qe_ic_info qe_ic_info[] = {
[1] = {
.mask = 0x00008000,
.mask_reg = QEIC_CIMR,
.pri_code = 0,
.pri_reg = QEIC_CIPWCC,
},
[2] = {
.mask = 0x00004000,
.mask_reg = QEIC_CIMR,
.pri_code = 1,
.pri_reg = QEIC_CIPWCC,
},
[3] = {
.mask = 0x00002000,
.mask_reg = QEIC_CIMR,
.pri_code = 2,
.pri_reg = QEIC_CIPWCC,
},
[10] = {
.mask = 0x00000040,
.mask_reg = QEIC_CIMR,
.pri_code = 1,
.pri_reg = QEIC_CIPZCC,
},
[11] = {
.mask = 0x00000020,
.mask_reg = QEIC_CIMR,
.pri_code = 2,
.pri_reg = QEIC_CIPZCC,
},
[12] = {
.mask = 0x00000010,
.mask_reg = QEIC_CIMR,
.pri_code = 3,
.pri_reg = QEIC_CIPZCC,
},
[13] = {
.mask = 0x00000008,
.mask_reg = QEIC_CIMR,
.pri_code = 4,
.pri_reg = QEIC_CIPZCC,
},
[14] = {
.mask = 0x00000004,
.mask_reg = QEIC_CIMR,
.pri_code = 5,
.pri_reg = QEIC_CIPZCC,
},
[15] = {
.mask = 0x00000002,
.mask_reg = QEIC_CIMR,
.pri_code = 6,
.pri_reg = QEIC_CIPZCC,
},
[20] = {
.mask = 0x10000000,
.mask_reg = QEIC_CRIMR,
.pri_code = 3,
.pri_reg = QEIC_CIPRTA,
},
[25] = {
.mask = 0x00800000,
.mask_reg = QEIC_CRIMR,
.pri_code = 0,
.pri_reg = QEIC_CIPRTB,
},
[26] = {
.mask = 0x00400000,
.mask_reg = QEIC_CRIMR,
.pri_code = 1,
.pri_reg = QEIC_CIPRTB,
},
[27] = {
.mask = 0x00200000,
.mask_reg = QEIC_CRIMR,
.pri_code = 2,
.pri_reg = QEIC_CIPRTB,
},
[28] = {
.mask = 0x00100000,
.mask_reg = QEIC_CRIMR,
.pri_code = 3,
.pri_reg = QEIC_CIPRTB,
},
[32] = {
.mask = 0x80000000,
.mask_reg = QEIC_CIMR,
.pri_code = 0,
.pri_reg = QEIC_CIPXCC,
},
[33] = {
.mask = 0x40000000,
.mask_reg = QEIC_CIMR,
.pri_code = 1,
.pri_reg = QEIC_CIPXCC,
},
[34] = {
.mask = 0x20000000,
.mask_reg = QEIC_CIMR,
.pri_code = 2,
.pri_reg = QEIC_CIPXCC,
},
[35] = {
.mask = 0x10000000,
.mask_reg = QEIC_CIMR,
.pri_code = 3,
.pri_reg = QEIC_CIPXCC,
},
[36] = {
.mask = 0x08000000,
.mask_reg = QEIC_CIMR,
.pri_code = 4,
.pri_reg = QEIC_CIPXCC,
},
[40] = {
.mask = 0x00800000,
.mask_reg = QEIC_CIMR,
.pri_code = 0,
.pri_reg = QEIC_CIPYCC,
},
[41] = {
.mask = 0x00400000,
.mask_reg = QEIC_CIMR,
.pri_code = 1,
.pri_reg = QEIC_CIPYCC,
},
[42] = {
.mask = 0x00200000,
.mask_reg = QEIC_CIMR,
.pri_code = 2,
.pri_reg = QEIC_CIPYCC,
},
[43] = {
.mask = 0x00100000,
.mask_reg = QEIC_CIMR,
.pri_code = 3,
.pri_reg = QEIC_CIPYCC,
},
};
static inline u32 qe_ic_read(volatile __be32 __iomem * base, unsigned int reg)
{
return in_be32(base + (reg >> 2));
}
static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg,
u32 value)
{
out_be32(base + (reg >> 2), value);
}
static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
{
return irq_desc[virq].chip_data;
}
#define virq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
static void qe_ic_unmask_irq(unsigned int virq)
{
struct qe_ic *qe_ic = qe_ic_from_irq(virq);
unsigned int src = virq_to_hw(virq);
unsigned long flags;
u32 temp;
spin_lock_irqsave(&qe_ic_lock, flags);
temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
temp | qe_ic_info[src].mask);
spin_unlock_irqrestore(&qe_ic_lock, flags);
}
static void qe_ic_mask_irq(unsigned int virq)
{
struct qe_ic *qe_ic = qe_ic_from_irq(virq);
unsigned int src = virq_to_hw(virq);
unsigned long flags;
u32 temp;
spin_lock_irqsave(&qe_ic_lock, flags);
temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
temp & ~qe_ic_info[src].mask);
/* Flush the above write before enabling interrupts; otherwise,
* spurious interrupts will sometimes happen. To be 100% sure
* that the write has reached the device before interrupts are
* enabled, the mask register would have to be read back; however,
* this is not required for correctness, only to avoid wasting
* time on a large number of spurious interrupts. In testing,
* a sync reduced the observed spurious interrupts to zero.
*/
mb();
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
spin_unlock_irqrestore(&qe_ic_lock, flags);
}
static struct irq_chip qe_ic_irq_chip = {
.typename = " QEIC ",
.unmask = qe_ic_unmask_irq,
.mask = qe_ic_mask_irq,
.mask_ack = qe_ic_mask_irq,
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
};
static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
{
struct qe_ic *qe_ic = h->host_data;
/* Exact match, unless qe_ic node is NULL */
return qe_ic->of_node == NULL || qe_ic->of_node == node;
}
static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
struct qe_ic *qe_ic = h->host_data;
struct irq_chip *chip;
if (qe_ic_info[hw].mask == 0) {
printk(KERN_ERR "Can't map reserved IRQ \n");
return -EINVAL;
}
/* Default chip */
chip = &qe_ic->hc_irq;
set_irq_chip_data(virq, qe_ic);
get_irq_desc(virq)->status |= IRQ_LEVEL;
set_irq_chip_and_handler(virq, chip, handle_level_irq);
return 0;
}
static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct,
u32 * intspec, unsigned int intsize,
irq_hw_number_t * out_hwirq,
unsigned int *out_flags)
{
*out_hwirq = intspec[0];
if (intsize > 1)
*out_flags = intspec[1];
else
*out_flags = IRQ_TYPE_NONE;
return 0;
}
static struct irq_host_ops qe_ic_host_ops = {
.match = qe_ic_host_match,
.map = qe_ic_host_map,
.xlate = qe_ic_host_xlate,
};
/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
{
int irq;
BUG_ON(qe_ic == NULL);
/* get the interrupt source vector. */
irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
if (irq == 0)
return NO_IRQ;
return irq_linear_revmap(qe_ic->irqhost, irq);
}
/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
{
int irq;
BUG_ON(qe_ic == NULL);
/* get the interrupt source vector. */
irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
if (irq == 0)
return NO_IRQ;
return irq_linear_revmap(qe_ic->irqhost, irq);
}
void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc)
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
{
struct qe_ic *qe_ic = desc->handler_data;
unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
}
void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc)
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
{
struct qe_ic *qe_ic = desc->handler_data;
unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
}
void __init qe_ic_init(struct device_node *node, unsigned int flags)
{
struct qe_ic *qe_ic;
struct resource res;
u32 temp = 0, ret, high_active = 0;
qe_ic = alloc_bootmem(sizeof(struct qe_ic));
if (qe_ic == NULL)
return;
memset(qe_ic, 0, sizeof(struct qe_ic));
qe_ic->of_node = of_node_get(node);
[POWERPC] Add QUICC Engine (QE) infrastructure Add QUICC Engine (QE) configuration, header files, and QE management and library code that are used by QE devices drivers. Includes Leo's modifications up to, and including, the platform_device to of_device adaptation: "The series of patches add generic QE infrastructure called qe_lib, and MPC8360EMDS board support. Qe_lib is used by QE device drivers such as ucc_geth driver. This version updates QE interrupt controller to use new irq mapping mechanism, addresses all the comments received with last submission and includes some style fixes. v2: Change to use device tree for BCSR and MURAM; Remove I/O port interrupt handling code as it is not generic enough. v3: Address comments from Kumar; Update definition of several device tree nodes; Copyright style change." In addition, the following changes have been made: o removed typedefs o uint -> u32 conversions o removed following defines: QE_SIZEOF_BD, BD_BUFFER_ARG, BD_BUFFER_CLEAR, BD_BUFFER, BD_STATUS_AND_LENGTH_SET, BD_STATUS_AND_LENGTH, and BD_BUFFER_SET because they hid sizeof/in_be32/out_be32 operations from the reader. o fixed qe_snums_init() serial num assignment to use a const array o made CONFIG_UCC_FAST select UCC_SLOW o reduced NR_QE_IC_INTS from 128 to 64 o remove _IO_BASE, etc. defines (not used) o removed irrelevant comments, added others to resemble removed BD_ defines o realigned struct definitions in headers o various other style fixes including things like pinMask -> pin_mask o fixed a ton of whitespace issues o marked ioregs as __be32/__be16 o removed platform_device code and redundant get_qe_base() o removed redundant comments o added cpu_relax() to qe_reset o uncasted all get_property() assignments o eliminated unneeded casts o eliminated immrbar_phys_to_virt (not used) Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Shlomi Gridish <gridish@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
2006-10-04 04:10:46 +00:00
qe_ic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
NR_QE_IC_INTS, &qe_ic_host_ops, 0);
if (qe_ic->irqhost == NULL) {
of_node_put(node);
return;
}
ret = of_address_to_resource(node, 0, &res);
if (ret)
return;
qe_ic->regs = ioremap(res.start, res.end - res.start + 1);
qe_ic->irqhost->host_data = qe_ic;
qe_ic->hc_irq = qe_ic_irq_chip;
qe_ic->virq_high = irq_of_parse_and_map(node, 0);
qe_ic->virq_low = irq_of_parse_and_map(node, 1);
if (qe_ic->virq_low == NO_IRQ) {
printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
return;
}
/* default priority scheme is grouped. If spread mode is */
/* required, configure cicr accordingly. */
if (flags & QE_IC_SPREADMODE_GRP_W)
temp |= CICR_GWCC;
if (flags & QE_IC_SPREADMODE_GRP_X)
temp |= CICR_GXCC;
if (flags & QE_IC_SPREADMODE_GRP_Y)
temp |= CICR_GYCC;
if (flags & QE_IC_SPREADMODE_GRP_Z)
temp |= CICR_GZCC;
if (flags & QE_IC_SPREADMODE_GRP_RISCA)
temp |= CICR_GRTA;
if (flags & QE_IC_SPREADMODE_GRP_RISCB)
temp |= CICR_GRTB;
/* choose destination signal for highest priority interrupt */
if (flags & QE_IC_HIGH_SIGNAL) {
temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
high_active = 1;
}
qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
set_irq_data(qe_ic->virq_low, qe_ic);
set_irq_chained_handler(qe_ic->virq_low, qe_ic_cascade_low);
if (qe_ic->virq_high != NO_IRQ) {
set_irq_data(qe_ic->virq_high, qe_ic);
set_irq_chained_handler(qe_ic->virq_high, qe_ic_cascade_high);
}
printk("QEIC (%d IRQ sources) at %p\n", NR_QE_IC_INTS, qe_ic->regs);
}
void qe_ic_set_highest_priority(unsigned int virq, int high)
{
struct qe_ic *qe_ic = qe_ic_from_irq(virq);
unsigned int src = virq_to_hw(virq);
u32 temp = 0;
temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
temp &= ~CICR_HP_MASK;
temp |= src << CICR_HP_SHIFT;
temp &= ~CICR_HPIT_MASK;
temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
}
/* Set Priority level within its group, from 1 to 8 */
int qe_ic_set_priority(unsigned int virq, unsigned int priority)
{
struct qe_ic *qe_ic = qe_ic_from_irq(virq);
unsigned int src = virq_to_hw(virq);
u32 temp;
if (priority > 8 || priority == 0)
return -EINVAL;
if (src > 127)
return -EINVAL;
if (qe_ic_info[src].pri_reg == 0)
return -EINVAL;
temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
if (priority < 4) {
temp &= ~(0x7 << (32 - priority * 3));
temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
} else {
temp &= ~(0x7 << (24 - priority * 3));
temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
}
qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
return 0;
}
/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
{
struct qe_ic *qe_ic = qe_ic_from_irq(virq);
unsigned int src = virq_to_hw(virq);
u32 temp, control_reg = QEIC_CICNR, shift = 0;
if (priority > 2 || priority == 0)
return -EINVAL;
switch (qe_ic_info[src].pri_reg) {
case QEIC_CIPZCC:
shift = CICNR_ZCC1T_SHIFT;
break;
case QEIC_CIPWCC:
shift = CICNR_WCC1T_SHIFT;
break;
case QEIC_CIPYCC:
shift = CICNR_YCC1T_SHIFT;
break;
case QEIC_CIPXCC:
shift = CICNR_XCC1T_SHIFT;
break;
case QEIC_CIPRTA:
shift = CRICR_RTA1T_SHIFT;
control_reg = QEIC_CRICR;
break;
case QEIC_CIPRTB:
shift = CRICR_RTB1T_SHIFT;
control_reg = QEIC_CRICR;
break;
default:
return -EINVAL;
}
shift += (2 - priority) * 2;
temp = qe_ic_read(qe_ic->regs, control_reg);
temp &= ~(SIGNAL_MASK << shift);
temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
qe_ic_write(qe_ic->regs, control_reg, temp);
return 0;
}
static struct sysdev_class qe_ic_sysclass = {
set_kset_name("qe_ic"),
};
static struct sys_device device_qe_ic = {
.id = 0,
.cls = &qe_ic_sysclass,
};
static int __init init_qe_ic_sysfs(void)
{
int rc;
printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
rc = sysdev_class_register(&qe_ic_sysclass);
if (rc) {
printk(KERN_ERR "Failed registering qe_ic sys class\n");
return -ENODEV;
}
rc = sysdev_register(&device_qe_ic);
if (rc) {
printk(KERN_ERR "Failed registering qe_ic sys device\n");
return -ENODEV;
}
return 0;
}
subsys_initcall(init_qe_ic_sysfs);