LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH ] powerpc:  pass UPIO_TSI flag to 8259 serial driver
From: Benjamin Herrenschmidt @ 2006-08-23 21:52 UTC (permalink / raw)
  To: Zang Roy-r61911; +Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
In-Reply-To: <44EC15A1.4090807@freescale.com>

On Wed, 2006-08-23 at 16:45 +0800, Zang Roy-r61911 wrote:
> Benjamin Herrenschmidt wrote:
> > On Wed, 2006-08-23 at 10:20 +0800, Zang Roy-r61911 wrote:
> >   
> >> The patch passes the UPIO_TSI flag to general 8259 serial driver
> >>     
> >
> > Patch looks damaged to me... appart from that, what it does looks ok to
> > me.
> Sorry. It seems imported by my mail client. Please pick up the following 
> one.

Seems to be damaged as well ! What mail client do you use ? 

Ben.

> Signed-off-by: Roy Zang	<tie-fei.zang@freescale.com>
> 
>  ---
> 
>  arch/powerpc/kernel/legacy_serial.c |    8 ++++++--
>  1 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/legacy_serial.c 
> b/arch/powerpc/kernel/legacy_serial.c
> index 359ab89..07c2c00 100644
> --- a/arch/powerpc/kernel/legacy_serial.c
> +++ b/arch/powerpc/kernel/legacy_serial.c
> @@ -115,6 +115,7 @@ static int __init add_legacy_soc_port(st
>      u64 addr;
>      u32 *addrp;
>      upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
> +    struct device_node *tsi = of_get_parent(np);
>  
>      /* We only support ports that have a clock frequency properly
>       * encoded in the device-tree.
> @@ -134,7 +135,10 @@ static int __init add_legacy_soc_port(st
>      /* Add port, irq will be dealt with later. We passed a translated
>       * IO port value. It will be fixed up later along with the irq
>       */
> -    return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
> +    if (tsi && !strcmp(tsi->type, "tsi-bridge"))
> +        return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, 
> flags, 0);
> +    else
> +        return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, 
> flags, 0);
>  }
>  
>  static int __init add_legacy_isa_port(struct device_node *np,
> @@ -464,7 +468,7 @@ static int __init serial_dev_init(void)
>              fixup_port_irq(i, np, port);
>          if (port->iotype == UPIO_PORT)
>              fixup_port_pio(i, np, port);
> -        if (port->iotype == UPIO_MEM)
> +        if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI))
>              fixup_port_mmio(i, np, port);
>      }
>  

^ permalink raw reply

* Re: CompactFlash on PQII Pro
From: Kumar Gala @ 2006-08-23 23:04 UTC (permalink / raw)
  To: bwarren; +Cc: linuxppc-embedded
In-Reply-To: <1156371402.17977.21.camel@saruman.qstreams.net>


On Aug 23, 2006, at 5:16 PM, Ben Warren wrote:

> Hello,
>
> I have a custom board where we've hung a CompactFlash on the local bus
> of an MPC8349 processor, intending to use it in 'True IDE' mode.  The
> closest thing I've found in the kernel tree is
> drivers/ide/ppc/ide-m8xx.c, although it's *very* possible I'm not
> looking in the right place.
>
> I believe my chip's local bus is similar to the 8xx, so making this
> driver work with my hardware doesn't seem like that big a deal.  I  
> fully
> expect to have to monkey with UPM timings among other things.  On the
> other hand, this seems like something other people would have done,
> maybe with one of the other PQ families like 82xx or 85xx.
>
> Does anyone have a patch, suggestions or flames they can throw my way?

I know I posted a patch for cf-ide.c to lkml some time ago, this was  
to do a CF in true ide mode using the 83xx localbus.

http://marc.theaimsgroup.com/?l=linux-kernel&m=113877891224982&w=2

We did some UPM setup in u-boot to use two CS on Localbus for this.

- kumar

^ permalink raw reply

* Re: PCI resource allocation MPC8540ADS
From: Kumar Gala @ 2006-08-23 23:06 UTC (permalink / raw)
  To: Clint Thomas; +Cc: linuxppc-embedded
In-Reply-To: <3C02138692C13C4BB675FE7EA240952918DFB7@bluefin.Soneticom.local>


On Aug 23, 2006, at 4:11 PM, Clint Thomas wrote:

> Hey guys,
>
> I have a development board based loosely off the MPC8540ADS design  
> that I am trying to move to the Linux kernel 2.6. I already have  
> this system working successfully in Linux Kernel 2.4, but after  
> dealing with compilation and load errors, i've come to the point  
> where I can get to a console. However, this problem at boot time  
> keeps me from using a lot of onboard hardware. When I enable PCI  
> support in the Kernel configuration, this is the text I get at boot  
> time...

which 2.6 kernel are you using?

> PCI: Probing PCI hardware
> PCI: Cannot allocate resource region 1 of PCI bridge 1
> PCI: Cannot allocate resource region 2 of PCI bridge 1
> PCI: bridge 1 resource 2 moved to 9ff00000..9fffffff
> PCI: Cannot allocate resource region 1 of PCI bridge 2
> PCI: Cannot allocate resource region 2 of PCI bridge 2
> PCI: bridge 2 resource 2 moved to 9fe00000..9fefffff
> PCI: Cannot allocate resource region 1 of device 0000:00:14.0
> PCI: Cannot allocate resource region 2 of device 0000:00:14.0
> PCI: Cannot allocate resource region 0 of device 0000:01:01.0
> PCI: Cannot allocate resource region 1 of device 0000:01:01.0
> PCI: Cannot allocate resource region 2 of device 0000:01:01.0
> PCI: Cannot allocate resource region 0 of device 0000:01:05.0
> PCI: Cannot allocate resource region 1 of device 0000:01:05.0
> PCI: Cannot allocate resource region 2 of device 0000:01:05.0
> PCI: Cannot allocate resource region 0 of device 0000:01:06.0
> PCI: Cannot allocate resource region 0 of device 0000:01:06.1
> PCI: Cannot allocate resource region 0 of device 0000:01:06.2
> PCI: Failed to allocate mem resource #0:1000000@0 for 0000:01:01.0
> PCI: Failed to allocate I/O resource #1:100@1000 for 0000:01:01.0
> PCI: Failed to allocate mem resource #2:1000@0 for 0000:01:01.0
> PCI: Failed to allocate mem resource #0:10000@0 for 0000:01:05.0
> PCI: Failed to allocate mem resource #2:10000@0 for 0000:01:05.0
> PCI: Failed to allocate mem resource #0:1000@0 for 0000:01:06.0
> PCI: Failed to allocate mem resource #0:1000@0 for 0000:01:06.1
> PCI: Failed to allocate mem resource #0:100@0 for 0000:01:06.2
>
> the system is using a PLX PCI bridge chip. Like I said, this works  
> fine in my 2.4 distribution. Thanks for any and all help!

can you post an lspci -v output.

- kumar

^ permalink raw reply

* Re: boot problems on pseries
From: Linas Vepstas @ 2006-08-23 23:59 UTC (permalink / raw)
  To: dtutty; +Cc: linuxppc-dev
In-Reply-To: <20060822165023.GA4807@hooton>

On Tue, Aug 22, 2006 at 12:50:26PM -0400, dtutty@porchlight.ca wrote:
> Boot failures:
> 
> 	1.	CD not recognized as bootable, so use OF manually.
> 	2.	OF manually will boot yaboot.
> 	3.	yaboot doesn't find its config in the /etc directory
> 		of the cd, nor in the / directory of the CD with the
> 		yaboot executable.
> 	4.	when manually from yaboot attempt to boot a kernel
> 		image, get either:
> 			a)	CLAIMED	FAILED	

Olaf's suggestion to use netboot is a good one.

Have you tried googling "yaboot claim fail"?

I see suggetions to run yabootconfig, which normally
writes stuff to a special boot partition at /dev/sda1  
No clue how to do this for a CD.

The BSD faq has a long discussion

http://www.netbsd.org/Ports/macppc/faq.html#ofw-claim-failed

which seems to indicate that some load or offset is being
incorrectly specified.

There seem to be plenty of other discussions as well

--linas

^ permalink raw reply

* Please pull powerpc.git 'merge' branch
From: Paul Mackerras @ 2006-08-24  0:44 UTC (permalink / raw)
  To: gregkh, linuxppc-dev

Greg,

Please do:

git pull \
git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git merge

to get another set of PowerPC updates for 2.6.18.

Thanks,
Paul.

 arch/powerpc/boot/dts/mpc8540ads.dts              |  257 +++++++++++++++++
 arch/powerpc/boot/dts/mpc8541cds.dts              |  244 ++++++++++++++++
 arch/powerpc/boot/dts/mpc8548cds.dts              |  287 +++++++++++++++++++
 arch/powerpc/boot/dts/mpc8555cds.dts              |  244 ++++++++++++++++
 arch/powerpc/kernel/legacy_serial.c               |    8 -
 arch/powerpc/kernel/prom_parse.c                  |   13 -
 arch/powerpc/kernel/time.c                        |   25 +-
 arch/powerpc/kernel/traps.c                       |    8 -
 arch/powerpc/mm/hugetlbpage.c                     |    2 
 arch/powerpc/platforms/85xx/Kconfig               |    1 
 arch/powerpc/platforms/85xx/mpc85xx_ads.c         |  162 ++++-------
 arch/powerpc/platforms/85xx/mpc85xx_cds.c         |  210 ++++++--------
 arch/powerpc/platforms/86xx/mpc8641_hpcn.h        |   32 --
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c        |  324 +++++++++++----------
 arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c |   73 ++---
 arch/powerpc/platforms/powermac/bootx_init.c      |   15 +
 arch/powerpc/sysdev/fsl_soc.c                     |   30 +-
 arch/powerpc/sysdev/tsi108_dev.c                  |   10 -
 arch/powerpc/sysdev/tsi108_pci.c                  |   21 +
 include/asm-powerpc/pgalloc.h                     |    2 
 include/asm-powerpc/system.h                      |    9 +
 include/asm-powerpc/tsi108.h                      |   14 +
 include/asm-powerpc/tsi108_irq.h                  |  124 ++++++++
 23 files changed, 1593 insertions(+), 522 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/mpc8540ads.dts
 create mode 100644 arch/powerpc/boot/dts/mpc8541cds.dts
 create mode 100644 arch/powerpc/boot/dts/mpc8548cds.dts
 create mode 100644 arch/powerpc/boot/dts/mpc8555cds.dts
 create mode 100644 include/asm-powerpc/tsi108_irq.h

Adam Litke:
      [POWERPC] hugepage BUG fix

Andy Fleming:
      [POWERPC] Fix interrupts on 8540 ADS board
      [POWERPC] Fix CDS IRQ handling and PCI code
      [POWERPC] Add 85xx DTS files to powerpc
      [POWERPC] Fix FEC node in 8540 ADS dts

Benjamin Herrenschmidt:
      [POWERPC] Fix BootX booting with an initrd

Jon Loeliger:
      [POWERPC] Rewrite the PPC 86xx IRQ handling to use Flat Device Tree

Li Yang:
      [POWERPC] Fix compile problem without CONFIG_PCI

Nathan Lynch:
      [POWERPC] Fix gettimeofday inaccuracies

Paul Mackerras:
      [POWERPC] Correct masks used in emulating some instructions

Zang Roy-r61911:
      [POWERPC] Update mpc7448hpc2 board irq support using device tree
      [POWERPC] Pass UPIO_TSI flag to 8259 serial driver

^ permalink raw reply

* [PATCH 1/3] Adapt ipic driver to new host_ops interface, add set_irq_type to set IRQ sense
From: Kim Phillips @ 2006-08-24  1:39 UTC (permalink / raw)
  To: linuxppc-dev

This converts ipic code to Benh's IRQ mods.  For the IPIC, IRQ sense values in the device tree equal those in include/linux/irq.h; that's 8 for low assertion (most internal IRQs on mpc83xx), and 2 for high-to-low change.

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>

---

please apply to 2.6.18

 arch/powerpc/sysdev/ipic.c |  281 +++++++++++++++++++++++++++++---------------
 arch/powerpc/sysdev/ipic.h |   23 +++-
 include/asm-powerpc/ipic.h |    6 -
 3 files changed, 208 insertions(+), 102 deletions(-)

diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 46801f5..8db65d5 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -19,14 +19,16 @@ #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 <asm/irq.h>
 #include <asm/io.h>
+#include <asm/prom.h>
 #include <asm/ipic.h>
-#include <asm/mpc83xx.h>
 
 #include "ipic.h"
 
-static struct ipic p_ipic;
 static struct ipic * primary_ipic;
 
 static struct ipic_info ipic_info[] = {
@@ -373,15 +375,17 @@ static inline void ipic_write(volatile u
 	out_be32(base + (reg >> 2), value);
 }
 
-static inline struct ipic * ipic_from_irq(unsigned int irq)
+static inline struct ipic * ipic_from_irq(unsigned int virq)
 {
 	return primary_ipic;
 }
 
-static void ipic_enable_irq(unsigned int irq)
+#define ipic_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
+
+static void ipic_unmask_irq(unsigned int virq)
 {
-	struct ipic *ipic = ipic_from_irq(irq);
-	unsigned int src = irq - ipic->irq_offset;
+	struct ipic *ipic = ipic_from_irq(virq);
+	unsigned int src = ipic_irq_to_hw(virq);
 	u32 temp;
 
 	temp = ipic_read(ipic->regs, ipic_info[src].mask);
@@ -389,10 +393,10 @@ static void ipic_enable_irq(unsigned int
 	ipic_write(ipic->regs, ipic_info[src].mask, temp);
 }
 
-static void ipic_disable_irq(unsigned int irq)
+static void ipic_mask_irq(unsigned int virq)
 {
-	struct ipic *ipic = ipic_from_irq(irq);
-	unsigned int src = irq - ipic->irq_offset;
+	struct ipic *ipic = ipic_from_irq(virq);
+	unsigned int src = ipic_irq_to_hw(virq);
 	u32 temp;
 
 	temp = ipic_read(ipic->regs, ipic_info[src].mask);
@@ -400,47 +404,170 @@ static void ipic_disable_irq(unsigned in
 	ipic_write(ipic->regs, ipic_info[src].mask, temp);
 }
 
-static void ipic_disable_irq_and_ack(unsigned int irq)
+static void ipic_ack_irq(unsigned int virq)
 {
-	struct ipic *ipic = ipic_from_irq(irq);
-	unsigned int src = irq - ipic->irq_offset;
+	struct ipic *ipic = ipic_from_irq(virq);
+	unsigned int src = ipic_irq_to_hw(virq);
 	u32 temp;
 
-	ipic_disable_irq(irq);
+	temp = ipic_read(ipic->regs, ipic_info[src].pend);
+	temp |= (1 << (31 - ipic_info[src].bit));
+	ipic_write(ipic->regs, ipic_info[src].pend, temp);
+}
+
+static void ipic_mask_irq_and_ack(unsigned int virq)
+{
+	struct ipic *ipic = ipic_from_irq(virq);
+	unsigned int src = ipic_irq_to_hw(virq);
+	u32 temp;
+
+	temp = ipic_read(ipic->regs, ipic_info[src].mask);
+	temp &= ~(1 << (31 - ipic_info[src].bit));
+	ipic_write(ipic->regs, ipic_info[src].mask, temp);
 
 	temp = ipic_read(ipic->regs, ipic_info[src].pend);
 	temp |= (1 << (31 - ipic_info[src].bit));
 	ipic_write(ipic->regs, ipic_info[src].pend, temp);
 }
 
-static void ipic_end_irq(unsigned int irq)
+static void ipic_end_irq(unsigned int virq)
+{
+	if (!(irq_desc[virq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		ipic_unmask_irq(virq);
+}
+
+static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
+{
+	struct ipic *ipic = ipic_from_irq(virq);
+	unsigned int src = ipic_irq_to_hw(virq);
+	struct irq_desc *desc = get_irq_desc(virq);
+	unsigned int vold, vnew, edibit;
+
+	if (flow_type == IRQ_TYPE_NONE)
+		flow_type = IRQ_TYPE_LEVEL_LOW;
+	if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) {
+		printk(KERN_ERR "ipic: sense type 0x%x not supported\n",
+			flow_type);
+		return -EINVAL;
+	}
+
+	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
+	if (flow_type & IRQ_TYPE_LEVEL_LOW)  {
+		desc->status |= IRQ_LEVEL;
+		set_irq_handler(virq, handle_level_irq);
+	} else {
+		set_irq_handler(virq, handle_edge_irq);
+	}
+
+	if (src == IPIC_IRQ_EXT0)
+		edibit = 15;
+	else
+		if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7)
+			edibit = (14 - (src - IPIC_IRQ_EXT1));
+		else
+			/* only EXT IRQ senses are programmable on ipic */
+			return 0;
+
+	vold = ipic_read(ipic->regs, IPIC_SECNR);
+	if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) {
+		vnew = vold | (1 << edibit);
+	} else {
+		vnew = vold & ~(1 << edibit);
+	}
+	if (vold != vnew)
+		ipic_write(ipic->regs, IPIC_SECNR, vnew);
+	return 0;
+}
+
+static struct irq_chip ipic_irq_chip = {
+	.typename	= " IPIC  ",
+	.unmask		= ipic_unmask_irq,
+	.mask		= ipic_mask_irq,
+	.mask_ack	= ipic_mask_irq_and_ack,
+	.ack		= ipic_ack_irq,
+	.end		= ipic_end_irq,
+	.set_type	= ipic_set_irq_type,
+};
+
+static int ipic_host_match(struct irq_host *h, struct device_node *node)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		ipic_enable_irq(irq);
+	struct ipic *ipic = h->host_data;
+
+	/* Exact match, unless ipic node is NULL */
+	return ipic->of_node == NULL || ipic->of_node == node;
+}
+
+static int ipic_host_map(struct irq_host *h, unsigned int virq,
+			 irq_hw_number_t hw)
+{
+	struct ipic *ipic = h->host_data;
+	struct irq_chip *chip;
+
+	/* Default chip */
+	chip = &ipic->hc_irq;
+
+	set_irq_chip_data(virq, ipic);
+	set_irq_chip(virq, chip);
+
+	return 0;
 }
 
-struct hw_interrupt_type ipic = {
-	.typename = " IPIC  ",
-	.enable = ipic_enable_irq,
-	.disable = ipic_disable_irq,
-	.ack = ipic_disable_irq_and_ack,
-	.end = ipic_end_irq,
+static int ipic_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];
+	/* device tree interrupt sense values are assigned either
+	   LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change) */
+	if (intsize > 1 && (intspec[1] & (IRQ_TYPE_LEVEL_LOW |
+					  IRQ_TYPE_EDGE_FALLING)))
+		*out_flags = intspec[1];
+	else
+		*out_flags = IRQ_TYPE_NONE;
+	return 0;
+}
+
+static struct irq_host_ops ipic_host_ops = {
+	.match	= ipic_host_match,
+	.map	= ipic_host_map,
+	.xlate	= ipic_host_xlate,
 };
 
-void __init ipic_init(phys_addr_t phys_addr,
-		unsigned int flags,
-		unsigned int irq_offset,
-		unsigned char *senses,
-		unsigned int senses_count)
+void __init ipic_init(struct device_node *node,
+		unsigned int flags)
 {
-	u32 i, temp = 0;
+	struct ipic	*ipic;
+	struct resource res;
+	u32 temp = 0, ret;
+
+	ipic = alloc_bootmem(sizeof(struct ipic));
+	if (ipic == NULL)
+		return;
+
+	memset(ipic, 0, sizeof(struct ipic));
+	ipic->of_node = node ? of_node_get(node) : NULL;
+
+	ipic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
+				       NR_IPIC_INTS,
+				       &ipic_host_ops, 0);
+	if (ipic->irqhost == NULL) {
+		of_node_put(node);
+		return;
+	}
 
-	primary_ipic = &p_ipic;
-	primary_ipic->regs = ioremap(phys_addr, MPC83xx_IPIC_SIZE);
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret)
+		return;
+
+	ipic->regs = ioremap(res.start, res.end - res.start + 1);
 
