LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 1/1] powerpc: Fix multicast problem in fs_enet driver
From: Scott Wood @ 2011-04-20 16:23 UTC (permalink / raw)
  To: Andrea Galbusera; +Cc: netdev, linuxppc-dev, linux-kernel, Vitaly Bordug
In-Reply-To: <1303289719-16913-1-git-send-email-gizero@gmail.com>

On Wed, 20 Apr 2011 10:55:19 +0200
Andrea Galbusera <gizero@gmail.com> wrote:

> mac-fec.c was setting individual UDP address registers instead of multicast
> group address registers when joining a multicast group.
> This prevented from correctly receiving UDP multicast packets.
> According to datasheet, replaced hash_table_high and hash_table_low
> with grp_hash_table_high and grp_hash_table_low respectively.
> 
> Tested on a MPC5121 based board.
> 
> Signed-off-by: Andrea Galbusera <gizero@gmail.com>
> ---
>  drivers/net/fs_enet/mac-fec.c |    8 ++++----
>  1 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
> index 61035fc..b9fbc83 100644
> --- a/drivers/net/fs_enet/mac-fec.c
> +++ b/drivers/net/fs_enet/mac-fec.c
> @@ -226,8 +226,8 @@ static void set_multicast_finish(struct net_device *dev)
>  	}
>  
>  	FC(fecp, r_cntrl, FEC_RCNTRL_PROM);
> -	FW(fecp, hash_table_high, fep->fec.hthi);
> -	FW(fecp, hash_table_low, fep->fec.htlo);
> +	FW(fecp, grp_hash_table_high, fep->fec.hthi);
> +	FW(fecp, grp_hash_table_low, fep->fec.htlo);
>  }
>  
>  static void set_multicast_list(struct net_device *dev)
> @@ -273,8 +273,8 @@ static void restart(struct net_device *dev)
>  	/*
>  	 * Reset all multicast.
>  	 */
> -	FW(fecp, hash_table_high, fep->fec.hthi);
> -	FW(fecp, hash_table_low, fep->fec.htlo);
> +	FW(fecp, grp_hash_table_high, fep->fec.hthi);
> +	FW(fecp, grp_hash_table_low, fep->fec.htlo);
>  
>  	/*
>  	 * Set maximum receive buffer size.

This will break on 8xx which does not have grp_hash_table_*.  It has only
one set of hash table registers which are used only for multicast -- so
8xx should have fec_hash_table_* renamed to fec_grp_hash_table_* in struct
fec.

-Scott

^ permalink raw reply

* Re: hvc_console: Don't access hvc_task if not initialised
From: Greg KH @ 2011-04-20 14:34 UTC (permalink / raw)
  To: Amit Shah; +Cc: Rusty Russell, linux-kernel, Milton Miller, linuxppc-dev
In-Reply-To: <20110420123330.GB3519@amit-x200.redhat.com>

On Wed, Apr 20, 2011 at 06:03:30PM +0530, Amit Shah wrote:
> On (Mon) 28 Mar 2011 [11:52:05], Milton Miller wrote:
> > On Fri, 25 Mar 2011 about 14:17:14 +0530, Amit Shah wrote:
> > > On (Thu) 24 Mar 2011 [08:58:04], Milton Miller wrote:
> > > > On Thu, 24 Mar 2011 07:29:58 -0000, Amit Shah wrote:
> > > > > hvc_open() can be called without having any backing device.  This
> > > > > results in a call to hvc_kick() which calls wake_up_process on a NULL
> > > > > pointer.  
> > > > 
> > > > How is hvc_open called without a hvc_driver registered to the tty layer?
> > > 
> > > This gets reproduced in a couple of scenarios, I'm trying to get more
> > > information.
> 
> OK - I finally could reproduce myself, albiet it's a panic in
> hvc_open, not the one mentioned earlier.
> 
> hvc_console is built into the kernel and virtio_console is a module.
> This sequence triggers a panic:
> 
> - modprobe virtio_console
> - agetty /dev/hvc0 9600 vt100
> - rmmod virtio_console
> - modprobe virtio_console
> - agetty /dev/hvc0 9600 vt100
> 
> A patch that I had sent previously, to hvc_remove() a port when the
> associated virtio_console port gets unplugged, fixes this panic.
> 
> Stricter checking in hvc_open(), as you mentioned, will solve the
> other one as well.

Care to either create this patch, or resend your original one, if you
want it applied?

thanks,

greg k-h

^ permalink raw reply

* Re: hvc_console: Don't access hvc_task if not initialised
From: Amit Shah @ 2011-04-20 12:33 UTC (permalink / raw)
  To: Milton Miller; +Cc: linuxppc-dev, Rusty Russell, linux-kernel, greg
In-Reply-To: <hvc-kick-notask-2@mdm.bga.com>

On (Mon) 28 Mar 2011 [11:52:05], Milton Miller wrote:
> On Fri, 25 Mar 2011 about 14:17:14 +0530, Amit Shah wrote:
> > On (Thu) 24 Mar 2011 [08:58:04], Milton Miller wrote:
> > > On Thu, 24 Mar 2011 07:29:58 -0000, Amit Shah wrote:
> > > > hvc_open() can be called without having any backing device.  This
> > > > results in a call to hvc_kick() which calls wake_up_process on a NULL
> > > > pointer.  
> > > 
> > > How is hvc_open called without a hvc_driver registered to the tty layer?
> > 
> > This gets reproduced in a couple of scenarios, I'm trying to get more
> > information.

OK - I finally could reproduce myself, albiet it's a panic in
hvc_open, not the one mentioned earlier.

hvc_console is built into the kernel and virtio_console is a module.
This sequence triggers a panic:

- modprobe virtio_console
- agetty /dev/hvc0 9600 vt100
- rmmod virtio_console
- modprobe virtio_console
- agetty /dev/hvc0 9600 vt100

A patch that I had sent previously, to hvc_remove() a port when the
associated virtio_console port gets unplugged, fixes this panic.

Stricter checking in hvc_open(), as you mentioned, will solve the
other one as well.

Thanks!

		Amit

^ permalink raw reply

* Re: [BUG] rebuild_sched_domains considered dangerous
From: Peter Zijlstra @ 2011-04-20 10:07 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Martin Schwidefsky, linuxppc-dev, linux-kernel@vger.kernel.org,
	Jesse Larrew
In-Reply-To: <1299766211.2308.4468.camel@twins>

On Thu, 2011-03-10 at 15:10 +0100, Peter Zijlstra wrote:
>=20
> Also, still waiting to hear from the Power7 folks on how often they
> think to rebuild the topology and how they think that makes sense,
> afaict Power7 does have actual NUMA nodes unlike s390, so I'm still not
> seeing how that's going to work properly at all.=20

Jesse care to answer? I hear from Ben you're responsible for that mess.

^ permalink raw reply

* [PATCH 1/1] powerpc: Fix multicast problem in fs_enet driver
From: Andrea Galbusera @ 2011-04-20  8:55 UTC (permalink / raw)
  To: Pantelis Antoniou, Vitaly Bordug
  Cc: netdev, linuxppc-dev, linux-kernel, Andrea Galbusera

mac-fec.c was setting individual UDP address registers instead of multicast
group address registers when joining a multicast group.
This prevented from correctly receiving UDP multicast packets.
According to datasheet, replaced hash_table_high and hash_table_low
with grp_hash_table_high and grp_hash_table_low respectively.

Tested on a MPC5121 based board.

Signed-off-by: Andrea Galbusera <gizero@gmail.com>
---
 drivers/net/fs_enet/mac-fec.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 61035fc..b9fbc83 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -226,8 +226,8 @@ static void set_multicast_finish(struct net_device *dev)
 	}
 
 	FC(fecp, r_cntrl, FEC_RCNTRL_PROM);
-	FW(fecp, hash_table_high, fep->fec.hthi);
-	FW(fecp, hash_table_low, fep->fec.htlo);
+	FW(fecp, grp_hash_table_high, fep->fec.hthi);
+	FW(fecp, grp_hash_table_low, fep->fec.htlo);
 }
 
 static void set_multicast_list(struct net_device *dev)
@@ -273,8 +273,8 @@ static void restart(struct net_device *dev)
 	/*
 	 * Reset all multicast.
 	 */
-	FW(fecp, hash_table_high, fep->fec.hthi);
-	FW(fecp, hash_table_low, fep->fec.htlo);
+	FW(fecp, grp_hash_table_high, fep->fec.hthi);
+	FW(fecp, grp_hash_table_low, fep->fec.htlo);
 
 	/*
 	 * Set maximum receive buffer size.
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH] powerpc: stop exporting irq_map
From: Grant Likely @ 2011-04-20  8:45 UTC (permalink / raw)
  To: benh, linuxppc-dev, linux-kernel

First step in eliminating irq_map[] table entirely.  This patch makes the
irq_map[] table only accessible by arch/powerpc/kernel/irq.c

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/powerpc/include/asm/irq.h                   |   15 +---
 arch/powerpc/kernel/irq.c                        |   26 +++++++
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |    4 +
 arch/powerpc/platforms/52xx/media5200.c          |    4 +
 arch/powerpc/platforms/52xx/mpc52xx_pic.c        |   79 ++++------------------
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |    4 +
 arch/powerpc/platforms/85xx/socrates_fpga_pic.c  |   26 ++-----
 arch/powerpc/platforms/86xx/gef_pic.c            |   10 +--
 arch/powerpc/platforms/8xx/m8xx_setup.c          |    2 -
 arch/powerpc/platforms/cell/axon_msi.c           |    2 -
 arch/powerpc/platforms/cell/spider-pic.c         |   10 +--
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |    8 +-
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |    8 +-
 arch/powerpc/platforms/iseries/irq.c             |   10 +--
 arch/powerpc/platforms/powermac/pic.c            |   12 ++-
 arch/powerpc/platforms/pseries/ras.c             |    4 +
 arch/powerpc/platforms/pseries/xics.c            |   14 ++--
 arch/powerpc/sysdev/cpm1.c                       |    8 +-
 arch/powerpc/sysdev/cpm2_pic.c                   |   10 +--
 arch/powerpc/sysdev/ipic.c                       |   16 ++--
 arch/powerpc/sysdev/mpc8xx_pic.c                 |   10 +--
 arch/powerpc/sysdev/mpc8xxx_gpio.c               |   12 ++-
 arch/powerpc/sysdev/mpic.c                       |   28 ++++----
 arch/powerpc/sysdev/mv64x60_pic.c                |   14 ++--
 arch/powerpc/sysdev/qe_lib/qe_ic.c               |    6 +-
 arch/powerpc/sysdev/uic.c                        |   12 +--
 arch/powerpc/sysdev/xilinx_intc.c                |    8 +-
 27 files changed, 147 insertions(+), 215 deletions(-)

diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index 67ab5fb..e1983d5 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -128,19 +128,10 @@ struct irq_host {
 	struct device_node	*of_node;
 };
 
-/* The main irq map itself is an array of NR_IRQ entries containing the
- * associate host and irq number. An entry with a host of NULL is free.
- * An entry can be allocated if it's free, the allocator always then sets
- * hwirq first to the host's invalid irq number and then fills ops.
- */
-struct irq_map_entry {
-	irq_hw_number_t	hwirq;
-	struct irq_host	*host;
-};
-
-extern struct irq_map_entry irq_map[NR_IRQS];
-
+struct irq_data;
+extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
+extern struct irq_host *virq_to_host(unsigned int virq);
 
 /**
  * irq_alloc_host - Allocate a new irq_host data structure
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index f621b7d..422672b 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -477,20 +477,42 @@ void do_softirq(void)
  * IRQ controller and virtual interrupts
  */
 
+/* The main irq map itself is an array of NR_IRQ entries containing the
+ * associate host and irq number. An entry with a host of NULL is free.
+ * An entry can be allocated if it's free, the allocator always then sets
+ * hwirq first to the host's invalid irq number and then fills ops.
+ */
+struct irq_map_entry {
+	irq_hw_number_t	hwirq;
+	struct irq_host	*host;
+};
+
 static LIST_HEAD(irq_hosts);
 static DEFINE_RAW_SPINLOCK(irq_big_lock);
 static unsigned int revmap_trees_allocated;
 static DEFINE_MUTEX(revmap_trees_mutex);
-struct irq_map_entry irq_map[NR_IRQS];
+static struct irq_map_entry irq_map[NR_IRQS];
 static unsigned int irq_virq_count = NR_IRQS;
 static struct irq_host *irq_default_host;
 
+irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
+{
+	return irq_map[d->irq].hwirq;
+}
+EXPORT_SYMBOL_GPL(irqd_to_hwirq);
+
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
 	return irq_map[virq].hwirq;
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
+struct irq_host *virq_to_host(unsigned int virq)
+{
+	return irq_map[virq].host;
+}
+EXPORT_SYMBOL_GPL(virq_to_host);
+
 static int default_irq_host_match(struct irq_host *h, struct device_node *np)
 {
 	return h->of_node != NULL && h->of_node == np;
@@ -1098,7 +1120,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
 			struct irq_chip *chip;
 
 			seq_printf(m, "%5d  ", i);
-			seq_printf(m, "0x%05lx  ", virq_to_hw(i));
+			seq_printf(m, "0x%05lx  ", irq_map[i].hwirq);
 
 			chip = irq_desc_get_chip(desc);
 			if (chip && chip->name)
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index cfc4b20..a8bc0d4 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -61,7 +61,7 @@ irq_to_pic_bit(unsigned int irq)
 static void
 cpld_mask_irq(struct irq_data *d)
 {
-	unsigned int cpld_irq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpld_irq = (unsigned int)irqd_to_hwirq(d);
 	void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
 
 	out_8(pic_mask,
@@ -71,7 +71,7 @@ cpld_mask_irq(struct irq_data *d)
 static void
 cpld_unmask_irq(struct irq_data *d)
 {
-	unsigned int cpld_irq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpld_irq = (unsigned int)irqd_to_hwirq(d);
 	void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
 
 	out_8(pic_mask,
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 57a6a34..96f85e5 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -56,7 +56,7 @@ static void media5200_irq_unmask(struct irq_data *d)
 
 	spin_lock_irqsave(&media5200_irq.lock, flags);
 	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
-	val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[d->irq].hwirq);
+	val |= 1 << (MEDIA5200_IRQ_SHIFT + irqd_to_hwirq(d));
 	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
 	spin_unlock_irqrestore(&media5200_irq.lock, flags);
 }
@@ -68,7 +68,7 @@ static void media5200_irq_mask(struct irq_data *d)
 
 	spin_lock_irqsave(&media5200_irq.lock, flags);
 	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
-	val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[d->irq].hwirq));
+	val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irqd_to_hwirq(d)));
 	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
 	spin_unlock_irqrestore(&media5200_irq.lock, flags);
 }
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 1dd1540..bb61181 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -157,48 +157,30 @@ static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
  */
 static void mpc52xx_extirq_mask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_clrbit(&intr->ctrl, 11 - l2irq);
 }
 
 static void mpc52xx_extirq_unmask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&intr->ctrl, 11 - l2irq);
 }
 
 static void mpc52xx_extirq_ack(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&intr->ctrl, 27-l2irq);
 }
 
 static int mpc52xx_extirq_set_type(struct irq_data *d, unsigned int flow_type)
 {
 	u32 ctrl_reg, type;
-	int irq;
-	int l2irq;
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	void *handler = handle_level_irq;
 
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
-	pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type);
+	pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__,
+		(int) irqd_to_hwirq(d), l2irq, flow_type);
 
 	switch (flow_type) {
 	case IRQF_TRIGGER_HIGH: type = 0; break;
@@ -237,23 +219,13 @@ static int mpc52xx_null_set_type(struct irq_data *d, unsigned int flow_type)
 
 static void mpc52xx_main_mask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&intr->main_mask, 16 - l2irq);
 }
 
 static void mpc52xx_main_unmask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_clrbit(&intr->main_mask, 16 - l2irq);
 }
 
@@ -270,23 +242,13 @@ static struct irq_chip mpc52xx_main_irqchip = {
  */
 static void mpc52xx_periph_mask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&intr->per_mask, 31 - l2irq);
 }
 
 static void mpc52xx_periph_unmask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_clrbit(&intr->per_mask, 31 - l2irq);
 }
 