-	primary_ipic->irq_offset = irq_offset;
+	ipic->irqhost->host_data = ipic;
+	ipic->hc_irq = ipic_irq_chip;
 
-	ipic_write(primary_ipic->regs, IPIC_SICNR, 0x0);
+	/* init hw */
+	ipic_write(ipic->regs, IPIC_SICNR, 0x0);
 
 	/* default priority scheme is grouped. If spread mode is required
 	 * configure SICFR accordingly */
@@ -453,49 +580,35 @@ void __init ipic_init(phys_addr_t phys_a
 	if (flags & IPIC_SPREADMODE_MIX_B)
 		temp |= SICFR_MPSB;
 
-	ipic_write(primary_ipic->regs, IPIC_SICNR, temp);
+	ipic_write(ipic->regs, IPIC_SICNR, temp);
 
 	/* handle MCP route */
 	temp = 0;
 	if (flags & IPIC_DISABLE_MCP_OUT)
 		temp = SERCR_MCPR;
-	ipic_write(primary_ipic->regs, IPIC_SERCR, temp);
+	ipic_write(ipic->regs, IPIC_SERCR, temp);
 
 	/* handle routing of IRQ0 to MCP */
-	temp = ipic_read(primary_ipic->regs, IPIC_SEMSR);
+	temp = ipic_read(ipic->regs, IPIC_SEMSR);
 
 	if (flags & IPIC_IRQ0_MCP)
 		temp |= SEMSR_SIRQ0;
 	else
 		temp &= ~SEMSR_SIRQ0;
 
-	ipic_write(primary_ipic->regs, IPIC_SEMSR, temp);
-
-	for (i = 0 ; i < NR_IPIC_INTS ; i++) {
-		irq_desc[i+irq_offset].chip = &ipic;
-		irq_desc[i+irq_offset].status = IRQ_LEVEL;
-	}
+	ipic_write(ipic->regs, IPIC_SEMSR, temp);
 
-	temp = 0;
-	for (i = 0 ; i < senses_count ; i++) {
-		if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
-			temp |= 1 << (15 - i);
-			if (i != 0)
-				irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
-			else
-				irq_desc[irq_offset + MPC83xx_IRQ_EXT0].status = 0;
-		}
-	}
-	ipic_write(primary_ipic->regs, IPIC_SECNR, temp);
+	primary_ipic = ipic;
+	irq_set_default_host(primary_ipic->irqhost);
 
-	printk ("IPIC (%d IRQ sources, %d External IRQs) at %p\n", NR_IPIC_INTS,
-			senses_count, primary_ipic->regs);
+	printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS,
+			primary_ipic->regs);
 }
 
-int ipic_set_priority(unsigned int irq, unsigned int priority)
+int ipic_set_priority(unsigned int virq, unsigned int priority)
 {
-	struct ipic *ipic = ipic_from_irq(irq);
-	unsigned int src = irq - ipic->irq_offset;
+	struct ipic *ipic = ipic_from_irq(virq);
+	unsigned int src = ipic_irq_to_hw(virq);
 	u32 temp;
 
 	if (priority > 7)
@@ -520,10 +633,10 @@ int ipic_set_priority(unsigned int irq, 
 	return 0;
 }
 
-void ipic_set_highest_priority(unsigned int irq)
+void ipic_set_highest_priority(unsigned int virq)
 {
-	struct ipic *ipic = ipic_from_irq(irq);
-	unsigned int src = irq - ipic->irq_offset;
+	struct ipic *ipic = ipic_from_irq(virq);
+	unsigned int src = ipic_irq_to_hw(virq);
 	u32 temp;
 
 	temp = ipic_read(ipic->regs, IPIC_SICFR);
@@ -537,37 +650,10 @@ void ipic_set_highest_priority(unsigned 
 
 void ipic_set_default_priority(void)
 {
-	ipic_set_priority(MPC83xx_IRQ_TSEC1_TX, 0);
-	ipic_set_priority(MPC83xx_IRQ_TSEC1_RX, 1);
-	ipic_set_priority(MPC83xx_IRQ_TSEC1_ERROR, 2);
-	ipic_set_priority(MPC83xx_IRQ_TSEC2_TX, 3);
-	ipic_set_priority(MPC83xx_IRQ_TSEC2_RX, 4);
-	ipic_set_priority(MPC83xx_IRQ_TSEC2_ERROR, 5);
-	ipic_set_priority(MPC83xx_IRQ_USB2_DR, 6);
-	ipic_set_priority(MPC83xx_IRQ_USB2_MPH, 7);
-
-	ipic_set_priority(MPC83xx_IRQ_UART1, 0);
-	ipic_set_priority(MPC83xx_IRQ_UART2, 1);
-	ipic_set_priority(MPC83xx_IRQ_SEC2, 2);
-	ipic_set_priority(MPC83xx_IRQ_IIC1, 5);
-	ipic_set_priority(MPC83xx_IRQ_IIC2, 6);
-	ipic_set_priority(MPC83xx_IRQ_SPI, 7);
-	ipic_set_priority(MPC83xx_IRQ_RTC_SEC, 0);
-	ipic_set_priority(MPC83xx_IRQ_PIT, 1);
-	ipic_set_priority(MPC83xx_IRQ_PCI1, 2);
-	ipic_set_priority(MPC83xx_IRQ_PCI2, 3);
-	ipic_set_priority(MPC83xx_IRQ_EXT0, 4);
-	ipic_set_priority(MPC83xx_IRQ_EXT1, 5);
-	ipic_set_priority(MPC83xx_IRQ_EXT2, 6);
-	ipic_set_priority(MPC83xx_IRQ_EXT3, 7);
-	ipic_set_priority(MPC83xx_IRQ_RTC_ALR, 0);
-	ipic_set_priority(MPC83xx_IRQ_MU, 1);
-	ipic_set_priority(MPC83xx_IRQ_SBA, 2);
-	ipic_set_priority(MPC83xx_IRQ_DMA, 3);
-	ipic_set_priority(MPC83xx_IRQ_EXT4, 4);
-	ipic_set_priority(MPC83xx_IRQ_EXT5, 5);
-	ipic_set_priority(MPC83xx_IRQ_EXT6, 6);
-	ipic_set_priority(MPC83xx_IRQ_EXT7, 7);
+	ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT);
+	ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT);
+	ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT);
+	ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT);
 }
 
 void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq)
@@ -600,17 +686,20 @@ void ipic_clear_mcp_status(u32 mask)
 	ipic_write(primary_ipic->regs, IPIC_SERMR, mask);
 }
 
-/* Return an interrupt vector or -1 if no interrupt is pending. */
-int ipic_get_irq(struct pt_regs *regs)
+/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
+unsigned int ipic_get_irq(struct pt_regs *regs)
 {
 	int irq;
 
-	irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & 0x7f;
+	BUG_ON(primary_ipic == NULL);
+
+#define IPIC_SIVCR_VECTOR_MASK	0x7f
+	irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK;
 
 	if (irq == 0)    /* 0 --> no irq is pending */
-		irq = -1;
+		return NO_IRQ;
 
-	return irq;
+	return irq_linear_revmap(primary_ipic->irqhost, irq);
 }
 
 static struct sysdev_class ipic_sysclass = {
diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
index a60c9d1..c28e589 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -15,7 +15,18 @@ #define __IPIC_H__
 
 #include <asm/ipic.h>
 
-#define MPC83xx_IPIC_SIZE	(0x00100)
+#define NR_IPIC_INTS 128
+
+/* External IRQS */
+#define IPIC_IRQ_EXT0 48
+#define IPIC_IRQ_EXT1 17
+#define IPIC_IRQ_EXT7 23
+
+/* Default Priority Registers */
+#define IPIC_SIPRR_A_DEFAULT 0x05309770
+#define IPIC_SIPRR_D_DEFAULT 0x05309770
+#define IPIC_SMPRR_A_DEFAULT 0x05309770
+#define IPIC_SMPRR_B_DEFAULT 0x05309770
 
 /* System Global Interrupt Configuration Register */
 #define	SICFR_IPSA	0x00010000
@@ -31,7 +42,15 @@ #define SERCR_MCPR	0x00000001
 
 struct ipic {
 	volatile u32 __iomem	*regs;
-	unsigned int		irq_offset;
+
+	/* The remapper for this IPIC */
+	struct irq_host		*irqhost;
+
+	/* The "linux" controller struct */
+	struct irq_chip		hc_irq;
+
+	/* The device node of the interrupt controller */
+	struct device_node	*of_node;
 };
 
 struct ipic_info {
diff --git a/include/asm-powerpc/ipic.h b/include/asm-powerpc/ipic.h
index 0fe396a..3f55df4 100644
--- a/include/asm-powerpc/ipic.h
+++ b/include/asm-powerpc/ipic.h
@@ -69,9 +69,7 @@ enum ipic_mcp_irq {
 	IPIC_MCP_MU   = 7,
 };
 
-extern void ipic_init(phys_addr_t phys_addr, unsigned int flags,
-		unsigned int irq_offset,
-		unsigned char *senses, unsigned int senses_count);
+extern void ipic_init(struct device_node *node, unsigned int flags);
 extern int ipic_set_priority(unsigned int irq, unsigned int priority);
 extern void ipic_set_highest_priority(unsigned int irq);
 extern void ipic_set_default_priority(void);
@@ -79,7 +77,7 @@ extern void ipic_enable_mcp(enum ipic_mc
 extern void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq);
 extern u32 ipic_get_mcp_status(void);
 extern void ipic_clear_mcp_status(u32 mask);
-extern int ipic_get_irq(struct pt_regs *regs);
+extern unsigned int ipic_get_irq(struct pt_regs *regs);
 
 #endif /* __ASM_IPIC_H__ */
 #endif /* __KERNEL__ */
-- 
2006_06_07.01.gittree_pull-dirty

^ permalink raw reply related

* [PATCH 2/3] Fix MPC834x SYS platform to get IRQ data from device tree and use new IRQ layer
From: Kim Phillips @ 2006-08-24  1:39 UTC (permalink / raw)
  To: linuxppc-dev

This fixes MPC834x SYS platform code to get IRQ data (including PCI) from the device tree, and to use the new IPIC code.

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>

---

please apply to 2.6.18

 arch/powerpc/platforms/83xx/mpc834x_sys.c |   58 +++++------------------------
 arch/powerpc/platforms/83xx/mpc83xx.h     |    1 +
 arch/powerpc/platforms/83xx/pci.c         |   10 +++++
 3 files changed, 21 insertions(+), 48 deletions(-)

diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c
index 5eadf9d..d864571 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c
@@ -43,33 +43,6 @@ unsigned long isa_io_base = 0;
 unsigned long isa_mem_base = 0;
 #endif
 
-#ifdef CONFIG_PCI
-static int
-mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
-{
-	static char pci_irq_table[][4] =
-	    /*
-	     *      PCI IDSEL/INTPIN->INTLINE
-	     *       A      B      C      D
-	     */
-	{
-		{PIRQA, PIRQB, PIRQC, PIRQD},	/* idsel 0x11 */
-		{PIRQC, PIRQD, PIRQA, PIRQB},	/* idsel 0x12 */
-		{PIRQD, PIRQA, PIRQB, PIRQC},	/* idsel 0x13 */
-		{0, 0, 0, 0},
-		{PIRQA, PIRQB, PIRQC, PIRQD},	/* idsel 0x15 */
-		{PIRQD, PIRQA, PIRQB, PIRQC},	/* idsel 0x16 */
-		{PIRQC, PIRQD, PIRQA, PIRQB},	/* idsel 0x17 */
-		{PIRQB, PIRQC, PIRQD, PIRQA},	/* idsel 0x18 */
-		{0, 0, 0, 0},			/* idsel 0x19 */
-		{0, 0, 0, 0},			/* idsel 0x20 */
-	};
-
-	const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
-	return PCI_IRQ_TABLE_LOOKUP;
-}
-#endif				/* CONFIG_PCI */
-
 /* ************************************************************************
  *
  * Setup the architecture
@@ -96,8 +69,6 @@ #ifdef CONFIG_PCI
 	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
 		add_bridge(np);
 
-	ppc_md.pci_swizzle = common_swizzle;
-	ppc_md.pci_map_irq = mpc83xx_map_irq;
 	ppc_md.pci_exclude_device = mpc83xx_exclude_device;
 #endif
 
@@ -110,25 +81,13 @@ #endif
 
 void __init mpc834x_sys_init_IRQ(void)
 {
-	u8 senses[8] = {
-		0,			/* EXT 0 */
-		IRQ_SENSE_LEVEL,	/* EXT 1 */
-		IRQ_SENSE_LEVEL,	/* EXT 2 */
-		0,			/* EXT 3 */
-#ifdef CONFIG_PCI
-		IRQ_SENSE_LEVEL,	/* EXT 4 */
-		IRQ_SENSE_LEVEL,	/* EXT 5 */
-		IRQ_SENSE_LEVEL,	/* EXT 6 */
-		IRQ_SENSE_LEVEL,	/* EXT 7 */
-#else
-		0,			/* EXT 4 */
-		0,			/* EXT 5 */
-		0,			/* EXT 6 */
-		0,			/* EXT 7 */
-#endif
-	};
-
-	ipic_init(get_immrbase() + 0x00700, 0, 0, senses, 8);
+	struct device_node *np;
+
+	np = of_find_node_by_type(NULL, "ipic");
+	if (!np)
+		return;
+
+	ipic_init(np, 0);
 
 	/* Initialize the default interrupt mapping priorities,
 	 * in case the boot rom changed something on us.
@@ -178,4 +137,7 @@ define_machine(mpc834x_sys) {
 	.time_init		= mpc83xx_time_init,
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
+#ifdef CONFIG_PCI
+	.pcibios_fixup		= mpc83xx_pcibios_fixup,
+#endif
 };
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index 01cae10..2c82bca 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -11,6 +11,7 @@ #include <linux/device.h>
 
 extern int add_bridge(struct device_node *dev);
 extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
+extern void mpc83xx_pcibios_fixup(void);
 extern void mpc83xx_restart(char *cmd);
 extern long mpc83xx_time_init(void);
 
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 9c36505..ae12547 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -45,6 +45,16 @@ int mpc83xx_exclude_device(u_char bus, u
 	return PCIBIOS_SUCCESSFUL;
 }
 
+void __init mpc83xx_pcibios_fixup(void)
+{
+	struct pci_dev *dev = NULL;
+
+	/* map all the PCI irqs */
+	dev = NULL;
+	for_each_pci_dev(dev)
+		pci_read_irq_line(dev);
+}
+
 int __init add_bridge(struct device_node *dev)
 {
 	int len;
-- 
2006_06_07.01.gittree_pull-dirty

^ permalink raw reply related

* [PATCH 3/3] Add MPC8349E MDS device tree source file to arch/powerpc/boot/dts
From: Kim Phillips @ 2006-08-24  1:39 UTC (permalink / raw)
  To: linuxppc-dev

Add MPC8349E MDS device tree source file to arch/powerpc/boot/dts


Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
---

 arch/powerpc/boot/dts/mpc8349emds.dts |  327 +++++++++++++++++++++++++++++++++
 1 files changed, 327 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8349emds.dts b/arch/powerpc/boot/dts/mpc8349emds.dts
new file mode 100644
index 0000000..0c37274
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8349emds.dts
@@ -0,0 +1,327 @@
+/*
+ * MPC8349E MDS Device Tree Source
+ *
+ * Copyright 2005, 2006 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+/ {
+	model = "MPC8349EMDS";
+	compatible = "MPC834xMDS";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#cpus = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8349@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <0>;	// from bootloader
+			bus-frequency = <0>;		// from bootloader
+			clock-frequency = <0>;		// from bootloader
+			32-bit;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <00000000 10000000>;	// 256MB at 0
+	};
+
+	soc8349@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <0 e0000000 00100000>;
+		reg = <e0000000 00000200>;
+		bus-frequency = <0>;
+
+		wdt@200 {
+			device_type = "watchdog";
+			compatible = "mpc83xx_wdt";
+			reg = <200 100>;
+		};
+
+		i2c@3000 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3000 100>;
+			interrupts = <e 8>;
+			interrupt-parent = <700>;
+			dfsrr;
+		};
+
+		i2c@3100 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3100 100>;
+			interrupts = <f 8>;
+			interrupt-parent = <700>;
+			dfsrr;
+		};
+
+		spi@7000 {
+			device_type = "spi";
+			compatible = "mpc83xx_spi";
+			reg = <7000 1000>;
+			interrupts = <10 8>;
+			interrupt-parent = <700>;
+			mode = <0>;
+		};
+
+		/* phy type (ULPI or SERIAL) are only types supportted for MPH */
+		/* port = 0 or 1 */
+		usb@22000 {
+			device_type = "usb";
+			compatible = "fsl-usb2-mph";
+			reg = <22000 1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <700>;
+			interrupts = <27 2>;
+			phy_type = "ulpi";
+			port1;
+		};
+		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
+		usb@23000 {
+			device_type = "usb";
+			compatible = "fsl-usb2-dr";
+			reg = <23000 1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <700>;
+			interrupts = <26 2>;
+			phy_type = "ulpi";
+		};
+
+		mdio@24520 {
+			device_type = "mdio";
+			compatible = "gianfar";
+			reg = <24520 20>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			linux,phandle = <24520>;
+			ethernet-phy@0 {
+				linux,phandle = <2452000>;
+				interrupt-parent = <700>;
+				interrupts = <11 2>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+			ethernet-phy@1 {
+				linux,phandle = <2452001>;
+				interrupt-parent = <700>;
+				interrupts = <12 2>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		ethernet@24000 {
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <24000 1000>;
+			address = [ 00 00 00 00 00 00 ];
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <20 8 21 8 22 8>;
+			interrupt-parent = <700>;
+			phy-handle = <2452000>;
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "TSEC";
+			compatible = "gianfar";
+			reg = <25000 1000>;
+			address = [ 00 00 00 00 00 00 ];
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <23 8 24 8 25 8>;
+			interrupt-parent = <700>;
+			phy-handle = <2452001>;
+		};
+
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>;
+			clock-frequency = <0>;
+			interrupts = <9 8>;
+			interrupt-parent = <700>;
+		};
+
+		serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4600 100>;
+			clock-frequency = <0>;
+			interrupts = <a 8>;
+			interrupt-parent = <700>;
+		};
+
+		pci@8500 {
+			interrupt-map-mask = <f800 0 0 7>;
+			interrupt-map = <
+
+					/* IDSEL 0x11 */
+					 8800 0 0 1 700 14 0
+					 8800 0 0 2 700 15 0
+					 8800 0 0 3 700 16 0
+					 8800 0 0 4 700 17 0
+
+					/* IDSEL 0x12 */
+					 9000 0 0 1 700 16 0
+					 9000 0 0 2 700 17 0
+					 9000 0 0 3 700 14 0
+					 9000 0 0 4 700 15 0
+
+					/* IDSEL 0x13 */
+					 9800 0 0 1 700 17 0
+					 9800 0 0 2 700 14 0
+					 9800 0 0 3 700 15 0
+					 9800 0 0 4 700 16 0
+
+					/* IDSEL 0x15 */
+					 a800 0 0 1 700 14 0
+					 a800 0 0 2 700 15 0
+					 a800 0 0 3 700 16 0
+					 a800 0 0 4 700 17 0
+
+					/* IDSEL 0x16 */
+					 b000 0 0 1 700 17 0
+					 b000 0 0 2 700 14 0
+					 b000 0 0 3 700 15 0
+					 b000 0 0 4 700 16 0
+
+					/* IDSEL 0x17 */
+					 b800 0 0 1 700 16 0
+					 b800 0 0 2 700 17 0
+					 b800 0 0 3 700 14 0
+					 b800 0 0 4 700 15 0
+
+					/* IDSEL 0x18 */
+					 b000 0 0 1 700 15 0
+					 b000 0 0 2 700 16 0
+					 b000 0 0 3 700 17 0
+					 b000 0 0 4 700 14 0>;
+			interrupt-parent = <700>;
+			interrupts = <42 8>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 a0000000 a0000000 0 10000000
+				  42000000 0 80000000 80000000 0 10000000
+				  01000000 0 00000000 e2000000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8500 100>;
+			compatible = "83xx";
+			device_type = "pci";
+		};
+
+		pci@8600 {
+			interrupt-map-mask = <f800 0 0 7>;
+			interrupt-map = <
+
+					/* IDSEL 0x11 */
+					 8800 0 0 1 700 14 0
+					 8800 0 0 2 700 15 0
+					 8800 0 0 3 700 16 0
+					 8800 0 0 4 700 17 0
+
+					/* IDSEL 0x12 */
+					 9000 0 0 1 700 16 0
+					 9000 0 0 2 700 17 0
+					 9000 0 0 3 700 14 0
+					 9000 0 0 4 700 15 0
+
+					/* IDSEL 0x13 */
+					 9800 0 0 1 700 17 0
+					 9800 0 0 2 700 14 0
+					 9800 0 0 3 700 15 0
+					 9800 0 0 4 700 16 0
+
+					/* IDSEL 0x15 */
+					 a800 0 0 1 700 14 0
+					 a800 0 0 2 700 15 0
+					 a800 0 0 3 700 16 0
+					 a800 0 0 4 700 17 0
+
+					/* IDSEL 0x16 */
+					 b000 0 0 1 700 17 0
+					 b000 0 0 2 700 14 0
+					 b000 0 0 3 700 15 0
+					 b000 0 0 4 700 16 0
+
+					/* IDSEL 0x17 */
+					 b800 0 0 1 700 16 0
+					 b800 0 0 2 700 17 0
+					 b800 0 0 3 700 14 0
+					 b800 0 0 4 700 15 0
+
+					/* IDSEL 0x18 */
+					 b000 0 0 1 700 15 0
+					 b000 0 0 2 700 16 0
+					 b000 0 0 3 700 17 0
+					 b000 0 0 4 700 14 0>;
+			interrupt-parent = <700>;
+			interrupts = <42 8>;
+			bus-range = <0 0>;
+			ranges = <02000000 0 b0000000 b0000000 0 10000000
+				  42000000 0 90000000 90000000 0 10000000
+				  01000000 0 00000000 e2100000 0 00100000>;
+			clock-frequency = <3f940aa>;
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8600 100>;
+			compatible = "83xx";
+			device_type = "pci";
+		};
+
+		/* May need to remove if on a part without crypto engine */
+		crypto@30000 {
+			device_type = "crypto";
+			model = "SEC2";
+			compatible = "talitos";
+			reg = <30000 10000>;
+			interrupts = <b 8>;
+			interrupt-parent = <700>;
+			num-channels = <4>;
+			channel-fifo-len = <18>;
+			exec-units-mask = <0000007e>;
+			/* desc mask is for rev2.0,
+			 * we need runtime fixup for >2.0 */
+			descriptor-types-mask = <01010ebf>;
+		};
+
+		/* IPIC
+		 * interrupts cell = <intr #, sense>
+		 * sense == 8: Level, low assertion
+		 * sense == 2: Edge, high-to-low change
+		 */
+		pic@700 {
+			linux,phandle = <700>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <700 100>;
+			built-in;
+			device_type = "ipic";
+		};
+	};
+};
-- 
2006_06_07.01.gittree_pull-dirty

^ permalink raw reply related

* Re: [PATCH 1/3] Adapt ipic driver to new host_ops interface, add set_irq_type to set IRQ sense
From: Kumar Gala @ 2006-08-24  1:58 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev
In-Reply-To: <20060823203928.3c5f9509.kim.phillips@freescale.com>


On Aug 23, 2006, at 8:39 PM, Kim Phillips wrote:

> This converts ipic code to Benh's IRQ mods.  For the IPIC, IRQ  
> sense values in the device tree equal those in include/linux/irq.h;  
> that's 8 for low assertion (most internal IRQs on mpc83xx), and 2  
> for high-to-low change.
>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>

This breaks the arch/ppc build of 83xx, can we clone ipic as it  
stands move that over to arch/ppc and apply your changes on top of that.

- kumar

^ permalink raw reply

* Re: [PATCH 3/3] Add MPC8349E MDS device tree source file to arch/powerpc/boot/dts
From: Kumar Gala @ 2006-08-24  2:02 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev
In-Reply-To: <20060823203944.34c85a6a.kim.phillips@freescale.com>


On Aug 23, 2006, at 8:39 PM, Kim Phillips wrote:

> Add MPC8349E MDS device tree source file to arch/powerpc/boot/dts
>
>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
>
>  arch/powerpc/boot/dts/mpc8349emds.dts |  327 ++++++++++++++++++++++ 
> +++++++++++
>  1 files changed, 327 insertions(+), 0 deletions(-)

Can we rename the defconfig to match the dts, mpc834x_sys was a bad  
choice but what was I to do.  Things seem to have stabilized on MDS  
so we should go with that.

> +
> +		/* IPIC
> +		 * interrupts cell = <intr #, sense>
> +		 * sense == 8: Level, low assertion
> +		 * sense == 2: Edge, high-to-low change
> +		 */

Would be good to add a comment that we match IORESOURCE_IRQ_* defn.

> +		pic@700 {
> +			linux,phandle = <700>;
> +			interrupt-controller;
> +			#address-cells = <0>;
> +			#interrupt-cells = <2>;
> +			reg = <700 100>;
> +			built-in;
> +			device_type = "ipic";
> +		};
> +	};
> +};
> -- 
> 2006_06_07.01.gittree_pull-dirty

^ permalink raw reply

* RE: ioremap() fails for >64 MB
From: alva @ 2006-08-24  2:54 UTC (permalink / raw)
  To: Phil.Nitschke, 'Matt Porter'; +Cc: linuxppc-embedded
In-Reply-To: <1156327238.6735.9.camel@lamorak.int.avalon.com.au>

I think 64MB limitation of ioremap() is due to the kernel's page size.
When compiling kernel, it has an option to choose the memory page size
which is default 64MB. To use memory greater than 64MB, there is two
methods. One is to make the kernel's page size larger as Phil Nitschke
said. Another is to modify ioremap() a little bit --- just make it use
another file for "mmap" while larger than 64MB. Since the central
concept of linux is file-based, I think more files are not harmful that
only waste a little bit inode structure. And it is much more feasible
that one can choose to use file in memory or harddisk or mounted device
harddisk/memory ... ...

-----Original Message-----
From: linuxppc-embedded-bounces+vows_siu=yahoo.com.hk@ozlabs.org
[mailto:linuxppc-embedded-bounces+vows_siu=yahoo.com.hk@ozlabs.org] On
Behalf Of Phil Nitschke
Sent: Wednesday, August 23, 2006 6:01 PM
To: Matt Porter
Cc: linuxppc-embedded@ozlabs.org
Subject: Re: ioremap() fails for >64 MB

On Tue, 2006-08-22 at 09:22 -0500, Matt Porter wrote:
> On Tue, Aug 22, 2006 at 05:11:09PM +0930, Phil Nitschke wrote:
> > Hi all,
> > 
> > I have 2 GB memory on a 7448 processor, and want to reserve a huge
chunk
> > of it at boot-time, then ioremap() it into the kernel space inside a
> > device driver.  So far I've succeeded with 64 MB, but can't go any
> > higher, as mm/vmalloc.c tells me: "allocation failed: out of vmalloc
> > space - use vmalloc=<size> to increase size."
> > 
> > So I tried adding a vmalloc line to the kernel command line as
follows:
> > Kernel cmd line: root=/dev/nfs rw mem=1920M vmalloc=1024M
nfsroot=... 
>  
> Yeah, that suggestion is bogus. That option can't help with getting
> more vmalloc space in this case.
> 
> > So the vmalloc=<size> argument has made no difference.  What do I
need
> > to do to make this work?
> 
> Go to the "Advanced setup" menu. There's a number of options to
provide
> fine-grained control of the PPC kernel virtual address space.

<SNIP>

Thanks Matt (and others) for your suggestions.  Matt has given me the
answers I was looking for.

Since my (2 GB) memory is within the (4 GB) addressable by a 32-bit
processor, why do I need high memory at all?  

Are there performance implications on this platform from having a non
optimal low/high ratio?

> That said, why don't you just use alloc_bootmem() to reserve memory
> for your driver at boot time? 

I avoided this simply because I wanted to load/unload my driver (during
development), and alloc_bootmem() seemed better suited to drivers
compiled into the kernel.  But I'll look again at this idea if further
problems arise with the approach above.

Thanks again,

-- 
Phil

_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded

-- 
No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.1.405 / Virus Database: 268.11.5/425 - Release Date:
2006/8/22
 

-- 
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.1.405 / Virus Database: 268.11.5/426 - Release Date:
2006/8/23
 

^ permalink raw reply

* Re: [PATCH 1/3] Adapt ipic driver to new host_ops interface, add set_irq_type to set IRQ sense
From: Benjamin Herrenschmidt @ 2006-08-24  3:44 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev
In-Reply-To: <20060823203928.3c5f9509.kim.phillips@freescale.com>

On Wed, 2006-08-23 at 20:39 -0500, Kim Phillips wrote:

A lot of it looks good, a few nits though:

> -static void ipic_disable_irq_and_ack(unsigned int irq)
> +static void ipic_ack_irq(unsigned int virq)
>  {
> -	struct ipic *ipic = ipic_from_irq(irq);
> -	unsigned int src = irq - ipic->irq_offset;
> +	struct ipic *ipic = ipic_from_irq(virq);
> +	unsigned int src = ipic_irq_to_hw(virq);
>  	u32 temp;
>  
> -	ipic_disable_irq(irq);
> +	temp = ipic_read(ipic->regs, ipic_info[src].pend);
> +	temp |= (1 << (31 - ipic_info[src].bit));
> +	ipic_write(ipic->regs, ipic_info[src].pend, temp);
> +}

You should have a spinlock protecting you here as you are or'ing bits in
that register from several interrupt sources. The common code provides a
per-source spinlock, but various sources mask/ack routines might be
racing.

> +static void ipic_mask_irq_and_ack(unsigned int virq)
> +{
> +	struct ipic *ipic = ipic_from_irq(virq);
> +	unsigned int src = ipic_irq_to_hw(virq);
> +	u32 temp;
> +
> +	temp = ipic_read(ipic->regs, ipic_info[src].mask);
> +	temp &= ~(1 << (31 - ipic_info[src].bit));
> +	ipic_write(ipic->regs, ipic_info[src].mask, temp);
>  
>  	temp = ipic_read(ipic->regs, ipic_info[src].pend);
>  	temp |= (1 << (31 - ipic_info[src].bit));
>  	ipic_write(ipic->regs, ipic_info[src].pend, temp);
>  }

Same comment as above.
 
> -static void ipic_end_irq(unsigned int irq)
> +static void ipic_end_irq(unsigned int virq)
> +{
> +	if (!(irq_desc[virq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
> +		ipic_unmask_irq(virq);
> +}

You should not need the above. It depends which handler you are using.
If you use the level/edge handlers, they should take care of doing the
appropriate unmasking when necessary (look at kernel/irq/chip.c)

> +static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
> +{
> +	struct ipic *ipic = ipic_from_irq(virq);
> +	unsigned int src = ipic_irq_to_hw(virq);
> +	struct irq_desc *desc = get_irq_desc(virq);
> +	unsigned int vold, vnew, edibit;
> +
> +	if (flow_type == IRQ_TYPE_NONE)
> +		flow_type = IRQ_TYPE_LEVEL_LOW;
> +	if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) {
> +		printk(KERN_ERR "ipic: sense type 0x%x not supported\n",
> +			flow_type);
> +		return -EINVAL;
> +	}
> +
> +	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
> +	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
> +	if (flow_type & IRQ_TYPE_LEVEL_LOW)  {
> +		desc->status |= IRQ_LEVEL;
> +		set_irq_handler(virq, handle_level_irq);
> +	} else {
> +		set_irq_handler(virq, handle_edge_irq);
> +	}
> +
> +	if (src == IPIC_IRQ_EXT0)
> +		edibit = 15;
> +	else
> +		if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7)
> +			edibit = (14 - (src - IPIC_IRQ_EXT1));
> +		else
> +			/* only EXT IRQ senses are programmable on ipic */
> +			return 0;

You should fail if attempting to program one of non-programmable ones to
something different than their default type then.

> +	vold = ipic_read(ipic->regs, IPIC_SECNR);
> +	if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) {
> +		vnew = vold | (1 << edibit);
> +	} else {
> +		vnew = vold & ~(1 << edibit);
> +	}
> +	if (vold != vnew)
> +		ipic_write(ipic->regs, IPIC_SECNR, vnew);
> +	return 0;
> +}
> +
> +static struct irq_chip ipic_irq_chip = {
> +	.typename	= " IPIC  ",
> +	.unmask		= ipic_unmask_irq,
> +	.mask		= ipic_mask_irq,
> +	.mask_ack	= ipic_mask_irq_and_ack,
> +	.ack		= ipic_ack_irq,
> +	.end		= ipic_end_irq,
> +	.set_type	= ipic_set_irq_type,
> +};
> +
> +static int ipic_host_match(struct irq_host *h, struct device_node *node)
>  {
> -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
> -		ipic_enable_irq(irq);
> +	struct ipic *ipic = h->host_data;
> +
> +	/* Exact match, unless ipic node is NULL */
> +	return ipic->of_node == NULL || ipic->of_node == node;
> +}
> +
> +static int ipic_host_map(struct irq_host *h, unsigned int virq,
> +			 irq_hw_number_t hw)
> +{
> +	struct ipic *ipic = h->host_data;
> +	struct irq_chip *chip;
> +
> +	/* Default chip */
> +	chip = &ipic->hc_irq;
> +
> +	set_irq_chip_data(virq, ipic);
> +	set_irq_chip(virq, chip);
> +
> +	return 0;
>  }

Shouldn't you call set_irq_type() (or at least set a handler) here to
setup a default type ? The common code will only call set_irq_type() if
an explicit non-default and different than the current setting handler
is set.

> -struct hw_interrupt_type ipic = {
> -	.typename = " IPIC  ",
> -	.enable = ipic_enable_irq,
> -	.disable = ipic_disable_irq,
> -	.ack = ipic_disable_irq_and_ack,
> -	.end = ipic_end_irq,
> +static int ipic_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];
> +	/* device tree interrupt sense values are assigned either
> +	   LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change) */
> +	if (intsize > 1 && (intspec[1] & (IRQ_TYPE_LEVEL_LOW |
> +					  IRQ_TYPE_EDGE_FALLING)))

I'm not sure about the usefulness of the second part of that test...  If
it is, shouldn't you also mask out the other bits in the assignement
below : ?