@@ -303,34 +265,19 @@ static struct irq_chip mpc52xx_periph_irqchip = {
  */
 static void mpc52xx_sdma_mask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&sdma->IntMask, l2irq);
 }
 
 static void mpc52xx_sdma_unmask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_clrbit(&sdma->IntMask, l2irq);
 }
 
 static void mpc52xx_sdma_ack(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	out_be32(&sdma->IntPend, 1 << l2irq);
 }
 
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 4a4eb6f..5d6c34c 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -42,7 +42,7 @@ struct pq2ads_pci_pic {
 static void pq2ads_pci_mask_irq(struct irq_data *d)
 {
 	struct pq2ads_pci_pic *priv = irq_data_get_irq_chip_data(d);
-	int irq = NUM_IRQS - virq_to_hw(d->irq) - 1;
+	int irq = NUM_IRQS - irqd_to_hwirq(d) - 1;
 
 	if (irq != -1) {
 		unsigned long flags;
@@ -58,7 +58,7 @@ static void pq2ads_pci_mask_irq(struct irq_data *d)
 static void pq2ads_pci_unmask_irq(struct irq_data *d)
 {
 	struct pq2ads_pci_pic *priv = irq_data_get_irq_chip_data(d);
-	int irq = NUM_IRQS - virq_to_hw(d->irq) - 1;
+	int irq = NUM_IRQS - irqd_to_hwirq(d) - 1;
 
 	if (irq != -1) {
 		unsigned long flags;
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index db86462..12cb9bb 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -48,8 +48,6 @@ static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
 	[8] = {0, IRQ_TYPE_LEVEL_HIGH},
 };
 
-#define socrates_fpga_irq_to_hw(virq)    ((unsigned int)irq_map[virq].hwirq)
-
 static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
 
 static void __iomem *socrates_fpga_pic_iobase;
@@ -110,11 +108,9 @@ void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
 static void socrates_fpga_pic_ack(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq, irq_line;
+	unsigned int irq_line, hwirq = irqd_to_hwirq(d);
 	uint32_t mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -127,12 +123,10 @@ static void socrates_fpga_pic_ack(struct irq_data *d)
 static void socrates_fpga_pic_mask(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int irq_line;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -145,12 +139,10 @@ static void socrates_fpga_pic_mask(struct irq_data *d)
 static void socrates_fpga_pic_mask_ack(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int irq_line;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -164,12 +156,10 @@ static void socrates_fpga_pic_mask_ack(struct irq_data *d)
 static void socrates_fpga_pic_unmask(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int irq_line;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -182,12 +172,10 @@ static void socrates_fpga_pic_unmask(struct irq_data *d)
 static void socrates_fpga_pic_eoi(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int irq_line;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -201,12 +189,10 @@ static int socrates_fpga_pic_set_type(struct irq_data *d,
 		unsigned int flow_type)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int polarity;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE)
 		return -EINVAL;
 
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 0beec7d..94594e5 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -46,8 +46,6 @@
 #define GEF_PIC_CPU0_MCP_MASK	GEF_PIC_MCP_MASK(0)
 #define GEF_PIC_CPU1_MCP_MASK	GEF_PIC_MCP_MASK(1)
 
-#define gef_irq_to_hw(virq)    ((unsigned int)irq_map[virq].hwirq)
-
 
 static DEFINE_RAW_SPINLOCK(gef_pic_lock);
 
@@ -113,11 +111,9 @@ void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
 static void gef_pic_mask(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	u32 mask;
 
-	hwirq = gef_irq_to_hw(d->irq);
-
 	raw_spin_lock_irqsave(&gef_pic_lock, flags);
 	mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
 	mask &= ~(1 << hwirq);
@@ -136,11 +132,9 @@ static void gef_pic_mask_ack(struct irq_data *d)
 static void gef_pic_unmask(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	u32 mask;
 
-	hwirq = gef_irq_to_hw(d->irq);
-
 	raw_spin_lock_irqsave(&gef_pic_lock, flags);
 	mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
 	mask |= (1 << hwirq);
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 9ecce99..1e12108 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -150,7 +150,7 @@ void __init mpc8xx_calibrate_decr(void)
 	 */
 	cpu = of_find_node_by_type(NULL, "cpu");
 	virq= irq_of_parse_and_map(cpu, 0);
-	irq = irq_map[virq].hwirq;
+	irq = virq_to_hw(virq);
 
 	sys_tmr2 = immr_map(im_sit);
 	out_be16(&sys_tmr2->sit_tbscr, ((1 << (7 - (irq/2))) << 8) |
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index bb5ebf8..1e3329e 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -113,7 +113,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
 		pr_devel("axon_msi: woff %x roff %x msi %x\n",
 			  write_offset, msic->read_offset, msi);
 
-		if (msi < NR_IRQS && irq_map[msi].host == msic->irq_host) {
+		if (msi < NR_IRQS && virq_to_host(msi) == msic->irq_host) {
 			generic_handle_irq(msi);
 			msic->fifo_virt[idx] = cpu_to_le32(0xffffffff);
 		} else {
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index c5cf50e..34d2b99 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -70,7 +70,7 @@ static struct spider_pic spider_pics[SPIDER_CHIP_COUNT];
 
 static struct spider_pic *spider_virq_to_pic(unsigned int virq)
 {
-	return irq_map[virq].host->host_data;
+	return virq_to_host(virq)->host_data;
 }
 
 static void __iomem *spider_get_irq_config(struct spider_pic *pic,
@@ -82,7 +82,7 @@ static void __iomem *spider_get_irq_config(struct spider_pic *pic,
 static void spider_unmask_irq(struct irq_data *d)
 {
 	struct spider_pic *pic = spider_virq_to_pic(d->irq);
-	void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
+	void __iomem *cfg = spider_get_irq_config(pic, irqd_to_hwirq(d));
 
 	out_be32(cfg, in_be32(cfg) | 0x30000000u);
 }
@@ -90,7 +90,7 @@ static void spider_unmask_irq(struct irq_data *d)
 static void spider_mask_irq(struct irq_data *d)
 {
 	struct spider_pic *pic = spider_virq_to_pic(d->irq);
-	void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
+	void __iomem *cfg = spider_get_irq_config(pic, irqd_to_hwirq(d));
 
 	out_be32(cfg, in_be32(cfg) & ~0x30000000u);
 }
@@ -98,7 +98,7 @@ static void spider_mask_irq(struct irq_data *d)
 static void spider_ack_irq(struct irq_data *d)
 {
 	struct spider_pic *pic = spider_virq_to_pic(d->irq);
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
 
 	/* Reset edge detection logic if necessary
 	 */
@@ -117,7 +117,7 @@ static int spider_set_irq_type(struct irq_data *d, unsigned int type)
 {
 	unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
 	struct spider_pic *pic = spider_virq_to_pic(d->irq);
-	unsigned int hw = irq_map[d->irq].hwirq;
+	unsigned int hw = irqd_to_hwirq(d);
 	void __iomem *cfg = spider_get_irq_config(pic, hw);
 	u32 old_mask;
 	u32 ic;
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index 12aa62b..77cbe4c 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -48,7 +48,7 @@
 
 static void flipper_pic_mask_and_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 	u32 mask = 1 << irq;
 
@@ -59,7 +59,7 @@ static void flipper_pic_mask_and_ack(struct irq_data *d)
 
 static void flipper_pic_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	/* this is at least needed for RSW */
@@ -68,7 +68,7 @@ static void flipper_pic_ack(struct irq_data *d)
 
 static void flipper_pic_mask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	clrbits32(io_base + FLIPPER_IMR, 1 << irq);
@@ -76,7 +76,7 @@ static void flipper_pic_mask(struct irq_data *d)
 
 static void flipper_pic_unmask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	setbits32(io_base + FLIPPER_IMR, 1 << irq);
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 2bdddfc..44b398b 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -43,7 +43,7 @@
 
 static void hlwd_pic_mask_and_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 	u32 mask = 1 << irq;
 
@@ -53,7 +53,7 @@ static void hlwd_pic_mask_and_ack(struct irq_data *d)
 
 static void hlwd_pic_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	out_be32(io_base + HW_BROADWAY_ICR, 1 << irq);
@@ -61,7 +61,7 @@ static void hlwd_pic_ack(struct irq_data *d)
 
 static void hlwd_pic_mask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
@@ -69,7 +69,7 @@ static void hlwd_pic_mask(struct irq_data *d)
 
 static void hlwd_pic_unmask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 52a6889..375c21c 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -171,7 +171,7 @@ static void iseries_enable_IRQ(struct irq_data *d)
 {
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	/* The IRQ has already been locked by the caller */
 	bus = REAL_IRQ_TO_BUS(rirq);
@@ -188,7 +188,7 @@ static unsigned int iseries_startup_IRQ(struct irq_data *d)
 {
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	bus = REAL_IRQ_TO_BUS(rirq);
 	function = REAL_IRQ_TO_FUNC(rirq);
@@ -234,7 +234,7 @@ static void iseries_shutdown_IRQ(struct irq_data *d)
 {
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	/* irq should be locked by the caller */
 	bus = REAL_IRQ_TO_BUS(rirq);
@@ -257,7 +257,7 @@ static void iseries_disable_IRQ(struct irq_data *d)
 {
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	/* The IRQ has already been locked by the caller */
 	bus = REAL_IRQ_TO_BUS(rirq);
@@ -271,7 +271,7 @@ static void iseries_disable_IRQ(struct irq_data *d)
 
 static void iseries_end_IRQ(struct irq_data *d)
 {
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq),
 		(REAL_IRQ_TO_IDSEL(rirq) << 4) + REAL_IRQ_TO_FUNC(rirq));
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 023f240..2f34ad0 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -84,7 +84,7 @@ static void __pmac_retrigger(unsigned int irq_nr)
 
 static void pmac_mask_and_ack_irq(struct irq_data *d)
 {
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
         unsigned long flags;
@@ -106,7 +106,7 @@ static void pmac_mask_and_ack_irq(struct irq_data *d)
 
 static void pmac_ack_irq(struct irq_data *d)
 {
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
         unsigned long flags;
@@ -152,7 +152,7 @@ static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
 static unsigned int pmac_startup_irq(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
 
@@ -169,7 +169,7 @@ static unsigned int pmac_startup_irq(struct irq_data *d)
 static void pmac_mask_irq(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
 
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
         __clear_bit(src, ppc_cached_irq_mask);
@@ -180,7 +180,7 @@ static void pmac_mask_irq(struct irq_data *d)
 static void pmac_unmask_irq(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
 
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	__set_bit(src, ppc_cached_irq_mask);
@@ -193,7 +193,7 @@ static int pmac_retrigger(struct irq_data *d)
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
-	__pmac_retrigger(irq_map[d->irq].hwirq);
+	__pmac_retrigger(irqd_to_hwirq(d));
 	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 	return 1;
 }
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index c55d7ad..164a8eb 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -122,7 +122,7 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id)
 
 	status = rtas_call(ras_check_exception_token, 6, 1, NULL,
 			   RTAS_VECTOR_EXTERNAL_INTERRUPT,
-			   irq_map[irq].hwirq,
+			   virq_to_hw(irq),
 			   RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS,
 			   critical, __pa(&ras_log_buf),
 				rtas_get_error_log_max());
@@ -157,7 +157,7 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
 
 	status = rtas_call(ras_check_exception_token, 6, 1, NULL,
 			   RTAS_VECTOR_EXTERNAL_INTERRUPT,
-			   irq_map[irq].hwirq,
+			   virq_to_hw(irq),
 			   RTAS_INTERNAL_ERROR, 1 /*Time Critical */,
 			   __pa(&ras_log_buf),
 				rtas_get_error_log_max());
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index d690133..784e614 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -210,7 +210,7 @@ static void xics_unmask_irq(struct irq_data *d)
 
 	pr_devel("xics: unmask virq %d\n", d->irq);
 
-	hwirq = (unsigned int)irq_map[d->irq].hwirq;
+	hwirq = (unsigned int)irqd_to_hwirq(d);
 	pr_devel(" -> map to hwirq 0x%x\n", hwirq);
 	if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
 		return;
@@ -280,7 +280,7 @@ static void xics_mask_irq(struct irq_data *d)
 
 	pr_devel("xics: mask virq %d\n", d->irq);
 
-	hwirq = (unsigned int)irq_map[d->irq].hwirq;
+	hwirq = (unsigned int)irqd_to_hwirq(d);
 	if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
 		return;
 	xics_mask_real_irq(hwirq);
@@ -373,7 +373,7 @@ static unsigned char pop_cppr(void)
 
 static void xics_eoi_direct(struct irq_data *d)
 {
-	unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int hwirq = (unsigned int)irqd_to_hwirq(d);
 
 	iosync();
 	direct_xirr_info_set((pop_cppr() << 24) | hwirq);
@@ -381,7 +381,7 @@ static void xics_eoi_direct(struct irq_data *d)
 
 static void xics_eoi_lpar(struct irq_data *d)
 {
-	unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int hwirq = (unsigned int)irqd_to_hwirq(d);
 
 	iosync();
 	lpar_xirr_info_set((pop_cppr() << 24) | hwirq);
@@ -395,7 +395,7 @@ xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force)
 	int xics_status[2];
 	int irq_server;
 
-	hwirq = (unsigned int)irq_map[d->irq].hwirq;
+	hwirq = (unsigned int)irqd_to_hwirq(d);
 	if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
 		return -1;
 
@@ -900,9 +900,9 @@ void xics_migrate_irqs_away(void)
 		/* We can't set affinity on ISA interrupts */
 		if (virq < NUM_ISA_INTERRUPTS)
 			continue;
-		if (irq_map[virq].host != xics_host)
+		if (virq_to_host(virq) != xics_host)
 			continue;
-		hwirq = (unsigned int)irq_map[virq].hwirq;
+		hwirq = (unsigned int)virq_to_hw(virq);
 		/* We need to get IPIs still. */
 		if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
 			continue;
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index e0bc944..350787c 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -58,21 +58,21 @@ static struct irq_host *cpm_pic_host;
 
 static void cpm_mask_irq(struct irq_data *d)
 {
-	unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
 
 	clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
 }
 
 static void cpm_unmask_irq(struct irq_data *d)
 {
-	unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
 
 	setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
 }
 
 static void cpm_end_irq(struct irq_data *d)
 {
-	unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
 
 	out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
 }
@@ -157,7 +157,7 @@ unsigned int cpm_pic_init(void)
 		goto end;
 
 	/* Initialize the CPM interrupt controller. */
-	hwirq = (unsigned int)irq_map[sirq].hwirq;
+	hwirq = (unsigned int)virq_to_hw(sirq);
 	out_be32(&cpic_reg->cpic_cicr,
 	    (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
 		((hwirq/2) << 13) | CICR_HP_MASK);
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index 5495c1b..bcab50e 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -81,7 +81,7 @@ static const u_char irq_to_siubit[] = {
 static void cpm2_mask_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = virq_to_hw(d->irq);
+	unsigned int irq_nr = irqd_to_hwirq(d);
 
 	bit = irq_to_siubit[irq_nr];
 	word = irq_to_siureg[irq_nr];
@@ -93,7 +93,7 @@ static void cpm2_mask_irq(struct irq_data *d)
 static void cpm2_unmask_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = virq_to_hw(d->irq);
+	unsigned int irq_nr = irqd_to_hwirq(d);
 
 	bit = irq_to_siubit[irq_nr];
 	word = irq_to_siureg[irq_nr];
@@ -105,7 +105,7 @@ static void cpm2_unmask_irq(struct irq_data *d)
 static void cpm2_ack(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = virq_to_hw(d->irq);
+	unsigned int irq_nr = irqd_to_hwirq(d);
 
 	bit = irq_to_siubit[irq_nr];
 	word = irq_to_siureg[irq_nr];
@@ -116,7 +116,7 @@ static void cpm2_ack(struct irq_data *d)
 static void cpm2_end_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = virq_to_hw(d->irq);
+	unsigned int irq_nr = irqd_to_hwirq(d);
 
 	bit = irq_to_siubit[irq_nr];
 	word = irq_to_siureg[irq_nr];
@@ -133,7 +133,7 @@ static void cpm2_end_irq(struct irq_data *d)
 
 static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
-	unsigned int src = virq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned int vold, vnew, edibit;
 
 	/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index fa438be..f0ece79 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -521,12 +521,10 @@ static inline struct ipic * ipic_from_irq(unsigned int virq)
 	return primary_ipic;
 }
 
-#define ipic_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
-
 static void ipic_unmask_irq(struct irq_data *d)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -542,7 +540,7 @@ static void ipic_unmask_irq(struct irq_data *d)
 static void ipic_mask_irq(struct irq_data *d)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -562,7 +560,7 @@ static void ipic_mask_irq(struct irq_data *d)
 static void ipic_ack_irq(struct irq_data *d)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -581,7 +579,7 @@ static void ipic_ack_irq(struct irq_data *d)
 static void ipic_mask_irq_and_ack(struct irq_data *d)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -604,7 +602,7 @@ static void ipic_mask_irq_and_ack(struct irq_data *d)
 static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned int vold, vnew, edibit;
 
 	if (flow_type == IRQ_TYPE_NONE)
@@ -793,7 +791,7 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 int ipic_set_priority(unsigned int virq, unsigned int priority)
 {
 	struct ipic *ipic = ipic_from_irq(virq);
-	unsigned int src = ipic_irq_to_hw(virq);
+	unsigned int src = virq_to_hw(virq);
 	u32 temp;
 
 	if (priority > 7)
@@ -821,7 +819,7 @@ int ipic_set_priority(unsigned int virq, unsigned int priority)
 void ipic_set_highest_priority(unsigned int virq)
 {
 	struct ipic *ipic = ipic_from_irq(virq);
-	unsigned int src = ipic_irq_to_hw(virq);
+	unsigned int src = virq_to_hw(virq);
 	u32 temp;
 
 	temp = ipic_read(ipic->regs, IPIC_SICFR);
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index a88800f..20924f2 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -28,7 +28,7 @@ int cpm_get_irq(struct pt_regs *regs);
 static void mpc8xx_unmask_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
 
 	bit = irq_nr & 0x1f;
 	word = irq_nr >> 5;
@@ -40,7 +40,7 @@ static void mpc8xx_unmask_irq(struct irq_data *d)
 static void mpc8xx_mask_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
 
 	bit = irq_nr & 0x1f;
 	word = irq_nr >> 5;
@@ -52,7 +52,7 @@ static void mpc8xx_mask_irq(struct irq_data *d)
 static void mpc8xx_ack(struct irq_data *d)
 {
 	int	bit;
-	unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
 
 	bit = irq_nr & 0x1f;
 	out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
@@ -61,7 +61,7 @@ static void mpc8xx_ack(struct irq_data *d)
 static void mpc8xx_end_irq(struct irq_data *d)
 {
 	int bit, word;
-	unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
 
 	bit = irq_nr & 0x1f;
 	word = irq_nr >> 5;
@@ -73,7 +73,7 @@ static void mpc8xx_end_irq(struct irq_data *d)
 static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
 	if (flow_type & IRQ_TYPE_EDGE_FALLING) {
-		irq_hw_number_t hw = (unsigned int)irq_map[d->irq].hwirq;
+		irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d);
 		unsigned int siel = in_be32(&siu_reg->sc_siel);
 
 		/* only external IRQ senses are programmable */
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
index 0892a28..fb4963a 100644
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c
@@ -163,7 +163,7 @@ static void mpc8xxx_irq_unmask(struct irq_data *d)
 
 	spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
-	setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+	setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 
 	spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
@@ -176,7 +176,7 @@ static void mpc8xxx_irq_mask(struct irq_data *d)
 
 	spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
-	clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+	clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 
 	spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
@@ -186,7 +186,7 @@ static void mpc8xxx_irq_ack(struct irq_data *d)
 	struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
 	struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
 
-	out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+	out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 }
 
 static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
@@ -199,14 +199,14 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
 	case IRQ_TYPE_EDGE_FALLING:
 		spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 		setbits32(mm->regs + GPIO_ICR,
-			  mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+			  mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 		spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 		break;
 
 	case IRQ_TYPE_EDGE_BOTH:
 		spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 		clrbits32(mm->regs + GPIO_ICR,
-			  mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+			  mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 		spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 		break;
 
@@ -221,7 +221,7 @@ static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
 {
 	struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
 	struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
-	unsigned long gpio = virq_to_hw(d->irq);
+	unsigned long gpio = irqd_to_hwirq(d);
 	void __iomem *reg;
 	unsigned int shift;
 	unsigned long flags;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index f91c065..824a94f 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -607,8 +607,6 @@ static int irq_choose_cpu(const struct cpumask *mask)
 }
 #endif
 
-#define mpic_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
-
 /* Find an mpic associated with a given linux interrupt */
 static struct mpic *mpic_find(unsigned int irq)
 {
@@ -621,7 +619,7 @@ static struct mpic *mpic_find(unsigned int irq)
 /* Determine if the linux irq is an IPI */
 static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq)
 {
-	unsigned int src = mpic_irq_to_hw(irq);
+	unsigned int src = virq_to_hw(irq);
 
 	return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);
 }
@@ -674,7 +672,7 @@ void mpic_unmask_irq(struct irq_data *d)
 {
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, d->irq, src);
 
@@ -695,7 +693,7 @@ void mpic_mask_irq(struct irq_data *d)
 {
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, d->irq, src);
 
@@ -733,7 +731,7 @@ void mpic_end_irq(struct irq_data *d)
 static void mpic_unmask_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	mpic_unmask_irq(d);
 
@@ -744,7 +742,7 @@ static void mpic_unmask_ht_irq(struct irq_data *d)
 static unsigned int mpic_startup_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	mpic_unmask_irq(d);
 	mpic_startup_ht_interrupt(mpic, src, irqd_is_level_type(d));
@@ -755,7 +753,7 @@ static unsigned int mpic_startup_ht_irq(struct irq_data *d)
 static void mpic_shutdown_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	mpic_shutdown_ht_interrupt(mpic, src);
 	mpic_mask_irq(d);
@@ -764,7 +762,7 @@ static void mpic_shutdown_ht_irq(struct irq_data *d)
 static void mpic_end_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 #ifdef DEBUG_IRQ
 	DBG("%s: end_irq: %d\n", mpic->name, d->irq);
@@ -785,7 +783,7 @@ static void mpic_end_ht_irq(struct irq_data *d)
 static void mpic_unmask_ipi(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_ipi(d);
-	unsigned int src = mpic_irq_to_hw(d->irq) - mpic->ipi_vecs[0];
+	unsigned int src = virq_to_hw(d->irq) - mpic->ipi_vecs[0];
 
 	DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, d->irq, src);
 	mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
@@ -816,7 +814,7 @@ int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 		      bool force)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
 		int cpuid = irq_choose_cpu(cpumask);
@@ -862,7 +860,7 @@ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
 int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned int vecpri, vold, vnew;
 
 	DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
@@ -898,7 +896,7 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
 void mpic_set_vector(unsigned int virq, unsigned int vector)
 {
 	struct mpic *mpic = mpic_from_irq(virq);
-	unsigned int src = mpic_irq_to_hw(virq);
+	unsigned int src = virq_to_hw(virq);
 	unsigned int vecpri;
 
 	DBG("mpic: set_vector(mpic:@%p,virq:%d,src:%d,vector:0x%x)\n",
@@ -916,7 +914,7 @@ void mpic_set_vector(unsigned int virq, unsigned int vector)
 void mpic_set_destination(unsigned int virq, unsigned int cpuid)
 {
 	struct mpic *mpic = mpic_from_irq(virq);
-	unsigned int src = mpic_irq_to_hw(virq);
+	unsigned int src = virq_to_hw(virq);
 
 	DBG("mpic: set_destination(mpic:@%p,virq:%d,src:%d,cpuid:0x%x)\n",
 	    mpic, virq, src, cpuid);
@@ -1427,7 +1425,7 @@ void __init mpic_set_serial_int(struct mpic *mpic, int enable)
 void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
 {
 	struct mpic *mpic = mpic_find(irq);
-	unsigned int src = mpic_irq_to_hw(irq);
+	unsigned int src = virq_to_hw(irq);
 	unsigned long flags;
 	u32 reg;
 
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index e9c633c..14d1302 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -78,7 +78,7 @@ static struct irq_host *mv64x60_irq_host;
 
 static void mv64x60_mask_low(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -91,7 +91,7 @@ static void mv64x60_mask_low(struct irq_data *d)
 
 static void mv64x60_unmask_low(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -115,7 +115,7 @@ static struct irq_chip mv64x60_chip_low = {
 
 static void mv64x60_mask_high(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -128,7 +128,7 @@ static void mv64x60_mask_high(struct irq_data *d)
 
 static void mv64x60_unmask_high(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -152,7 +152,7 @@ static struct irq_chip mv64x60_chip_high = {
 
 static void mv64x60_mask_gpp(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -165,7 +165,7 @@ static void mv64x60_mask_gpp(struct irq_data *d)
 
 static void mv64x60_mask_ack_gpp(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -180,7 +180,7 @@ static void mv64x60_mask_ack_gpp(struct irq_data *d)
 
 static void mv64x60_unmask_gpp(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 832d692..b2acda0 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -197,12 +197,10 @@ static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
 	return irq_data_get_irq_chip_data(d);
 }
 
-#define virq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
-
 static void qe_ic_unmask_irq(struct irq_data *d)
 {
 	struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
-	unsigned int src = virq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -218,7 +216,7 @@ static void qe_ic_unmask_irq(struct irq_data *d)
 static void qe_ic_mask_irq(struct irq_data *d)
 {
 	struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
-	unsigned int src = virq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 5d91385..984cd20 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -41,8 +41,6 @@
 #define UIC_VR		0x7
 #define UIC_VCR		0x8
 
-#define uic_irq_to_hw(virq)	(irq_map[virq].hwirq)
-
 struct uic *primary_uic;
 
 struct uic {
@@ -58,7 +56,7 @@ struct uic {
 static void uic_unmask_irq(struct irq_data *d)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 er, sr;
 
@@ -76,7 +74,7 @@ static void uic_unmask_irq(struct irq_data *d)
 static void uic_mask_irq(struct irq_data *d)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 er;
 
@@ -90,7 +88,7 @@ static void uic_mask_irq(struct irq_data *d)
 static void uic_ack_irq(struct irq_data *d)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 
 	spin_lock_irqsave(&uic->lock, flags);
@@ -101,7 +99,7 @@ static void uic_ack_irq(struct irq_data *d)
 static void uic_mask_ack_irq(struct irq_data *d)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 er, sr;
 
@@ -126,7 +124,7 @@ static void uic_mask_ack_irq(struct irq_data *d)
 static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	int trigger, polarity;
 	u32 tr, pr, mask;
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 0a13fc1..6183799 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -71,7 +71,7 @@ static unsigned char xilinx_intc_map_senses[] = {
  */
 static void xilinx_intc_mask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void * regs = irq_data_get_irq_chip_data(d);
 	pr_debug("mask: %d\n", irq);
 	out_be32(regs + XINTC_CIE, 1 << irq);
@@ -87,7 +87,7 @@ static int xilinx_intc_set_type(struct irq_data *d, unsigned int flow_type)
  */
 static void xilinx_intc_level_unmask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void * regs = irq_data_get_irq_chip_data(d);
 	pr_debug("unmask: %d\n", irq);
 	out_be32(regs + XINTC_SIE, 1 << irq);
@@ -112,7 +112,7 @@ static struct irq_chip xilinx_intc_level_irqchip = {
  */
 static void xilinx_intc_edge_unmask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void *regs = irq_data_get_irq_chip_data(d);
 	pr_debug("unmask: %d\n", irq);
 	out_be32(regs + XINTC_SIE, 1 << irq);
@@ -120,7 +120,7 @@ static void xilinx_intc_edge_unmask(struct irq_data *d)
 
 static void xilinx_intc_edge_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void * regs = irq_data_get_irq_chip_data(d);
 	pr_debug("ack: %d\n", irq);
 	out_be32(regs + XINTC_IAR, 1 << irq);

^ permalink raw reply related

* Re: [PATCH] driver/FSL SATA: Update RX_WATER_MARK for TRANSCFG
From: Takada, Kazunori @ 2011-04-20  5:41 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org

Dear linux-ppc-dev Team

I am Kazunori Takada, and the occupation of FAE of AVNET Japan.=20

This time, the question on this patch has been received from the customer w=
ho is using MPC8377E.=20
Therefore, it E-mailed ..this...=20
The question from the customer is described to the following.

The bit of reception FIFO overflow is set in the system. Therefore, it trie=
s to plan it with this patch.=20
It is a question here.=20
Q1.
By what details was this patch introduced?
Please teach the problem of becoming the chance of the patch introduction.=
=20

Q2.
I think that the reception overflow was generated.=20
Please teach the name of the maker and the maker serial number of the SATA =
disk used when this problem occurs.

Best Regards,

Kazunori Takada
AVNET Japan

^ permalink raw reply

* [PATCH] powerpc/85xx:DTS: Fix PCIe IDSEL for Px020RDB
From: Prabhakar Kushwaha @ 2011-04-20  4:12 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss; +Cc: meet2prabhu, Prabhakar Kushwaha

PCIe device in legacy mode can trigger interrupts using the wires #INTA, #INTB
,#INTC and #INTD. PCI devices are obligated to use #INTx for interrupts under
legacy mode.  Each PCI slot or device is typically wired to different inputs on
the interrupt controller. 

So, Define interrupt-map and interrupt-map-mask properties for device tree to
of map each PCI interrupt signal to the inputs of the interrupt controller.

Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
---
 Based upon git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git(branch master)

 This patch has depedency on following 2 patches
 	-- powerpc/85xx: P2020 DTS: re-organize dts files
	-- powerpc/85xx: P1020 DTS : re-organize dts files

 arch/powerpc/boot/dts/p1020rdb.dts            |   16 ++++++++++++++++
 arch/powerpc/boot/dts/p2020rdb.dts            |   16 ++++++++++++++++
 arch/powerpc/boot/dts/p2020rdb_camp_core0.dts |    8 ++++++++
 arch/powerpc/boot/dts/p2020rdb_camp_core1.dts |    8 ++++++++
 4 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/p1020rdb.dts b/arch/powerpc/boot/dts/p1020rdb.dts
index 7ed4793..d6a8ae4 100644
--- a/arch/powerpc/boot/dts/p1020rdb.dts
+++ b/arch/powerpc/boot/dts/p1020rdb.dts
@@ -257,6 +257,14 @@
 	pci0: pcie@ffe09000 {
 		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x4 0x1
+			0000 0x0 0x0 0x2 &mpic 0x5 0x1
+			0000 0x0 0x0 0x3 &mpic 0x6 0x1
+			0000 0x0 0x0 0x4 &mpic 0x7 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
@@ -275,6 +283,14 @@
 	pci1: pcie@ffe0a000 {
 		ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x0 0x1
+			0000 0x0 0x0 0x2 &mpic 0x1 0x1
+			0000 0x0 0x0 0x3 &mpic 0x2 0x1
+			0000 0x0 0x0 0x4 &mpic 0x3 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
diff --git a/arch/powerpc/boot/dts/p2020rdb.dts b/arch/powerpc/boot/dts/p2020rdb.dts
index 60a0a8c..3782a58 100644
--- a/arch/powerpc/boot/dts/p2020rdb.dts
+++ b/arch/powerpc/boot/dts/p2020rdb.dts
@@ -249,6 +249,14 @@
 	pci1: pcie@ffe09000 {
 		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x4 0x1
+			0000 0x0 0x0 0x2 &mpic 0x5 0x1
+			0000 0x0 0x0 0x3 &mpic 0x6 0x1
+			0000 0x0 0x0 0x4 &mpic 0x7 0x1
+			>;
 			pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
@@ -267,6 +275,14 @@
 	pci2: pcie@ffe0a000 {
 		ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x0 0x1
+			0000 0x0 0x0 0x2 &mpic 0x1 0x1
+			0000 0x0 0x0 0x3 &mpic 0x2 0x1
+			0000 0x0 0x0 0x4 &mpic 0x3 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
index 72c912f..fc8dddd 100644
--- a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
+++ b/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
@@ -175,6 +175,14 @@
 	pci1: pcie@ffe09000 {
 		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x4 0x1
+			0000 0x0 0x0 0x2 &mpic 0x5 0x1
+			0000 0x0 0x0 0x3 &mpic 0x6 0x1
+			0000 0x0 0x0 0x4 &mpic 0x7 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
index eb572cc..261c34b 100644
--- a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
+++ b/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
@@ -203,6 +203,14 @@
 	pci2: pcie@ffe0a000 {
 		ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x0 0x1
+			0000 0x0 0x0 0x2 &mpic 0x1 0x1
+			0000 0x0 0x0 0x3 &mpic 0x2 0x1
+			0000 0x0 0x0 0x4 &mpic 0x3 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
-- 
1.7.3

^ permalink raw reply related

* Re: [PATCH] cxgb4: use pgprot_writecombine() on powerpc
From: Benjamin Herrenschmidt @ 2011-04-20  3:07 UTC (permalink / raw)
  To: Nishanth Aravamudan; +Cc: Steve Wise, linuxppc-dev, Anton Blanchard
In-Reply-To: <20110415172716.GA5881@us.ibm.com>


> > >Given that this depends on a patch in Ben's tree, should this go in via
> > >the powerpc tree? Presuming Steve acks it, of course.
> > >
> > >  drivers/infiniband/hw/cxgb4/t4.h |    5 +----
> > >  1 files changed, 1 insertions(+), 4 deletions(-)
> > >
> > 
> > Acked-by: Steve Wise <swise@opengridcomputing.com>
> > 
> > I suppose it should go into the same tree with the commit that adds this function.
> 
> Ben, I don't think this is in your tree yet, will you be taking it?

Thanks Steve. Yes, I'll put this in powerpc-next.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 1/2] powerpc: document the FSL MPIC message register binding
From: Scott Wood @ 2011-04-19 18:33 UTC (permalink / raw)
  To: Meador Inge
  Cc: openmcapi-dev, Hollis Blanchard, devicetree-discuss, linuxppc-dev
In-Reply-To: <4DADD3D2.6070805@mentor.com>

On Tue, 19 Apr 2011 13:26:26 -0500
Meador Inge <meador_inge@mentor.com> wrote:

> On 04/19/2011 12:52 PM, Scott Wood wrote:
> > On Tue, 19 Apr 2011 11:59:34 -0500
> > Meador Inge <meador_inge@mentor.com> wrote:
> > 
> >>  Aliases are of the form 'msgr-block<n>',
> >> +    where <n> is an integer specifying the block's number.  Numbers shall start
> >> +    at 0.
> > 
> > The hw docs refer to "group A" and "group B", not "block 0" and "block 1".
> > 
> > Plus, I'd put "mpic-" in the alias name.
> 
> Are you suggesting that the alias should be called: 'mpic-groupA',
> 'mpic-groupB', 'mpic-groupC', etc... ?

I was thinking something like "mpic-msgr-group-a", "mpic-msgr-group-b" --
though if you want to use numbers instead to more easily map to potential
APIs, that's OK.

-Scott

^ permalink raw reply

* Re: [PATCH 1/2] powerpc: document the FSL MPIC message register binding
From: Meador Inge @ 2011-04-19 18:26 UTC (permalink / raw)
  To: Scott Wood
  Cc: openmcapi-dev, Hollis Blanchard, devicetree-discuss, linuxppc-dev
In-Reply-To: <20110419125214.560f4b99@schlenkerla.am.freescale.net>

On 04/19/2011 12:52 PM, Scott Wood wrote:
> On Tue, 19 Apr 2011 11:59:34 -0500
> Meador Inge <meador_inge@mentor.com> wrote:
> 
>> +    - interrupt-parent: Specifies the interrupt parent of the message register
>> +      block.  The type shall be a <phandle> and the value of that <phandle>
>> +      shall point to the interrupt parent.
> 
> interrupt-parent is not required; it can be inherited from an ancestor.  In
> any case, this description doesn't say anything specifically about MPIC
> message nodes.

Removed.

>>  The default value shall be
>> +      all a string of consecutive ones where the length of the run is equal
>> +      to the number of registers in the block.  For example, a block with
>> +      four registers shall default to 0xF.
> 
> Could be more simply worded as, "If not present, all message registers in
> the group are available."

That is much better.

>> +Required alias:
>> +
>> +    In order for a message register block to be discovered it *must* define
>> +    an alias in the 'aliases' node.
> 
> I think the "in order to be discovered" statement is specific to your use
> case.
> 
>>  Aliases are of the form 'msgr-block<n>',
>> +    where <n> is an integer specifying the block's number.  Numbers shall start
>> +    at 0.
> 
> The hw docs refer to "group A" and "group B", not "block 0" and "block 1".
> 
> Plus, I'd put "mpic-" in the alias name.

Are you suggesting that the alias should be called: 'mpic-groupA',
'mpic-groupB', 'mpic-groupC', etc... ?  Or just that I should use the terminology
group instead of block where discussing things in the binding?


>> +Example:
>> +
>> +	/* The aliases needed to define an order on the message register blocks.
>> +	 */
>> +	aliases {
>> +		msgr-block0 = &msgr_block0;
>> +		msgr-block1 = &msgr_block1;
>> +	};
>> +
>> +	msgr_block0: msgr-block@41400 {
>> +		compatible = "fsl,mpic-v3.1-msgr";
>> +		reg = <0x41400 0x200>;
>> +		// Message registers 0 and 3 in this block can receive interrupts on
>> +		// sources 0xb0 and 0xb2, respectively.
>> +		interrupts = <0xb0 2 0xb2 2>;
>> +		msg-receive-mask = <0x5>;
>> +		interrupt-parent = <&mpic>;
>> +	};
> 
> A mask of 0x5 specifies message registers 0 and 2 (as do interrupts 0xb0
> and 0xb2), not 0 and 3.
> 

Fixed.  Thanks.

-- 
Meador Inge     | meador_inge AT mentor.com
Mentor Embedded | http://www.mentor.com/embedded-software

^ permalink raw reply

* Re: [PATCH 1/2] powerpc: document the FSL MPIC message register binding
From: Scott Wood @ 2011-04-19 17:52 UTC (permalink / raw)
  To: Meador Inge
  Cc: openmcapi-dev, Hollis Blanchard, devicetree-discuss, linuxppc-dev
In-Reply-To: <1303232375-25014-2-git-send-email-meador_inge@mentor.com>

On Tue, 19 Apr 2011 11:59:34 -0500
Meador Inge <meador_inge@mentor.com> wrote:

> +    - interrupt-parent: Specifies the interrupt parent of the message register
> +      block.  The type shall be a <phandle> and the value of that <phandle>
> +      shall point to the interrupt parent.

interrupt-parent is not required; it can be inherited from an ancestor.  In
any case, this description doesn't say anything specifically about MPIC
message nodes.

>  The default value shall be
> +      all a string of consecutive ones where the length of the run is equal
> +      to the number of registers in the block.  For example, a block with
> +      four registers shall default to 0xF.

Could be more simply worded as, "If not present, all message registers in
the group are available."

> +Required alias:
> +
> +    In order for a message register block to be discovered it *must* define
> +    an alias in the 'aliases' node.

I think the "in order to be discovered" statement is specific to your use
case.

>  Aliases are of the form 'msgr-block<n>',
> +    where <n> is an integer specifying the block's number.  Numbers shall start
> +    at 0.

The hw docs refer to "group A" and "group B", not "block 0" and "block 1".

Plus, I'd put "mpic-" in the alias name.

> +Example:
> +
> +	/* The aliases needed to define an order on the message register blocks.
> +	 */
> +	aliases {
> +		msgr-block0 = &msgr_block0;
> +		msgr-block1 = &msgr_block1;
> +	};
> +
> +	msgr_block0: msgr-block@41400 {
> +		compatible = "fsl,mpic-v3.1-msgr";
> +		reg = <0x41400 0x200>;
> +		// Message registers 0 and 3 in this block can receive interrupts on
> +		// sources 0xb0 and 0xb2, respectively.
> +		interrupts = <0xb0 2 0xb2 2>;
> +		msg-receive-mask = <0x5>;
> +		interrupt-parent = <&mpic>;
> +	};

A mask of 0x5 specifies message registers 0 and 2 (as do interrupts 0xb0
and 0xb2), not 0 and 3.

-Scott

^ permalink raw reply

* [PATCH 2/2] powerpc: add support for MPIC message register API
From: Meador Inge @ 2011-04-19 16:59 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: openmcapi-dev, devicetree-discuss, Hollis Blanchard
In-Reply-To: <1303232375-25014-1-git-send-email-meador_inge@mentor.com>

Some MPIC implementations contain one or more blocks of message registers
that are used to send messages between cores via IPIs.  A simple API has
been added to access (get/put, read, write, etc ...) these message registers.
The available message registers are initially discovered via nodes in the
device tree.  A separate commit contains a binding for the message register
nodes.

Signed-off-by: Meador Inge <meador_inge@mentor.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Hollis Blanchard <hollis_blanchard@mentor.com>
---
 arch/powerpc/include/asm/mpic_msgr.h |   35 +++++
 arch/powerpc/platforms/Kconfig       |    8 +
 arch/powerpc/sysdev/Makefile         |    3 +-
 arch/powerpc/sysdev/mpic_msgr.c      |  279 ++++++++++++++++++++++++++++++++++
 4 files changed, 324 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/include/asm/mpic_msgr.h
 create mode 100644 arch/powerpc/sysdev/mpic_msgr.c

diff --git a/arch/powerpc/include/asm/mpic_msgr.h b/arch/powerpc/include/asm/mpic_msgr.h
new file mode 100644
index 0000000..370dcb4
--- /dev/null
+++ b/arch/powerpc/include/asm/mpic_msgr.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2011-2012, Meador Inge, Mentor Graphics Corporation.
+ *
+ * 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; version 2 of the
+ * License.
+ *
+ */
+
+#ifndef _ASM_MPIC_MSGR_H
+#define _ASM_MPIC_MSGR_H
+
+#include <linux/types.h>
+
+struct mpic_msgr {
+	u32 __iomem *addr;
+	u32 __iomem *mer;
+	u32 __iomem	*msr;
+	int irq;
+	atomic_t in_use;
+	int num;
+};
+
+extern struct mpic_msgr* mpic_msgr_get(unsigned int reg_num);
+extern void mpic_msgr_put(struct mpic_msgr* msgr);
+extern void mpic_msgr_enable(struct mpic_msgr *msgr);
+extern void mpic_msgr_disable(struct mpic_msgr *msgr);
+extern void mpic_msgr_write(struct mpic_msgr *msgr, u32 message);
+extern u32 mpic_msgr_read(struct mpic_msgr *msgr);
+extern void mpic_msgr_clear(struct mpic_msgr *msgr);
+extern void mpic_msgr_set_destination(struct mpic_msgr *msgr, u32 cpu_num);
+extern int mpic_msgr_get_irq(struct mpic_msgr *msgr);
+
+#endif
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index f7b0772..4d65593 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -78,6 +78,14 @@ config MPIC_WEIRD
 	bool
 	default n
 
+config MPIC_MSGR
+	bool "MPIC message register support"
+	depends on MPIC
+	default n
+	help
+	  Enables support for the MPIC message registers.  These
+	  registers are used for inter-processor communication.
+
 config PPC_I8259
 	bool
 	default n
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 1e0c933..6d40185 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -3,7 +3,8 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 ccflags-$(CONFIG_PPC64)		:= -mno-minimal-toc
 
 mpic-msi-obj-$(CONFIG_PCI_MSI)	+= mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
-obj-$(CONFIG_MPIC)		+= mpic.o $(mpic-msi-obj-y)
+mpic-msgr-obj-$(CONFIG_MPIC_MSGR)	+= mpic_msgr.o
+obj-$(CONFIG_MPIC)		+= mpic.o $(mpic-msi-obj-y) $(mpic-msgr-obj-y)
 fsl-msi-obj-$(CONFIG_PCI_MSI)	+= fsl_msi.o
 obj-$(CONFIG_PPC_MSI_BITMAP)	+= msi_bitmap.o
 
diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
new file mode 100644
index 0000000..352bfa6
--- /dev/null
+++ b/arch/powerpc/sysdev/mpic_msgr.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2011-2012, Meador Inge, Mentor Graphics Corporation.
+ *
+ * Some ideas based on un-pushed work done by Vivek Mahajan, Jason Jin, and
+ * Mingkai Hu from 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; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/list.h>
+#include <linux/of_platform.h>
+#include <linux/errno.h>
+#include <asm/prom.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+#include <asm/mpic_msgr.h>
+
+#define MPIC_MSGR_REGISTERS_PER_BLOCK 4
+#define MSGR_INUSE 0
+#define MSGR_FREE 1
+
+/* Internal structure used *only* for IO mapping register blocks. */
+struct mpic_msgr_block {
+	struct msgr {
+		u32 msgr;
+		u8 res[12];
+	} msgrs[MPIC_MSGR_REGISTERS_PER_BLOCK];
+	u8 res0[192];
+	u32 mer;
+	u8 res1[12];
+	u32 msr;
+};
+
+static struct mpic_msgr **mpic_msgrs = 0;
+static unsigned int mpic_msgr_count = 0;
+
+struct mpic_msgr* mpic_msgr_get(unsigned int reg_num)
+{
+	struct mpic_msgr* msgr;
+
+	if (reg_num >= mpic_msgr_count)
+		return ERR_PTR(-ENODEV);
+
+	msgr = mpic_msgrs[reg_num];
+
+	if (atomic_cmpxchg(&msgr->in_use, MSGR_FREE, MSGR_INUSE) == MSGR_FREE)
+		return msgr;
+
+	return ERR_PTR(-EBUSY);
+}
+EXPORT_SYMBOL(mpic_msgr_get);
+
+void mpic_msgr_put(struct mpic_msgr* msgr)
+{
+	atomic_set(&msgr->in_use, MSGR_FREE);
+}
+EXPORT_SYMBOL(mpic_msgr_put);
+
+void mpic_msgr_enable(struct mpic_msgr *msgr)
+{
+	out_be32(msgr->mer, in_be32(msgr->mer) | (1 << msgr->num));
+}
+EXPORT_SYMBOL(mpic_msgr_enable);
+
+void mpic_msgr_disable(struct mpic_msgr *msgr)
+{
+	out_be32(msgr->mer, in_be32(msgr->mer) & ~(1 << msgr->num));
+}
+EXPORT_SYMBOL(mpic_msgr_disable);
+
+void mpic_msgr_write(struct mpic_msgr *msgr, u32 message)
+{
+	out_be32(msgr->addr, message);
+}
+EXPORT_SYMBOL(mpic_msgr_write);
+
+u32 mpic_msgr_read(struct mpic_msgr *msgr)
+{
+	return in_be32(msgr->addr);
+}
+EXPORT_SYMBOL(mpic_msgr_read);
+
+void mpic_msgr_clear(struct mpic_msgr *msgr)
+{
+	(void) mpic_msgr_read(msgr);
+}
+EXPORT_SYMBOL(mpic_msgr_clear);
+
+void mpic_msgr_set_destination(struct mpic_msgr *msgr, u32 cpu_num)
+{
+	out_be32(msgr->addr, 1 << cpu_num);
+}
+EXPORT_SYMBOL(mpic_msgr_set_destination);
+
+int mpic_msgr_get_irq(struct mpic_msgr *msgr)
+{
+	return msgr->irq;
+}
+EXPORT_SYMBOL(mpic_msgr_get_irq);
+
+/* The following three functions are used to compute the order and number of
+ * the message register blocks.  They are clearly very inefficent.  However,
+ * they are called *only* a few times during device initialization.
+ */
+static unsigned int mpic_msgr_number_of_blocks(void)
+{
+	unsigned int count;
+	struct device_node *aliases;
+
+	count = 0;
+	aliases = of_find_node_by_name(NULL, "aliases");
+
+	if (aliases) {
+		char buf[32];
+
+		for (;;) {
+			snprintf(buf, sizeof(buf), "msgr-block%d", count);
+			if (!of_find_property(aliases, buf, NULL))
+				break;
+
+			count += 1;
+		}
+	}
+
+	return count;
+}
+
+static unsigned int mpic_msgr_number_of_registers(void)
+{
+	return mpic_msgr_number_of_blocks() * MPIC_MSGR_REGISTERS_PER_BLOCK;
+}
+
+static int mpic_msgr_block_number(struct device_node *node)
+{
+	struct device_node *aliases;
+	unsigned int index, number_of_blocks;
+	char buf[64];
+
+	number_of_blocks = mpic_msgr_number_of_blocks();
+	aliases = of_find_node_by_name(NULL, "aliases");
+	if (!aliases)
+		return -1;
+
+	for (index = 0; index < number_of_blocks; ++index) {
+		struct property *prop;
+
+		snprintf(buf, sizeof(buf), "msgr-block%d", index);
+		prop = of_find_property(aliases, buf, NULL);
+		if (node == of_find_node_by_path(prop->value))
+			break;
+	}
+
+	return index == number_of_blocks ? -1 : index;
+}
+
+/* The probe function for a single message register block.
+ */
+static __devinit int mpic_msgr_probe(struct platform_device *dev)
+{
+	struct mpic_msgr_block __iomem *msgr_block;
+	int block_number;
+	struct resource rsrc;
+	unsigned int i;
+	unsigned int irq_index;
+	struct device_node *np = dev->dev.of_node;
+	unsigned int receive_mask;
+	const unsigned int *prop;
+
+	if (!np) {
+		dev_err(&dev->dev, "Device OF-Node is NULL");
+		return -EFAULT;
+	}
+
+	/* Allocate the message register array upon the first device
+	 * registered.
+	 */
+	if (!mpic_msgrs) {
+		mpic_msgr_count = mpic_msgr_number_of_registers();
+		dev_info(&dev->dev, "Found %d message registers\n", mpic_msgr_count);
+
+		mpic_msgrs = kzalloc(sizeof(struct mpic_msgr) * mpic_msgr_count,
+							 GFP_KERNEL);
+		if (!mpic_msgrs) {
+			dev_err(&dev->dev, "No memory for message register blocks\n");
+			return -ENOMEM;
+		}
+	}
+	dev_info(&dev->dev, "Of-device full name %s\n", np->full_name);
+
+	/* IO map the message register block. */
+	of_address_to_resource(np, 0, &rsrc);
+	msgr_block = ioremap(rsrc.start, rsrc.end - rsrc.start);
+	if (!msgr_block) {
+		dev_err(&dev->dev, "Failed to iomap MPIC message registers");
+		return -EFAULT;
+	}
+
+	/* Ensure the block has a defined order. */
+	block_number = mpic_msgr_block_number(np);
+	if (block_number < 0) {
+		dev_err(&dev->dev, "Failed to find message register block alias\n");
+		return -ENODEV;
+	}
+	dev_info(&dev->dev, "Setting up message register block %d\n", block_number);
+
+	/* Grab the receive mask which specifies what registers can receive
+	 * interrupts.
+	 */
+	prop = of_get_property(np, "msg-receive-mask", NULL);
+	receive_mask = (prop) ? *prop : 0xF;
+
+	/* Build up the appropriate message register data structures. */
+	for (i = 0, irq_index = 0; i < MPIC_MSGR_REGISTERS_PER_BLOCK; ++i) {
+		struct mpic_msgr *msgr;
+		unsigned int reg_number;
+
+		msgr = kzalloc(sizeof(struct mpic_msgr), GFP_KERNEL);
+		if (!msgr) {
+			dev_err(&dev->dev, "No memory for message register\n");
+			return -ENOMEM;
+		}
+
+		reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i;
+		msgr->addr = &msgr_block->msgrs[i].msgr;
+		msgr->mer = &msgr_block->mer;
+		msgr->msr = &msgr_block->msr;
+		atomic_set(&msgr->in_use, MSGR_FREE);
+		msgr->num = reg_number;
+
+		if (receive_mask & (1 << i)) {
+			struct resource irq;
+
+			if (of_irq_to_resource(np, irq_index, &irq) == NO_IRQ) {
+				dev_err(&dev->dev, "Missing interrupt specifier");
+				kfree(msgr);
+				return -EFAULT;
+			}
+			msgr->irq = irq.start;
+			irq_index += 1;
+		} else {
+			msgr->irq = NO_IRQ;
+		}
+
+		mpic_msgrs[reg_number] = msgr;
+		mpic_msgr_disable(msgr);
+		dev_info(&dev->dev, "Register %d initialized: irq %d\n",
+				 msgr->num, msgr->irq);
+	
+	}
+
+	return 0;
+}
+
+static const struct of_device_id mpic_msgr_ids[] = {
+	{
+		.compatible = "fsl,mpic-v3.1-msgr",
+		.data = NULL,
+	},
+	{}
+};
+
+static struct platform_driver mpic_msgr_driver = {
+	.driver = {
+		.name = "mpic-msgr",
+		.owner = THIS_MODULE,
+		.of_match_table = mpic_msgr_ids,
+	},
+	.probe = mpic_msgr_probe,
+};
+
+static __init int mpic_msgr_init(void)
+{
+	return platform_driver_register(&mpic_msgr_driver);
+}
+subsys_initcall(mpic_msgr_init);
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 1/2] powerpc: document the FSL MPIC message register binding
From: Meador Inge @ 2011-04-19 16:59 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: openmcapi-dev, devicetree-discuss, Hollis Blanchard
In-Reply-To: <1303232375-25014-1-git-send-email-meador_inge@mentor.com>

This binding documents how the message register blocks found in some FSL
MPIC implementations shall be represented in a device tree.

Signed-off-by: Meador Inge <meador_inge@mentor.com>
Cc: Hollis Blanchard <hollis_blanchard@mentor.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 .../devicetree/bindings/powerpc/fsl/mpic-msgr.txt  |   71 ++++++++++++++++++++
 1 files changed, 71 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/mpic-msgr.txt

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mpic-msgr.txt b/Documentation/devicetree/bindings/powerpc/fsl/mpic-msgr.txt
new file mode 100644
index 0000000..41f1965
--- /dev/null
+++ b/Documentation/devicetree/bindings/powerpc/fsl/mpic-msgr.txt
@@ -0,0 +1,71 @@
+* FSL MPIC Message Registers
+
+This binding specifies what properties must be available in the device tree
+representation of the message register blocks found in some FSL MPIC
+implementations.
+
+Required properties:
+
+    - compatible: Specifies the compatibility list for the message register
+      block.  The type shall be <string> and the value shall be of the form
+      "fsl,mpic-v<version>-msgr", where <version> is the version number of
+      the MPIC containing the message registers.
+
+    - reg: Specifies the base physical address(s) and size(s) of the
+      message register block's addressable register space.  The type shall be
+      <prop-encoded-array>.
+
+    - interrupts: Specifies a list of interrupt source and level-sense pairs.
+      The type shall be <prop-encoded-array>.  The length shall be equal to
+      the number of bits set in the 'msg-receive-mask' property value.
+
+    - interrupt-parent: Specifies the interrupt parent of the message register
+      block.  The type shall be a <phandle> and the value of that <phandle>
+      shall point to the interrupt parent.
+
+Optional properties:
+
+    - msg-receive-mask: Specifies what registers in the containing block are
+      allowed to receive interrupts.  The value is a bit mask where a set bit
+      at bit 'n' indicates that message register 'n' can receive interrupts.
+      The type shall be <prop-encoded-array>.  The default value shall be
+      all a string of consecutive ones where the length of the run is equal
+      to the number of registers in the block.  For example, a block with
+      four registers shall default to 0xF.
+
+Required alias:
+
+    In order for a message register block to be discovered it *must* define
+    an alias in the 'aliases' node.  Aliases are of the form 'msgr-block<n>',
+    where <n> is an integer specifying the block's number.  Numbers shall start
+    at 0.
+
+Example:
+
+	/* The aliases needed to define an order on the message register blocks.
+	 */
+	aliases {
+		msgr-block0 = &msgr_block0;
+		msgr-block1 = &msgr_block1;
+	};
+
+	msgr_block0: msgr-block@41400 {
+		compatible = "fsl,mpic-v3.1-msgr";
+		reg = <0x41400 0x200>;
+		// Message registers 0 and 3 in this block can receive interrupts on
+		// sources 0xb0 and 0xb2, respectively.
+		interrupts = <0xb0 2 0xb2 2>;
+		msg-receive-mask = <0x5>;
+		interrupt-parent = <&mpic>;
+	};
+
+	msgr_block1: msgr-block@42400 {
+		compatible = "fsl,mpic-v3.1-msgr";
+		reg = <0x42400 0x200>;
+		// Message registers 0 and 3 in this block can receive interrupts on
+		// sources 0xb4 and 0xb6, respectively.
+		interrupts = <0xb4 2 0xb6 2>;
+		msg-receive-mask = <0x5>;
+		interrupt-parent = <&mpic>;
+	};
+
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 0/2] powerpc: define and implement MPIC message register support
From: Meador Inge @ 2011-04-19 16:59 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: openmcapi-dev, devicetree-discuss, Hollis Blanchard

This patch set defines a binding for FSL MPIC message registers and implements
an API for accessing those message registers.  Testing was done on a MPC8572DS
in an Linux-Linux AMP setup using OpenMCAPI (www.openmcapi.org) to communicate
between OS instances.  The message register API is used by the OpenMCAPI shared 
memory driver to send notifications between cores.

Signed-off-by: Meador Inge <meador_inge@mentor.com>
Cc: Hollis Blanchard <hollis_blanchard@mentor.com>

Meador Inge (2):
  powerpc: document the FSL MPIC message register binding
  powerpc: add support for MPIC message register API

 .../devicetree/bindings/powerpc/fsl/mpic-msgr.txt  |   71 +++++
 arch/powerpc/include/asm/mpic_msgr.h               |   35 +++
 arch/powerpc/platforms/Kconfig                     |    8 +
 arch/powerpc/sysdev/Makefile                       |    3 +-
 arch/powerpc/sysdev/mpic_msgr.c                    |  279 ++++++++++++++++++++
 5 files changed, 395 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/mpic-msgr.txt
 create mode 100644 arch/powerpc/include/asm/mpic_msgr.h
 create mode 100644 arch/powerpc/sysdev/mpic_msgr.c

^ permalink raw reply

* Info reg. MapleD
From: Dmitry Eremin-Solenikov @ 2011-04-19 14:49 UTC (permalink / raw)
  To: linuxppc-dev

Hello, colleagues,

I've recently got my hands on MapleD (ppc970fx ev. kit, XSC-100) board.
I'm trying to fixup several issues with it and further enhance Linux
support for this device. However somewhere in the long history of this
board the original developers disk that came with it got lost.

Thus I'm looking for several parts of information that might help me:
* Schematics for the board
* datasheet/user manual for CPC925 nothern bridge (does such thing ever
  existed? Maybe someone can convince IBM to publish it?)

-- 
With best wishes
Dmitry

^ permalink raw reply

* [PATCH][upstream] powerpc: Adding bindings for flexcan controller
From: Bhaskar Upadhaya @ 2011-04-19 13:58 UTC (permalink / raw)
  To: devicetree-discuss, linuxppc-dev; +Cc: Bhaskar Upadhaya, inuxppc-dev

From: Bhaskar Upadhaya <bhaskar.upadhaya@freescale.com>

Signed-off-by: Bhaskar Upadhaya <bhaskar.upadhaya@freescale.com>
Acked-By: Scott Wood <scottwood@freescale.com>
---
Based upon git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git (branch -> master)

 .../devicetree/bindings/net/can/fsl-flexcan.txt    |   61 ++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)
 create mode 100755 Documentation/devicetree/bindings/net/can/fsl-flexcan.txt

diff --git a/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
new file mode 100755
index 0000000..1a729f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
@@ -0,0 +1,61 @@
+CAN Device Tree Bindings
+------------------------
+2011 Freescale Semiconductor, Inc.
+
+fsl,flexcan-v1.0 nodes
+-----------------------
+In addition to the required compatible-, reg- and interrupt-properties, you can
+also specify which clock source shall be used for the controller.
+
+CPI Clock- Can Protocol Interface Clock
+	This CLK_SRC bit of CTRL(control register) selects the clock source to
+	the CAN Protocol Interface(CPI) to be either the peripheral clock
+	(driven by the PLL) or the crystal oscillator clock. The selected clock
+	is the one fed to the prescaler to generate the Serial Clock (Sclock).
+	The PRESDIV field of CTRL(control register) controls a prescaler that
+	generates the Serial Clock (Sclock), whose period defines the
+	time quantum used to compose the CAN waveform.
+
+Can Engine Clock Source
+	There are two sources for CAN clock
+	- Platform Clock  It represents the bus clock
+	- Oscillator Clock
+
+	Peripheral Clock (PLL)
+	--------------
+		     |
+		    ---------		      -------------
+		    |       |CPI Clock	      | Prescaler |       Sclock
+		    |       |---------------->| (1.. 256) |------------>
+		    ---------		      -------------
+                     |  |
+	--------------  ---------------------CLK_SRC
+	Oscillator Clock
+
+- fsl,flexcan-clock-source : CAN Engine Clock Source.This property selects
+			     the peripheral clock. PLL clock is fed to the
+			     prescaler to generate the Serial Clock (Sclock).
+			     Valid values are "oscillator" and "platform"
+			     "oscillator": CAN engine clock source is oscillator clock.
+			     "platform" The CAN engine clock source is the bus clock
+		             (platform clock).
+
+- fsl,flexcan-clock-divider : for the reference and system clock, an additional
+			      clock divider can be specified.
+- clock-frequency: frequency required to calculate the bitrate for FlexCAN.
+
+Note:
+	- v1.0 of flexcan-v1.0 represent the IP block version for P1010 SOC.
+	- P1010 does not have oscillator as the Clock Source.So the default
+	  Clock Source is platform clock.
+Examples:
+
+	can0@1c000 {
+		compatible = "fsl,flexcan-v1.0";
+		reg = <0x1c000 0x1000>;
+		interrupts = <48 0x2>;
+		interrupt-parent = <&mpic>;
+		fsl,flexcan-clock-source = "platform";
+		fsl,flexcan-clock-divider = <2>;
+		clock-frequency = <fixed by u-boot>;
+	};
-- 
1.5.6.5

^ permalink raw reply related

* RE: [PATCH 12/14] PM / UNICORE32: Use struct syscore_ops instead of sysdevs for PM
From: Guan Xuetao @ 2011-04-19  8:02 UTC (permalink / raw)
  To: 'Rafael J. Wysocki', 'LKML'
  Cc: 'Kevin Hilman', 'Jeremy Fitzhardinge',
	'Russell King', 'Konrad Rzeszutek Wilk',
	'Greg KH', 'Ralf Baechle', 'Ben Dooks',
	'Jiri Kosina', 'Kay Sievers',
	'Mike Frysinger', 'Linux PM mailing list',
	linux-omap, linuxppc-dev, 'Hans-Christian Egtvedt',
	linux-arm-kernel
In-Reply-To: <201104172313.45854.rjw@sisk.pl>



> -----Original Message-----
> From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> Sent: Monday, April 18, 2011 5:14 AM
> To: LKML
> Cc: Greg KH; Kay Sievers; Linux PM mailing list; Russell King; linux-omap@vger.kernel.org; Kevin Hilman; linux-arm-
> kernel@lists.infradead.org; Ben Dooks; Mike Frysinger; Ralf Baechle; Hans-Christian Egtvedt; Guan Xuetao; Benjamin Herrenschmidt;
> linuxppc-dev@lists.ozlabs.org; Jiri Kosina; Konrad Rzeszutek Wilk; Jeremy Fitzhardinge
> Subject: [PATCH 12/14] PM / UNICORE32: Use struct syscore_ops instead of sysdevs for PM
> 
> From: Rafael J. Wysocki <rjw@sisk.pl>
> 
> Make some UNICORE32 architecture's code use struct syscore_ops
> objects for power management instead of sysdev classes and sysdevs.
> 
> This simplifies the code and reduces the kernel's memory footprint.
> It also is necessary for removing sysdevs from the kernel entirely in
> the future.
> 
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>

Acked-by: Guan Xuetao <gxt@mprc.pku.edu.cn>

^ permalink raw reply

* [PATCH][RFC] mpc52xx, common: setup port_config and cdm settings through DTS
From: Heiko Schocher @ 2011-04-19  6:04 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: devictree-discuss, Heiko Schocher, Grant Likely, Wolfgang Denk

If firmware does not setup the "GPS Port Configuration Register"
and the "CDM 48MHz Fractional Divider Configuration Register",
it can be corrected through DTS.

Signed-off-by: Heiko Schocher <hs@denx.de>
cc: devictree-discuss@lists.ozlabs.org
cc: linuxppc-dev@lists.ozlabs.org
cc: Grant Likely <glikely@secretlab.ca>
cc: Wolfgang Denk <wd@denx.de>
---
 .../devicetree/bindings/powerpc/fsl/mpc5200.txt    |   16 +++++++++++
 arch/powerpc/platforms/52xx/mpc52xx_common.c       |   27 ++++++++++++++++++++
 2 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt b/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt
index 4ccb2cd..0c1c6c8 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt
@@ -155,6 +155,9 @@ Each GPIO controller node should have the empty property gpio-controller and
 according to the bit numbers in the GPIO control registers. The second cell
 is for flags which is currently unused.
 
+If firmware does not setup port_config correct, it can be modified
+through the "fsl,init-port-config" property in the "fsl,mpc5200-gpio" node.
+
 fsl,mpc5200-fec nodes
 ---------------------
 The FEC node can specify one of the following properties to configure
@@ -196,3 +199,16 @@ External interrupts:
 fsl,mpc5200-mscan nodes
 -----------------------
 See file can.txt in this directory.
+
+fsl,mpc5200-cdm nodes
+---------------------
+- setup "CDM 48MHz Fractional Divider Configuration Register"
+  If firmware does not setup this register correct, you can
+  modify it with the following properties:
+
+  - fsl,init-ext-48mhz-en
+    see MPC5200BUM Table 5-11 Bits 0-7
+  - fsl,init-fd-enable
+    see MPC5200BUM Table 5-11 Bits 8-15
+  - fsl,init-fd-counters
+    see MPC5200BUM Table 5-11 Bits 16-31
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 41f3a7e..41099f3 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -136,6 +136,8 @@ void __init
 mpc52xx_map_common_devices(void)
 {
 	struct device_node *np;
+	const u32 *prop;
+	int plen;
 
 	/* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
 	 * possibly from a interrupt context. wdt is only implement
@@ -153,11 +155,36 @@ mpc52xx_map_common_devices(void)
 	/* Clock Distribution Module, used by PSC clock setting function */
 	np = of_find_matching_node(NULL, mpc52xx_cdm_ids);
 	mpc52xx_cdm = of_iomap(np, 0);
+	prop = of_get_property(np, "fsl,init-ext-48mhz-en", &plen);
+	if (prop) {
+		pr_debug("ext-48mhz-en: old:%x new:%x\n",
+			in_8(&mpc52xx_cdm->ext_48mhz_en), *prop);
+		out_8(&mpc52xx_cdm->ext_48mhz_en, *prop);
+	}
+	prop = of_get_property(np, "fsl,init-fd-enable", &plen);
+	if (prop) {
+		pr_debug("fd-enable: old:%x new:%x\n",
+			in_8(&mpc52xx_cdm->fd_enable), *prop);
+		out_8(&mpc52xx_cdm->fd_enable, *prop);
+	}
+	prop = of_get_property(np, "fsl,init-fd-counters", &plen);
+	if (prop) {
+		pr_debug("fd-counters: old:%x new:%x\n",
+			in_be16(&mpc52xx_cdm->fd_counters), *prop);
+		out_be16(&mpc52xx_cdm->fd_counters, *prop);
+	}
 	of_node_put(np);
 
 	/* simple_gpio registers */
 	np = of_find_matching_node(NULL, mpc52xx_gpio_simple);
 	simple_gpio = of_iomap(np, 0);
+	/* fixup the port_config register */
+	prop = of_get_property(np, "fsl,init-port-config", &plen);
+	if (prop) {
+		pr_info("port-config: old:%x new:%x\n",
+			in_be32(&simple_gpio->port_config), *prop);
+		out_be32(&simple_gpio->port_config, *prop);
+	}
 	of_node_put(np);
 
 	/* wkup_gpio registers */
-- 
1.7.4.4

^ permalink raw reply related

* Re: [PATCH 10/14] PM / MIPS: Use struct syscore_ops instead of sysdevs for PM
From: Lars-Peter Clausen @ 2011-04-19  3:08 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Kevin Hilman, Guan Xuetao, Russell King, Konrad Rzeszutek Wilk,
	Greg KH, LKML, Ralf Baechle, Jeremy Fitzhardinge, Ben Dooks,
	Jiri Kosina, Kay Sievers, Mike Frysinger, Linux PM mailing list,
	linux-omap, linuxppc-dev, Hans-Christian Egtvedt,
	linux-arm-kernel
In-Reply-To: <201104172312.35060.rjw@sisk.pl>

On 04/17/2011 11:12 PM, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
> 
> Convert some MIPS architecture's code to using struct syscore_ops
> objects for power management instead of sysdev classes and sysdevs.
> 
> This simplifies the code and reduces the kernel's memory footprint.
> It also is necessary for removing sysdevs from the kernel entirely in
> the future.
> 
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>

For the jz4740 part:
Acked-and-tested-by: Lars-Peter Clausen <lars@metafoo.de>

> ---
>  arch/mips/alchemy/common/dbdma.c |   92 +++++++++++----------------------------
>  arch/mips/alchemy/common/irq.c   |   62 +++++++++-----------------
>  arch/mips/jz4740/gpio.c          |   52 +++++++++-------------
>  arch/mips/kernel/i8259.c         |   26 +++--------
>  4 files changed, 80 insertions(+), 152 deletions(-)
> 
> Index: linux-2.6/arch/mips/alchemy/common/irq.c
> ===================================================================
> --- linux-2.6.orig/arch/mips/alchemy/common/irq.c
> +++ linux-2.6/arch/mips/alchemy/common/irq.c
> @@ -30,7 +30,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/irq.h>
>  #include <linux/slab.h>
> -#include <linux/sysdev.h>
> +#include <linux/syscore_ops.h>
>  
>  #include <asm/irq_cpu.h>
>  #include <asm/mipsregs.h>
> @@ -556,17 +556,15 @@ void __init arch_init_irq(void)
>  	}
>  }
>  
> -struct alchemy_ic_sysdev {
> -	struct sys_device sysdev;
> +struct alchemy_ic {
>  	void __iomem *base;
>  	unsigned long pmdata[7];
>  };
>  
> -static int alchemy_ic_suspend(struct sys_device *dev, pm_message_t state)
> -{
> -	struct alchemy_ic_sysdev *icdev =
> -			container_of(dev, struct alchemy_ic_sysdev, sysdev);
> +static struct alchemy_ic alchemy_ic_data[2];
>  
> +static void alchemy_suspend_one_ic(struct alchemy_ic *icdev)
> +{
>  	icdev->pmdata[0] = __raw_readl(icdev->base + IC_CFG0RD);
>  	icdev->pmdata[1] = __raw_readl(icdev->base + IC_CFG1RD);
>  	icdev->pmdata[2] = __raw_readl(icdev->base + IC_CFG2RD);
> @@ -574,15 +572,17 @@ static int alchemy_ic_suspend(struct sys
>  	icdev->pmdata[4] = __raw_readl(icdev->base + IC_ASSIGNRD);
>  	icdev->pmdata[5] = __raw_readl(icdev->base + IC_WAKERD);
>  	icdev->pmdata[6] = __raw_readl(icdev->base + IC_MASKRD);
> +}
>  
> +static int alchemy_ic_suspend(void)
> +{
> +	alchemy_suspend_one_ic(alchemy_ic_data);
> +	alchemy_suspend_one_ic(alchemy_ic_data + 1);
>  	return 0;
>  }
>  
> -static int alchemy_ic_resume(struct sys_device *dev)
> +static void alchemy_resume_one_ic(struct alchemy_ic *icdev)
>  {
> -	struct alchemy_ic_sysdev *icdev =
> -			container_of(dev, struct alchemy_ic_sysdev, sysdev);
> -
>  	__raw_writel(0xffffffff, icdev->base + IC_MASKCLR);
>  	__raw_writel(0xffffffff, icdev->base + IC_CFG0CLR);
>  	__raw_writel(0xffffffff, icdev->base + IC_CFG1CLR);
> @@ -604,42 +604,26 @@ static int alchemy_ic_resume(struct sys_
>  
>  	__raw_writel(icdev->pmdata[6], icdev->base + IC_MASKSET);
>  	wmb();
> +}
>  
> -	return 0;
> +static void alchemy_ic_resume(void)
> +{
> +	alchemy_resume_one_ic(alchemy_ic_data + 1);
> +	alchemy_resume_one_ic(alchemy_ic_data);
>  }
>  
> -static struct sysdev_class alchemy_ic_sysdev_class = {
> -	.name		= "ic",
> +static struct syscore_ops alchemy_ic_syscore_ops = {
>  	.suspend	= alchemy_ic_suspend,
>  	.resume		= alchemy_ic_resume,
>  };
>  
> -static int __init alchemy_ic_sysdev_init(void)
> +static int __init alchemy_ic_syscore_init(void)
>  {
> -	struct alchemy_ic_sysdev *icdev;
> -	unsigned long icbase[2] = { IC0_PHYS_ADDR, IC1_PHYS_ADDR };
> -	int err, i;
> -
> -	err = sysdev_class_register(&alchemy_ic_sysdev_class);
> -	if (err)
> -		return err;
> -
> -	for (i = 0; i < 2; i++) {
> -		icdev = kzalloc(sizeof(struct alchemy_ic_sysdev), GFP_KERNEL);
> -		if (!icdev)
> -			return -ENOMEM;
> -
> -		icdev->base = ioremap(icbase[i], 0x1000);
> -
> -		icdev->sysdev.id = i;
> -		icdev->sysdev.cls = &alchemy_ic_sysdev_class;
> -		err = sysdev_register(&icdev->sysdev);
> -		if (err) {
> -			kfree(icdev);
> -			return err;
> -		}
> -	}
> +	alchemy_ic_data[0].base = ioremap(icbase[IC0_PHYS_ADDR], 0x1000);
> +	alchemy_ic_data[1].base = ioremap(icbase[IC1_PHYS_ADDR], 0x1000);
> +
> +	register_syscore_ops(&alchemy_ic_syscore_ops);
>  
>  	return 0;
>  }
> -device_initcall(alchemy_ic_sysdev_init);
> +device_initcall(alchemy_ic_syscore_init);
> Index: linux-2.6/arch/mips/alchemy/common/dbdma.c
> ===================================================================
> --- linux-2.6.orig/arch/mips/alchemy/common/dbdma.c
> +++ linux-2.6/arch/mips/alchemy/common/dbdma.c
> @@ -36,7 +36,7 @@
>  #include <linux/spinlock.h>
>  #include <linux/interrupt.h>
>  #include <linux/module.h>
> -#include <linux/sysdev.h>
> +#include <linux/syscore_ops.h>
>  #include <asm/mach-au1x00/au1000.h>
>  #include <asm/mach-au1x00/au1xxx_dbdma.h>
>  
> @@ -957,37 +957,30 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au
>  	return nbytes;
>  }
>  
> +static u32 alchemy_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][6];
>  
> -struct alchemy_dbdma_sysdev {
> -	struct sys_device sysdev;
> -	u32 pm_regs[NUM_DBDMA_CHANS + 1][6];
> -};
> -
> -static int alchemy_dbdma_suspend(struct sys_device *dev,
> -				 pm_message_t state)
> +static int alchemy_dbdma_suspend(void)
>  {
> -	struct alchemy_dbdma_sysdev *sdev =
> -		container_of(dev, struct alchemy_dbdma_sysdev, sysdev);
>  	int i;
>  	u32 addr;
>  
>  	addr = DDMA_GLOBAL_BASE;
> -	sdev->pm_regs[0][0] = au_readl(addr + 0x00);
> -	sdev->pm_regs[0][1] = au_readl(addr + 0x04);
> -	sdev->pm_regs[0][2] = au_readl(addr + 0x08);
> -	sdev->pm_regs[0][3] = au_readl(addr + 0x0c);
> +	alchemy_dbdma_pm_regs[0][0] = au_readl(addr + 0x00);
> +	alchemy_dbdma_pm_regs[0][1] = au_readl(addr + 0x04);
> +	alchemy_dbdma_pm_regs[0][2] = au_readl(addr + 0x08);
> +	alchemy_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c);
>  
>  	/* save channel configurations */
>  	for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
> -		sdev->pm_regs[i][0] = au_readl(addr + 0x00);
> -		sdev->pm_regs[i][1] = au_readl(addr + 0x04);
> -		sdev->pm_regs[i][2] = au_readl(addr + 0x08);
> -		sdev->pm_regs[i][3] = au_readl(addr + 0x0c);
> -		sdev->pm_regs[i][4] = au_readl(addr + 0x10);
> -		sdev->pm_regs[i][5] = au_readl(addr + 0x14);
> +		alchemy_dbdma_pm_regs[i][0] = au_readl(addr + 0x00);
> +		alchemy_dbdma_pm_regs[i][1] = au_readl(addr + 0x04);
> +		alchemy_dbdma_pm_regs[i][2] = au_readl(addr + 0x08);
> +		alchemy_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c);
> +		alchemy_dbdma_pm_regs[i][4] = au_readl(addr + 0x10);
> +		alchemy_dbdma_pm_regs[i][5] = au_readl(addr + 0x14);
>  
>  		/* halt channel */
> -		au_writel(sdev->pm_regs[i][0] & ~1, addr + 0x00);
> +		au_writel(alchemy_dbdma_pm_regs[i][0] & ~1, addr + 0x00);
>  		au_sync();
>  		while (!(au_readl(addr + 0x14) & 1))
>  			au_sync();
> @@ -1001,62 +994,35 @@ static int alchemy_dbdma_suspend(struct
>  	return 0;
>  }
>  
> -static int alchemy_dbdma_resume(struct sys_device *dev)
> +static void alchemy_dbdma_resume(void)
>  {
> -	struct alchemy_dbdma_sysdev *sdev =
> -		container_of(dev, struct alchemy_dbdma_sysdev, sysdev);
>  	int i;
>  	u32 addr;
>  
>  	addr = DDMA_GLOBAL_BASE;
> -	au_writel(sdev->pm_regs[0][0], addr + 0x00);
> -	au_writel(sdev->pm_regs[0][1], addr + 0x04);
> -	au_writel(sdev->pm_regs[0][2], addr + 0x08);
> -	au_writel(sdev->pm_regs[0][3], addr + 0x0c);
> +	au_writel(alchemy_dbdma_pm_regs[0][0], addr + 0x00);
> +	au_writel(alchemy_dbdma_pm_regs[0][1], addr + 0x04);
> +	au_writel(alchemy_dbdma_pm_regs[0][2], addr + 0x08);
> +	au_writel(alchemy_dbdma_pm_regs[0][3], addr + 0x0c);
>  
>  	/* restore channel configurations */
>  	for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
> -		au_writel(sdev->pm_regs[i][0], addr + 0x00);
> -		au_writel(sdev->pm_regs[i][1], addr + 0x04);
> -		au_writel(sdev->pm_regs[i][2], addr + 0x08);
> -		au_writel(sdev->pm_regs[i][3], addr + 0x0c);
> -		au_writel(sdev->pm_regs[i][4], addr + 0x10);
> -		au_writel(sdev->pm_regs[i][5], addr + 0x14);
> +		au_writel(alchemy_dbdma_pm_regs[i][0], addr + 0x00);
> +		au_writel(alchemy_dbdma_pm_regs[i][1], addr + 0x04);
> +		au_writel(alchemy_dbdma_pm_regs[i][2], addr + 0x08);
> +		au_writel(alchemy_dbdma_pm_regs[i][3], addr + 0x0c);
> +		au_writel(alchemy_dbdma_pm_regs[i][4], addr + 0x10);
> +		au_writel(alchemy_dbdma_pm_regs[i][5], addr + 0x14);
>  		au_sync();
>  		addr += 0x100;	/* next channel base */
>  	}
> -
> -	return 0;
>  }
>  
> -static struct sysdev_class alchemy_dbdma_sysdev_class = {
> -	.name		= "dbdma",
> +static struct syscore_ops alchemy_dbdma_syscore_ops = {
>  	.suspend	= alchemy_dbdma_suspend,
>  	.resume		= alchemy_dbdma_resume,
>  };
>  
> -static int __init alchemy_dbdma_sysdev_init(void)
> -{
> -	struct alchemy_dbdma_sysdev *sdev;
> -	int ret;
> -
> -	ret = sysdev_class_register(&alchemy_dbdma_sysdev_class);
> -	if (ret)
> -		return ret;
> -
> -	sdev = kzalloc(sizeof(struct alchemy_dbdma_sysdev), GFP_KERNEL);
> -	if (!sdev)
> -		return -ENOMEM;
> -
> -	sdev->sysdev.id = -1;
> -	sdev->sysdev.cls = &alchemy_dbdma_sysdev_class;
> -	ret = sysdev_register(&sdev->sysdev);
> -	if (ret)
> -		kfree(sdev);
> -
> -	return ret;
> -}
> -
>  static int __init au1xxx_dbdma_init(void)
>  {
>  	int irq_nr, ret;
> @@ -1084,11 +1050,7 @@ static int __init au1xxx_dbdma_init(void
>  	else {
>  		dbdma_initialized = 1;
>  		printk(KERN_INFO "Alchemy DBDMA initialized\n");
> -		ret = alchemy_dbdma_sysdev_init();
> -		if (ret) {
> -			printk(KERN_ERR "DBDMA PM init failed\n");
> -			ret = 0;
> -		}
> +		register_syscore_ops(&alchemy_dbdma_syscore_ops);
>  	}
>  
>  	return ret;
> Index: linux-2.6/arch/mips/jz4740/gpio.c
> ===================================================================
> --- linux-2.6.orig/arch/mips/jz4740/gpio.c
> +++ linux-2.6/arch/mips/jz4740/gpio.c
> @@ -18,7 +18,7 @@
>  #include <linux/init.h>
>  
>  #include <linux/spinlock.h>
> -#include <linux/sysdev.h>
> +#include <linux/syscore_ops.h>
>  #include <linux/io.h>
>  #include <linux/gpio.h>
>  #include <linux/delay.h>
> @@ -86,7 +86,6 @@ struct jz_gpio_chip {
>  	spinlock_t lock;
>  
>  	struct gpio_chip gpio_chip;
> -	struct sys_device sysdev;
>  };
>  
>  static struct jz_gpio_chip jz4740_gpio_chips[];
> @@ -459,49 +458,47 @@ static struct jz_gpio_chip jz4740_gpio_c
>  	JZ4740_GPIO_CHIP(D),
>  };
>  
> -static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev)
> +static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip)
>  {
> -	return container_of(dev, struct jz_gpio_chip, sysdev);
> +	chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
> +	writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
> +	writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
>  }
>  
> -static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state)
> +static int jz4740_gpio_suspend(void)
>  {
> -	struct jz_gpio_chip *chip = sysdev_to_chip(dev);
> +	int i;
>  
> -	chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
> -	writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
> -	writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
> +	for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); i++)
> +		jz4740_gpio_suspend_chip(&jz4740_gpio_chips[i]);
>  
>  	return 0;
>  }
>  
> -static int jz4740_gpio_resume(struct sys_device *dev)
> +static void jz4740_gpio_resume_chip(struct jz_gpio_chip *chip)
>  {
> -	struct jz_gpio_chip *chip = sysdev_to_chip(dev);
>  	uint32_t mask = chip->suspend_mask;
>  
>  	writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR);
>  	writel(mask, chip->base + JZ_REG_GPIO_MASK_SET);
> +}
>  
> -	return 0;
> +static void jz4740_gpio_resume(void)
> +{
> +	int i;
> +
> +	for (i = ARRAY_SIZE(jz4740_gpio_chips) - 1; i >= 0 ; i--)
> +		jz4740_gpio_resume_chip(&jz4740_gpio_chips[i]);
>  }
>  
> -static struct sysdev_class jz4740_gpio_sysdev_class = {
> -	.name = "gpio",
> +static struct syscore_ops jz4740_gpio_syscore_ops = {
>  	.suspend = jz4740_gpio_suspend,
>  	.resume = jz4740_gpio_resume,
>  };
>  
> -static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
> +static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
>  {
> -	int ret, irq;
> -
> -	chip->sysdev.id = id;
> -	chip->sysdev.cls = &jz4740_gpio_sysdev_class;
> -	ret = sysdev_register(&chip->sysdev);
> -
> -	if (ret)
> -		return ret;
> +	int irq;
>  
>  	spin_lock_init(&chip->lock);
>  
> @@ -519,22 +516,17 @@ static int jz4740_gpio_chip_init(struct
>  		irq_set_chip_and_handler(irq, &jz_gpio_irq_chip,
>  					 handle_level_irq);
>  	}
> -
> -	return 0;
>  }
>  
>  static int __init jz4740_gpio_init(void)
>  {
>  	unsigned int i;
> -	int ret;
> -
> -	ret = sysdev_class_register(&jz4740_gpio_sysdev_class);
> -	if (ret)
> -		return ret;
>  
>  	for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i)
>  		jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
>  
> +	register_syscore_ops(&jz4740_gpio_syscore_ops);
> +
>  	printk(KERN_INFO "JZ4740 GPIO initialized\n");
>  
>  	return 0;
> Index: linux-2.6/arch/mips/kernel/i8259.c
> ===================================================================
> --- linux-2.6.orig/arch/mips/kernel/i8259.c
> +++ linux-2.6/arch/mips/kernel/i8259.c
> @@ -14,7 +14,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/kernel.h>
>  #include <linux/spinlock.h>
> -#include <linux/sysdev.h>
> +#include <linux/syscore_ops.h>
>  #include <linux/irq.h>
>  
>  #include <asm/i8259.h>
> @@ -215,14 +215,13 @@ spurious_8259A_irq:
>  	}
>  }
>  
> -static int i8259A_resume(struct sys_device *dev)
> +static void i8259A_resume(void)
>  {
>  	if (i8259A_auto_eoi >= 0)
>  		init_8259A(i8259A_auto_eoi);
> -	return 0;
>  }
>  
> -static int i8259A_shutdown(struct sys_device *dev)
> +static void i8259A_shutdown(void)
>  {
>  	/* Put the i8259A into a quiescent state that
>  	 * the kernel initialization code can get it
> @@ -232,29 +231,20 @@ static int i8259A_shutdown(struct sys_de
>  		outb(0xff, PIC_MASTER_IMR);	/* mask all of 8259A-1 */
>  		outb(0xff, PIC_SLAVE_IMR);	/* mask all of 8259A-1 */
>  	}
> -	return 0;
>  }
>  
> -static struct sysdev_class i8259_sysdev_class = {
> -	.name = "i8259",
> +static struct syscore_ops i8259_syscore_ops = {
>  	.resume = i8259A_resume,
>  	.shutdown = i8259A_shutdown,
>  };
>  
> -static struct sys_device device_i8259A = {
> -	.id	= 0,
> -	.cls	= &i8259_sysdev_class,
> -};
> -
> -static int __init i8259A_init_sysfs(void)
> +static int __init i8259A_init_syscore(void)
>  {
> -	int error = sysdev_class_register(&i8259_sysdev_class);
> -	if (!error)
> -		error = sysdev_register(&device_i8259A);
> -	return error;
> +	register_syscore_ops(&i8259_syscore_ops);
> +	return 0;
>  }
>  
> -device_initcall(i8259A_init_sysfs);
> +device_initcall(i8259A_init_syscore);
>  
>  static void init_8259A(int auto_eoi)
>  {
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* Re: [PATCH 10/15] powerpc: Define slb0_limit() for BOOK3E
From: Benjamin Herrenschmidt @ 2011-04-18 22:50 UTC (permalink / raw)
  To: Kumar Gala
  Cc: Michael Ellerman, Jimi Xenidis, jack, imunsie, linuxppc-dev,
	David Gibson
In-Reply-To: <5313E556-6BFA-48D0-921F-7CF91892514A@freescale.com>

On Mon, 2011-04-18 at 17:30 -0500, Kumar Gala wrote:
> > On Mon, 2011-04-18 at 07:42 -0500, Kumar Gala wrote:
> >> Let's rename this function to something 'linear_map'.  As on FSL
> >> Book-E 64 we do things a bit differently and have more covered in
> >> linear map than 1G
> > 
> > It's not quite linear_map. It's whatever can be accessed without
> taking
> > exceptions. IE. What is bolted.
> > 
> > It should probably go into a variable initialized by the mm code
> tho.
> > 
> > Cheers,
> > Ben.
> 
> Is this 'ppc64_rma_size' ? 

Not quite either :-)

The RMA (on server) is the amount of memory that is accessible in real
mode (with MMU off).

SLB0 is segment 0, which is 256M or 1T depending on what segment size we
use, and is a bolted segment in Linux. Thus all accesses to SLB0 are
guaranteed to not generate an SLB miss fault. Since on server our linear
mapping is bolted in the hash, what that means is that any access to
memory in segment 0 is guaranteed to not take an exception (ie not
clobber SRR0/1 for example).

We re-use the SLB0 concept on BookE to represent the bolted portion of
the linear mapping since it has the same characteristics, ie, accesses
will not cause an exception that can clobber SRR0/1.

The patch Michael posted is indeed a bit gross (it's my code btw :-) and
we'll need to clean it up, my idea is to have a global set by the
platform, but maybe we can have some generic code that performs a TLB
search for IPROT entries :-)

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 12/15] powerpc/book3e: Use way 3 for linear mapping bolted entry
From: Benjamin Herrenschmidt @ 2011-04-18 22:44 UTC (permalink / raw)
  To: Kumar Gala
  Cc: Michael Ellerman, Jimi Xenidis, jack, imunsie, linuxppc-dev,
	David Gibson
In-Reply-To: <7086A97F-A6A6-4D25-9FA7-20959C74E440@kernel.crashing.org>


> >> Seems like this should have a MMU Feature bit or something for A2.
> > 
> > Too early. We haven't detected the CPU and are establishing the initial
> > TLB entry here.
> 
> How about wrapping with CONFIG_PPC_A2

YUCK :-)

> > Any reason why that wouldn't work on something else anyways ?
> 
> No, I wasn't paying attention to what this code exactly was (not enough
> context in the diff), I see its our initial setup so not a big deal.
>   Was thinking this was run-time exception handler code.

No, it's the boot time bolted entry.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 10/15] powerpc: Define slb0_limit() for BOOK3E
From: Kumar Gala @ 2011-04-18 22:30 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Michael Ellerman, Jimi Xenidis, jack, imunsie, linuxppc-dev,
	David Gibson
In-Reply-To: <1303162902.28876.164.camel@pasglop>


On Apr 18, 2011, at 4:41 PM, Benjamin Herrenschmidt wrote:

> On Mon, 2011-04-18 at 07:42 -0500, Kumar Gala wrote:
>> Let's rename this function to something 'linear_map'.  As on FSL
>> Book-E 64 we do things a bit differently and have more covered in
>> linear map than 1G
> 
> It's not quite linear_map. It's whatever can be accessed without taking
> exceptions. IE. What is bolted.
> 
> It should probably go into a variable initialized by the mm code tho.
> 
> Cheers,
> Ben.

Is this 'ppc64_rma_size' ?

- k

^ permalink raw reply

* Re: [PATCH 12/15] powerpc/book3e: Use way 3 for linear mapping bolted entry
From: Kumar Gala @ 2011-04-18 22:27 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Michael Ellerman, Jimi Xenidis, jack, imunsie, linuxppc-dev,
	David Gibson
In-Reply-To: <1303162834.28876.163.camel@pasglop>


On Apr 18, 2011, at 4:40 PM, Benjamin Herrenschmidt wrote:

> On Mon, 2011-04-18 at 07:43 -0500, Kumar Gala wrote:
>> On Apr 15, 2011, at 3:32 AM, Michael Ellerman wrote:
>>=20
>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>=20
>>> An erratum on A2 can lead to the bolted entry we insert for the =
linear
>>> mapping being evicted, to avoid that write the bolted entry to way =
3.
>>>=20
>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
>>> ---
>>> arch/powerpc/kernel/exceptions-64e.S |    5 +++--
>>> 1 files changed, 3 insertions(+), 2 deletions(-)
>>>=20
>>> diff --git a/arch/powerpc/kernel/exceptions-64e.S =
b/arch/powerpc/kernel/exceptions-64e.S
>>> index 5c43063..e6c0926 100644
>>> --- a/arch/powerpc/kernel/exceptions-64e.S
>>> +++ b/arch/powerpc/kernel/exceptions-64e.S
>>> @@ -864,8 +864,9 @@ have_hes:
>>> 	 * that will have to be made dependent on whether we are running =
under
>>> 	 * a hypervisor I suppose.
>>> 	 */
>>> -	ori	r3,r3,MAS0_HES | MAS0_WQ_ALLWAYS
>>> -	mtspr	SPRN_MAS0,r3
>>> +	ori	r11,r3,MAS0_WQ_ALLWAYS
>>> +	oris	r11,r11,MAS0_ESEL(3)@h /* Use way 3: workaround A2 =
erratum 376 */
>>> +	mtspr	SPRN_MAS0,r11
>>> 	lis	r3,(MAS1_VALID | MAS1_IPROT)@h
>>> 	ori	r3,r3,BOOK3E_PAGESZ_1GB << MAS1_TSIZE_SHIFT
>>> 	mtspr	SPRN_MAS1,r3
>>=20
>> Seems like this should have a MMU Feature bit or something for A2.
>=20
> Too early. We haven't detected the CPU and are establishing the =
initial
> TLB entry here.

How about wrapping with CONFIG_PPC_A2

> Any reason why that wouldn't work on something else anyways ?

No, I wasn't paying attention to what this code exactly was (not enough =
context in the diff), I see its our initial setup so not a big deal.  =
Was thinking this was run-time exception handler code.

- k

^ permalink raw reply

* Re: [PATCH 9/14] PM / Blackfin: Use struct syscore_ops instead of sysdevs for PM
From: Rafael J. Wysocki @ 2011-04-18 21:43 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Kevin Hilman, Guan Xuetao, Russell King, Konrad Rzeszutek Wilk,
	Greg KH, LKML, Ralf Baechle, Jeremy Fitzhardinge, Ben Dooks,
	Jiri Kosina, Kay Sievers, Linux PM mailing list, linux-omap,
	linuxppc-dev, Hans-Christian Egtvedt, linux-arm-kernel
In-Reply-To: <BANLkTi=BRXtsG0wK6SbK-6L-xzwMccR3eQ@mail.gmail.com>

On Monday, April 18, 2011, Mike Frysinger wrote:
> On Sun, Apr 17, 2011 at 17:11, Rafael J. Wysocki wrote:
> > Convert some Blackfin architecture's code to using struct syscore_ops
> > objects for power management instead of sysdev classes and sysdevs.
> >
> > This simplifies the code and reduces the kernel's memory footprint.
> > It also is necessary for removing sysdevs from the kernel entirely in
> > the future.
> 
> looks straight forward enough ...
> Acked-by: Mike Frysinger <vapier@gentoo.org>
> 
> > +static struct syscore_ops nmi_syscore_ops = {
> >        .resume         = nmi_wdt_resume,
> >        .suspend        = nmi_wdt_suspend,
> >  };
> 
> a bit sad this couldnt be made const

Well, that would trigger a compiler warning from register_syscore_ops().

However, I'm going to make that change change everywhere at once when all of
the conversions have been made, since it looks like we're only going to have
static syscore_ops.

Thanks,
Rafael

^ 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