> +		*out_flags = intspec[1];
> +	else
> +		*out_flags = IRQ_TYPE_NONE;
> +	return 0;
> +}
> +
> +static struct irq_host_ops ipic_host_ops = {
> +	.match	= ipic_host_match,
> +	.map	= ipic_host_map,
> +	.xlate	= ipic_host_xlate,
>  };
>  
> -void __init ipic_init(phys_addr_t phys_addr,
> -		unsigned int flags,
> -		unsigned int irq_offset,
> -		unsigned char *senses,
> -		unsigned int senses_count)
> +void __init ipic_init(struct device_node *node,
> +		unsigned int flags)
>  {
> -	u32 i, temp = 0;
> +	struct ipic	*ipic;
> +	struct resource res;
> +	u32 temp = 0, ret;
> +
> +	ipic = alloc_bootmem(sizeof(struct ipic));
> +	if (ipic == NULL)
> +		return;
> +
> +	memset(ipic, 0, sizeof(struct ipic));
> +	ipic->of_node = node ? of_node_get(node) : NULL;
> +
> +	ipic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
> +				       NR_IPIC_INTS,
> +				       &ipic_host_ops, 0);
> +	if (ipic->irqhost == NULL) {
> +		of_node_put(node);
> +		return;
> +	}
>  
> -	primary_ipic = &p_ipic;
> -	primary_ipic->regs = ioremap(phys_addr, MPC83xx_IPIC_SIZE);
> +	ret = of_address_to_resource(node, 0, &res);
> +	if (ret)
> +		return;
> +
> +	ipic->regs = ioremap(res.start, res.end - res.start + 1);
>  
> -	primary_ipic->irq_offset = irq_offset;
> +	ipic->irqhost->host_data = ipic;
> +	ipic->hc_irq = ipic_irq_chip;
>  
> -	ipic_write(primary_ipic->regs, IPIC_SICNR, 0x0);
> +	/* init hw */
> +	ipic_write(ipic->regs, IPIC_SICNR, 0x0);
>  
>  	/* default priority scheme is grouped. If spread mode is required
>  	 * configure SICFR accordingly */
> @@ -453,49 +580,35 @@ void __init ipic_init(phys_addr_t phys_a
>  	if (flags & IPIC_SPREADMODE_MIX_B)
>  		temp |= SICFR_MPSB;
>  
> -	ipic_write(primary_ipic->regs, IPIC_SICNR, temp);
> +	ipic_write(ipic->regs, IPIC_SICNR, temp);
>  
>  	/* handle MCP route */
>  	temp = 0;
>  	if (flags & IPIC_DISABLE_MCP_OUT)
>  		temp = SERCR_MCPR;
> -	ipic_write(primary_ipic->regs, IPIC_SERCR, temp);
> +	ipic_write(ipic->regs, IPIC_SERCR, temp);
>  
>  	/* handle routing of IRQ0 to MCP */
> -	temp = ipic_read(primary_ipic->regs, IPIC_SEMSR);
> +	temp = ipic_read(ipic->regs, IPIC_SEMSR);
>  
>  	if (flags & IPIC_IRQ0_MCP)
>  		temp |= SEMSR_SIRQ0;
>  	else
>  		temp &= ~SEMSR_SIRQ0;
>  
> -	ipic_write(primary_ipic->regs, IPIC_SEMSR, temp);
> -
> -	for (i = 0 ; i < NR_IPIC_INTS ; i++) {
> -		irq_desc[i+irq_offset].chip = &ipic;
> -		irq_desc[i+irq_offset].status = IRQ_LEVEL;
> -	}
> +	ipic_write(ipic->regs, IPIC_SEMSR, temp);
>  
> -	temp = 0;
> -	for (i = 0 ; i < senses_count ; i++) {
> -		if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
> -			temp |= 1 << (15 - i);
> -			if (i != 0)
> -				irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
> -			else
> -				irq_desc[irq_offset + MPC83xx_IRQ_EXT0].status = 0;
> -		}
> -	}
> -	ipic_write(primary_ipic->regs, IPIC_SECNR, temp);
> +	primary_ipic = ipic;
> +	irq_set_default_host(primary_ipic->irqhost);
>  
> -	printk ("IPIC (%d IRQ sources, %d External IRQs) at %p\n", NR_IPIC_INTS,
> -			senses_count, primary_ipic->regs);
> +	printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS,
> +			primary_ipic->regs);
>  }
>  
> -int ipic_set_priority(unsigned int irq, unsigned int priority)
> +int ipic_set_priority(unsigned int virq, unsigned int priority)
>  {
> -	struct ipic *ipic = ipic_from_irq(irq);
> -	unsigned int src = irq - ipic->irq_offset;
> +	struct ipic *ipic = ipic_from_irq(virq);
> +	unsigned int src = ipic_irq_to_hw(virq);
>  	u32 temp;
>  
>  	if (priority > 7)
> @@ -520,10 +633,10 @@ int ipic_set_priority(unsigned int irq, 
>  	return 0;
>  }
>  
> -void ipic_set_highest_priority(unsigned int irq)
> +void ipic_set_highest_priority(unsigned int virq)
>  {
> -	struct ipic *ipic = ipic_from_irq(irq);
> -	unsigned int src = irq - ipic->irq_offset;
> +	struct ipic *ipic = ipic_from_irq(virq);
> +	unsigned int src = ipic_irq_to_hw(virq);
>  	u32 temp;
>  
>  	temp = ipic_read(ipic->regs, IPIC_SICFR);
> @@ -537,37 +650,10 @@ void ipic_set_highest_priority(unsigned 
>  
>  void ipic_set_default_priority(void)
>  {
> -	ipic_set_priority(MPC83xx_IRQ_TSEC1_TX, 0);
> -	ipic_set_priority(MPC83xx_IRQ_TSEC1_RX, 1);
> -	ipic_set_priority(MPC83xx_IRQ_TSEC1_ERROR, 2);
> -	ipic_set_priority(MPC83xx_IRQ_TSEC2_TX, 3);
> -	ipic_set_priority(MPC83xx_IRQ_TSEC2_RX, 4);
> -	ipic_set_priority(MPC83xx_IRQ_TSEC2_ERROR, 5);
> -	ipic_set_priority(MPC83xx_IRQ_USB2_DR, 6);
> -	ipic_set_priority(MPC83xx_IRQ_USB2_MPH, 7);
> -
> -	ipic_set_priority(MPC83xx_IRQ_UART1, 0);
> -	ipic_set_priority(MPC83xx_IRQ_UART2, 1);
> -	ipic_set_priority(MPC83xx_IRQ_SEC2, 2);
> -	ipic_set_priority(MPC83xx_IRQ_IIC1, 5);
> -	ipic_set_priority(MPC83xx_IRQ_IIC2, 6);
> -	ipic_set_priority(MPC83xx_IRQ_SPI, 7);
> -	ipic_set_priority(MPC83xx_IRQ_RTC_SEC, 0);
> -	ipic_set_priority(MPC83xx_IRQ_PIT, 1);
> -	ipic_set_priority(MPC83xx_IRQ_PCI1, 2);
> -	ipic_set_priority(MPC83xx_IRQ_PCI2, 3);
> -	ipic_set_priority(MPC83xx_IRQ_EXT0, 4);
> -	ipic_set_priority(MPC83xx_IRQ_EXT1, 5);
> -	ipic_set_priority(MPC83xx_IRQ_EXT2, 6);
> -	ipic_set_priority(MPC83xx_IRQ_EXT3, 7);
> -	ipic_set_priority(MPC83xx_IRQ_RTC_ALR, 0);
> -	ipic_set_priority(MPC83xx_IRQ_MU, 1);
> -	ipic_set_priority(MPC83xx_IRQ_SBA, 2);
> -	ipic_set_priority(MPC83xx_IRQ_DMA, 3);
> -	ipic_set_priority(MPC83xx_IRQ_EXT4, 4);
> -	ipic_set_priority(MPC83xx_IRQ_EXT5, 5);
> -	ipic_set_priority(MPC83xx_IRQ_EXT6, 6);
> -	ipic_set_priority(MPC83xx_IRQ_EXT7, 7);
> +	ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT);
> +	ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT);
> +	ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT);
> +	ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT);
>  }
>  
>  void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq)
> @@ -600,17 +686,20 @@ void ipic_clear_mcp_status(u32 mask)
>  	ipic_write(primary_ipic->regs, IPIC_SERMR, mask);
>  }
>  
> -/* Return an interrupt vector or -1 if no interrupt is pending. */
> -int ipic_get_irq(struct pt_regs *regs)
> +/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
> +unsigned int ipic_get_irq(struct pt_regs *regs)
>  {
>  	int irq;
>  
> -	irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & 0x7f;
> +	BUG_ON(primary_ipic == NULL);
> +
> +#define IPIC_SIVCR_VECTOR_MASK	0x7f
> +	irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK;
>  
>  	if (irq == 0)    /* 0 --> no irq is pending */
> -		irq = -1;
> +		return NO_IRQ;
>  
> -	return irq;
> +	return irq_linear_revmap(primary_ipic->irqhost, irq);
>  }
>  
>  static struct sysdev_class ipic_sysclass = {
> diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
> index a60c9d1..c28e589 100644
> --- a/arch/powerpc/sysdev/ipic.h
> +++ b/arch/powerpc/sysdev/ipic.h
> @@ -15,7 +15,18 @@ #define __IPIC_H__
>  
>  #include <asm/ipic.h>
>  
> -#define MPC83xx_IPIC_SIZE	(0x00100)
> +#define NR_IPIC_INTS 128
> +
> +/* External IRQS */
> +#define IPIC_IRQ_EXT0 48
> +#define IPIC_IRQ_EXT1 17
> +#define IPIC_IRQ_EXT7 23
> +
> +/* Default Priority Registers */
> +#define IPIC_SIPRR_A_DEFAULT 0x05309770
> +#define IPIC_SIPRR_D_DEFAULT 0x05309770
> +#define IPIC_SMPRR_A_DEFAULT 0x05309770
> +#define IPIC_SMPRR_B_DEFAULT 0x05309770
>  
>  /* System Global Interrupt Configuration Register */
>  #define	SICFR_IPSA	0x00010000
> @@ -31,7 +42,15 @@ #define SERCR_MCPR	0x00000001
>  
>  struct ipic {
>  	volatile u32 __iomem	*regs;
> -	unsigned int		irq_offset;
> +
> +	/* The remapper for this IPIC */
> +	struct irq_host		*irqhost;
> +
> +	/* The "linux" controller struct */
> +	struct irq_chip		hc_irq;
> +
> +	/* The device node of the interrupt controller */
> +	struct device_node	*of_node;
>  };
>  
>  struct ipic_info {
> diff --git a/include/asm-powerpc/ipic.h b/include/asm-powerpc/ipic.h
> index 0fe396a..3f55df4 100644
> --- a/include/asm-powerpc/ipic.h
> +++ b/include/asm-powerpc/ipic.h
> @@ -69,9 +69,7 @@ enum ipic_mcp_irq {
>  	IPIC_MCP_MU   = 7,
>  };
>  
> -extern void ipic_init(phys_addr_t phys_addr, unsigned int flags,
> -		unsigned int irq_offset,
> -		unsigned char *senses, unsigned int senses_count);
> +extern void ipic_init(struct device_node *node, unsigned int flags);
>  extern int ipic_set_priority(unsigned int irq, unsigned int priority);
>  extern void ipic_set_highest_priority(unsigned int irq);
>  extern void ipic_set_default_priority(void);
> @@ -79,7 +77,7 @@ extern void ipic_enable_mcp(enum ipic_mc
>  extern void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq);
>  extern u32 ipic_get_mcp_status(void);
>  extern void ipic_clear_mcp_status(u32 mask);
> -extern int ipic_get_irq(struct pt_regs *regs);
> +extern unsigned int ipic_get_irq(struct pt_regs *regs);
>  
>  #endif /* __ASM_IPIC_H__ */
>  #endif /* __KERNEL__ */

^ permalink raw reply

* Re: [PATCH 1/3] Adapt ipic driver to new host_ops interface, add set_irq_type to set IRQ sense
From: Benjamin Herrenschmidt @ 2006-08-24  3:45 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <FBC2DEDA-6D07-4FD6-93FD-E1D37145AB7F@kernel.crashing.org>

On Wed, 2006-08-23 at 20:58 -0500, Kumar Gala wrote:
> On Aug 23, 2006, at 8:39 PM, Kim Phillips wrote:
> 
> > This converts ipic code to Benh's IRQ mods.  For the IPIC, IRQ  
> > sense values in the device tree equal those in include/linux/irq.h;  
> > that's 8 for low assertion (most internal IRQs on mpc83xx), and 2  
> > for high-to-low change.
> >
> > Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> > Signed-off-by: Li Yang <leoli@freescale.com>
> 
> This breaks the arch/ppc build of 83xx, can we clone ipic as it  
> stands move that over to arch/ppc and apply your changes on top of that.

Yup, we should do that, like I did for i8259, at least until
arch/powerpc 83xx is in good enough shape that the arch/ppc one can be
dropped completely.

Ben.
 

^ permalink raw reply

* Re: [PATCH 2/3] Fix MPC834x SYS platform to get IRQ data from device tree and use new IRQ layer
From: Benjamin Herrenschmidt @ 2006-08-24  3:46 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev
In-Reply-To: <20060823203937.578cae45.kim.phillips@freescale.com>


> +void __init mpc83xx_pcibios_fixup(void)
> +{
> +	struct pci_dev *dev = NULL;
> +
> +	/* map all the PCI irqs */
> +	dev = NULL;
> +	for_each_pci_dev(dev)
> +		pci_read_irq_line(dev);
> +}
> +
Some seriously redundant assignements above :) I'm not even sure we need
the initial assignement at all in the first place anyway.

Appart from that, looks good.

Cheers,
Ben.

^ permalink raw reply

* Re: Please pull powerpc.git 'merge' branch
From: Paul Mackerras @ 2006-08-24  4:02 UTC (permalink / raw)
  To: Greg KH; +Cc: linuxppc-dev
In-Reply-To: <20060824010508.GA17848@suse.de>

Greg KH writes:

> $ git pull  git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git merge
> Already up-to-date.
> 
> Perhaps I should be pulling from a different branch?

No, that's the right branch, but the mirroring was very slow. My
update of hours ago has only just propagated out.  Try again now.

Thanks,
Paul.

^ permalink raw reply

* Re: Please pull powerpc.git 'merge' branch
From: Greg KH @ 2006-08-24  4:10 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17645.9406.384676.189697@cargo.ozlabs.ibm.com>

On Thu, Aug 24, 2006 at 02:02:06PM +1000, Paul Mackerras wrote:
> Greg KH writes:
> 
> > $ git pull  git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git merge
> > Already up-to-date.
> > 
> > Perhaps I should be pulling from a different branch?
> 
> No, that's the right branch, but the mirroring was very slow. My
> update of hours ago has only just propagated out.  Try again now.

Ok, that worked.  I can pull from master@kernel.org too, which would
have worked here :)

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH ] powerpc:  pass UPIO_TSI flag to 8259 serial driver
From: Zang Roy-r61911 @ 2006-08-24  4:43 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
In-Reply-To: <1156369941.8433.57.camel@localhost.localdomain>

On Thu, 2006-08-24 at 05:52, Benjamin Herrenschmidt wrote:
> On Wed, 2006-08-23 at 16:45 +0800, Zang Roy-r61911 wrote:
> > Benjamin Herrenschmidt wrote:
> > > On Wed, 2006-08-23 at 10:20 +0800, Zang Roy-r61911 wrote:
> > >   
> > >> The patch passes the UPIO_TSI flag to general 8259 serial driver
> > >>     
> > >
> > > Patch looks damaged to me... appart from that, what it does looks
> ok to
> > > me.
> > Sorry. It seems imported by my mail client. Please pick up the
> following 
> > one.
> 
> Seems to be damaged as well ! What mail client do you use ? 
> 
> Ben.
Evolution 1.2.2. I had found the reason and tested on my side.
Paul, if you do not modify it by hand, please select the following :-).
I will repost the mpic and mpc7448hph2 irq update patch.Very sorry for that.

Signed-off-by: Roy Zang       <tie-fei.zang@freescale.com> 

---
 arch/powerpc/kernel/legacy_serial.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 359ab89..07c2c00 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -115,6 +115,7 @@ static int __init add_legacy_soc_port(st
 	u64 addr;
 	u32 *addrp;
 	upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
+	struct device_node *tsi = of_get_parent(np);
 
 	/* We only support ports that have a clock frequency properly
 	 * encoded in the device-tree.
@@ -134,7 +135,10 @@ static int __init add_legacy_soc_port(st
 	/* Add port, irq will be dealt with later. We passed a translated
 	 * IO port value. It will be fixed up later along with the irq
 	 */
-	return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
+	if (tsi && !strcmp(tsi->type, "tsi-bridge"))
+		return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0);
+	else 
+		return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
 }
 
 static int __init add_legacy_isa_port(struct device_node *np,
@@ -464,7 +468,7 @@ static int __init serial_dev_init(void)
 			fixup_port_irq(i, np, port);
 		if (port->iotype == UPIO_PORT)
 			fixup_port_pio(i, np, port);
-		if (port->iotype == UPIO_MEM)
+		if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI))
 			fixup_port_mmio(i, np, port);
 	}
 
-- 
1.4.0

^ permalink raw reply related

* Re: [PATCH ] powerpc:  pass UPIO_TSI flag to 8259 serial driver
From: Benjamin Herrenschmidt @ 2006-08-24  5:17 UTC (permalink / raw)
  To: Zang Roy-r61911; +Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
In-Reply-To: <1156394597.5310.42.camel@localhost.localdomain>


> Evolution 1.2.2. I had found the reason and tested on my side.
> Paul, if you do not modify it by hand, please select the following :-).
> I will repost the mpic and mpc7448hph2 irq update patch.Very sorry for that.

Ok, the trick with evolution is to use the "preformat" style.

Typically, when posting a patch, I write my description, put the caret
where I want to insert the patch itself, set the style to
"Preformat" (from the pop-up menu just above the text editing zone), and
do Insert->Text File from the menu.

You can also select a bit of text/patch and change the style to
"Preformat" afterward if you missed it before doing the import.

Ben.


> Signed-off-by: Roy Zang       <tie-fei.zang@freescale.com> 
> 
> ---
>  arch/powerpc/kernel/legacy_serial.c |    8 ++++++--
>  1 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
> index 359ab89..07c2c00 100644
> --- a/arch/powerpc/kernel/legacy_serial.c
> +++ b/arch/powerpc/kernel/legacy_serial.c
> @@ -115,6 +115,7 @@ static int __init add_legacy_soc_port(st
>  	u64 addr;
>  	u32 *addrp;
>  	upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
> +	struct device_node *tsi = of_get_parent(np);
>  
>  	/* We only support ports that have a clock frequency properly
>  	 * encoded in the device-tree.
> @@ -134,7 +135,10 @@ static int __init add_legacy_soc_port(st
>  	/* Add port, irq will be dealt with later. We passed a translated
>  	 * IO port value. It will be fixed up later along with the irq
>  	 */
> -	return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
> +	if (tsi && !strcmp(tsi->type, "tsi-bridge"))
> +		return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0);
> +	else 
> +		return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
>  }
>  
>  static int __init add_legacy_isa_port(struct device_node *np,
> @@ -464,7 +468,7 @@ static int __init serial_dev_init(void)
>  			fixup_port_irq(i, np, port);
>  		if (port->iotype == UPIO_PORT)
>  			fixup_port_pio(i, np, port);
> -		if (port->iotype == UPIO_MEM)
> +		if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI))
>  			fixup_port_mmio(i, np, port);
>  	}
>  

^ permalink raw reply

* Re: [PATCH] powerpc: update mpc7448hpc2 board irq support usingdevice tree
From: Zang Roy-r61911 @ 2006-08-24  5:29 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Paul Mackerras, Alexandre.Bounine,
	Yang Xin-Xin-r48390
In-Reply-To: <1156304338.8433.21.camel@localhost.localdomain>

On Wed, 2006-08-23 at 11:38, Benjamin Herrenschmidt wrote:
> On Wed, 2006-08-23 at 10:19 +0800, Zang Roy-r61911 wrote:
> > The patch rewrites mpc7448hpc2 board irq support according to the
> new
> > mpic 
> > device tree interface.
> 
> Same comment as the other patch, it looks like it got wrapped by your
> mailer. Also make sure you don't add trailing whitespaces (if you
> quilt,
> the latest version detects them and has an option to fix them up for
> you).
> 
> Appart from that, what the patch does looks good.
> 
> Cheers,
> Ben.
> 

Repost the patch, fix the word wrap.

Signed-off-by: Roy Zang       <tie-fei.zang@freescale.com> 

---
 arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c |   73 ++++--------
 arch/powerpc/sysdev/tsi108_dev.c                  |   10 +-
 arch/powerpc/sysdev/tsi108_pci.c                  |   21 ++--
 include/asm-powerpc/tsi108.h                      |   14 +-
 include/asm-powerpc/tsi108_irq.h                  |  124 +++++++++++++++++++++
 5 files changed, 174 insertions(+), 68 deletions(-)

diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index d7a4fc7..6a0c179 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -1,7 +1,7 @@
 /*
  * mpc7448_hpc2.c
  *
- * Board setup routines for the Freescale Taiga platform
+ * Board setup routines for the Freescale mpc7448hpc2(taiga) platform
  *
  * Author: Jacob Pan
  *	 jacob.pan@freescale.com
@@ -12,10 +12,10 @@
  *
  * Copyright 2004-2006 Freescale Semiconductor, Inc.
  *
- * This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
+ * 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/config.h>
@@ -62,43 +62,8 @@ #endif
 extern int tsi108_setup_pci(struct device_node *dev);
 extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
 extern void tsi108_pci_int_init(void);
-extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused);
-
-/*
- * Define all of the IRQ senses and polarities.  Taken from the
- * mpc7448hpc  manual.
- * Note:  Likely, this table and the following function should be
- *        obtained and derived from the OF Device Tree.
- */
-
-static u_char mpc7448_hpc2_pic_initsenses[] __initdata = {
-	/* External on-board sources */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* INT[0] XINT0 from FPGA */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* INT[1] XINT1 from FPGA */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* INT[2] PHY_INT from both GIGE */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* INT[3] RESERVED */
-	/* Internal Tsi108/109 interrupt sources */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* Reserved IRQ */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* Reserved IRQ */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* Reserved IRQ */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* Reserved IRQ */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* DMA0 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* DMA1 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* DMA2 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* DMA3 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* UART0 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* UART1 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* I2C */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* GPIO */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* GIGE0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* GIGE1 */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* Reserved IRQ */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* HLP */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* SDC */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* Processor IF */
-	(IRQ_SENSE_EDGE  | IRQ_POLARITY_POSITIVE),	/* Reserved IRQ */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* PCI/X block */
-};
+extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
+			    struct pt_regs *regs);
 
 int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
 {
@@ -229,6 +194,8 @@ static void __init mpc7448_hpc2_init_IRQ
 {
 	struct mpic *mpic;
 	phys_addr_t mpic_paddr = 0;
+	unsigned int cascade_pci_irq;
+	struct device_node *tsi_pci;
 	struct device_node *tsi_pic;
 
 	tsi_pic = of_find_node_by_type(NULL, "open-pic");
@@ -246,24 +213,31 @@ static void __init mpc7448_hpc2_init_IRQ
 	DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__,
 	    (u32) mpic_paddr);
 
-	mpic = mpic_alloc(mpic_paddr,
+	mpic = mpic_alloc(tsi_pic, mpic_paddr,
 			MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
 			MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108),
 			0, /* num_sources used */
-			TSI108_IRQ_BASE,
 			0, /* num_sources used */
-			NR_IRQS - 4 /* XXXX */,
-			mpc7448_hpc2_pic_initsenses,
-			sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC");
+			"Tsi108_PIC");
 
 	BUG_ON(mpic == NULL); /* XXXX */
-
 	mpic_init(mpic);
-	mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic);
+	
+	tsi_pci = of_find_node_by_type(NULL, "pci");
+	if (tsi_pci == 0) {
+		printk("%s: No tsi108 pci node found !\n", __FUNCTION__);
+		return;
+	}
+	
+	cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
+	set_irq_data(cascade_pci_irq, mpic);
+	set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+	
 	tsi108_pci_int_init();
 
 	/* Configure MPIC outputs to CPU0 */
 	tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
+	of_node_put(tsi_pic);
 }
 
 void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
@@ -320,6 +294,7 @@ static int mpc7448_machine_check_excepti
 	return 0;
 
 }
+
 define_machine(mpc7448_hpc2){
 	.name 			= "MPC7448 HPC2",
 	.probe 			= mpc7448_hpc2_probe,
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c
index 26a0cc8..f303846 100644
--- a/arch/powerpc/sysdev/tsi108_dev.c
+++ b/arch/powerpc/sysdev/tsi108_dev.c
@@ -93,13 +93,15 @@ static int __init tsi108_eth_of_init(voi
 			goto err;
 
 		r[1].name = "tx";
-		r[1].start = np->intrs[0].line;
-		r[1].end = np->intrs[0].line;
+		r[1].start = irq_of_parse_and_map(np, 0);
+		r[1].end = irq_of_parse_and_map(np, 0);
 		r[1].flags = IORESOURCE_IRQ;
+		DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
+			__FUNCTION__,r[1].name, r[1].start, r[1].end);
 
 		tsi_eth_dev =
 		    platform_device_register_simple("tsi-ethernet", i, &r[0],
-						    np->n_intrs + 1);
+						    1);
 
 		if (IS_ERR(tsi_eth_dev)) {
 			ret = PTR_ERR(tsi_eth_dev);
@@ -127,7 +129,7 @@ static int __init tsi108_eth_of_init(voi
 		tsi_eth_data.regs = r[0].start;
 		tsi_eth_data.phyregs = res.start;
 		tsi_eth_data.phy = *phy_id;
-		tsi_eth_data.irq_num = np->intrs[0].line;
+		tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0);
 		of_node_put(phy);
 		ret =
 		    platform_device_add_data(tsi_eth_dev, &tsi_eth_data,
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 3265d54..906b204 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -26,7 +26,6 @@ #include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 
-
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -228,7 +227,7 @@ int __init tsi108_setup_pci(struct devic
 
 	(hose)->ops = &tsi108_direct_pci_ops;
 
-	printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. "
+	printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. "
 	       "Firmware bus number: %d->%d\n",
 	       rsrc.start, hose->first_busno, hose->last_busno);
 
@@ -278,7 +277,7 @@ static void init_pci_source(void)
 	mb();
 }
 
-static inline int get_pci_source(void)
+static inline unsigned int get_pci_source(void)
 {
 	u_int temp = 0;
 	int irq = -1;
@@ -371,12 +370,12 @@ static void tsi108_pci_irq_end(u_int irq
  * Interrupt controller descriptor for cascaded PCI interrupt controller.
  */
 
-struct hw_interrupt_type tsi108_pci_irq = {
+static struct irq_chip tsi108_pci_irq = {
 	.typename = "tsi108_PCI_int",
-	.enable = tsi108_pci_irq_enable,
-	.disable = tsi108_pci_irq_disable,
+	.mask = tsi108_pci_irq_disable,
 	.ack = tsi108_pci_irq_ack,
 	.end = tsi108_pci_irq_end,
+	.unmask = tsi108_pci_irq_enable,
 };
 
 /*
@@ -399,14 +398,18 @@ void __init tsi108_pci_int_init(void)
 	DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
 	for (i = 0; i < NUM_PCI_IRQS; i++) {
-		irq_desc[i + IRQ_PCI_INTAD_BASE].handler = &tsi108_pci_irq;
+		irq_desc[i + IRQ_PCI_INTAD_BASE].chip = &tsi108_pci_irq;
 		irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL;
 	}
 
 	init_pci_source();
 }
 
-int tsi108_irq_cascade(struct pt_regs *regs, void *unused)
+void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
+			    struct pt_regs *regs)
 {
-	return get_pci_source();
+	unsigned int cascade_irq = get_pci_source();
+	if (cascade_irq != NO_IRQ)
+		generic_handle_irq(cascade_irq, regs);
+	desc->chip->eoi(irq); 
 }
diff --git a/include/asm-powerpc/tsi108.h b/include/asm-powerpc/tsi108.h
index c4c278d..e62250b 100644
--- a/include/asm-powerpc/tsi108.h
+++ b/include/asm-powerpc/tsi108.h
@@ -1,16 +1,18 @@
 /*
- * include/asm-ppc/tsi108.h
- *
  * common routine and memory layout for Tundra TSI108(Grendel) host bridge
  * memory controller.
  *
  * Author: Jacob Pan (jacob.pan@freescale.com)
  *	   Alex Bounine (alexandreb@tundra.com)
- * 2004 (c) Freescale Semiconductor Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
+ *	   
+ * Copyright 2004-2006 Freescale Semiconductor, Inc.
+ *
+ * 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.
  */
+
 #ifndef __PPC_KERNEL_TSI108_H
 #define __PPC_KERNEL_TSI108_H
 
diff --git a/include/asm-powerpc/tsi108_irq.h b/include/asm-powerpc/tsi108_irq.h
new file mode 100644
index 0000000..8ac1389
--- /dev/null
+++ b/include/asm-powerpc/tsi108_irq.h
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2005 Tundra Semiconductor Corp.
+ * Alex Bounine, <alexandreb at tundra.com).
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * definitions for interrupt controller initialization and external interrupt 
+ * demultiplexing on TSI108EMU/SVB boards.
+ */
+
+#ifndef _ASM_PPC_TSI108_IRQ_H
+#define _ASM_PPC_TSI108_IRQ_H
+
+/*
+ * Tsi108 interrupts
+ */
+#ifndef TSI108_IRQ_REG_BASE
+#define TSI108_IRQ_REG_BASE		0
+#endif
+
+#define TSI108_IRQ(x)		(TSI108_IRQ_REG_BASE + (x))
+
+#define TSI108_MAX_VECTORS	(36 + 4)	/* 36 sources + PCI INT demux */
+#define MAX_TASK_PRIO	0xF
+
+#define TSI108_IRQ_SPURIOUS	(TSI108_MAX_VECTORS)
+
+#define DEFAULT_PRIO_LVL	10	/* initial priority level */
+
+/* Interrupt vectors assignment to external and internal 
+ * sources of requests. */
+
+/* EXTERNAL INTERRUPT SOURCES */
+
+#define IRQ_TSI108_EXT_INT0	TSI108_IRQ(0)	/* External Source at INT[0] */
+#define IRQ_TSI108_EXT_INT1	TSI108_IRQ(1)	/* External Source at INT[1] */
+#define IRQ_TSI108_EXT_INT2	TSI108_IRQ(2)	/* External Source at INT[2] */
+#define IRQ_TSI108_EXT_INT3	TSI108_IRQ(3)	/* External Source at INT[3] */
+
+/* INTERNAL INTERRUPT SOURCES */
+
+#define IRQ_TSI108_RESERVED0	TSI108_IRQ(4)	/* Reserved IRQ */
+#define IRQ_TSI108_RESERVED1	TSI108_IRQ(5)	/* Reserved IRQ */
+#define IRQ_TSI108_RESERVED2	TSI108_IRQ(6)	/* Reserved IRQ */
+#define IRQ_TSI108_RESERVED3	TSI108_IRQ(7)	/* Reserved IRQ */
+#define IRQ_TSI108_DMA0		TSI108_IRQ(8)	/* DMA0 */
+#define IRQ_TSI108_DMA1		TSI108_IRQ(9)	/* DMA1 */
+#define IRQ_TSI108_DMA2		TSI108_IRQ(10)	/* DMA2 */
+#define IRQ_TSI108_DMA3		TSI108_IRQ(11)	/* DMA3 */
+#define IRQ_TSI108_UART0	TSI108_IRQ(12)	/* UART0 */
+#define IRQ_TSI108_UART1	TSI108_IRQ(13)	/* UART1 */
+#define IRQ_TSI108_I2C		TSI108_IRQ(14)	/* I2C */
+#define IRQ_TSI108_GPIO		TSI108_IRQ(15)	/* GPIO */
+#define IRQ_TSI108_GIGE0	TSI108_IRQ(16)	/* GIGE0 */
+#define IRQ_TSI108_GIGE1	TSI108_IRQ(17)	/* GIGE1 */
+#define IRQ_TSI108_RESERVED4	TSI108_IRQ(18)	/* Reserved IRQ */
+#define IRQ_TSI108_HLP		TSI108_IRQ(19)	/* HLP */
+#define IRQ_TSI108_SDRAM	TSI108_IRQ(20)	/* SDC */
+#define IRQ_TSI108_PROC_IF	TSI108_IRQ(21)	/* Processor IF */
+#define IRQ_TSI108_RESERVED5	TSI108_IRQ(22)	/* Reserved IRQ */
+#define IRQ_TSI108_PCI		TSI108_IRQ(23)	/* PCI/X block */
+
+#define IRQ_TSI108_MBOX0	TSI108_IRQ(24)	/* Mailbox 0 register */
+#define IRQ_TSI108_MBOX1	TSI108_IRQ(25)	/* Mailbox 1 register */
+#define IRQ_TSI108_MBOX2	TSI108_IRQ(26)	/* Mailbox 2 register */
+#define IRQ_TSI108_MBOX3	TSI108_IRQ(27)	/* Mailbox 3 register */
+
+#define IRQ_TSI108_DBELL0	TSI108_IRQ(28)	/* Doorbell 0 */
+#define IRQ_TSI108_DBELL1	TSI108_IRQ(29)	/* Doorbell 1 */
+#define IRQ_TSI108_DBELL2	TSI108_IRQ(30)	/* Doorbell 2 */
+#define IRQ_TSI108_DBELL3	TSI108_IRQ(31)	/* Doorbell 3 */
+
+#define IRQ_TSI108_TIMER0	TSI108_IRQ(32)	/* Global Timer 0 */
+#define IRQ_TSI108_TIMER1	TSI108_IRQ(33)	/* Global Timer 1 */
+#define IRQ_TSI108_TIMER2	TSI108_IRQ(34)	/* Global Timer 2 */
+#define IRQ_TSI108_TIMER3	TSI108_IRQ(35)	/* Global Timer 3 */
+
+/*
+ * PCI bus INTA# - INTD# lines demultiplexor
+ */
+#define IRQ_PCI_INTAD_BASE	TSI108_IRQ(36)
+#define IRQ_PCI_INTA		(IRQ_PCI_INTAD_BASE + 0)
+#define IRQ_PCI_INTB		(IRQ_PCI_INTAD_BASE + 1)
+#define IRQ_PCI_INTC		(IRQ_PCI_INTAD_BASE + 2)
+#define IRQ_PCI_INTD		(IRQ_PCI_INTAD_BASE + 3)
+#define NUM_PCI_IRQS		(4)
+
+/* number of entries in vector dispatch table */
+#define IRQ_TSI108_TAB_SIZE	(TSI108_MAX_VECTORS + 1)
+
+/* Mapping of MPIC outputs to processors' interrupt pins */
+
+#define IDIR_INT_OUT0		0x1
+#define IDIR_INT_OUT1		0x2
+#define IDIR_INT_OUT2		0x4
+#define IDIR_INT_OUT3		0x8
+
+/*---------------------------------------------------------------
+ * IRQ line configuration parameters */
+
+/* Interrupt delivery modes */
+typedef enum {
+	TSI108_IRQ_DIRECTED,
+	TSI108_IRQ_DISTRIBUTED,
+} TSI108_IRQ_MODE;
+#endif				/*  _ASM_PPC_TSI108_IRQ_H */
-- 
1.4.0

^ permalink raw reply related

* Re: [PATCH ] powerpc:  pass UPIO_TSI flag to 8259 serial driver
From: Zang Roy-r61911 @ 2006-08-24  5:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
In-Reply-To: <1156396647.8433.184.camel@localhost.localdomain>

On Thu, 2006-08-24 at 13:17, Benjamin Herrenschmidt wrote:
> > Evolution 1.2.2. I had found the reason and tested on my side.
> > Paul, if you do not modify it by hand, please select the following
> :-).
> > I will repost the mpic and mpc7448hph2 irq update patch.Very sorry
> for that.
> 
> Ok, the trick with evolution is to use the "preformat" style.
> 
> Typically, when posting a patch, I write my description, put the caret
> where I want to insert the patch itself, set the style to
> "Preformat" (from the pop-up menu just above the text editing zone),
> and
> do Insert->Text File from the menu.
> 
> You can also select a bit of text/patch and change the style to
> "Preformat" afterward if you missed it before doing the import.
> 
You words are  principle to post patch with evolution :-).
Roy

^ permalink raw reply

* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
From: Zang Roy-r61911 @ 2006-08-24  5:42 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Yang Xin-Xin-r48390, linuxppc-dev list
In-Reply-To: <7EA18FDD2DC2154AA3BD6D2F22A62A0E19E353@zch01exm23.fsl.freescale.net>

On Tue, 2006-08-22 at 18:07, Zang Roy-r61911 wrote:
> The patch adds new hardware information table for mpic. This 
> enables mpic code to deal with mpic controller with 
> hardware behavior difference.
> 
> CONFIG_MPIC_WEIRD is introduced in the code.
> If a board with non standard mpic controller,  it can select the
> CONFIG_MPIC_WEIRD with board and add its hardware information
> in the array mpic_infos.
> 
> TSI108/109 PIC takes the first index of weird  hardware information 
> table:) .  The table can be extended. The Tsi108/109 PIC looks like 
> standard OpenPIC but, in fact, is different in registers mapping and
> behavior.
> 
> The patch does not affect the behavior of standard mpic.
> CONFIG_MPIC_WEIRD
> excludes the weird mpic code when building standard mpic.
>     
> Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>
> Signed-off-by: Roy Zang	<tie-fei.zang@freescale.com> 
> 
Repost the patch. Fix the word wrap.

---
 arch/powerpc/Kconfig         |    8 +-
 arch/powerpc/sysdev/Makefile |    1 
 arch/powerpc/sysdev/mpic.c   |  187 +++++++++++++++++++++++++++++-------------
 include/asm-powerpc/mpic.h   |  114 ++++++++++++++++++++++++++
 4 files changed, 252 insertions(+), 58 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index abb325e..c88b647 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -440,11 +440,15 @@ config U3_DART
 	default n
 
 config MPIC
-	depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \
-			       || MPC7448HPC2
+	depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
 	bool
 	default y
 
+config MPIC_WEIRD
+	depends on MPC7448HPC2
+	bool
+	default y
+	
 config PPC_RTAS
 	bool
 	default n
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index cebfae2..8ae887b 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -3,6 +3,7 @@ EXTRA_CFLAGS			+= -mno-minimal-toc
 endif
 
 obj-$(CONFIG_MPIC)		+= mpic.o
+obj-$(CONFIG_MPIC_WEIRD)	+= mpic.o
 obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
 obj-$(CONFIG_PPC_MPC106)	+= grackle.o
 obj-$(CONFIG_BOOKE)		+= dcr.o
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 6e0281a..78e0515 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -54,6 +54,55 @@ #define distribute_irqs	(0)
 #endif
 #endif
 
+#ifdef CONFIG_MPIC_WEIRD
+static u32 mpic_infos[][INDEX_MPIC_WEIRD_END] = {
+	[0] = {	/* Tsi108/109 PIC */
+		TSI108_GREG_BASE,
+		TSI108_GREG_FEATURE_0,
+		TSI108_GREG_GLOBAL_CONF_0,
+		TSI108_GREG_VENDOR_ID,
+		TSI108_GREG_IPI_VECTOR_PRI_0,
+		TSI108_GREG_IPI_STRIDE,
+		TSI108_GREG_SPURIOUS,
+		TSI108_GREG_TIMER_FREQ,
+
+		TSI108_TIMER_BASE,
+		TSI108_TIMER_STRIDE,
+		TSI108_TIMER_CURRENT_CNT,
+		TSI108_TIMER_BASE_CNT,
+		TSI108_TIMER_VECTOR_PRI,
+		TSI108_TIMER_DESTINATION,
+
+		TSI108_CPU_BASE,
+		TSI108_CPU_STRIDE,
+		TSI108_CPU_IPI_DISPATCH_0,
+		TSI108_CPU_IPI_DISPATCH_STRIDE,
+		TSI108_CPU_CURRENT_TASK_PRI,
+		TSI108_CPU_WHOAMI,
+		TSI108_CPU_INTACK,
+		TSI108_CPU_EOI,
+
+		TSI108_IRQ_BASE,
+		TSI108_IRQ_STRIDE,
+		TSI108_IRQ_VECTOR_PRI,
+		TSI108_VECPRI_VECTOR_MASK,
+		TSI108_VECPRI_POLARITY_POSITIVE,
+		TSI108_VECPRI_POLARITY_NEGATIVE,
+		TSI108_VECPRI_SENSE_LEVEL,
+		TSI108_VECPRI_SENSE_EDGE,
+		TSI108_VECPRI_POLARITY_MASK,
+		TSI108_VECPRI_SENSE_MASK,
+		TSI108_IRQ_DESTINATION
+	},
+};
+#endif
+
+#ifdef CONFIG_MPIC_WEIRD
+#define MPIC_INFO(name) mpic->hw_set[INDEX_##name]
+#else
+#define MPIC_INFO(name) MPIC_##name
+#endif
+
 /*
  * Register accessor functions
  */
@@ -80,7 +129,8 @@ static inline void _mpic_write(unsigned 
 static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
 {
 	unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
-	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+	unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
+			      (ipi * MPIC_INFO(GREG_IPI_STRIDE));
 
 	if (mpic->flags & MPIC_BROKEN_IPI)
 		be = !be;
@@ -89,7 +139,8 @@ static inline u32 _mpic_ipi_read(struct 
 
 static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
 {
-	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+	unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
+			      (ipi * MPIC_INFO(GREG_IPI_STRIDE));
 
 	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
 }
@@ -120,7 +171,7 @@ static inline u32 _mpic_irq_read(struct 
 	unsigned int	idx = src_no & mpic->isu_mask;
 
 	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
-			  reg + (idx * MPIC_IRQ_STRIDE));
+			  reg + (idx * MPIC_INFO(IRQ_STRIDE)));
 }
 
 static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
@@ -130,7 +181,7 @@ static inline void _mpic_irq_write(struc
 	unsigned int	idx = src_no & mpic->isu_mask;
 
 	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
-		    reg + (idx * MPIC_IRQ_STRIDE), value);
+		    reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
 }
 
 #define mpic_read(b,r)		_mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
@@ -156,8 +207,8 @@ static void __init mpic_test_broken_ipi(
 {
 	u32 r;
 
-	mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK);
-	r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0);
+	mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK);
+	r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
 
 	if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
 		printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
@@ -394,8 +445,8 @@ static inline struct mpic * mpic_from_ir
 /* Send an EOI */
 static inline void mpic_eoi(struct mpic *mpic)
 {
-	mpic_cpu_write(MPIC_CPU_EOI, 0);
-	(void)mpic_cpu_read(MPIC_CPU_WHOAMI);
+	mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
+	(void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
 }
 
 #ifdef CONFIG_SMP
@@ -419,8 +470,8 @@ static void mpic_unmask_irq(unsigned int
 
 	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
 
-	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
-		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
+		       mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
 		       ~MPIC_VECPRI_MASK);
 	/* make sure mask gets to controller before we return to user */
 	do {
@@ -428,7 +479,7 @@ static void mpic_unmask_irq(unsigned int
 			printk(KERN_ERR "mpic_enable_irq timeout\n");
 			break;
 		}
-	} while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);
+	} while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);	
 }
 
 static void mpic_mask_irq(unsigned int irq)
@@ -439,8 +490,8 @@ static void mpic_mask_irq(unsigned int i
 
 	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
 
-	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
-		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
+		       mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
 		       MPIC_VECPRI_MASK);
 
 	/* make sure mask gets to controller before we return to user */
@@ -449,7 +500,7 @@ static void mpic_mask_irq(unsigned int i
 			printk(KERN_ERR "mpic_enable_irq timeout\n");
 			break;
 		}
-	} while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
+	} while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
 }
 
 static void mpic_end_irq(unsigned int irq)
@@ -560,24 +611,32 @@ static void mpic_set_affinity(unsigned i
 
 	cpus_and(tmp, cpumask, cpu_online_map);
 
-	mpic_irq_write(src, MPIC_IRQ_DESTINATION,
+	mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
 		       mpic_physmask(cpus_addr(tmp)[0]));	
 }
 
+#ifdef CONFIG_MPIC_WEIRD
+static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
+#else
 static unsigned int mpic_type_to_vecpri(unsigned int type)
+#endif
 {
 	/* Now convert sense value */
 	switch(type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_RISING:
-		return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_POSITIVE;
+		return MPIC_INFO(VECPRI_SENSE_EDGE) |
+		       MPIC_INFO(VECPRI_POLARITY_POSITIVE);
 	case IRQ_TYPE_EDGE_FALLING:
 	case IRQ_TYPE_EDGE_BOTH:
-		return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_NEGATIVE;
+		return MPIC_INFO(VECPRI_SENSE_EDGE) |
+		       MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
 	case IRQ_TYPE_LEVEL_HIGH:
-		return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_POSITIVE;
+		return MPIC_INFO(VECPRI_SENSE_LEVEL) |
+		       MPIC_INFO(VECPRI_POLARITY_POSITIVE);
 	case IRQ_TYPE_LEVEL_LOW:
 	default:
-		return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE;
+		return MPIC_INFO(VECPRI_SENSE_LEVEL) |
+		       MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
 	}
 }
 
@@ -609,13 +668,18 @@ static int mpic_set_irq_type(unsigned in
 		vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
 			MPIC_VECPRI_SENSE_EDGE;
 	else
+#ifdef CONFIG_MPIC_WEIRD
+		vecpri = mpic_type_to_vecpri(mpic, flow_type);
+#else
 		vecpri = mpic_type_to_vecpri(flow_type);
+#endif	
 
-	vold = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
-	vnew = vold & ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK);
+	vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
+	vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) | 
+			MPIC_INFO(VECPRI_SENSE_MASK));
 	vnew |= vecpri;
 	if (vold != vnew)
-		mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew);
+		mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
 
 	return 0;
 }
@@ -797,18 +861,23 @@ #endif /* CONFIG_SMP */
 	mpic->isu_size = isu_size;
 	mpic->irq_count = irq_count;
 	mpic->num_sources = 0; /* so far */
+	
+#ifdef CONFIG_MPIC_WEIRD
+	mpic->hw_set = mpic_infos[MPIC_GET_MOD_ID(flags)];
+#endif
 
 	/* Map the global registers */
-	mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
-	mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
+	mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000);
+	mpic->tmregs = mpic->gregs +
+		       ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2);
 	BUG_ON(mpic->gregs == NULL);
 
 	/* Reset */
 	if (flags & MPIC_WANTS_RESET) {
-		mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
-			   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
 			   | MPIC_GREG_GCONF_RESET);
-		while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+		while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
 		       & MPIC_GREG_GCONF_RESET)
 			mb();
 	}
@@ -817,7 +886,7 @@ #endif /* CONFIG_SMP */
 	 * MPICs, num sources as well. On ISU MPICs, sources are counted
 	 * as ISUs are added
 	 */
-	reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
+	reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
 	mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
 			  >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
 	if (isu_size == 0)
@@ -826,16 +895,16 @@ #endif /* CONFIG_SMP */
 
 	/* Map the per-CPU registers */
 	for (i = 0; i < mpic->num_cpus; i++) {
-		mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
-					   i * MPIC_CPU_STRIDE, 0x1000);
+		mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) +
+					   i * MPIC_INFO(CPU_STRIDE), 0x1000);
 		BUG_ON(mpic->cpuregs[i] == NULL);
 	}
 
 	/* Initialize main ISU if none provided */
 	if (mpic->isu_size == 0) {
 		mpic->isu_size = mpic->num_sources;
-		mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
-					MPIC_IRQ_STRIDE * mpic->isu_size);
+		mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE),
+					MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
 		BUG_ON(mpic->isus[0] == NULL);
 	}
 	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -879,7 +948,8 @@ void __init mpic_assign_isu(struct mpic 
 
 	BUG_ON(isu_num >= MPIC_MAX_ISU);
 
-	mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size);
+	mpic->isus[isu_num] = ioremap(phys_addr,
+				      MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
 	if ((isu_first + mpic->isu_size) > mpic->num_sources)
 		mpic->num_sources = isu_first + mpic->isu_size;
 }
@@ -904,14 +974,16 @@ void __init mpic_init(struct mpic *mpic)
 	printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);
 
 	/* Set current processor priority to max */
-	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
 
 	/* Initialize timers: just disable them all */
 	for (i = 0; i < 4; i++) {
 		mpic_write(mpic->tmregs,
-			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
+			   i * MPIC_INFO(TIMER_STRIDE) +
+			   MPIC_INFO(TIMER_DESTINATION), 0);
 		mpic_write(mpic->tmregs,
-			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
+			   i * MPIC_INFO(TIMER_STRIDE) + 
+			   MPIC_INFO(TIMER_VECTOR_PRI),
 			   MPIC_VECPRI_MASK |
 			   (MPIC_VEC_TIMER_0 + i));
 	}
@@ -940,21 +1012,23 @@ void __init mpic_init(struct mpic *mpic)
 			(8 << MPIC_VECPRI_PRIORITY_SHIFT);
 		
 		/* init hw */
-		mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
-		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
+		mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
+		mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
 			       1 << hard_smp_processor_id());
 	}
 	
 	/* Init spurrious vector */
-	mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS);
+	mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS);
 
-	/* Disable 8259 passthrough */
-	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
-		   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+	/* Disable 8259 passthrough, if supported */
+#ifndef CONFIG_MPIC_WEIRD
+	mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+		   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
 		   | MPIC_GREG_GCONF_8259_PTHROU_DIS);
+#endif
 
 	/* Set current processor priority to 0 */
-	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
 }
 
 void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
@@ -997,9 +1071,9 @@ void mpic_irq_set_priority(unsigned int 
 		mpic_ipi_write(src - MPIC_VEC_IPI_0,
 			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
 	} else {
-		reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI)
+		reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
 			& ~MPIC_VECPRI_PRIORITY_MASK;
-		mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
+		mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
 			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
 	}
 	spin_unlock_irqrestore(&mpic_lock, flags);
@@ -1017,7 +1091,7 @@ unsigned int mpic_irq_get_priority(unsig
 	if (is_ipi)
 		reg = mpic_ipi_read(src = MPIC_VEC_IPI_0);
 	else
-		reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
+		reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
 	spin_unlock_irqrestore(&mpic_lock, flags);
 	return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT;
 }
@@ -1043,12 +1117,12 @@ #ifdef CONFIG_SMP
  	 */
 	if (distribute_irqs) {
 	 	for (i = 0; i < mpic->num_sources ; i++)
-			mpic_irq_write(i, MPIC_IRQ_DESTINATION,
-				mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
+			mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+				mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk);
 	}
 
 	/* Set current processor priority to 0 */
-	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
 
 	spin_unlock_irqrestore(&mpic_lock, flags);
 #endif /* CONFIG_SMP */
@@ -1058,7 +1132,7 @@ int mpic_cpu_get_priority(void)
 {
 	struct mpic *mpic = mpic_primary;
 
-	return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
+	return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI));
 }
 
 void mpic_cpu_set_priority(int prio)
@@ -1066,7 +1140,7 @@ void mpic_cpu_set_priority(int prio)
 	struct mpic *mpic = mpic_primary;
 
 	prio &= MPIC_CPU_TASKPRI_MASK;
-	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
+	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio);
 }
 
 /*
@@ -1088,11 +1162,11 @@ void mpic_teardown_this_cpu(int secondar
 
 	/* let the mpic know we don't want intrs.  */
 	for (i = 0; i < mpic->num_sources ; i++)
-		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
-			mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
+		mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+			mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk);
 
 	/* Set current processor priority to max */
-	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
 
 	spin_unlock_irqrestore(&mpic_lock, flags);
 }
@@ -1108,7 +1182,8 @@ #ifdef DEBUG_IPI
 	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
 #endif
 
-	mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
+	mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
+		       ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
 		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
 }
 
@@ -1116,7 +1191,7 @@ unsigned int mpic_get_one_irq(struct mpi
 {
 	u32 src;
 
-	src = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
+	src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK);
 #ifdef DEBUG_LOW
 	DBG("%s: get_one_irq(): %d\n", mpic->name, src);
 #endif
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index eb241c9..faebdf2 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -41,6 +41,7 @@ #define MPIC_GREG_IPI_VECTOR_PRI_0	0x000
 #define MPIC_GREG_IPI_VECTOR_PRI_1	0x000b0
 #define MPIC_GREG_IPI_VECTOR_PRI_2	0x000c0
 #define MPIC_GREG_IPI_VECTOR_PRI_3	0x000d0
+#define MPIC_GREG_IPI_STRIDE		0x10
 #define MPIC_GREG_SPURIOUS		0x000e0
 #define MPIC_GREG_TIMER_FREQ		0x000f0
 
@@ -68,6 +69,7 @@ #define MPIC_CPU_IPI_DISPATCH_0		0x00040
 #define MPIC_CPU_IPI_DISPATCH_1		0x00050
 #define MPIC_CPU_IPI_DISPATCH_2		0x00060
 #define MPIC_CPU_IPI_DISPATCH_3		0x00070
+#define MPIC_CPU_IPI_DISPATCH_STRIDE	0x00010
 #define MPIC_CPU_CURRENT_TASK_PRI	0x00080
 #define 	MPIC_CPU_TASKPRI_MASK			0x0000000f
 #define MPIC_CPU_WHOAMI			0x00090
@@ -114,6 +116,103 @@ #define MPIC_VEC_TIMER_2	249
 #define MPIC_VEC_TIMER_1	248
 #define MPIC_VEC_TIMER_0	247
 
+#ifdef CONFIG_MPIC_WEIRD
+/*
+ * Tsi108 implementation of MPIC has many differences from the original one
+ */
+
+/*
+ * Global registers
+ */
+
+#define TSI108_GREG_BASE		0x00000
+#define TSI108_GREG_FEATURE_0		0x00000
+#define TSI108_GREG_GLOBAL_CONF_0	0x00004
+#define TSI108_GREG_VENDOR_ID		0x0000c
+#define TSI108_GREG_IPI_VECTOR_PRI_0	0x00204		/* Doorbell 0 */
+#define TSI108_GREG_IPI_STRIDE		0x0c
+#define TSI108_GREG_SPURIOUS		0x00010
+#define TSI108_GREG_TIMER_FREQ		0x00014
+
+/*
+ * Timer registers
+ */
+#define TSI108_TIMER_BASE		0x0030
+#define TSI108_TIMER_STRIDE		0x10
+#define TSI108_TIMER_CURRENT_CNT	0x00000
+#define TSI108_TIMER_BASE_CNT		0x00004
+#define TSI108_TIMER_VECTOR_PRI		0x00008
+#define TSI108_TIMER_DESTINATION	0x0000c
+
+/*
+ * Per-Processor registers
+ */
+#define TSI108_CPU_BASE			0x00300
+#define TSI108_CPU_STRIDE		0x00040
+#define TSI108_CPU_IPI_DISPATCH_0	0x00200
+#define TSI108_CPU_IPI_DISPATCH_STRIDE	0x00000
+#define TSI108_CPU_CURRENT_TASK_PRI	0x00000
+#define TSI108_CPU_WHOAMI		0xffffffff
+#define TSI108_CPU_INTACK		0x00004
+#define TSI108_CPU_EOI			0x00008
+
+/*
+ * Per-source registers
+ */
+#define TSI108_IRQ_BASE			0x00100
+#define TSI108_IRQ_STRIDE		0x00008
+#define TSI108_IRQ_VECTOR_PRI		0x00000
+#define TSI108_VECPRI_VECTOR_MASK	0x000000ff
+#define TSI108_VECPRI_POLARITY_POSITIVE	0x01000000
+#define TSI108_VECPRI_POLARITY_NEGATIVE	0x00000000
+#define TSI108_VECPRI_SENSE_LEVEL	0x02000000
+#define TSI108_VECPRI_SENSE_EDGE	0x00000000
+#define TSI108_VECPRI_POLARITY_MASK	0x01000000
+#define TSI108_VECPRI_SENSE_MASK	0x02000000
+#define TSI108_IRQ_DESTINATION		0x00004
+
+/* weird mpic variable index in the HW info array */
+enum MPIC_WEIRD_INDEX {
+	INDEX_GREG_BASE = 0,	/* Offset of global registers from MPIC base */
+	INDEX_GREG_FEATURE_0,	/* FRR0 offset from base */
+	INDEX_GREG_GLOBAL_CONF_0, /* Global Config register offset from base */
+	INDEX_GREG_VENDOR_ID,	/* VID register offset from base */
+	INDEX_GREG_IPI_VECTOR_PRI_0,	/* IPI Vector/Priority Registers */
+	INDEX_GREG_IPI_STRIDE, 		/* IPI Vector/Priority Registers spacing */
+	INDEX_GREG_SPURIOUS,		/* Spurious Vector Register */
+	INDEX_GREG_TIMER_FREQ,	/* Global Timer Frequency Reporting Register */
+
+	INDEX_TIMER_BASE,		/* Global Timer Registers base */
+	INDEX_TIMER_STRIDE,		/* Global Timer Registers spacing */
+	INDEX_TIMER_CURRENT_CNT,	/* Global Timer Current Count Register */
+	INDEX_TIMER_BASE_CNT,		/* Global Timer Base Count Register */
+	INDEX_TIMER_VECTOR_PRI,		/* Global Timer Vector/Priority Register */
+	INDEX_TIMER_DESTINATION,	/* Global Timer Destination Register */
+
+	INDEX_CPU_BASE,	/* Offset of cpu base */
+	INDEX_CPU_STRIDE,	/* Cpu register spacing*/
+	INDEX_CPU_IPI_DISPATCH_0,	/* IPI 0 Dispatch Command Register */
+	INDEX_CPU_IPI_DISPATCH_STRIDE,	/* IPI Dispatch spacing */
+	INDEX_CPU_CURRENT_TASK_PRI,/* Processor Current Task Priority Register */
+	INDEX_CPU_WHOAMI,	/* Who Am I Register */
+	INDEX_CPU_INTACK,	/* Interrupt Acknowledge Register */
+	INDEX_CPU_EOI,		/* End of Interrupt Register */
+
+	INDEX_IRQ_BASE,	/* Interrupt registers base */
+	INDEX_IRQ_STRIDE,	/* Interrupt registers spacing */
+	INDEX_IRQ_VECTOR_PRI,	/* Interrupt Vector/Priority Register */
+	INDEX_VECPRI_VECTOR_MASK,	/* Interrupt Vector Mask */
+	INDEX_VECPRI_POLARITY_POSITIVE,	/* Interrupt Positive Polarity bit */
+	INDEX_VECPRI_POLARITY_NEGATIVE,	/* Interrupt Negative Polarity bit */
+	INDEX_VECPRI_SENSE_LEVEL,	/* Interrupt Level Sense bit */
+	INDEX_VECPRI_SENSE_EDGE,	/* Interrupt edge Sense bit */
+	INDEX_VECPRI_POLARITY_MASK, /* Interrupt Polarity mask */
+	INDEX_VECPRI_SENSE_MASK, /* Interrupt sense mask */
+	INDEX_IRQ_DESTINATION,	/* Interrupt Destination Register */
+	INDEX_MPIC_WEIRD_END	/* Size of the hw info array */
+};
+#endif
+
 #ifdef CONFIG_MPIC_BROKEN_U3
 /* Fixup table entry */
 struct mpic_irq_fixup
@@ -170,6 +269,11 @@ #endif
 	volatile u32 __iomem	*tmregs;
 	volatile u32 __iomem	*cpuregs[MPIC_MAX_CPUS];
 	volatile u32 __iomem	*isus[MPIC_MAX_ISU];
+	
+#ifdef CONFIG_MPIC_WEIRD
+	/* Pointer to HW info array */
+	u32	*hw_set;
+#endif
 
 	/* link */
 	struct mpic		*next;
@@ -189,6 +293,16 @@ #define MPIC_BROKEN_IPI			0x00000008
 /* MPIC wants a reset */
 #define MPIC_WANTS_RESET		0x00000010
 
+#ifdef CONFIG_MPIC_WEIRD
+/* Spurious vector requires EOI */
+#define MPIC_SPV_EOI			0x00000020
+/* MPIC HW modification ID */
+#define MPIC_MOD_ID_MASK		0x00000f00
+#define MPIC_MOD_ID(val)		(((val) << 8) & MPIC_MOD_ID_MASK)
+#define MPIC_GET_MOD_ID(flags)		(((flags) & MPIC_MOD_ID_MASK) >> 8)
+#define	MPIC_ID_TSI108		0	/* Tsi108/109 PIC */
+#endif
+
 /* Allocate the controller structure and setup the linux irq descs
  * for the range if interrupts passed in. No HW initialization is
  * actually performed.
-- 
1.4.0

^ permalink raw reply related

* RE: [PATCH 1/3] Adapt ipic driver to new host_ops interface, addset_irq_type to set IRQ sense
From: Li Yang-r58472 @ 2006-08-24  5:44 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Phillips Kim-R1AAHA; +Cc: linuxppc-dev
In-Reply-To: <1156391081.8433.164.camel@localhost.localdomain>

> > +static int ipic_host_map(struct irq_host *h, unsigned int virq,
> > +			 irq_hw_number_t hw)
> > +{
> > +	struct ipic *ipic =3D h->host_data;
> > +	struct irq_chip *chip;
> > +
> > +	/* Default chip */
> > +	chip =3D &ipic->hc_irq;
> > +
> > +	set_irq_chip_data(virq, ipic);
> > +	set_irq_chip(virq, chip);
> > +
> > +	return 0;
> >  }
>=20
> Shouldn't you call set_irq_type() (or at least set a handler) here to
> setup a default type ? The common code will only call set_irq_type()
if
> an explicit non-default and different than the current setting handler
> is set.

But for IRQ with a specified type, set_irq_type() will be called two
times continuously.  Why not call the set_irq_type() in any case in
irq_create_of_mapping()?

^ permalink raw reply

* RE: [PATCH ] powerpc:  pass UPIO_TSI flag to 8259 serial driver
From: Li Yang-r58472 @ 2006-08-24  5:49 UTC (permalink / raw)
  To: Zang Roy-r61911, Benjamin Herrenschmidt
  Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
In-Reply-To: <1156397928.5913.38.camel@localhost.localdomain>

> -----Original Message-----
> From: linuxppc-dev-bounces+leoli=3Dfreescale.com@ozlabs.org
> [mailto:linuxppc-dev-bounces+leoli=3Dfreescale.com@ozlabs.org] On =
Behalf
Of Zang
> Roy-r61911
> Sent: Thursday, August 24, 2006 1:39 PM
> To: Benjamin Herrenschmidt
> Cc: linuxppc-dev list; Paul Mackerras; Yang Xin-Xin-r48390
> Subject: Re: [PATCH ] powerpc: pass UPIO_TSI flag to 8259 serial
driver
>=20
> On Thu, 2006-08-24 at 13:17, Benjamin Herrenschmidt wrote:
> > > Evolution 1.2.2. I had found the reason and tested on my side.
> > > Paul, if you do not modify it by hand, please select the following
> > :-).
> > > I will repost the mpic and mpc7448hph2 irq update patch.Very sorry
> > for that.
> >
> > Ok, the trick with evolution is to use the "preformat" style.
> >
> > Typically, when posting a patch, I write my description, put the
caret
> > where I want to insert the patch itself, set the style to
> > "Preformat" (from the pop-up menu just above the text editing zone),
> > and
> > do Insert->Text File from the menu.
> >
> > You can also select a bit of text/patch and change the style to
> > "Preformat" afterward if you missed it before doing the import.
> >
> You words are  principle to post patch with evolution :-).

Why did no one ever add a mail client guide to the kernel documentation?
It seems such problem happens a lot.

^ permalink raw reply

* Re: [PATCH] powerpc: update mpc7448hpc2 board irq support usingdevice tree
From: Benjamin Herrenschmidt @ 2006-08-24  5:50 UTC (permalink / raw)
  To: Zang Roy-r61911
  Cc: linuxppc-dev list, Paul Mackerras, Alexandre.Bounine,
	Yang Xin-Xin-r48390
In-Reply-To: <1156397344.5913.34.camel@localhost.localdomain>


> -struct hw_interrupt_type tsi108_pci_irq = {
> +static struct irq_chip tsi108_pci_irq = {
>  	.typename = "tsi108_PCI_int",
> -	.enable = tsi108_pci_irq_enable,
> -	.disable = tsi108_pci_irq_disable,
> +	.mask = tsi108_pci_irq_disable,
>  	.ack = tsi108_pci_irq_ack,
>  	.end = tsi108_pci_irq_end,
> +	.unmask = tsi108_pci_irq_enable,
>  };
>  
>  /*

While the patch as-is looks ok, it also looks like you could take
advantage of the new genirq code to clean up your TSI irq handling a
bit. You probably don't need a end() handler anymore provided that you
properly set your main handler to be either level, edge or fasteoi (in
which case, you need an eoi handler).

Ben.

^ permalink raw reply

* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
From: Benjamin Herrenschmidt @ 2006-08-24  5:54 UTC (permalink / raw)
  To: Zang Roy-r61911; +Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
In-Reply-To: <1156398135.5913.43.camel@localhost.localdomain>

On Thu, 2006-08-24 at 13:42 +0800, Zang Roy-r61911 wrote:
> On Tue, 2006-08-22 at 18:07, Zang Roy-r61911 wrote:
> > The patch adds new hardware information table for mpic. This 
> > enables mpic code to deal with mpic controller with 
> > hardware behavior difference.
> > 
> > CONFIG_MPIC_WEIRD is introduced in the code.
> > If a board with non standard mpic controller,  it can select the
> > CONFIG_MPIC_WEIRD with board and add its hardware information
> > in the array mpic_infos.
> > 
> > TSI108/109 PIC takes the first index of weird  hardware information 
> > table:) .  The table can be extended. The Tsi108/109 PIC looks like 
> > standard OpenPIC but, in fact, is different in registers mapping and
> > behavior.

The table should still contain the entries for a normal MPIC. One can
build a kernel that will boot both machines with the "weird" one and
with the normal one. Thus CONFIG_MPIC_WEIRD shall not exclude normal
MPICs, though not having it does exclude weird ones. I thus would
suggest to keep the table as it was in your earlier patches, that is
with the normal MPIC mapping at 0.

I intend to re-use that to handle another weird MPIC from some other
project :)

Cheers,
Ben. 

> > The patch does not affect the behavior of standard mpic.
> > CONFIG_MPIC_WEIRD
> > excludes the weird mpic code when building standard mpic.
> >     
> > Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>
> > Signed-off-by: Roy Zang	<tie-fei.zang@freescale.com> 
> > 
> Repost the patch. Fix the word wrap.
> 
> ---
>  arch/powerpc/Kconfig         |    8 +-
>  arch/powerpc/sysdev/Makefile |    1 
>  arch/powerpc/sysdev/mpic.c   |  187 +++++++++++++++++++++++++++++-------------
>  include/asm-powerpc/mpic.h   |  114 ++++++++++++++++++++++++++
>  4 files changed, 252 insertions(+), 58 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index abb325e..c88b647 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -440,11 +440,15 @@ config U3_DART
>  	default n
>  
>  config MPIC
> -	depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \
> -			       || MPC7448HPC2
> +	depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
>  	bool
>  	default y
>  
> +config MPIC_WEIRD
> +	depends on MPC7448HPC2
> +	bool
> +	default y
> +	
>  config PPC_RTAS
>  	bool
>  	default n
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
> index cebfae2..8ae887b 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -3,6 +3,7 @@ EXTRA_CFLAGS			+= -mno-minimal-toc
>  endif
>  
>  obj-$(CONFIG_MPIC)		+= mpic.o
> +obj-$(CONFIG_MPIC_WEIRD)	+= mpic.o
>  obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
>  obj-$(CONFIG_PPC_MPC106)	+= grackle.o
>  obj-$(CONFIG_BOOKE)		+= dcr.o
> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> index 6e0281a..78e0515 100644
> --- a/arch/powerpc/sysdev/mpic.c
> +++ b/arch/powerpc/sysdev/mpic.c
> @@ -54,6 +54,55 @@ #define distribute_irqs	(0)
>  #endif
>  #endif
>  
> +#ifdef CONFIG_MPIC_WEIRD
> +static u32 mpic_infos[][INDEX_MPIC_WEIRD_END] = {
> +	[0] = {	/* Tsi108/109 PIC */
> +		TSI108_GREG_BASE,
> +		TSI108_GREG_FEATURE_0,
> +		TSI108_GREG_GLOBAL_CONF_0,
> +		TSI108_GREG_VENDOR_ID,
> +		TSI108_GREG_IPI_VECTOR_PRI_0,
> +		TSI108_GREG_IPI_STRIDE,
> +		TSI108_GREG_SPURIOUS,
> +		TSI108_GREG_TIMER_FREQ,
> +
> +		TSI108_TIMER_BASE,
> +		TSI108_TIMER_STRIDE,
> +		TSI108_TIMER_CURRENT_CNT,
> +		TSI108_TIMER_BASE_CNT,
> +		TSI108_TIMER_VECTOR_PRI,
> +		TSI108_TIMER_DESTINATION,
> +
> +		TSI108_CPU_BASE,
> +		TSI108_CPU_STRIDE,
> +		TSI108_CPU_IPI_DISPATCH_0,
> +		TSI108_CPU_IPI_DISPATCH_STRIDE,
> +		TSI108_CPU_CURRENT_TASK_PRI,
> +		TSI108_CPU_WHOAMI,
> +		TSI108_CPU_INTACK,
> +		TSI108_CPU_EOI,
> +
> +		TSI108_IRQ_BASE,
> +		TSI108_IRQ_STRIDE,
> +		TSI108_IRQ_VECTOR_PRI,
> +		TSI108_VECPRI_VECTOR_MASK,
> +		TSI108_VECPRI_POLARITY_POSITIVE,
> +		TSI108_VECPRI_POLARITY_NEGATIVE,
> +		TSI108_VECPRI_SENSE_LEVEL,
> +		TSI108_VECPRI_SENSE_EDGE,
> +		TSI108_VECPRI_POLARITY_MASK,
> +		TSI108_VECPRI_SENSE_MASK,
> +		TSI108_IRQ_DESTINATION
> +	},
> +};
> +#endif
> +
> +#ifdef CONFIG_MPIC_WEIRD
> +#define MPIC_INFO(name) mpic->hw_set[INDEX_##name]
> +#else
> +#define MPIC_INFO(name) MPIC_##name
> +#endif
> +
>  /*
>   * Register accessor functions
>   */
> @@ -80,7 +129,8 @@ static inline void _mpic_write(unsigned 
>  static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
>  {
>  	unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
> -	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
> +	unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
> +			      (ipi * MPIC_INFO(GREG_IPI_STRIDE));
>  
>  	if (mpic->flags & MPIC_BROKEN_IPI)
>  		be = !be;
> @@ -89,7 +139,8 @@ static inline u32 _mpic_ipi_read(struct 
>  
>  static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
>  {
> -	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
> +	unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
> +			      (ipi * MPIC_INFO(GREG_IPI_STRIDE));
>  
>  	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
>  }
> @@ -120,7 +171,7 @@ static inline u32 _mpic_irq_read(struct 
>  	unsigned int	idx = src_no & mpic->isu_mask;
>  
>  	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
> -			  reg + (idx * MPIC_IRQ_STRIDE));
> +			  reg + (idx * MPIC_INFO(IRQ_STRIDE)));
>  }
>  
>  static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
> @@ -130,7 +181,7 @@ static inline void _mpic_irq_write(struc
>  	unsigned int	idx = src_no & mpic->isu_mask;
>  
>  	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
> -		    reg + (idx * MPIC_IRQ_STRIDE), value);
> +		    reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
>  }
>  
>  #define mpic_read(b,r)		_mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
> @@ -156,8 +207,8 @@ static void __init mpic_test_broken_ipi(
>  {
>  	u32 r;
>  
> -	mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK);
> -	r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0);
> +	mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK);
> +	r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
>  
>  	if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
>  		printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
> @@ -394,8 +445,8 @@ static inline struct mpic * mpic_from_ir
>  /* Send an EOI */
>  static inline void mpic_eoi(struct mpic *mpic)
>  {
> -	mpic_cpu_write(MPIC_CPU_EOI, 0);
> -	(void)mpic_cpu_read(MPIC_CPU_WHOAMI);
> +	mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
> +	(void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
>  }
>  
>  #ifdef CONFIG_SMP
> @@ -419,8 +470,8 @@ static void mpic_unmask_irq(unsigned int
>  
>  	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
>  
> -	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
> -		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
> +	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> +		       mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
>  		       ~MPIC_VECPRI_MASK);
>  	/* make sure mask gets to controller before we return to user */
>  	do {
> @@ -428,7 +479,7 @@ static void mpic_unmask_irq(unsigned int
>  			printk(KERN_ERR "mpic_enable_irq timeout\n");
>  			break;
>  		}
> -	} while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);
> +	} while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);	
>  }
>  
>  static void mpic_mask_irq(unsigned int irq)
> @@ -439,8 +490,8 @@ static void mpic_mask_irq(unsigned int i
>  
>  	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
>  
> -	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
> -		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
> +	mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> +		       mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
>  		       MPIC_VECPRI_MASK);
>  
>  	/* make sure mask gets to controller before we return to user */
> @@ -449,7 +500,7 @@ static void mpic_mask_irq(unsigned int i
>  			printk(KERN_ERR "mpic_enable_irq timeout\n");
>  			break;
>  		}
> -	} while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
> +	} while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
>  }
>  
>  static void mpic_end_irq(unsigned int irq)
> @@ -560,24 +611,32 @@ static void mpic_set_affinity(unsigned i
>  
>  	cpus_and(tmp, cpumask, cpu_online_map);
>  
> -	mpic_irq_write(src, MPIC_IRQ_DESTINATION,
> +	mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
>  		       mpic_physmask(cpus_addr(tmp)[0]));	
>  }
>  
> +#ifdef CONFIG_MPIC_WEIRD
> +static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
> +#else
>  static unsigned int mpic_type_to_vecpri(unsigned int type)
> +#endif
>  {
>  	/* Now convert sense value */
>  	switch(type & IRQ_TYPE_SENSE_MASK) {
>  	case IRQ_TYPE_EDGE_RISING:
> -		return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_POSITIVE;
> +		return MPIC_INFO(VECPRI_SENSE_EDGE) |
> +		       MPIC_INFO(VECPRI_POLARITY_POSITIVE);
>  	case IRQ_TYPE_EDGE_FALLING:
>  	case IRQ_TYPE_EDGE_BOTH:
> -		return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_NEGATIVE;
> +		return MPIC_INFO(VECPRI_SENSE_EDGE) |
> +		       MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
>  	case IRQ_TYPE_LEVEL_HIGH:
> -		return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_POSITIVE;
> +		return MPIC_INFO(VECPRI_SENSE_LEVEL) |
> +		       MPIC_INFO(VECPRI_POLARITY_POSITIVE);
>  	case IRQ_TYPE_LEVEL_LOW:
>  	default:
> -		return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE;
> +		return MPIC_INFO(VECPRI_SENSE_LEVEL) |
> +		       MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
>  	}
>  }
>  
> @@ -609,13 +668,18 @@ static int mpic_set_irq_type(unsigned in
>  		vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
>  			MPIC_VECPRI_SENSE_EDGE;
>  	else
> +#ifdef CONFIG_MPIC_WEIRD
> +		vecpri = mpic_type_to_vecpri(mpic, flow_type);
> +#else
>  		vecpri = mpic_type_to_vecpri(flow_type);
> +#endif	
>  
> -	vold = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
> -	vnew = vold & ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK);
> +	vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
> +	vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) | 
> +			MPIC_INFO(VECPRI_SENSE_MASK));
>  	vnew |= vecpri;
>  	if (vold != vnew)
> -		mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew);
> +		mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
>  
>  	return 0;
>  }
> @@ -797,18 +861,23 @@ #endif /* CONFIG_SMP */
>  	mpic->isu_size = isu_size;
>  	mpic->irq_count = irq_count;
>  	mpic->num_sources = 0; /* so far */
> +	
> +#ifdef CONFIG_MPIC_WEIRD
> +	mpic->hw_set = mpic_infos[MPIC_GET_MOD_ID(flags)];
> +#endif
>  
>  	/* Map the global registers */
> -	mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
> -	mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
> +	mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000);
> +	mpic->tmregs = mpic->gregs +
> +		       ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2);
>  	BUG_ON(mpic->gregs == NULL);
>  
>  	/* Reset */
>  	if (flags & MPIC_WANTS_RESET) {
> -		mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
> -			   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
> +		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
> +			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
>  			   | MPIC_GREG_GCONF_RESET);
> -		while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
> +		while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
>  		       & MPIC_GREG_GCONF_RESET)
>  			mb();
>  	}
> @@ -817,7 +886,7 @@ #endif /* CONFIG_SMP */
>  	 * MPICs, num sources as well. On ISU MPICs, sources are counted
>  	 * as ISUs are added
>  	 */
> -	reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
> +	reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
>  	mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
>  			  >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
>  	if (isu_size == 0)
> @@ -826,16 +895,16 @@ #endif /* CONFIG_SMP */
>  
>  	/* Map the per-CPU registers */
>  	for (i = 0; i < mpic->num_cpus; i++) {
> -		mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
> -					   i * MPIC_CPU_STRIDE, 0x1000);
> +		mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) +
> +					   i * MPIC_INFO(CPU_STRIDE), 0x1000);
>  		BUG_ON(mpic->cpuregs[i] == NULL);
>  	}
>  
>  	/* Initialize main ISU if none provided */
>  	if (mpic->isu_size == 0) {
>  		mpic->isu_size = mpic->num_sources;
> -		mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
> -					MPIC_IRQ_STRIDE * mpic->isu_size);
> +		mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE),
> +					MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
>  		BUG_ON(mpic->isus[0] == NULL);
>  	}
>  	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
> @@ -879,7 +948,8 @@ void __init mpic_assign_isu(struct mpic 
>  
>  	BUG_ON(isu_num >= MPIC_MAX_ISU);
>  
> -	mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size);
> +	mpic->isus[isu_num] = ioremap(phys_addr,
> +				      MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
>  	if ((isu_first + mpic->isu_size) > mpic->num_sources)
>  		mpic->num_sources = isu_first + mpic->isu_size;
>  }
> @@ -904,14 +974,16 @@ void __init mpic_init(struct mpic *mpic)
>  	printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);
>  
>  	/* Set current processor priority to max */
> -	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
> +	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
>  
>  	/* Initialize timers: just disable them all */
>  	for (i = 0; i < 4; i++) {
>  		mpic_write(mpic->tmregs,
> -			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
> +			   i * MPIC_INFO(TIMER_STRIDE) +
> +			   MPIC_INFO(TIMER_DESTINATION), 0);
>  		mpic_write(mpic->tmregs,
> -			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
> +			   i * MPIC_INFO(TIMER_STRIDE) + 
> +			   MPIC_INFO(TIMER_VECTOR_PRI),
>  			   MPIC_VECPRI_MASK |
>  			   (MPIC_VEC_TIMER_0 + i));
>  	}
> @@ -940,21 +1012,23 @@ void __init mpic_init(struct mpic *mpic)
>  			(8 << MPIC_VECPRI_PRIORITY_SHIFT);
>  		
>  		/* init hw */
> -		mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
> -		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
> +		mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
> +		mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
>  			       1 << hard_smp_processor_id());
>  	}
>  	
>  	/* Init spurrious vector */
> -	mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS);
> +	mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS);
>  
> -	/* Disable 8259 passthrough */
> -	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
> -		   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
> +	/* Disable 8259 passthrough, if supported */
> +#ifndef CONFIG_MPIC_WEIRD
> +	mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
> +		   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
>  		   | MPIC_GREG_GCONF_8259_PTHROU_DIS);
> +#endif
>  
>  	/* Set current processor priority to 0 */
> -	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
> +	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
>  }
>  
>  void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
> @@ -997,9 +1071,9 @@ void mpic_irq_set_priority(unsigned int 
>  		mpic_ipi_write(src - MPIC_VEC_IPI_0,
>  			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
>  	} else {
> -		reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI)
> +		reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
>  			& ~MPIC_VECPRI_PRIORITY_MASK;
> -		mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
> +		mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
>  			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
>  	}
>  	spin_unlock_irqrestore(&mpic_lock, flags);
> @@ -1017,7 +1091,7 @@ unsigned int mpic_irq_get_priority(unsig
>  	if (is_ipi)
>  		reg = mpic_ipi_read(src = MPIC_VEC_IPI_0);
>  	else
> -		reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
> +		reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
>  	spin_unlock_irqrestore(&mpic_lock, flags);
>  	return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT;
>  }
> @@ -1043,12 +1117,12 @@ #ifdef CONFIG_SMP
>   	 */
>  	if (distribute_irqs) {
>  	 	for (i = 0; i < mpic->num_sources ; i++)
> -			mpic_irq_write(i, MPIC_IRQ_DESTINATION,
> -				mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
> +			mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
> +				mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk);
>  	}
>  
>  	/* Set current processor priority to 0 */
> -	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
> +	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
>  
>  	spin_unlock_irqrestore(&mpic_lock, flags);
>  #endif /* CONFIG_SMP */
> @@ -1058,7 +1132,7 @@ int mpic_cpu_get_priority(void)
>  {
>  	struct mpic *mpic = mpic_primary;
>  
> -	return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
> +	return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI));
>  }
>  
>  void mpic_cpu_set_priority(int prio)
> @@ -1066,7 +1140,7 @@ void mpic_cpu_set_priority(int prio)
>  	struct mpic *mpic = mpic_primary;
>  
>  	prio &= MPIC_CPU_TASKPRI_MASK;
> -	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
> +	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio);
>  }
>  
>  /*
> @@ -1088,11 +1162,11 @@ void mpic_teardown_this_cpu(int secondar
>  
>  	/* let the mpic know we don't want intrs.  */
>  	for (i = 0; i < mpic->num_sources ; i++)
> -		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
> -			mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
> +		mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
> +			mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk);
>  
>  	/* Set current processor priority to max */
> -	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
> +	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
>  
>  	spin_unlock_irqrestore(&mpic_lock, flags);
>  }
> @@ -1108,7 +1182,8 @@ #ifdef DEBUG_IPI
>  	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
>  #endif
>  
> -	mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
> +	mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
> +		       ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
>  		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
>  }
>  
> @@ -1116,7 +1191,7 @@ unsigned int mpic_get_one_irq(struct mpi
>  {
>  	u32 src;
>  
> -	src = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
> +	src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK);
>  #ifdef DEBUG_LOW
>  	DBG("%s: get_one_irq(): %d\n", mpic->name, src);
>  #endif
> diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
> index eb241c9..faebdf2 100644
> --- a/include/asm-powerpc/mpic.h
> +++ b/include/asm-powerpc/mpic.h
> @@ -41,6 +41,7 @@ #define MPIC_GREG_IPI_VECTOR_PRI_0	0x000
>  #define MPIC_GREG_IPI_VECTOR_PRI_1	0x000b0
>  #define MPIC_GREG_IPI_VECTOR_PRI_2	0x000c0
>  #define MPIC_GREG_IPI_VECTOR_PRI_3	0x000d0
> +#define MPIC_GREG_IPI_STRIDE		0x10
>  #define MPIC_GREG_SPURIOUS		0x000e0
>  #define MPIC_GREG_TIMER_FREQ		0x000f0
>  
> @@ -68,6 +69,7 @@ #define MPIC_CPU_IPI_DISPATCH_0		0x00040
>  #define MPIC_CPU_IPI_DISPATCH_1		0x00050
>  #define MPIC_CPU_IPI_DISPATCH_2		0x00060
>  #define MPIC_CPU_IPI_DISPATCH_3		0x00070
> +#define MPIC_CPU_IPI_DISPATCH_STRIDE	0x00010
>  #define MPIC_CPU_CURRENT_TASK_PRI	0x00080
>  #define 	MPIC_CPU_TASKPRI_MASK			0x0000000f
>  #define MPIC_CPU_WHOAMI			0x00090
> @@ -114,6 +116,103 @@ #define MPIC_VEC_TIMER_2	249
>  #define MPIC_VEC_TIMER_1	248
>  #define MPIC_VEC_TIMER_0	247
>  
> +#ifdef CONFIG_MPIC_WEIRD
> +/*
> + * Tsi108 implementation of MPIC has many differences from the original one
> + */
> +
> +/*
> + * Global registers
> + */
> +
> +#define TSI108_GREG_BASE		0x00000
> +#define TSI108_GREG_FEATURE_0		0x00000
> +#define TSI108_GREG_GLOBAL_CONF_0	0x00004
> +#define TSI108_GREG_VENDOR_ID		0x0000c
> +#define TSI108_GREG_IPI_VECTOR_PRI_0	0x00204		/* Doorbell 0 */
> +#define TSI108_GREG_IPI_STRIDE		0x0c
> +#define TSI108_GREG_SPURIOUS		0x00010
> +#define TSI108_GREG_TIMER_FREQ		0x00014
> +
> +/*
> + * Timer registers
> + */
> +#define TSI108_TIMER_BASE		0x0030
> +#define TSI108_TIMER_STRIDE		0x10
> +#define TSI108_TIMER_CURRENT_CNT	0x00000
> +#define TSI108_TIMER_BASE_CNT		0x00004
> +#define TSI108_TIMER_VECTOR_PRI		0x00008
> +#define TSI108_TIMER_DESTINATION	0x0000c
> +
> +/*
> + * Per-Processor registers
> + */
> +#define TSI108_CPU_BASE			0x00300
> +#define TSI108_CPU_STRIDE		0x00040
> +#define TSI108_CPU_IPI_DISPATCH_0	0x00200
> +#define TSI108_CPU_IPI_DISPATCH_STRIDE	0x00000
> +#define TSI108_CPU_CURRENT_TASK_PRI	0x00000
> +#define TSI108_CPU_WHOAMI		0xffffffff
> +#define TSI108_CPU_INTACK		0x00004
> +#define TSI108_CPU_EOI			0x00008
> +
> +/*
> + * Per-source registers
> + */
> +#define TSI108_IRQ_BASE			0x00100
> +#define TSI108_IRQ_STRIDE		0x00008
> +#define TSI108_IRQ_VECTOR_PRI		0x00000
> +#define TSI108_VECPRI_VECTOR_MASK	0x000000ff
> +#define TSI108_VECPRI_POLARITY_POSITIVE	0x01000000
> +#define TSI108_VECPRI_POLARITY_NEGATIVE	0x00000000
> +#define TSI108_VECPRI_SENSE_LEVEL	0x02000000
> +#define TSI108_VECPRI_SENSE_EDGE	0x00000000
> +#define TSI108_VECPRI_POLARITY_MASK	0x01000000
> +#define TSI108_VECPRI_SENSE_MASK	0x02000000
> +#define TSI108_IRQ_DESTINATION		0x00004
> +
> +/* weird mpic variable index in the HW info array */
> +enum MPIC_WEIRD_INDEX {
> +	INDEX_GREG_BASE = 0,	/* Offset of global registers from MPIC base */
> +	INDEX_GREG_FEATURE_0,	/* FRR0 offset from base */
> +	INDEX_GREG_GLOBAL_CONF_0, /* Global Config register offset from base */
> +	INDEX_GREG_VENDOR_ID,	/* VID register offset from base */
> +	INDEX_GREG_IPI_VECTOR_PRI_0,	/* IPI Vector/Priority Registers */
> +	INDEX_GREG_IPI_STRIDE, 		/* IPI Vector/Priority Registers spacing */
> +	INDEX_GREG_SPURIOUS,		/* Spurious Vector Register */
> +	INDEX_GREG_TIMER_FREQ,	/* Global Timer Frequency Reporting Register */
> +
> +	INDEX_TIMER_BASE,		/* Global Timer Registers base */
> +	INDEX_TIMER_STRIDE,		/* Global Timer Registers spacing */
> +	INDEX_TIMER_CURRENT_CNT,	/* Global Timer Current Count Register */
> +	INDEX_TIMER_BASE_CNT,		/* Global Timer Base Count Register */
> +	INDEX_TIMER_VECTOR_PRI,		/* Global Timer Vector/Priority Register */
> +	INDEX_TIMER_DESTINATION,	/* Global Timer Destination Register */
> +
> +	INDEX_CPU_BASE,	/* Offset of cpu base */
> +	INDEX_CPU_STRIDE,	/* Cpu register spacing*/
> +	INDEX_CPU_IPI_DISPATCH_0,	/* IPI 0 Dispatch Command Register */
> +	INDEX_CPU_IPI_DISPATCH_STRIDE,	/* IPI Dispatch spacing */
> +	INDEX_CPU_CURRENT_TASK_PRI,/* Processor Current Task Priority Register */
> +	INDEX_CPU_WHOAMI,	/* Who Am I Register */
> +	INDEX_CPU_INTACK,	/* Interrupt Acknowledge Register */
> +	INDEX_CPU_EOI,		/* End of Interrupt Register */
> +
> +	INDEX_IRQ_BASE,	/* Interrupt registers base */
> +	INDEX_IRQ_STRIDE,	/* Interrupt registers spacing */
> +	INDEX_IRQ_VECTOR_PRI,	/* Interrupt Vector/Priority Register */
> +	INDEX_VECPRI_VECTOR_MASK,	/* Interrupt Vector Mask */
> +	INDEX_VECPRI_POLARITY_POSITIVE,	/* Interrupt Positive Polarity bit */
> +	INDEX_VECPRI_POLARITY_NEGATIVE,	/* Interrupt Negative Polarity bit */
> +	INDEX_VECPRI_SENSE_LEVEL,	/* Interrupt Level Sense bit */
> +	INDEX_VECPRI_SENSE_EDGE,	/* Interrupt edge Sense bit */
> +	INDEX_VECPRI_POLARITY_MASK, /* Interrupt Polarity mask */
> +	INDEX_VECPRI_SENSE_MASK, /* Interrupt sense mask */
> +	INDEX_IRQ_DESTINATION,	/* Interrupt Destination Register */
> +	INDEX_MPIC_WEIRD_END	/* Size of the hw info array */
> +};
> +#endif
> +
>  #ifdef CONFIG_MPIC_BROKEN_U3
>  /* Fixup table entry */
>  struct mpic_irq_fixup
> @@ -170,6 +269,11 @@ #endif
>  	volatile u32 __iomem	*tmregs;
>  	volatile u32 __iomem	*cpuregs[MPIC_MAX_CPUS];
>  	volatile u32 __iomem	*isus[MPIC_MAX_ISU];
> +	
> +#ifdef CONFIG_MPIC_WEIRD
> +	/* Pointer to HW info array */
> +	u32	*hw_set;
> +#endif
>  
>  	/* link */
>  	struct mpic		*next;
> @@ -189,6 +293,16 @@ #define MPIC_BROKEN_IPI			0x00000008
>  /* MPIC wants a reset */
>  #define MPIC_WANTS_RESET		0x00000010
>  
> +#ifdef CONFIG_MPIC_WEIRD
> +/* Spurious vector requires EOI */
> +#define MPIC_SPV_EOI			0x00000020
> +/* MPIC HW modification ID */
> +#define MPIC_MOD_ID_MASK		0x00000f00
> +#define MPIC_MOD_ID(val)		(((val) << 8) & MPIC_MOD_ID_MASK)
> +#define MPIC_GET_MOD_ID(flags)		(((flags) & MPIC_MOD_ID_MASK) >> 8)
> +#define	MPIC_ID_TSI108		0	/* Tsi108/109 PIC */
> +#endif
> +
>  /* Allocate the controller structure and setup the linux irq descs
>   * for the range if interrupts passed in. No HW initialization is
>   * actually performed.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox