* Re: Using CONFIG_PHYSICAL_START
From: Meador Inge @ 2011-02-16 20:02 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20110216132403.3466a83e@schlenkerla>
On 02/16/2011 01:24 PM, Scott Wood wrote:
> On Wed, 16 Feb 2011 12:00:25 -0600
> Meador Inge<meador_inge@mentor.com> wrote:
>
>> Hi Kumar,
>>
>> Quick question about the support for booting at a non-zero base address
>> (as committed here:
>> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=37dd2badcfcec35f5e21a0926968d77a404f03c3).
>> Is booting from a non-zero address as simple as changing
>> "CONFIG_PHYSICAL_START" (assuming it meets the alignment constraints, of
>> course)?
>
> Another option is to turn on CONFIG_RELOCATABLE. Note that you'll still
> have the same alignment constraints; it doesn't generate a truly relocatable
> binary (the effective addresses are fixed). But you don't have to specify
> the physical address at compile-time. This allows you to use the same
> kernel image for multiple AMP partitions.
>
>> For example, I want to boot from a non-zero address on the P1022DS. I
>> should just be able to change "CONFIG_PHYSICAL_START" to, say,
>> 0x08000000, and it should work, right? Any other bits that need to be
>> done (i.e. U-Boot or device tree magic)?
>
> You'll want the memory node adjusted for your restricted address range
> (I'm assuming that this is why you want to start at non-zero, and that
> you're not trying to have the kernel be located in the middle of its
> partition).
>
> There are some special u-boot variables (bootm_low/bootm_size) that govern
> placement of the kernel, fdt, etc.
Thanks Scott. I should have looked in the u-boot docs. There are very
clear instructions on how to setup an AMP environment in
'.../doc/README.mpc8572ds'
(http://git.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=blob;f=doc/README.mpc8572ds;h=06dab596bea52ab8d8c2ba89d86f793cc4881ccb;hb=HEAD).
> -Scott
>
>
--
Meador Inge | meador_inge AT mentor.com
Mentor Embedded | http://www.mentor.com/embedded-software
^ permalink raw reply
* Re: Using CONFIG_PHYSICAL_START
From: Scott Wood @ 2011-02-16 19:24 UTC (permalink / raw)
To: Meador Inge; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <4D5C10B9.9010702@mentor.com>
On Wed, 16 Feb 2011 12:00:25 -0600
Meador Inge <meador_inge@mentor.com> wrote:
> Hi Kumar,
>
> Quick question about the support for booting at a non-zero base address
> (as committed here:
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=37dd2badcfcec35f5e21a0926968d77a404f03c3).
> Is booting from a non-zero address as simple as changing
> "CONFIG_PHYSICAL_START" (assuming it meets the alignment constraints, of
> course)?
Another option is to turn on CONFIG_RELOCATABLE. Note that you'll still
have the same alignment constraints; it doesn't generate a truly relocatable
binary (the effective addresses are fixed). But you don't have to specify
the physical address at compile-time. This allows you to use the same
kernel image for multiple AMP partitions.
> For example, I want to boot from a non-zero address on the P1022DS. I
> should just be able to change "CONFIG_PHYSICAL_START" to, say,
> 0x08000000, and it should work, right? Any other bits that need to be
> done (i.e. U-Boot or device tree magic)?
You'll want the memory node adjusted for your restricted address range
(I'm assuming that this is why you want to start at non-zero, and that
you're not trying to have the kernel be located in the middle of its
partition).
There are some special u-boot variables (bootm_low/bootm_size) that govern
placement of the kernel, fdt, etc.
-Scott
^ permalink raw reply
* Using CONFIG_PHYSICAL_START
From: Meador Inge @ 2011-02-16 18:00 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev@lists.ozlabs.org
Hi Kumar,
Quick question about the support for booting at a non-zero base address
(as committed here:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=37dd2badcfcec35f5e21a0926968d77a404f03c3).
Is booting from a non-zero address as simple as changing
"CONFIG_PHYSICAL_START" (assuming it meets the alignment constraints, of
course)?
For example, I want to boot from a non-zero address on the P1022DS. I
should just be able to change "CONFIG_PHYSICAL_START" to, say,
0x08000000, and it should work, right? Any other bits that need to be
done (i.e. U-Boot or device tree magic)?
--
Meador Inge | meador_inge AT mentor.com
Mentor Embedded | http://www.mentor.com/embedded-software
^ permalink raw reply
* Bug in arch/powerpc/sysdev/fsl_gtm.c
From: Jean-Denis Boyer @ 2011-02-16 14:59 UTC (permalink / raw)
To: 'Anton Vorontsov',
'linuxppc-dev@lists.ozlabs.org'
[-- Attachment #1: Type: text/plain, Size: 1125 bytes --]
Hi.
There is a bug in the function gtm_set_ref_timer16.
When called, it correctly sets the requested timer,
but the other timer that shares the register GTCFR is reset.
The parameter 'clear' passed to macro clrsetbits_8 should not be
a bitwise complement, since the macro already complements it.
Here is a patch that should fix this issue.
--- linux-2.6.35.11/arch/powerpc/sysdev/fsl_gtm.c
+++ linux/arch/powerpc/sysdev/fsl_gtm.c
@@ -203,13 +203,10 @@
spin_lock_irqsave(>m->lock, flags);
/*
- * Properly reset timers: stop, reset, set up prescalers, reference
+ * Properly set timers: stop, set up prescalers, reference
* value and clear event register.
*/
- clrsetbits_8(tmr->gtcfr, ~(GTCFR_STP(num) | GTCFR_RST(num)),
- GTCFR_STP(num) | GTCFR_RST(num));
-
- setbits8(tmr->gtcfr, GTCFR_STP(num));
+ setbits8(tmr->gtcfr, GTCFR_STP(num) | GTCFR_RST(num));
if (tmr->gtpsr)
out_be16(tmr->gtpsr, psr);
Regards,
Jean-Denis Boyer, Eng.
Media5 Corporation - Mediatrix, M5T, Media5Boss
4229 Garlock Street, Sherbrooke (Québec), J1L 2C8, CANADA
(819)829-8749 x5241
[-- Attachment #2: fsl_gtm.patch --]
[-- Type: application/octet-stream, Size: 585 bytes --]
--- linux-2.6.35.11/arch/powerpc/sysdev/fsl_gtm.c
+++ linux/arch/powerpc/sysdev/fsl_gtm.c
@@ -203,13 +203,10 @@
spin_lock_irqsave(>m->lock, flags);
/*
- * Properly reset timers: stop, reset, set up prescalers, reference
+ * Properly set timers: stop, set up prescalers, reference
* value and clear event register.
*/
- clrsetbits_8(tmr->gtcfr, ~(GTCFR_STP(num) | GTCFR_RST(num)),
- GTCFR_STP(num) | GTCFR_RST(num));
-
- setbits8(tmr->gtcfr, GTCFR_STP(num));
+ setbits8(tmr->gtcfr, GTCFR_STP(num) | GTCFR_RST(num));
if (tmr->gtpsr)
out_be16(tmr->gtpsr, psr);
^ permalink raw reply
* Re: Question about flash allocation
From: Josh Boyer @ 2011-02-16 11:26 UTC (permalink / raw)
To: Mitsutaka Amano; +Cc: linuxppc-dev
In-Reply-To: <AANLkTimW1yZ+H=X+j=TYMM8-zZx5XaEPczek05KtKKxN@mail.gmail.com>
On Tue, Feb 15, 2011 at 11:28 PM, Mitsutaka Amano
<mitsutaka.amano@gmail.com> wrote:
> Hi,
>
> Why does CFI(or other flash memory) have to alloc amount of flash
> memory size to the vmalloc area(such as PHYSMAP or PHYSMAP_OF)?
> I wondered other devices seems to not allocating(e.g, most NAND flash,
> flash on ARM, MIPS and so on). I don't know difference between my
> board and other. Doesn't other devices need to allocate to vmalloc?
You asked this on the MTD mailing list already:
http://lists.infradead.org/pipermail/linux-mtd/2011-January/033787.html
The answers aren't going to change based on which list you ask.
As for the last question, the memory space for modules are in vmalloc
space, and any HW resources they ioremap are as well. However for
true memory allocations, most device drivers use kmalloc. Some use
vmalloc for large buffers that don't need to be physically contiguous
but there aren't that many.
josh
^ permalink raw reply
* Re: [RFC] Inter-processor Mailboxes Drivers
From: Hiroshi DOYU @ 2011-02-16 6:22 UTC (permalink / raw)
To: Hollis_Blanchard
Cc: meador_inge, jamie, linuxppc-dev, openmcapi-dev, linux-arm-kernel
In-Reply-To: <DD7A9A95166BF4418C4C1EB2033B6EE2038FAAF0@na3-mail.mgc.mentorg.com>
From: "ext Blanchard, Hollis" <Hollis_Blanchard@mentor.com>
Subject: Re: [RFC] Inter-processor Mailboxes Drivers
Date: Tue, 15 Feb 2011 15:38:25 -0800
> On 02/15/2011 01:58 PM, Meador Inge wrote:
>> On 02/14/2011 04:01 AM, Jamie Iles wrote:
>>> On Fri, Feb 11, 2011 at 03:19:51PM -0600, Meador Inge wrote:
>>>> 1. Hardware specific bits somewhere under '.../arch/*'. Drivers
>>>> for the MPIC message registers on Power and OMAP4 mailboxes,
>>>> for
>>>> example.
>>>> 2. A higher level driver under '.../drivers/mailbox/*'. That the
>>>> pieces in (1) would register with. This piece would expose the
>>>> main kernel API.
>>>> 3. Userspace interfaces for accessing the mailboxes. A
>>>> '/dev/mailbox1', '/dev/mailbox2', etc... mapping, for example.
>>>
>>> How about using virtio for all of this and having the mailbox as a
>>> notification/message passing driver for the virtio backend? There are
>>> already virtio console and network drivers that could be useful for the
>>> userspace part of it. drivers/virtio/virtio_ring.c might be a good
>>> starting point if you thought there was some mileage in this approach.
>>
>> To be honest, I am not that familiar with 'virtio', but I will take a
>> look. Thanks for the pointer. Maybe Hollis can speak to this idea more.
> My opinion is that virtio is (over?) complicated.
Considering the case of omap mailbox H/W, it is just a simple one way
4 slot x 32bit H/W FIFO, I also may think that this may be a bit too
much...
> I've looked into it in the past, and I'm definitely open to using it if
> somebody can demonstrate how easy it is, but adopting it wouldn't have
> helped OpenMCAPI with our use cases, and would have incurred extra pain,
> so we didn't.
>
> Hollis Blanchard
> Mentor Graphics, Embedded Systems Division
>
^ permalink raw reply
* Per process DSCR + somefixes (try#3)
From: Alexey Kardashevskiy @ 2011-02-16 5:38 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 532 bytes --]
step1: http://patchwork.ozlabs.org/patch/71489/
step2: http://patchwork.ozlabs.org/patch/81423/
In step2 I defined sysfs node as:
static SYSDEV_ATTR(dscr_default, 0600, show_dscr_default,
store_dscr_default);
and it caused problems with rhel6.
Now it is:
static SYSDEV_CLASS_ATTR(dscr_default, 0600, show_dscr_default,
store_dscr_default);
It works now on both 2.6.32 and 2.6.36 but is that correct?
--
Alexey Kardashevskiy
IBM OzLabs, LTC Team
e-mail/sametime: aik@au1.ibm.com
notes: Alexey Kardashevskiy/Australia/IBM
[-- Attachment #2: dscr.2.patch --]
[-- Type: text/x-patch, Size: 7077 bytes --]
diff -Nuar ../linus-before-dscr/arch/powerpc//include/asm/emulated_ops.h linus-dscr/arch/powerpc//include/asm/emulated_ops.h
--- ../linus-before-dscr/arch/powerpc//include/asm/emulated_ops.h 2010-10-27 14:25:45.000000000 +1100
+++ linus-dscr/arch/powerpc//include/asm/emulated_ops.h 2011-01-04 12:53:50.000000000 +1100
@@ -52,6 +52,10 @@
#ifdef CONFIG_VSX
struct ppc_emulated_entry vsx;
#endif
+#ifdef CONFIG_PPC64
+ struct ppc_emulated_entry mfdscr;
+ struct ppc_emulated_entry mtdscr;
+#endif
} ppc_emulated;
extern u32 ppc_warn_emulated;
diff -Nuar ../linus-before-dscr/arch/powerpc//include/asm/ppc-opcode.h linus-dscr/arch/powerpc//include/asm/ppc-opcode.h
--- ../linus-before-dscr/arch/powerpc//include/asm/ppc-opcode.h 2010-10-27 14:25:45.000000000 +1100
+++ linus-dscr/arch/powerpc//include/asm/ppc-opcode.h 2011-01-04 12:53:50.000000000 +1100
@@ -39,6 +39,10 @@
#define PPC_INST_RFCI 0x4c000066
#define PPC_INST_RFDI 0x4c00004e
#define PPC_INST_RFMCI 0x4c00004c
+#define PPC_INST_MFSPR_DSCR 0x7c1102a6
+#define PPC_INST_MFSPR_DSCR_MASK 0xfc1fffff
+#define PPC_INST_MTSPR_DSCR 0x7c1103a6
+#define PPC_INST_MTSPR_DSCR_MASK 0xfc1fffff
#define PPC_INST_STRING 0x7c00042a
#define PPC_INST_STRING_MASK 0xfc0007fe
diff -Nuar ../linus-before-dscr/arch/powerpc//include/asm/processor.h linus-dscr/arch/powerpc//include/asm/processor.h
--- ../linus-before-dscr/arch/powerpc//include/asm/processor.h 2010-10-27 14:25:45.000000000 +1100
+++ linus-dscr/arch/powerpc//include/asm/processor.h 2011-02-02 10:36:21.000000000 +1100
@@ -240,6 +240,10 @@
#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
void* kvm_shadow_vcpu; /* KVM internal data */
#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */
+#ifdef CONFIG_PPC64
+ unsigned long dscr;
+ int dscr_inherit;
+#endif
};
#define ARCH_MIN_TASKALIGN 16
diff -Nuar ../linus-before-dscr/arch/powerpc//kernel/asm-offsets.c linus-dscr/arch/powerpc//kernel/asm-offsets.c
--- ../linus-before-dscr/arch/powerpc//kernel/asm-offsets.c 2010-10-27 14:25:45.000000000 +1100
+++ linus-dscr/arch/powerpc//kernel/asm-offsets.c 2011-01-04 12:53:50.000000000 +1100
@@ -74,6 +74,7 @@
DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
DEFINE(SIGSEGV, SIGSEGV);
DEFINE(NMI_MASK, NMI_MASK);
+ DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr));
#else
DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));
#endif /* CONFIG_PPC64 */
diff -Nuar ../linus-before-dscr/arch/powerpc//kernel/entry_64.S linus-dscr/arch/powerpc//kernel/entry_64.S
--- ../linus-before-dscr/arch/powerpc//kernel/entry_64.S 2010-10-27 14:25:45.000000000 +1100
+++ linus-dscr/arch/powerpc//kernel/entry_64.S 2011-02-02 06:13:17.000000000 +1100
@@ -421,6 +421,12 @@
std r24,THREAD_VRSAVE(r3)
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_PPC64
+BEGIN_FTR_SECTION
+ mfspr r25,SPRN_DSCR
+ std r25,THREAD_DSCR(r3)
+END_FTR_SECTION_IFSET(CPU_FTR_DSCR)
+#endif
and. r0,r0,r22
beq+ 1f
andc r22,r22,r0
@@ -522,6 +528,15 @@
mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_PPC64
+BEGIN_FTR_SECTION
+ ld r0,THREAD_DSCR(r4)
+ cmpd r0,r25
+ beq 1f
+ mtspr SPRN_DSCR,r0
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_DSCR)
+#endif
/* r3-r13 are destroyed -- Cort */
REST_8GPRS(14, r1)
diff -Nuar ../linus-before-dscr/arch/powerpc//kernel/process.c linus-dscr/arch/powerpc//kernel/process.c
--- ../linus-before-dscr/arch/powerpc//kernel/process.c 2010-10-27 14:25:45.000000000 +1100
+++ linus-dscr/arch/powerpc//kernel/process.c 2011-02-16 16:27:37.000000000 +1100
@@ -700,6 +700,8 @@
/*
* Copy a thread..
*/
+extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
+
int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused, struct task_struct *p,
struct pt_regs *regs)
@@ -767,6 +769,20 @@
p->thread.ksp_vsid = sp_vsid;
}
#endif /* CONFIG_PPC_STD_MMU_64 */
+#ifdef CONFIG_PPC64
+ if (cpu_has_feature(CPU_FTR_DSCR)) {
+ if (current->thread.dscr_inherit) {
+ p->thread.dscr_inherit = 1;
+ p->thread.dscr = current->thread.dscr;
+ } else if (0 != dscr_default) {
+ p->thread.dscr_inherit = 1;
+ p->thread.dscr = dscr_default;
+ } else {
+ p->thread.dscr_inherit = 0;
+ p->thread.dscr = 0;
+ }
+ }
+#endif
/*
* The PPC64 ABI makes use of a TOC to contain function
diff -Nuar ../linus-before-dscr/arch/powerpc//kernel/sysfs.c linus-dscr/arch/powerpc//kernel/sysfs.c
--- ../linus-before-dscr/arch/powerpc//kernel/sysfs.c 2010-10-27 14:25:45.000000000 +1100
+++ linus-dscr/arch/powerpc//kernel/sysfs.c 2011-02-16 16:27:58.000000000 +1100
@@ -182,6 +182,41 @@
static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL);
static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr);
static SYSDEV_ATTR(purr, 0600, show_purr, store_purr);
+
+unsigned long dscr_default = 0;
+EXPORT_SYMBOL(dscr_default);
+
+static ssize_t show_dscr_default(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%lx\n", dscr_default);
+}
+
+static ssize_t __used store_dscr_default(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr, const char *buf,
+ size_t count)
+{
+ unsigned long val;
+ int ret = 0;
+
+ ret = sscanf(buf, "%lx", &val);
+ if (ret != 1)
+ return -EINVAL;
+ dscr_default = val;
+
+ return count;
+}
+
+static SYSDEV_CLASS_ATTR(dscr_default, 0600,
+ show_dscr_default, store_dscr_default);
+
+static void sysfs_create_dscr_default(void)
+{
+ int err = 0;
+ if (cpu_has_feature(CPU_FTR_DSCR))
+ err = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+ &attr_dscr_default.attr);
+}
#endif /* CONFIG_PPC64 */
#ifdef HAS_PPC_PMC_PA6T
@@ -617,6 +652,9 @@
if (cpu_online(cpu))
register_cpu_online(cpu);
}
+#ifdef CONFIG_PPC64
+ sysfs_create_dscr_default();
+#endif /* CONFIG_PPC64 */
return 0;
}
diff -Nuar ../linus-before-dscr/arch/powerpc//kernel/traps.c linus-dscr/arch/powerpc//kernel/traps.c
--- ../linus-before-dscr/arch/powerpc//kernel/traps.c 2010-10-27 14:25:45.000000000 +1100
+++ linus-dscr/arch/powerpc//kernel/traps.c 2011-02-16 16:00:18.000000000 +1100
@@ -919,6 +919,26 @@
return emulate_isel(regs, instword);
}
+#ifdef CONFIG_PPC64
+ /* Emulate the mfspr rD, DSCR. */
+ if (((instword & PPC_INST_MFSPR_DSCR_MASK) == PPC_INST_MFSPR_DSCR) &&
+ cpu_has_feature(CPU_FTR_DSCR)) {
+ PPC_WARN_EMULATED(mfdscr, regs);
+ rd = (instword >> 21) & 0x1f;
+ regs->gpr[rd] = mfspr(SPRN_DSCR);
+ return 0;
+ }
+ /* Emulate the mtspr DSCR, rD. */
+ if (((instword & PPC_INST_MTSPR_DSCR_MASK) == PPC_INST_MTSPR_DSCR) &&
+ cpu_has_feature(CPU_FTR_DSCR)) {
+ PPC_WARN_EMULATED(mtdscr, regs);
+ rd = (instword >> 21) & 0x1f;
+ mtspr(SPRN_DSCR, regs->gpr[rd]);
+ current->thread.dscr_inherit = 1;
+ return 0;
+ }
+#endif
+
return -EINVAL;
}
@@ -1516,6 +1536,10 @@
#ifdef CONFIG_VSX
WARN_EMULATED_SETUP(vsx),
#endif
+#ifdef CONFIG_PPC64
+ WARN_EMULATED_SETUP(mfdscr),
+ WARN_EMULATED_SETUP(mtdscr),
+#endif
};
u32 ppc_warn_emulated;
^ permalink raw reply
* Question about flash allocation
From: Mitsutaka Amano @ 2011-02-16 4:28 UTC (permalink / raw)
To: linuxppc-dev
Hi,
Why does CFI(or other flash memory) have to alloc amount of flash
memory size to the vmalloc area(such as PHYSMAP or PHYSMAP_OF)?
I wondered other devices seems to not allocating(e.g, most NAND flash,
flash on ARM, MIPS and so on). I don't know difference between my
board and other. Doesn't other devices need to allocate to vmalloc?
Thanks,
Mitsutaka
^ permalink raw reply
* Re: FSL USB in 2.6.37
From: Gary Thomas @ 2011-02-16 0:25 UTC (permalink / raw)
To: Anatolij Gustschin; +Cc: Linux PPC Development
In-Reply-To: <20110215191856.67f8f0c4@wker>
On 02/15/2011 11:18 AM, Anatolij Gustschin wrote:
> On Tue, 15 Feb 2011 10:47:17 -0700
> Gary Thomas<gary@mlbassoc.com> wrote:
>
>> I'm trying to get my platform support working in mainline
>> 2.6.37. I have a MPC8379 which is working well in 2.6.32.
>>
>> When I just move my platform to the new kernel, everything
>> works except for USB host mode. Nothing special about my
>> platform - it's pretty much like the FSL eval boards (as
>> far as this part is concerned). I can see it start up,
>> claim to power up the internal hub, but I never see the
>> state change interrupt from the hub.
>>
>> Are there any known gotchas here? Any ideas?
>
> Does this patch [1] help?
>
> [1] http://patchwork.ozlabs.org/patch/78260/
Indeed, it fixes my problem :-)
Thanks
--
------------------------------------------------------------
Gary Thomas | Consulting for the
MLB Associates | Embedded world
------------------------------------------------------------
^ permalink raw reply
* Re: [RFC] Inter-processor Mailboxes Drivers
From: Blanchard, Hollis @ 2011-02-15 23:38 UTC (permalink / raw)
To: Inge, Meador
Cc: openmcapi-dev, Jamie Iles, Hiroshi DOYU, linuxppc-dev,
linux-arm-kernel
In-Reply-To: <4D5AF712.3080509@mentor.com>
On 02/15/2011 01:58 PM, Meador Inge wrote:
> On 02/14/2011 04:01 AM, Jamie Iles wrote:
>> On Fri, Feb 11, 2011 at 03:19:51PM -0600, Meador Inge wrote:
>>> 1. Hardware specific bits somewhere under '.../arch/*'. =
Drivers
>>> for the MPIC message registers on Power and OMAP4 mailboxes, =
>>> for
>>> example.
>>> 2. A higher level driver under '.../drivers/mailbox/*'. That =
the
>>> pieces in (1) would register with. This piece would expose =
the
>>> main kernel API.
>>> 3. Userspace interfaces for accessing the mailboxes. A
>>> '/dev/mailbox1', '/dev/mailbox2', etc... mapping, for =
example.
>>
>> How about using virtio for all of this and having the mailbox as a
>> notification/message passing driver for the virtio backend? There =
are
>> already virtio console and network drivers that could be useful for =
the
>> userspace part of it. drivers/virtio/virtio_ring.c might be a good
>> starting point if you thought there was some mileage in this =
approach.
>
> To be honest, I am not that familiar with 'virtio', but I will take a=20
> look. Thanks for the pointer. Maybe Hollis can speak to this idea =
more.
My opinion is that virtio is (over?) complicated.
I've looked into it in the past, and I'm definitely open to using it if=20
somebody can demonstrate how easy it is, but adopting it wouldn't have=20
helped OpenMCAPI with our use cases, and would have incurred extra pain, =
so we didn't.
Hollis Blanchard
Mentor Graphics, Embedded Systems Division
^ permalink raw reply
* Re: [RFC] Inter-processor Mailboxes Drivers
From: Meador Inge @ 2011-02-15 21:58 UTC (permalink / raw)
To: Jamie Iles
Cc: openmcapi-dev, Blanchard, Hollis, Hiroshi DOYU, linuxppc-dev,
linux-arm-kernel
In-Reply-To: <20110214100104.GC4371@pulham.picochip.com>
On 02/14/2011 04:01 AM, Jamie Iles wrote:
> On Fri, Feb 11, 2011 at 03:19:51PM -0600, Meador Inge wrote:
>> 1. Hardware specific bits somewhere under '.../arch/*'. Drivers
>> for the MPIC message registers on Power and OMAP4 mailboxes, for
>> example.
>> 2. A higher level driver under '.../drivers/mailbox/*'. That the
>> pieces in (1) would register with. This piece would expose the
>> main kernel API.
>> 3. Userspace interfaces for accessing the mailboxes. A
>> '/dev/mailbox1', '/dev/mailbox2', etc... mapping, for example.
>
> How about using virtio for all of this and having the mailbox as a
> notification/message passing driver for the virtio backend? There are
> already virtio console and network drivers that could be useful for the
> userspace part of it. drivers/virtio/virtio_ring.c might be a good
> starting point if you thought there was some mileage in this approach.
To be honest, I am not that familiar with 'virtio', but I will take a
look. Thanks for the pointer. Maybe Hollis can speak to this idea more.
> Jamie
>
--
Meador Inge | meador_inge AT mentor.com
Mentor Embedded | http://www.mentor.com/embedded-software
^ permalink raw reply
* Re: [PATCH] powerpc: irq_data conversion
From: Grant Likely @ 2011-02-15 20:06 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: tglx, linuxppc-dev
In-Reply-To: <20110215060158.GG1727@mail.wantstofly.org>
On Mon, Feb 14, 2011 at 11:01 PM, Lennert Buytenhek
<buytenh@wantstofly.org> wrote:
> On Mon, Feb 14, 2011 at 11:07:15AM -0700, Grant Likely wrote:
>
>> > This patch converts powerpc over to the new irq_data based irq_chip
>> > functions, as was done earlier for ARM and some other architectures.
>> >
>> > struct irq_data is described here:
>> >
>> > =A0 =A0 http://git.kernel.org/?p=3Dlinux/kernel/git/torvalds/linux-2.6=
.git;a=3Dcommit;h=3Dff7dcd44dd446db2c3e13bdedf2d52b8e0127f16
>> >
>> > The new irq_chip functions are described here:
>> >
>> > =A0 =A0 http://git.kernel.org/?p=3Dlinux/kernel/git/torvalds/linux-2.6=
.git;a=3Dcommit;h=3Df8822657e799b02c55556c99a601261e207a299d
>> >
>> > As I don't have powerpc hardware myself, this hasn't been well-tested
>> > at all -- build and run-time testing would be much appreciated.
>>
>> Apply warning:
>>
>> /home/grant/hacking/linux-2.6/.git/rebase-apply/patch:3470: space before=
tab in indent.
>> =A0 =A0 =A0 .irq_mask_ack =A0 =3D uic_mask_ack_irq,
>> warning: 1 line adds whitespace errors.
>
> The original uic.c already had the space there, but yes, there's no
> reason not to fix that while we're at it -- thanks.
Particularly when you're touching that particular line. :-)
More errors with ppc64_defconfig:
02/15 12:55:39 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/sysdev/mpic.c: In
function 'mpic_from_ipi': 02/15 12:55:39 ERROR|base_utils:0106|
[stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/sysdev/mpic.c:6=
41:
error: 'struct irq_desc' has no member named 'chip_data' 02/15
12:55:39 ERROR|base_utils:0106| [stderr] make[2]: ***
[arch/powerpc/sysdev/mpic.o] Error 1
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:
In function 'ps3_virq_setup':
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:205:
error: passing argument 1 of 'ps3_chip_mask' makes pointer from
integer without a cast
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:102:
note: expected 'struct irq_data *' but argument is of type 'unsigned
int'
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:
In function 'ps3_irq_plug_destroy':
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:299:
error: passing argument 1 of 'ps3_chip_mask' makes pointer from
integer without a cast
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:102:
note: expected 'struct irq_data *' but argument is of type 'unsigned
int'
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:
In function 'ps3_event_receive_port_destroy':
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:360:
error: passing argument 1 of 'ps3_chip_mask' makes pointer from
integer without a cast
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:102:
note: expected 'struct irq_data *' but argument is of type 'unsigned
int'
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:
In function 'ps3_io_irq_destroy':
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:495:
error: passing argument 1 of 'ps3_chip_mask' makes pointer from
integer without a cast
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:102:
note: expected 'struct irq_data *' but argument is of type 'unsigned
int'
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:
In function 'ps3_vuart_irq_destroy':
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:556:
error: passing argument 1 of 'ps3_chip_mask' makes pointer from
integer without a cast
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:102:
note: expected 'struct irq_data *' but argument is of type 'unsigned
int'
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:
In function 'ps3_spe_irq_destroy':
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:608:
error: passing argument 1 of 'ps3_chip_mask' makes pointer from
integer without a cast
02/15 12:55:58 ERROR|base_utils:0106| [stderr]
/home/autotest/data/kernelcross/linux/arch/powerpc/platforms/ps3/interrupt.=
c:102:
note: expected 'struct irq_data *' but argument is of type 'unsigned
int'
02/15 12:55:58 ERROR|base_utils:0106| [stderr] make[3]: ***
[arch/powerpc/platforms/ps3/interrupt.o] Error 1
Also running it through the ozlabs build tester again:
http://kisskb.ellerman.id.au/kisskb/branch/13/
Results should be available there sometime in the next 6-12 hours
g.
>
>
> diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platfor=
ms/pasemi/setup.c
> index f372ec1..a6067b3 100644
> --- a/arch/powerpc/platforms/pasemi/setup.c
> +++ b/arch/powerpc/platforms/pasemi/setup.c
> @@ -240,7 +240,7 @@ static __init void pas_init_IRQ(void)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0nmi_virq =3D irq_create_mapping(NULL, *nmi=
prop);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mpic_irq_set_priority(nmi_virq, 15);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISIN=
G);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 mpic_unmask_irq(nmi_virq);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 mpic_unmask_irq(irq_get_irq_data(nmi_virq))=
;
> =A0 =A0 =A0 =A0}
>
> =A0 =A0 =A0 =A0of_node_put(mpic_node);
> @@ -266,7 +266,7 @@ static int pas_machine_check_handler(struct pt_regs *=
regs)
> =A0 =A0 =A0 =A0if (nmi_virq !=3D NO_IRQ && mpic_get_mcirq() =3D=3D nmi_vi=
rq) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0printk(KERN_ERR "NMI delivered\n");
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0debugger(regs);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 mpic_end_irq(nmi_virq);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 mpic_end_irq(irq_get_irq_data(nmi_virq));
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto out;
> =A0 =A0 =A0 =A0}
>
>
>> I'm running it through the ozlabs build tester:
>>
>> http://kisskb.ellerman.id.au/kisskb/branch/13/
>>
>> Results should be available there sometime in the next 6-12 hours
>
> Great, thanks.
>
>
> thanks,
> Lennert
>
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: FSL USB in 2.6.37
From: Anatolij Gustschin @ 2011-02-15 18:18 UTC (permalink / raw)
To: Gary Thomas; +Cc: Linux PPC Development
In-Reply-To: <4D5ABC25.80104@mlbassoc.com>
On Tue, 15 Feb 2011 10:47:17 -0700
Gary Thomas <gary@mlbassoc.com> wrote:
> I'm trying to get my platform support working in mainline
> 2.6.37. I have a MPC8379 which is working well in 2.6.32.
>
> When I just move my platform to the new kernel, everything
> works except for USB host mode. Nothing special about my
> platform - it's pretty much like the FSL eval boards (as
> far as this part is concerned). I can see it start up,
> claim to power up the internal hub, but I never see the
> state change interrupt from the hub.
>
> Are there any known gotchas here? Any ideas?
Does this patch [1] help?
[1] http://patchwork.ozlabs.org/patch/78260/
^ permalink raw reply
* FSL USB in 2.6.37
From: Gary Thomas @ 2011-02-15 17:47 UTC (permalink / raw)
To: Linux PPC Development
I'm trying to get my platform support working in mainline
2.6.37. I have a MPC8379 which is working well in 2.6.32.
When I just move my platform to the new kernel, everything
works except for USB host mode. Nothing special about my
platform - it's pretty much like the FSL eval boards (as
far as this part is concerned). I can see it start up,
claim to power up the internal hub, but I never see the
state change interrupt from the hub.
Are there any known gotchas here? Any ideas?
Thanks
--
------------------------------------------------------------
Gary Thomas | Consulting for the
MLB Associates | Embedded world
------------------------------------------------------------
^ permalink raw reply
* Please pull 'next' branch of 4xx tree
From: Josh Boyer @ 2011-02-15 14:54 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
Hi Ben,
Please pull the 'next' branch of the 4xx tree. These commits have been
sitting there for a while and I wanted to get them into your branch
before tackling the latest round of 476 stuff from Shaggy.
josh
The following changes since commit 5d7d8072edc11080a7cf6cc37c9f4e61ca1e93c9:
powerpc/pseries: Fix build of topology stuff without CONFIG_NUMA (2011-01-12 10:56:29 +1100)
are available in the git repository at:
ssh://master.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git next
Dave Kleikamp (2):
powerpc/476: define specific cpu table entry DD2 core
powerpc/476: Workaround for PLB6 hang
Rupjyoti Sarmah (1):
powerpc/44x: PHY fixup for USB on canyonlands board
Tirumala Marri (1):
powerpc/44x: Add USB DWC DTS entry to Canyonlands board
arch/powerpc/boot/dts/canyonlands.dts | 24 +++++
arch/powerpc/include/asm/cputable.h | 3 +-
arch/powerpc/kernel/cputable.c | 22 ++++-
arch/powerpc/mm/tlb_nohash_low.S | 35 +++++++
arch/powerpc/platforms/44x/44x.h | 4 +
arch/powerpc/platforms/44x/Kconfig | 1 -
arch/powerpc/platforms/44x/Makefile | 1 +
arch/powerpc/platforms/44x/canyonlands.c | 134 ++++++++++++++++++++++++++++
arch/powerpc/platforms/44x/ppc44x_simple.c | 1 -
9 files changed, 218 insertions(+), 7 deletions(-)
create mode 100644 arch/powerpc/platforms/44x/canyonlands.c
^ permalink raw reply
* Re: [PATCH] powerpc: irq_data conversion
From: Lennert Buytenhek @ 2011-02-15 6:01 UTC (permalink / raw)
To: Grant Likely; +Cc: tglx, linuxppc-dev, glikely
In-Reply-To: <20110214180715.GA30647@angua.secretlab.ca>
On Mon, Feb 14, 2011 at 11:07:15AM -0700, Grant Likely wrote:
> > This patch converts powerpc over to the new irq_data based irq_chip
> > functions, as was done earlier for ARM and some other architectures.
> >
> > struct irq_data is described here:
> >
> > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ff7dcd44dd446db2c3e13bdedf2d52b8e0127f16
> >
> > The new irq_chip functions are described here:
> >
> > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f8822657e799b02c55556c99a601261e207a299d
> >
> > As I don't have powerpc hardware myself, this hasn't been well-tested
> > at all -- build and run-time testing would be much appreciated.
>
> Apply warning:
>
> /home/grant/hacking/linux-2.6/.git/rebase-apply/patch:3470: space before tab in indent.
> .irq_mask_ack = uic_mask_ack_irq,
> warning: 1 line adds whitespace errors.
The original uic.c already had the space there, but yes, there's no
reason not to fix that while we're at it -- thanks.
> It seems to work fine on my ppc32 MPC5200 based Lite5200 board.
>
> Got a build failure from my limited build farm:
>
> 02/14 10:38:57 ERROR|base_utils:0106| [stderr] cc1: warnings being treated as errors
> 02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/platforms/pasemi/setup.c: In function 'pas_init_IRQ':
> 02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/platforms/pasemi/setup.c:243: error: passing argument 1 of 'mpic_unmask_irq' makes pointer from integer without a cast
> 02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/include/asm/mpic.h:470: note: expected 'struct irq_data *' but argument is of type 'int'
> 02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/platforms/pasemi/setup.c: In function 'pas_machine_check_handler':
> 02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/platforms/pasemi/setup.c:269: error: passing argument 1 of 'mpic_end_irq' makes pointer from integer without a cast
> 02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/include/asm/mpic.h:474: note: expected 'struct irq_data *' but argument is of type 'int'
> 02/14 10:38:57 ERROR|base_utils:0106| [stderr] make[3]: *** [arch/powerpc/platforms/pasemi/setup.o] Error 1
OK, that should be fixed by this:
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index f372ec1..a6067b3 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -240,7 +240,7 @@ static __init void pas_init_IRQ(void)
nmi_virq = irq_create_mapping(NULL, *nmiprop);
mpic_irq_set_priority(nmi_virq, 15);
set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
- mpic_unmask_irq(nmi_virq);
+ mpic_unmask_irq(irq_get_irq_data(nmi_virq));
}
of_node_put(mpic_node);
@@ -266,7 +266,7 @@ static int pas_machine_check_handler(struct pt_regs *regs)
if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
printk(KERN_ERR "NMI delivered\n");
debugger(regs);
- mpic_end_irq(nmi_virq);
+ mpic_end_irq(irq_get_irq_data(nmi_virq));
goto out;
}
> I'm running it through the ozlabs build tester:
>
> http://kisskb.ellerman.id.au/kisskb/branch/13/
>
> Results should be available there sometime in the next 6-12 hours
Great, thanks.
thanks,
Lennert
^ permalink raw reply related
* Re: [PATCH V8 03/10] USB/ppc4xx: Add Synopsys DWC OTG Core InterfaceLayer
From: Greg KH @ 2011-02-15 1:04 UTC (permalink / raw)
To: David Laight
Cc: Tirumala Marri, linux-usb, Alexander Gordeev, Mark Miesfeld,
linuxppc-dev, Fushen Chen
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6D8AC4D@saturn3.aculab.com>
On Mon, Feb 14, 2011 at 08:53:21AM -0000, David Laight wrote:
>
> > > Sorry, I don't understand that. I think u32 is always 32bit
> > > 4byte on all archs. Right?
> >
> > Yes.
> >
> > Use an unsigned long if you want to hold a pointer correctly on all
> > arches.
>
> Although that is true for many systems (and probably all ppc Linux)
> it isn't necessarily true (eg 64 bit Microsoft Windows).
Again, it is true for all Linux architectures. We aren't caring about
any other operating systems here, sorry.
> C99 inttypes.h should define uintptr_t as an unsigned integer
> type that is large enough to hold a (data) pointer.
> I'm not sure if this is defined for the Linux kernel.
uint* aren't to be used within the kernel as they make no sense.
thanks,
greg k-h
^ permalink raw reply
* Re: [RFC] Inter-processor Mailboxes Drivers
From: Blanchard, Hollis @ 2011-02-14 23:05 UTC (permalink / raw)
To: Linus Walleij
Cc: Inge, Meador, openmcapi-dev, Hiroshi DOYU, linuxppc-dev,
linux-arm-kernel
In-Reply-To: <AANLkTin+ZSNHX2iv=XwWCgxy330UJwhkf1T=4BMXZ22s@mail.gmail.com>
On 02/13/2011 01:24 PM, Linus Walleij wrote:
>> > 3. Userspace interfaces for accessing the mailboxes. A
>> > '/dev/mailbox1', '/dev/mailbox2', etc... mapping, for =
example.
> What kind of business does userspace have with directly using
> mailboxes? Enlighten me so I get it... in our system these are
> used by protocols, such as net/caif/* thru drivers/net/caif/*, and
> we have similar kernelspace functionality for Phonet.
>
> CAIF and Phonet on the other hand, have custom openings
> down to the thing that exists on the other end of the mailbox.
> Most of these systems tend to talk some funny protocol that
> is often better handled by the kernel than by any userspace.
>
> So is this for the situation when you have no intermediate
> protocol between your userpace and the other CPU's
> subsystem? Or are you thinking about handling that
> protocol in userspace? That is generally not such a good idea
> for efficiency reasons.
OpenMCAPI (http://openmcapi.org) implements the MCAPI specification,=20
which is a simple application-level communication API that uses shared=20
memory. The API could be layered over any protocol, but was more or less =
designed for simple shared-memory systems, e.g. fixed topology, no=20
retransmission, etc.
Currently, we implement almost all of this as a shared library, plus a=20
very small kernel driver. The only requirements on the kernel are to=20
allow userspace to map the shared memory area, and provide an IPI=20
mechanism (and allow the process to sleep while waiting). Applications=20
sync with each other using normal atomic memory operations.
We're now trying to optimize the transfer of scalars on platforms that=20
provide mailboxes (beyond simple IPIs), which is why we're looking at=20
defining a user-facing API to such hardware.
I'll add that we haven't done serious optimization yet, but the numbers=20
we do have seem reasonable. What are the "efficiency" issues you're=20
worried about?
Hollis Blanchard
Mentor Graphics, Embedded Systems Division
^ permalink raw reply
* Re: [PATCH] powerpc: irq_data conversion
From: Grant Likely @ 2011-02-14 18:07 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: tglx, linuxppc-dev, glikely
In-Reply-To: <20110211125213.GE1240@mail.wantstofly.org>
On Fri, Feb 11, 2011 at 01:52:13PM +0100, Lennert Buytenhek wrote:
> This patch converts powerpc over to the new irq_data based irq_chip
> functions, as was done earlier for ARM and some other architectures.
>
> struct irq_data is described here:
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ff7dcd44dd446db2c3e13bdedf2d52b8e0127f16
>
> The new irq_chip functions are described here:
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f8822657e799b02c55556c99a601261e207a299d
>
> As I don't have powerpc hardware myself, this hasn't been well-tested
> at all -- build and run-time testing would be much appreciated.
Apply warning:
/home/grant/hacking/linux-2.6/.git/rebase-apply/patch:3470: space before tab in indent.
.irq_mask_ack = uic_mask_ack_irq,
warning: 1 line adds whitespace errors.
It seems to work fine on my ppc32 MPC5200 based Lite5200 board.
Got a build failure from my limited build farm:
02/14 10:38:57 ERROR|base_utils:0106| [stderr] cc1: warnings being treated as errors
02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/platforms/pasemi/setup.c: In function 'pas_init_IRQ':
02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/platforms/pasemi/setup.c:243: error: passing argument 1 of 'mpic_unmask_irq' makes pointer from integer without a cast
02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/include/asm/mpic.h:470: note: expected 'struct irq_data *' but argument is of type 'int'
02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/platforms/pasemi/setup.c: In function 'pas_machine_check_handler':
02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/platforms/pasemi/setup.c:269: error: passing argument 1 of 'mpic_end_irq' makes pointer from integer without a cast
02/14 10:38:57 ERROR|base_utils:0106| [stderr] /home/autotest/data/kernelcross/linux/arch/powerpc/include/asm/mpic.h:474: note: expected 'struct irq_data *' but argument is of type 'int'
02/14 10:38:57 ERROR|base_utils:0106| [stderr] make[3]: *** [arch/powerpc/platforms/pasemi/setup.o] Error 1
I'm running it through the ozlabs build tester:
http://kisskb.ellerman.id.au/kisskb/branch/13/
Results should be available there sometime in the next 6-12 hours
g.
>
> Signed-off-by: Lennert Buytenhek <buytenh@secretlab.ca>
> ---
> arch/powerpc/Kconfig | 1 +
> arch/powerpc/include/asm/mpic.h | 6 +-
> arch/powerpc/include/asm/qe_ic.h | 19 ++--
> arch/powerpc/kernel/irq.c | 23 +++--
> arch/powerpc/kernel/machine_kexec.c | 21 ++--
> arch/powerpc/platforms/512x/mpc5121_ads_cpld.c | 14 ++--
> arch/powerpc/platforms/52xx/media5200.c | 21 ++--
> arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 26 +++---
> arch/powerpc/platforms/52xx/mpc52xx_pic.c | 80 +++++++-------
> arch/powerpc/platforms/82xx/pq2ads-pci-pic.c | 27 +++---
> arch/powerpc/platforms/85xx/ksi8560.c | 3 +-
> arch/powerpc/platforms/85xx/mpc85xx_ads.c | 3 +-
> arch/powerpc/platforms/85xx/mpc85xx_ds.c | 3 +-
> arch/powerpc/platforms/85xx/sbc8560.c | 3 +-
> arch/powerpc/platforms/85xx/socrates_fpga_pic.c | 40 ++++----
> arch/powerpc/platforms/85xx/stx_gp3.c | 3 +-
> arch/powerpc/platforms/85xx/tqm85xx.c | 3 +-
> arch/powerpc/platforms/86xx/gef_pic.c | 22 ++--
> arch/powerpc/platforms/86xx/pic.c | 5 +-
> arch/powerpc/platforms/8xx/m8xx_setup.c | 9 ++-
> arch/powerpc/platforms/cell/axon_msi.c | 3 +-
> arch/powerpc/platforms/cell/beat_interrupt.c | 36 +++---
> arch/powerpc/platforms/cell/interrupt.c | 30 +++---
> arch/powerpc/platforms/cell/setup.c | 6 +-
> arch/powerpc/platforms/cell/spider-pic.c | 43 ++++----
> arch/powerpc/platforms/chrp/setup.c | 5 +-
> arch/powerpc/platforms/embedded6xx/flipper-pic.c | 32 +++---
> arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 41 ++++----
> arch/powerpc/platforms/iseries/irq.c | 43 ++++----
> arch/powerpc/platforms/powermac/pic.c | 48 +++++----
> arch/powerpc/platforms/ps3/interrupt.c | 28 +++---
> arch/powerpc/platforms/pseries/setup.c | 5 +-
> arch/powerpc/platforms/pseries/xics.c | 75 +++++++------
> arch/powerpc/sysdev/cpm1.c | 18 ++--
> arch/powerpc/sysdev/cpm2_pic.c | 32 +++---
> arch/powerpc/sysdev/fsl_msi.c | 19 ++--
> arch/powerpc/sysdev/i8259.c | 42 ++++----
> arch/powerpc/sysdev/ipic.c | 54 +++++-----
> arch/powerpc/sysdev/mpc8xx_pic.c | 32 +++---
> arch/powerpc/sysdev/mpc8xxx_gpio.c | 42 ++++----
> arch/powerpc/sysdev/mpic.c | 127 +++++++++++-----------
> arch/powerpc/sysdev/mpic.h | 5 +-
> arch/powerpc/sysdev/mpic_pasemi_msi.c | 18 ++--
> arch/powerpc/sysdev/mpic_u3msi.c | 18 ++--
> arch/powerpc/sysdev/mv64x60_pic.c | 46 ++++----
> arch/powerpc/sysdev/qe_lib/qe_ic.c | 20 ++--
> arch/powerpc/sysdev/tsi108_pci.c | 41 ++++----
> arch/powerpc/sysdev/uic.c | 59 +++++-----
> arch/powerpc/sysdev/xilinx_intc.c | 48 +++++----
> 49 files changed, 705 insertions(+), 643 deletions(-)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 7d69e9b..71ba047 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -134,6 +134,7 @@ config PPC
> select HAVE_GENERIC_HARDIRQS
> select HAVE_SPARSE_IRQ
> select IRQ_PER_CPU
> + select GENERIC_HARDIRQS_NO_DEPRECATED
>
> config EARLY_PRINTK
> bool
> diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
> index e000cce..946ec49 100644
> --- a/arch/powerpc/include/asm/mpic.h
> +++ b/arch/powerpc/include/asm/mpic.h
> @@ -467,11 +467,11 @@ extern void mpic_request_ipis(void);
> void smp_mpic_message_pass(int target, int msg);
>
> /* Unmask a specific virq */
> -extern void mpic_unmask_irq(unsigned int irq);
> +extern void mpic_unmask_irq(struct irq_data *d);
> /* Mask a specific virq */
> -extern void mpic_mask_irq(unsigned int irq);
> +extern void mpic_mask_irq(struct irq_data *d);
> /* EOI a specific virq */
> -extern void mpic_end_irq(unsigned int irq);
> +extern void mpic_end_irq(struct irq_data *d);
>
> /* Fetch interrupt from a given mpic */
> extern unsigned int mpic_get_one_irq(struct mpic *mpic);
> diff --git a/arch/powerpc/include/asm/qe_ic.h b/arch/powerpc/include/asm/qe_ic.h
> index cf51966..9e2cb20 100644
> --- a/arch/powerpc/include/asm/qe_ic.h
> +++ b/arch/powerpc/include/asm/qe_ic.h
> @@ -81,7 +81,7 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high);
> static inline void qe_ic_cascade_low_ipic(unsigned int irq,
> struct irq_desc *desc)
> {
> - struct qe_ic *qe_ic = desc->handler_data;
> + struct qe_ic *qe_ic = get_irq_desc_data(desc);
> unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
>
> if (cascade_irq != NO_IRQ)
> @@ -91,7 +91,7 @@ static inline void qe_ic_cascade_low_ipic(unsigned int irq,
> static inline void qe_ic_cascade_high_ipic(unsigned int irq,
> struct irq_desc *desc)
> {
> - struct qe_ic *qe_ic = desc->handler_data;
> + struct qe_ic *qe_ic = get_irq_desc_data(desc);
> unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
>
> if (cascade_irq != NO_IRQ)
> @@ -101,32 +101,35 @@ static inline void qe_ic_cascade_high_ipic(unsigned int irq,
> static inline void qe_ic_cascade_low_mpic(unsigned int irq,
> struct irq_desc *desc)
> {
> - struct qe_ic *qe_ic = desc->handler_data;
> + struct qe_ic *qe_ic = get_irq_desc_data(desc);
> unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
> + struct irq_chip *chip = get_irq_desc_chip(desc);
>
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
>
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
>
> static inline void qe_ic_cascade_high_mpic(unsigned int irq,
> struct irq_desc *desc)
> {
> - struct qe_ic *qe_ic = desc->handler_data;
> + struct qe_ic *qe_ic = get_irq_desc_data(desc);
> unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
> + struct irq_chip *chip = get_irq_desc_chip(desc);
>
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
>
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
>
> static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
> struct irq_desc *desc)
> {
> - struct qe_ic *qe_ic = desc->handler_data;
> + struct qe_ic *qe_ic = get_irq_desc_data(desc);
> unsigned int cascade_irq;
> + struct irq_chip *chip = get_irq_desc_chip(desc);
>
> cascade_irq = qe_ic_get_high_irq(qe_ic);
> if (cascade_irq == NO_IRQ)
> @@ -135,7 +138,7 @@ static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
>
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
>
> #endif /* _ASM_POWERPC_QE_IC_H */
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index ce557f6..4a9fa84 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -237,6 +237,7 @@ int show_interrupts(struct seq_file *p, void *v)
> int i = *(loff_t *) v, j, prec;
> struct irqaction *action;
> struct irq_desc *desc;
> + struct irq_chip *chip;
>
> if (i > nr_irqs)
> return 0;
> @@ -270,8 +271,9 @@ int show_interrupts(struct seq_file *p, void *v)
> for_each_online_cpu(j)
> seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
>
> - if (desc->chip)
> - seq_printf(p, " %-16s", desc->chip->name);
> + chip = get_irq_desc_chip(desc);
> + if (chip)
> + seq_printf(p, " %-16s", chip->name);
> else
> seq_printf(p, " %-16s", "None");
> seq_printf(p, " %-8s", (desc->status & IRQ_LEVEL) ? "Level" : "Edge");
> @@ -313,6 +315,8 @@ void fixup_irqs(const struct cpumask *map)
> alloc_cpumask_var(&mask, GFP_KERNEL);
>
> for_each_irq(irq) {
> + struct irq_chip *chip;
> +
> desc = irq_to_desc(irq);
> if (!desc)
> continue;
> @@ -320,13 +324,15 @@ void fixup_irqs(const struct cpumask *map)
> if (desc->status & IRQ_PER_CPU)
> continue;
>
> - cpumask_and(mask, desc->affinity, map);
> + chip = get_irq_desc_chip(desc);
> +
> + cpumask_and(mask, desc->irq_data.affinity, map);
> if (cpumask_any(mask) >= nr_cpu_ids) {
> printk("Breaking affinity for irq %i\n", irq);
> cpumask_copy(mask, map);
> }
> - if (desc->chip->set_affinity)
> - desc->chip->set_affinity(irq, mask);
> + if (chip->irq_set_affinity)
> + chip->irq_set_affinity(&desc->irq_data, mask, true);
> else if (desc->action && !(warned++))
> printk("Cannot set affinity for irq %i\n", irq);
> }
> @@ -1159,11 +1165,14 @@ static int virq_debug_show(struct seq_file *m, void *private)
> raw_spin_lock_irqsave(&desc->lock, flags);
>
> if (desc->action && desc->action->handler) {
> + struct irq_chip *chip;
> +
> seq_printf(m, "%5d ", i);
> seq_printf(m, "0x%05lx ", virq_to_hw(i));
>
> - if (desc->chip && desc->chip->name)
> - p = desc->chip->name;
> + chip = get_irq_desc_chip(desc);
> + if (chip && chip->name)
> + p = chip->name;
> else
> p = none;
> seq_printf(m, "%-15s ", p);
> diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
> index 49a170a..976de37 100644
> --- a/arch/powerpc/kernel/machine_kexec.c
> +++ b/arch/powerpc/kernel/machine_kexec.c
> @@ -26,20 +26,23 @@ void machine_kexec_mask_interrupts(void) {
>
> for_each_irq(i) {
> struct irq_desc *desc = irq_to_desc(i);
> + struct irq_chip *chip;
>
> - if (!desc || !desc->chip)
> + if (!desc)
> continue;
>
> - if (desc->chip->eoi &&
> - desc->status & IRQ_INPROGRESS)
> - desc->chip->eoi(i);
> + chip = get_irq_desc_chip(desc);
> + if (!chip)
> + continue;
> +
> + if (chip->irq_eoi && desc->status & IRQ_INPROGRESS)
> + chip->irq_eoi(&desc->irq_data);
>
> - if (desc->chip->mask)
> - desc->chip->mask(i);
> + if (chip->irq_mask)
> + chip->irq_mask(&desc->irq_data);
>
> - if (desc->chip->disable &&
> - !(desc->status & IRQ_DISABLED))
> - desc->chip->disable(i);
> + if (chip->irq_disable && !(desc->status & IRQ_DISABLED))
> + chip->irq_disable(&desc->irq_data);
> }
> }
>
> diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
> index 4ecf4cf..fde0ea5 100644
> --- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
> +++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
> @@ -59,9 +59,9 @@ irq_to_pic_bit(unsigned int irq)
> }
>
> static void
> -cpld_mask_irq(unsigned int irq)
> +cpld_mask_irq(struct irq_data *d)
> {
> - unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
> + unsigned int cpld_irq = (unsigned int)irq_map[d->irq].hwirq;
> void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
>
> out_8(pic_mask,
> @@ -69,9 +69,9 @@ cpld_mask_irq(unsigned int irq)
> }
>
> static void
> -cpld_unmask_irq(unsigned int irq)
> +cpld_unmask_irq(struct irq_data *d)
> {
> - unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
> + unsigned int cpld_irq = (unsigned int)irq_map[d->irq].hwirq;
> void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
>
> out_8(pic_mask,
> @@ -80,9 +80,9 @@ cpld_unmask_irq(unsigned int irq)
>
> static struct irq_chip cpld_pic = {
> .name = "CPLD PIC",
> - .mask = cpld_mask_irq,
> - .ack = cpld_mask_irq,
> - .unmask = cpld_unmask_irq,
> + .irq_mask = cpld_mask_irq,
> + .irq_ack = cpld_mask_irq,
> + .irq_unmask = cpld_unmask_irq,
> };
>
> static int
> diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
> index 2c7780c..2bd1e6c 100644
> --- a/arch/powerpc/platforms/52xx/media5200.c
> +++ b/arch/powerpc/platforms/52xx/media5200.c
> @@ -49,45 +49,46 @@ struct media5200_irq {
> };
> struct media5200_irq media5200_irq;
>
> -static void media5200_irq_unmask(unsigned int virq)
> +static void media5200_irq_unmask(struct irq_data *d)
> {
> unsigned long flags;
> u32 val;
>
> spin_lock_irqsave(&media5200_irq.lock, flags);
> val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
> - val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq);
> + val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[d->irq].hwirq);
> out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
> spin_unlock_irqrestore(&media5200_irq.lock, flags);
> }
>
> -static void media5200_irq_mask(unsigned int virq)
> +static void media5200_irq_mask(struct irq_data *d)
> {
> unsigned long flags;
> u32 val;
>
> spin_lock_irqsave(&media5200_irq.lock, flags);
> val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
> - val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq));
> + val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[d->irq].hwirq));
> out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
> spin_unlock_irqrestore(&media5200_irq.lock, flags);
> }
>
> static struct irq_chip media5200_irq_chip = {
> .name = "Media5200 FPGA",
> - .unmask = media5200_irq_unmask,
> - .mask = media5200_irq_mask,
> - .mask_ack = media5200_irq_mask,
> + .irq_unmask = media5200_irq_unmask,
> + .irq_mask = media5200_irq_mask,
> + .irq_mask_ack = media5200_irq_mask,
> };
>
> void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> int sub_virq, val;
> u32 status, enable;
>
> /* Mask off the cascaded IRQ */
> raw_spin_lock(&desc->lock);
> - desc->chip->mask(virq);
> + chip->irq_mask(&desc->irq_data);
> raw_spin_unlock(&desc->lock);
>
> /* Ask the FPGA for IRQ status. If 'val' is 0, then no irqs
> @@ -105,9 +106,9 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
>
> /* Processing done; can reenable the cascade now */
> raw_spin_lock(&desc->lock);
> - desc->chip->ack(virq);
> + chip->irq_ack(&desc->irq_data);
> if (!(desc->status & IRQ_DISABLED))
> - desc->chip->unmask(virq);
> + chip->irq_unmask(&desc->irq_data);
> raw_spin_unlock(&desc->lock);
> }
>
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
> index e0d703c..fe6cc5d 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
> @@ -135,9 +135,9 @@ DEFINE_MUTEX(mpc52xx_gpt_list_mutex);
> * Cascaded interrupt controller hooks
> */
>
> -static void mpc52xx_gpt_irq_unmask(unsigned int virq)
> +static void mpc52xx_gpt_irq_unmask(struct irq_data *d)
> {
> - struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
> + struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(d->irq);
> unsigned long flags;
>
> spin_lock_irqsave(&gpt->lock, flags);
> @@ -145,9 +145,9 @@ static void mpc52xx_gpt_irq_unmask(unsigned int virq)
> spin_unlock_irqrestore(&gpt->lock, flags);
> }
>
> -static void mpc52xx_gpt_irq_mask(unsigned int virq)
> +static void mpc52xx_gpt_irq_mask(struct irq_data *d)
> {
> - struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
> + struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(d->irq);
> unsigned long flags;
>
> spin_lock_irqsave(&gpt->lock, flags);
> @@ -155,20 +155,20 @@ static void mpc52xx_gpt_irq_mask(unsigned int virq)
> spin_unlock_irqrestore(&gpt->lock, flags);
> }
>
> -static void mpc52xx_gpt_irq_ack(unsigned int virq)
> +static void mpc52xx_gpt_irq_ack(struct irq_data *d)
> {
> - struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
> + struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(d->irq);
>
> out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK);
> }
>
> -static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
> +static int mpc52xx_gpt_irq_set_type(struct irq_data *d, unsigned int flow_type)
> {
> - struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
> + struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(d->irq);
> unsigned long flags;
> u32 reg;
>
> - dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, virq, flow_type);
> + dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, d->irq, flow_type);
>
> spin_lock_irqsave(&gpt->lock, flags);
> reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
> @@ -184,10 +184,10 @@ static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
>
> static struct irq_chip mpc52xx_gpt_irq_chip = {
> .name = "MPC52xx GPT",
> - .unmask = mpc52xx_gpt_irq_unmask,
> - .mask = mpc52xx_gpt_irq_mask,
> - .ack = mpc52xx_gpt_irq_ack,
> - .set_type = mpc52xx_gpt_irq_set_type,
> + .irq_unmask = mpc52xx_gpt_irq_unmask,
> + .irq_mask = mpc52xx_gpt_irq_mask,
> + .irq_ack = mpc52xx_gpt_irq_ack,
> + .irq_set_type = mpc52xx_gpt_irq_set_type,
> };
>
> void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> index 4bf4bf7..9f3ed58 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> @@ -155,47 +155,47 @@ static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
> /*
> * IRQ[0-3] interrupt irq_chip
> */
> -static void mpc52xx_extirq_mask(unsigned int virq)
> +static void mpc52xx_extirq_mask(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> io_be_clrbit(&intr->ctrl, 11 - l2irq);
> }
>
> -static void mpc52xx_extirq_unmask(unsigned int virq)
> +static void mpc52xx_extirq_unmask(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> io_be_setbit(&intr->ctrl, 11 - l2irq);
> }
>
> -static void mpc52xx_extirq_ack(unsigned int virq)
> +static void mpc52xx_extirq_ack(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> io_be_setbit(&intr->ctrl, 27-l2irq);
> }
>
> -static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
> +static int mpc52xx_extirq_set_type(struct irq_data *d, unsigned int flow_type)
> {
> u32 ctrl_reg, type;
> int irq;
> int l2irq;
> void *handler = handle_level_irq;
>
> - irq = irq_map[virq].hwirq;
> + 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);
> @@ -214,44 +214,44 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
> ctrl_reg |= (type << (22 - (l2irq * 2)));
> out_be32(&intr->ctrl, ctrl_reg);
>
> - __set_irq_handler_unlocked(virq, handler);
> + __set_irq_handler_unlocked(d->irq, handler);
>
> return 0;
> }
>
> static struct irq_chip mpc52xx_extirq_irqchip = {
> .name = "MPC52xx External",
> - .mask = mpc52xx_extirq_mask,
> - .unmask = mpc52xx_extirq_unmask,
> - .ack = mpc52xx_extirq_ack,
> - .set_type = mpc52xx_extirq_set_type,
> + .irq_mask = mpc52xx_extirq_mask,
> + .irq_unmask = mpc52xx_extirq_unmask,
> + .irq_ack = mpc52xx_extirq_ack,
> + .irq_set_type = mpc52xx_extirq_set_type,
> };
>
> /*
> * Main interrupt irq_chip
> */
> -static int mpc52xx_null_set_type(unsigned int virq, unsigned int flow_type)
> +static int mpc52xx_null_set_type(struct irq_data *d, unsigned int flow_type)
> {
> return 0; /* Do nothing so that the sense mask will get updated */
> }
>
> -static void mpc52xx_main_mask(unsigned int virq)
> +static void mpc52xx_main_mask(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> io_be_setbit(&intr->main_mask, 16 - l2irq);
> }
>
> -static void mpc52xx_main_unmask(unsigned int virq)
> +static void mpc52xx_main_unmask(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> io_be_clrbit(&intr->main_mask, 16 - l2irq);
> @@ -259,32 +259,32 @@ static void mpc52xx_main_unmask(unsigned int virq)
>
> static struct irq_chip mpc52xx_main_irqchip = {
> .name = "MPC52xx Main",
> - .mask = mpc52xx_main_mask,
> - .mask_ack = mpc52xx_main_mask,
> - .unmask = mpc52xx_main_unmask,
> - .set_type = mpc52xx_null_set_type,
> + .irq_mask = mpc52xx_main_mask,
> + .irq_mask_ack = mpc52xx_main_mask,
> + .irq_unmask = mpc52xx_main_unmask,
> + .irq_set_type = mpc52xx_null_set_type,
> };
>
> /*
> * Peripherals interrupt irq_chip
> */
> -static void mpc52xx_periph_mask(unsigned int virq)
> +static void mpc52xx_periph_mask(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> io_be_setbit(&intr->per_mask, 31 - l2irq);
> }
>
> -static void mpc52xx_periph_unmask(unsigned int virq)
> +static void mpc52xx_periph_unmask(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> io_be_clrbit(&intr->per_mask, 31 - l2irq);
> @@ -292,43 +292,43 @@ static void mpc52xx_periph_unmask(unsigned int virq)
>
> static struct irq_chip mpc52xx_periph_irqchip = {
> .name = "MPC52xx Peripherals",
> - .mask = mpc52xx_periph_mask,
> - .mask_ack = mpc52xx_periph_mask,
> - .unmask = mpc52xx_periph_unmask,
> - .set_type = mpc52xx_null_set_type,
> + .irq_mask = mpc52xx_periph_mask,
> + .irq_mask_ack = mpc52xx_periph_mask,
> + .irq_unmask = mpc52xx_periph_unmask,
> + .irq_set_type = mpc52xx_null_set_type,
> };
>
> /*
> * SDMA interrupt irq_chip
> */
> -static void mpc52xx_sdma_mask(unsigned int virq)
> +static void mpc52xx_sdma_mask(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> io_be_setbit(&sdma->IntMask, l2irq);
> }
>
> -static void mpc52xx_sdma_unmask(unsigned int virq)
> +static void mpc52xx_sdma_unmask(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> io_be_clrbit(&sdma->IntMask, l2irq);
> }
>
> -static void mpc52xx_sdma_ack(unsigned int virq)
> +static void mpc52xx_sdma_ack(struct irq_data *d)
> {
> int irq;
> int l2irq;
>
> - irq = irq_map[virq].hwirq;
> + irq = irq_map[d->irq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> out_be32(&sdma->IntPend, 1 << l2irq);
> @@ -336,10 +336,10 @@ static void mpc52xx_sdma_ack(unsigned int virq)
>
> static struct irq_chip mpc52xx_sdma_irqchip = {
> .name = "MPC52xx SDMA",
> - .mask = mpc52xx_sdma_mask,
> - .unmask = mpc52xx_sdma_unmask,
> - .ack = mpc52xx_sdma_ack,
> - .set_type = mpc52xx_null_set_type,
> + .irq_mask = mpc52xx_sdma_mask,
> + .irq_unmask = mpc52xx_sdma_unmask,
> + .irq_ack = mpc52xx_sdma_ack,
> + .irq_set_type = mpc52xx_null_set_type,
> };
>
> /**
> diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
> index 5a55d87..a0cd8ae 100644
> --- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
> +++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
> @@ -39,10 +39,10 @@ struct pq2ads_pci_pic {
>
> #define NUM_IRQS 32
>
> -static void pq2ads_pci_mask_irq(unsigned int virq)
> +static void pq2ads_pci_mask_irq(struct irq_data *d)
> {
> - struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
> - int irq = NUM_IRQS - virq_to_hw(virq) - 1;
> + struct pq2ads_pci_pic *priv = get_irq_chip_data(d->irq);
> + int irq = NUM_IRQS - virq_to_hw(d->irq) - 1;
>
> if (irq != -1) {
> unsigned long flags;
> @@ -55,10 +55,10 @@ static void pq2ads_pci_mask_irq(unsigned int virq)
> }
> }
>
> -static void pq2ads_pci_unmask_irq(unsigned int virq)
> +static void pq2ads_pci_unmask_irq(struct irq_data *d)
> {
> - struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
> - int irq = NUM_IRQS - virq_to_hw(virq) - 1;
> + struct pq2ads_pci_pic *priv = get_irq_chip_data(d->irq);
> + int irq = NUM_IRQS - virq_to_hw(d->irq) - 1;
>
> if (irq != -1) {
> unsigned long flags;
> @@ -71,18 +71,17 @@ static void pq2ads_pci_unmask_irq(unsigned int virq)
>
> static struct irq_chip pq2ads_pci_ic = {
> .name = "PQ2 ADS PCI",
> - .end = pq2ads_pci_unmask_irq,
> - .mask = pq2ads_pci_mask_irq,
> - .mask_ack = pq2ads_pci_mask_irq,
> - .ack = pq2ads_pci_mask_irq,
> - .unmask = pq2ads_pci_unmask_irq,
> - .enable = pq2ads_pci_unmask_irq,
> - .disable = pq2ads_pci_mask_irq
> + .irq_mask = pq2ads_pci_mask_irq,
> + .irq_mask_ack = pq2ads_pci_mask_irq,
> + .irq_ack = pq2ads_pci_mask_irq,
> + .irq_unmask = pq2ads_pci_unmask_irq,
> + .irq_enable = pq2ads_pci_unmask_irq,
> + .irq_disable = pq2ads_pci_mask_irq
> };
>
> static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
> {
> - struct pq2ads_pci_pic *priv = desc->handler_data;
> + struct pq2ads_pci_pic *priv = get_irq_desc_data(desc);
> u32 stat, mask, pend;
> int bit;
>
> diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c
> index f4d36b5..64447e4 100644
> --- a/arch/powerpc/platforms/85xx/ksi8560.c
> +++ b/arch/powerpc/platforms/85xx/ksi8560.c
> @@ -56,12 +56,13 @@ static void machine_restart(char *cmd)
>
> static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> int cascade_irq;
>
> while ((cascade_irq = cpm2_get_irq()) >= 0)
> generic_handle_irq(cascade_irq);
>
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
>
> static void __init ksi8560_pic_init(void)
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
> index 9438a89..1352d11 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
> @@ -50,12 +50,13 @@ static int mpc85xx_exclude_device(struct pci_controller *hose,
>
> static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> int cascade_irq;
>
> while ((cascade_irq = cpm2_get_irq()) >= 0)
> generic_handle_irq(cascade_irq);
>
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
>
> #endif /* CONFIG_CPM2 */
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> index 8190bc2..793ead7 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> @@ -47,12 +47,13 @@
> #ifdef CONFIG_PPC_I8259
> static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> unsigned int cascade_irq = i8259_irq();
>
> if (cascade_irq != NO_IRQ) {
> generic_handle_irq(cascade_irq);
> }
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
> #endif /* CONFIG_PPC_I8259 */
>
> diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c
> index a5ad1c7..d7e28ec 100644
> --- a/arch/powerpc/platforms/85xx/sbc8560.c
> +++ b/arch/powerpc/platforms/85xx/sbc8560.c
> @@ -41,12 +41,13 @@
>
> static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> int cascade_irq;
>
> while ((cascade_irq = cpm2_get_irq()) >= 0)
> generic_handle_irq(cascade_irq);
>
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
>
> #endif /* CONFIG_CPM2 */
> diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
> index d48527f..79d85ac 100644
> --- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
> +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
> @@ -93,6 +93,7 @@ static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq)
>
> void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> unsigned int cascade_irq;
>
> /*
> @@ -103,17 +104,16 @@ void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
>
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
> - desc->chip->eoi(irq);
> -
> + chip->irq_eoi(&desc->irq_data);
> }
>
> -static void socrates_fpga_pic_ack(unsigned int virq)
> +static void socrates_fpga_pic_ack(struct irq_data *d)
> {
> unsigned long flags;
> unsigned int hwirq, irq_line;
> uint32_t mask;
>
> - hwirq = socrates_fpga_irq_to_hw(virq);
> + hwirq = socrates_fpga_irq_to_hw(d->irq);
>
> irq_line = fpga_irqs[hwirq].irq_line;
> raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
> @@ -124,14 +124,14 @@ static void socrates_fpga_pic_ack(unsigned int virq)
> raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
> }
>
> -static void socrates_fpga_pic_mask(unsigned int virq)
> +static void socrates_fpga_pic_mask(struct irq_data *d)
> {
> unsigned long flags;
> unsigned int hwirq;
> int irq_line;
> u32 mask;
>
> - hwirq = socrates_fpga_irq_to_hw(virq);
> + hwirq = socrates_fpga_irq_to_hw(d->irq);
>
> irq_line = fpga_irqs[hwirq].irq_line;
> raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
> @@ -142,14 +142,14 @@ static void socrates_fpga_pic_mask(unsigned int virq)
> raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
> }
>
> -static void socrates_fpga_pic_mask_ack(unsigned int virq)
> +static void socrates_fpga_pic_mask_ack(struct irq_data *d)
> {
> unsigned long flags;
> unsigned int hwirq;
> int irq_line;
> u32 mask;
>
> - hwirq = socrates_fpga_irq_to_hw(virq);
> + hwirq = socrates_fpga_irq_to_hw(d->irq);
>
> irq_line = fpga_irqs[hwirq].irq_line;
> raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
> @@ -161,14 +161,14 @@ static void socrates_fpga_pic_mask_ack(unsigned int virq)
> raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
> }
>
> -static void socrates_fpga_pic_unmask(unsigned int virq)
> +static void socrates_fpga_pic_unmask(struct irq_data *d)
> {
> unsigned long flags;
> unsigned int hwirq;
> int irq_line;
> u32 mask;
>
> - hwirq = socrates_fpga_irq_to_hw(virq);
> + hwirq = socrates_fpga_irq_to_hw(d->irq);
>
> irq_line = fpga_irqs[hwirq].irq_line;
> raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
> @@ -179,14 +179,14 @@ static void socrates_fpga_pic_unmask(unsigned int virq)
> raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
> }
>
> -static void socrates_fpga_pic_eoi(unsigned int virq)
> +static void socrates_fpga_pic_eoi(struct irq_data *d)
> {
> unsigned long flags;
> unsigned int hwirq;
> int irq_line;
> u32 mask;
>
> - hwirq = socrates_fpga_irq_to_hw(virq);
> + hwirq = socrates_fpga_irq_to_hw(d->irq);
>
> irq_line = fpga_irqs[hwirq].irq_line;
> raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
> @@ -197,7 +197,7 @@ static void socrates_fpga_pic_eoi(unsigned int virq)
> raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
> }
>
> -static int socrates_fpga_pic_set_type(unsigned int virq,
> +static int socrates_fpga_pic_set_type(struct irq_data *d,
> unsigned int flow_type)
> {
> unsigned long flags;
> @@ -205,7 +205,7 @@ static int socrates_fpga_pic_set_type(unsigned int virq,
> int polarity;
> u32 mask;
>
> - hwirq = socrates_fpga_irq_to_hw(virq);
> + hwirq = socrates_fpga_irq_to_hw(d->irq);
>
> if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE)
> return -EINVAL;
> @@ -233,12 +233,12 @@ static int socrates_fpga_pic_set_type(unsigned int virq,
>
> static struct irq_chip socrates_fpga_pic_chip = {
> .name = "FPGA-PIC",
> - .ack = socrates_fpga_pic_ack,
> - .mask = socrates_fpga_pic_mask,
> - .mask_ack = socrates_fpga_pic_mask_ack,
> - .unmask = socrates_fpga_pic_unmask,
> - .eoi = socrates_fpga_pic_eoi,
> - .set_type = socrates_fpga_pic_set_type,
> + .irq_ack = socrates_fpga_pic_ack,
> + .irq_mask = socrates_fpga_pic_mask,
> + .irq_mask_ack = socrates_fpga_pic_mask_ack,
> + .irq_unmask = socrates_fpga_pic_unmask,
> + .irq_eoi = socrates_fpga_pic_eoi,
> + .irq_set_type = socrates_fpga_pic_set_type,
> };
>
> static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
> diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c
> index bc33d18..2b62b06 100644
> --- a/arch/powerpc/platforms/85xx/stx_gp3.c
> +++ b/arch/powerpc/platforms/85xx/stx_gp3.c
> @@ -46,12 +46,13 @@
>
> static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> int cascade_irq;
>
> while ((cascade_irq = cpm2_get_irq()) >= 0)
> generic_handle_irq(cascade_irq);
>
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
> #endif /* CONFIG_CPM2 */
>
> diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
> index 5e847d0..2265b68 100644
> --- a/arch/powerpc/platforms/85xx/tqm85xx.c
> +++ b/arch/powerpc/platforms/85xx/tqm85xx.c
> @@ -44,12 +44,13 @@
>
> static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> int cascade_irq;
>
> while ((cascade_irq = cpm2_get_irq()) >= 0)
> generic_handle_irq(cascade_irq);
>
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
> #endif /* CONFIG_CPM2 */
>
> diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
> index 6df9e25..0adfe3b 100644
> --- a/arch/powerpc/platforms/86xx/gef_pic.c
> +++ b/arch/powerpc/platforms/86xx/gef_pic.c
> @@ -95,6 +95,7 @@ static int gef_pic_cascade_irq;
>
> void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> unsigned int cascade_irq;
>
> /*
> @@ -106,17 +107,16 @@ void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
>
> - desc->chip->eoi(irq);
> -
> + chip->irq_eoi(&desc->irq_data);
> }
>
> -static void gef_pic_mask(unsigned int virq)
> +static void gef_pic_mask(struct irq_data *d)
> {
> unsigned long flags;
> unsigned int hwirq;
> u32 mask;
>
> - hwirq = gef_irq_to_hw(virq);
> + 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));
> @@ -125,21 +125,21 @@ static void gef_pic_mask(unsigned int virq)
> raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
> }
>
> -static void gef_pic_mask_ack(unsigned int virq)
> +static void gef_pic_mask_ack(struct irq_data *d)
> {
> /* Don't think we actually have to do anything to ack an interrupt,
> * we just need to clear down the devices interrupt and it will go away
> */
> - gef_pic_mask(virq);
> + gef_pic_mask(d);
> }
>
> -static void gef_pic_unmask(unsigned int virq)
> +static void gef_pic_unmask(struct irq_data *d)
> {
> unsigned long flags;
> unsigned int hwirq;
> u32 mask;
>
> - hwirq = gef_irq_to_hw(virq);
> + 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));
> @@ -150,9 +150,9 @@ static void gef_pic_unmask(unsigned int virq)
>
> static struct irq_chip gef_pic_chip = {
> .name = "gefp",
> - .mask = gef_pic_mask,
> - .mask_ack = gef_pic_mask_ack,
> - .unmask = gef_pic_unmask,
> + .irq_mask = gef_pic_mask,
> + .irq_mask_ack = gef_pic_mask_ack,
> + .irq_unmask = gef_pic_unmask,
> };
>
>
> diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c
> index 668275d..cbe3363 100644
> --- a/arch/powerpc/platforms/86xx/pic.c
> +++ b/arch/powerpc/platforms/86xx/pic.c
> @@ -19,10 +19,13 @@
> #ifdef CONFIG_PPC_I8259
> static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> unsigned int cascade_irq = i8259_irq();
> +
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
> - desc->chip->eoi(irq);
> +
> + chip->irq_eoi(&desc->irq_data);
> }
> #endif /* CONFIG_PPC_I8259 */
>
> diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
> index 60168c1..fabb108 100644
> --- a/arch/powerpc/platforms/8xx/m8xx_setup.c
> +++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
> @@ -218,15 +218,20 @@ void mpc8xx_restart(char *cmd)
>
> static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip;
> int cascade_irq;
>
> if ((cascade_irq = cpm_get_irq()) >= 0) {
> struct irq_desc *cdesc = irq_to_desc(cascade_irq);
>
> generic_handle_irq(cascade_irq);
> - cdesc->chip->eoi(cascade_irq);
> +
> + chip = get_irq_desc_chip(cdesc);
> + chip->irq_eoi(&cdesc->irq_data);
> }
> - desc->chip->eoi(irq);
> +
> + chip = get_irq_desc_chip(desc);
> + chip->irq_eoi(&desc->irq_data);
> }
>
> /* Initialize the internal interrupt controllers. The number of
> diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
> index e3e379c..c07930f 100644
> --- a/arch/powerpc/platforms/cell/axon_msi.c
> +++ b/arch/powerpc/platforms/cell/axon_msi.c
> @@ -93,6 +93,7 @@ static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
>
> static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> struct axon_msic *msic = get_irq_data(irq);
> u32 write_offset, msi;
> int idx;
> @@ -145,7 +146,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
> msic->read_offset &= MSIC_FIFO_SIZE_MASK;
> }
>
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
>
> static struct axon_msic *find_msi_translator(struct pci_dev *dev)
> diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
> index 682af97..0b8f7d7 100644
> --- a/arch/powerpc/platforms/cell/beat_interrupt.c
> +++ b/arch/powerpc/platforms/cell/beat_interrupt.c
> @@ -61,59 +61,59 @@ static inline void beatic_update_irq_mask(unsigned int irq_plug)
> panic("Failed to set mask IRQ!");
> }
>
> -static void beatic_mask_irq(unsigned int irq_plug)
> +static void beatic_mask_irq(struct irq_data *d)
> {
> unsigned long flags;
>
> raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
> - beatic_irq_mask_enable[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
> - beatic_update_irq_mask(irq_plug);
> + beatic_irq_mask_enable[d->irq/64] &= ~(1UL << (63 - (d->irq%64)));
> + beatic_update_irq_mask(d->irq);
> raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
> }
>
> -static void beatic_unmask_irq(unsigned int irq_plug)
> +static void beatic_unmask_irq(struct irq_data *d)
> {
> unsigned long flags;
>
> raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
> - beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
> - beatic_update_irq_mask(irq_plug);
> + beatic_irq_mask_enable[d->irq/64] |= 1UL << (63 - (d->irq%64));
> + beatic_update_irq_mask(d->irq);
> raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
> }
>
> -static void beatic_ack_irq(unsigned int irq_plug)
> +static void beatic_ack_irq(struct irq_data *d)
> {
> unsigned long flags;
>
> raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
> - beatic_irq_mask_ack[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
> - beatic_update_irq_mask(irq_plug);
> + beatic_irq_mask_ack[d->irq/64] &= ~(1UL << (63 - (d->irq%64)));
> + beatic_update_irq_mask(d->irq);
> raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
> }
>
> -static void beatic_end_irq(unsigned int irq_plug)
> +static void beatic_end_irq(struct irq_data *d)
> {
> s64 err;
> unsigned long flags;
>
> - err = beat_downcount_of_interrupt(irq_plug);
> + err = beat_downcount_of_interrupt(d->irq);
> if (err != 0) {
> if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */
> panic("Failed to downcount IRQ! Error = %16llx", err);
>
> - printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug);
> + printk(KERN_ERR "IRQ over-downcounted, plug %d\n", d->irq);
> }
> raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
> - beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
> - beatic_update_irq_mask(irq_plug);
> + beatic_irq_mask_ack[d->irq/64] |= 1UL << (63 - (d->irq%64));
> + beatic_update_irq_mask(d->irq);
> raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
> }
>
> static struct irq_chip beatic_pic = {
> .name = "CELL-BEAT",
> - .unmask = beatic_unmask_irq,
> - .mask = beatic_mask_irq,
> - .eoi = beatic_end_irq,
> + .irq_unmask = beatic_unmask_irq,
> + .irq_mask = beatic_mask_irq,
> + .irq_eoi = beatic_end_irq,
> };
>
> /*
> @@ -232,7 +232,7 @@ unsigned int beatic_get_irq(void)
>
> ret = beatic_get_irq_plug();
> if (ret != NO_IRQ)
> - beatic_ack_irq(ret);
> + beatic_ack_irq(irq_get_irq_data(ret));
> return ret;
> }
>
> diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
> index 10eb1a4..624d26e 100644
> --- a/arch/powerpc/platforms/cell/interrupt.c
> +++ b/arch/powerpc/platforms/cell/interrupt.c
> @@ -72,15 +72,15 @@ static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
> return (node << IIC_IRQ_NODE_SHIFT) | (class << 4) | unit;
> }
>
> -static void iic_mask(unsigned int irq)
> +static void iic_mask(struct irq_data *d)
> {
> }
>
> -static void iic_unmask(unsigned int irq)
> +static void iic_unmask(struct irq_data *d)
> {
> }
>
> -static void iic_eoi(unsigned int irq)
> +static void iic_eoi(struct irq_data *d)
> {
> struct iic *iic = &__get_cpu_var(cpu_iic);
> out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]);
> @@ -89,19 +89,21 @@ static void iic_eoi(unsigned int irq)
>
> static struct irq_chip iic_chip = {
> .name = "CELL-IIC",
> - .mask = iic_mask,
> - .unmask = iic_unmask,
> - .eoi = iic_eoi,
> + .irq_mask = iic_mask,
> + .irq_unmask = iic_unmask,
> + .irq_eoi = iic_eoi,
> };
>
>
> -static void iic_ioexc_eoi(unsigned int irq)
> +static void iic_ioexc_eoi(struct irq_data *d)
> {
> }
>
> static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
> {
> - struct cbe_iic_regs __iomem *node_iic = (void __iomem *)desc->handler_data;
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> + struct cbe_iic_regs __iomem *node_iic =
> + (void __iomem *)get_irq_desc_data(desc);
> unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
> unsigned long bits, ack;
> int cascade;
> @@ -128,15 +130,15 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
> if (ack)
> out_be64(&node_iic->iic_is, ack);
> }
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> }
>
>
> static struct irq_chip iic_ioexc_chip = {
> .name = "CELL-IOEX",
> - .mask = iic_mask,
> - .unmask = iic_unmask,
> - .eoi = iic_ioexc_eoi,
> + .irq_mask = iic_mask,
> + .irq_unmask = iic_unmask,
> + .irq_eoi = iic_ioexc_eoi,
> };
>
> /* Get an IRQ number from the pending state register of the IIC */
> @@ -237,6 +239,8 @@ extern int noirqdebug;
>
> static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> +
> raw_spin_lock(&desc->lock);
>
> desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
> @@ -275,7 +279,7 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
>
> desc->status &= ~IRQ_INPROGRESS;
> out_eoi:
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> raw_spin_unlock(&desc->lock);
> }
>
> diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
> index 6919957..6a28d02 100644
> --- a/arch/powerpc/platforms/cell/setup.c
> +++ b/arch/powerpc/platforms/cell/setup.c
> @@ -187,13 +187,15 @@ machine_subsys_initcall(cell, cell_publish_devices);
>
> static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
> {
> - struct mpic *mpic = desc->handler_data;
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> + struct mpic *mpic = get_irq_desc_data(desc);
> unsigned int virq;
>
> virq = mpic_get_one_irq(mpic);
> if (virq != NO_IRQ)
> generic_handle_irq(virq);
> - desc->chip->eoi(irq);
> +
> + chip->irq_eoi(&desc->irq_data);
> }
>
> static void __init mpic_init_IRQ(void)
> diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
> index 3f2e557..b38cdfc 100644
> --- a/arch/powerpc/platforms/cell/spider-pic.c
> +++ b/arch/powerpc/platforms/cell/spider-pic.c
> @@ -79,30 +79,30 @@ static void __iomem *spider_get_irq_config(struct spider_pic *pic,
> return pic->regs + TIR_CFGA + 8 * src;
> }
>
> -static void spider_unmask_irq(unsigned int virq)
> +static void spider_unmask_irq(struct irq_data *d)
> {
> - struct spider_pic *pic = spider_virq_to_pic(virq);
> - void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
> + struct spider_pic *pic = spider_virq_to_pic(d->irq);
> + void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
>
> out_be32(cfg, in_be32(cfg) | 0x30000000u);
> }
>
> -static void spider_mask_irq(unsigned int virq)
> +static void spider_mask_irq(struct irq_data *d)
> {
> - struct spider_pic *pic = spider_virq_to_pic(virq);
> - void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
> + struct spider_pic *pic = spider_virq_to_pic(d->irq);
> + void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
>
> out_be32(cfg, in_be32(cfg) & ~0x30000000u);
> }
>
> -static void spider_ack_irq(unsigned int virq)
> +static void spider_ack_irq(struct irq_data *d)
> {
> - struct spider_pic *pic = spider_virq_to_pic(virq);
> - unsigned int src = irq_map[virq].hwirq;
> + struct spider_pic *pic = spider_virq_to_pic(d->irq);
> + unsigned int src = irq_map[d->irq].hwirq;
>
> /* Reset edge detection logic if necessary
> */
> - if (irq_to_desc(virq)->status & IRQ_LEVEL)
> + if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
> return;
>
> /* Only interrupts 47 to 50 can be set to edge */
> @@ -113,13 +113,13 @@ static void spider_ack_irq(unsigned int virq)
> out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf));
> }
>
> -static int spider_set_irq_type(unsigned int virq, unsigned int type)
> +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(virq);
> - unsigned int hw = irq_map[virq].hwirq;
> + struct spider_pic *pic = spider_virq_to_pic(d->irq);
> + unsigned int hw = irq_map[d->irq].hwirq;
> void __iomem *cfg = spider_get_irq_config(pic, hw);
> - struct irq_desc *desc = irq_to_desc(virq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
> u32 old_mask;
> u32 ic;
>
> @@ -169,10 +169,10 @@ static int spider_set_irq_type(unsigned int virq, unsigned int type)
>
> static struct irq_chip spider_pic = {
> .name = "SPIDER",
> - .unmask = spider_unmask_irq,
> - .mask = spider_mask_irq,
> - .ack = spider_ack_irq,
> - .set_type = spider_set_irq_type,
> + .irq_unmask = spider_unmask_irq,
> + .irq_mask = spider_mask_irq,
> + .irq_ack = spider_ack_irq,
> + .irq_set_type = spider_set_irq_type,
> };
>
> static int spider_host_map(struct irq_host *h, unsigned int virq,
> @@ -207,7 +207,8 @@ static struct irq_host_ops spider_host_ops = {
>
> static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc)
> {
> - struct spider_pic *pic = desc->handler_data;
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> + struct spider_pic *pic = get_irq_desc_data(desc);
> unsigned int cs, virq;
>
> cs = in_be32(pic->regs + TIR_CS) >> 24;
> @@ -215,9 +216,11 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc)
> virq = NO_IRQ;
> else
> virq = irq_linear_revmap(pic->host, cs);
> +
> if (virq != NO_IRQ)
> generic_handle_irq(virq);
> - desc->chip->eoi(irq);
> +
> + chip->irq_eoi(&desc->irq_data);
> }
>
> /* For hooking up the cascace we have a problem. Our device-tree is
> diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
> index 8553cc4..4c12884 100644
> --- a/arch/powerpc/platforms/chrp/setup.c
> +++ b/arch/powerpc/platforms/chrp/setup.c
> @@ -365,10 +365,13 @@ void __init chrp_setup_arch(void)
>
> static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> unsigned int cascade_irq = i8259_irq();
> +
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
> - desc->chip->eoi(irq);
> +
> + chip->irq_eoi(&desc->irq_data);
> }
>
> /*
> diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
> index c278bd3..d7287e8 100644
> --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
> +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
> @@ -46,10 +46,10 @@
> *
> */
>
> -static void flipper_pic_mask_and_ack(unsigned int virq)
> +static void flipper_pic_mask_and_ack(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void __iomem *io_base = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void __iomem *io_base = get_irq_chip_data(d->irq);
> u32 mask = 1 << irq;
>
> clrbits32(io_base + FLIPPER_IMR, mask);
> @@ -57,27 +57,27 @@ static void flipper_pic_mask_and_ack(unsigned int virq)
> out_be32(io_base + FLIPPER_ICR, mask);
> }
>
> -static void flipper_pic_ack(unsigned int virq)
> +static void flipper_pic_ack(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void __iomem *io_base = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void __iomem *io_base = get_irq_chip_data(d->irq);
>
> /* this is at least needed for RSW */
> out_be32(io_base + FLIPPER_ICR, 1 << irq);
> }
>
> -static void flipper_pic_mask(unsigned int virq)
> +static void flipper_pic_mask(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void __iomem *io_base = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void __iomem *io_base = get_irq_chip_data(d->irq);
>
> clrbits32(io_base + FLIPPER_IMR, 1 << irq);
> }
>
> -static void flipper_pic_unmask(unsigned int virq)
> +static void flipper_pic_unmask(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void __iomem *io_base = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void __iomem *io_base = get_irq_chip_data(d->irq);
>
> setbits32(io_base + FLIPPER_IMR, 1 << irq);
> }
> @@ -85,10 +85,10 @@ static void flipper_pic_unmask(unsigned int virq)
>
> static struct irq_chip flipper_pic = {
> .name = "flipper-pic",
> - .ack = flipper_pic_ack,
> - .mask_ack = flipper_pic_mask_and_ack,
> - .mask = flipper_pic_mask,
> - .unmask = flipper_pic_unmask,
> + .irq_ack = flipper_pic_ack,
> + .irq_mask_ack = flipper_pic_mask_and_ack,
> + .irq_mask = flipper_pic_mask,
> + .irq_unmask = flipper_pic_unmask,
> };
>
> /*
> diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
> index a771f91..c6f5fd6 100644
> --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
> +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
> @@ -41,36 +41,36 @@
> *
> */
>
> -static void hlwd_pic_mask_and_ack(unsigned int virq)
> +static void hlwd_pic_mask_and_ack(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void __iomem *io_base = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void __iomem *io_base = get_irq_chip_data(d->irq);
> u32 mask = 1 << irq;
>
> clrbits32(io_base + HW_BROADWAY_IMR, mask);
> out_be32(io_base + HW_BROADWAY_ICR, mask);
> }
>
> -static void hlwd_pic_ack(unsigned int virq)
> +static void hlwd_pic_ack(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void __iomem *io_base = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void __iomem *io_base = get_irq_chip_data(d->irq);
>
> out_be32(io_base + HW_BROADWAY_ICR, 1 << irq);
> }
>
> -static void hlwd_pic_mask(unsigned int virq)
> +static void hlwd_pic_mask(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void __iomem *io_base = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void __iomem *io_base = get_irq_chip_data(d->irq);
>
> clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
> }
>
> -static void hlwd_pic_unmask(unsigned int virq)
> +static void hlwd_pic_unmask(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void __iomem *io_base = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void __iomem *io_base = get_irq_chip_data(d->irq);
>
> setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
> }
> @@ -78,10 +78,10 @@ static void hlwd_pic_unmask(unsigned int virq)
>
> static struct irq_chip hlwd_pic = {
> .name = "hlwd-pic",
> - .ack = hlwd_pic_ack,
> - .mask_ack = hlwd_pic_mask_and_ack,
> - .mask = hlwd_pic_mask,
> - .unmask = hlwd_pic_unmask,
> + .irq_ack = hlwd_pic_ack,
> + .irq_mask_ack = hlwd_pic_mask_and_ack,
> + .irq_mask = hlwd_pic_mask,
> + .irq_unmask = hlwd_pic_unmask,
> };
>
> /*
> @@ -129,11 +129,12 @@ static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
> static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
> struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> struct irq_host *irq_host = get_irq_data(cascade_virq);
> unsigned int virq;
>
> raw_spin_lock(&desc->lock);
> - desc->chip->mask(cascade_virq); /* IRQ_LEVEL */
> + chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */
> raw_spin_unlock(&desc->lock);
>
> virq = __hlwd_pic_get_irq(irq_host);
> @@ -143,9 +144,9 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
> pr_err("spurious interrupt!\n");
>
> raw_spin_lock(&desc->lock);
> - desc->chip->ack(cascade_virq); /* IRQ_LEVEL */
> - if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
> - desc->chip->unmask(cascade_virq);
> + chip->irq_ack(&desc->irq_data); /* IRQ_LEVEL */
> + if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
> + chip->irq_unmask(&desc->irq_data);
> raw_spin_unlock(&desc->lock);
> }
>
> diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
> index ba446bf..4fb96f0 100644
> --- a/arch/powerpc/platforms/iseries/irq.c
> +++ b/arch/powerpc/platforms/iseries/irq.c
> @@ -167,11 +167,11 @@ static void pci_event_handler(struct HvLpEvent *event)
> * This will be called by device drivers (via enable_IRQ)
> * to enable INTA in the bridge interrupt status register.
> */
> -static void iseries_enable_IRQ(unsigned int irq)
> +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[irq].hwirq;
> + unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
>
> /* The IRQ has already been locked by the caller */
> bus = REAL_IRQ_TO_BUS(rirq);
> @@ -184,23 +184,23 @@ static void iseries_enable_IRQ(unsigned int irq)
> }
>
> /* This is called by iseries_activate_IRQs */
> -static unsigned int iseries_startup_IRQ(unsigned int irq)
> +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[irq].hwirq;
> + unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
>
> bus = REAL_IRQ_TO_BUS(rirq);
> function = REAL_IRQ_TO_FUNC(rirq);
> dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
>
> /* Link the IRQ number to the bridge */
> - HvCallXm_connectBusUnit(bus, sub_bus, dev_id, irq);
> + HvCallXm_connectBusUnit(bus, sub_bus, dev_id, d->irq);
>
> /* Unmask bridge interrupts in the FISR */
> mask = 0x01010000 << function;
> HvCallPci_unmaskFisr(bus, sub_bus, dev_id, mask);
> - iseries_enable_IRQ(irq);
> + iseries_enable_IRQ(d);
> return 0;
> }
>
> @@ -215,21 +215,26 @@ void __init iSeries_activate_IRQs()
>
> for_each_irq (irq) {
> struct irq_desc *desc = irq_to_desc(irq);
> + struct irq_chip *chip;
>
> - if (desc && desc->chip && desc->chip->startup) {
> + if (!desc)
> + continue;
> +
> + chip = get_irq_desc_chip(desc);
> + if (chip && chip->irq_startup) {
> raw_spin_lock_irqsave(&desc->lock, flags);
> - desc->chip->startup(irq);
> + chip->irq_startup(&desc->irq_data);
> raw_spin_unlock_irqrestore(&desc->lock, flags);
> }
> }
> }
>
> /* this is not called anywhere currently */
> -static void iseries_shutdown_IRQ(unsigned int irq)
> +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[irq].hwirq;
> + unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
>
> /* irq should be locked by the caller */
> bus = REAL_IRQ_TO_BUS(rirq);
> @@ -248,11 +253,11 @@ static void iseries_shutdown_IRQ(unsigned int irq)
> * This will be called by device drivers (via disable_IRQ)
> * to disable INTA in the bridge interrupt status register.
> */
> -static void iseries_disable_IRQ(unsigned int irq)
> +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[irq].hwirq;
> + unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
>
> /* The IRQ has already been locked by the caller */
> bus = REAL_IRQ_TO_BUS(rirq);
> @@ -264,9 +269,9 @@ static void iseries_disable_IRQ(unsigned int irq)
> HvCallPci_maskInterrupts(bus, sub_bus, dev_id, mask);
> }
>
> -static void iseries_end_IRQ(unsigned int irq)
> +static void iseries_end_IRQ(struct irq_data *d)
> {
> - unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
> + unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
>
> HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq),
> (REAL_IRQ_TO_IDSEL(rirq) << 4) + REAL_IRQ_TO_FUNC(rirq));
> @@ -274,11 +279,11 @@ static void iseries_end_IRQ(unsigned int irq)
>
> static struct irq_chip iseries_pic = {
> .name = "iSeries",
> - .startup = iseries_startup_IRQ,
> - .shutdown = iseries_shutdown_IRQ,
> - .unmask = iseries_enable_IRQ,
> - .mask = iseries_disable_IRQ,
> - .eoi = iseries_end_IRQ
> + .irq_startup = iseries_startup_IRQ,
> + .irq_shutdown = iseries_shutdown_IRQ,
> + .irq_unmask = iseries_enable_IRQ,
> + .irq_mask = iseries_disable_IRQ,
> + .irq_eoi = iseries_end_IRQ
> };
>
> /*
> diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
> index 890d5f7..c55812b 100644
> --- a/arch/powerpc/platforms/powermac/pic.c
> +++ b/arch/powerpc/platforms/powermac/pic.c
> @@ -82,9 +82,9 @@ static void __pmac_retrigger(unsigned int irq_nr)
> }
> }
>
> -static void pmac_mask_and_ack_irq(unsigned int virq)
> +static void pmac_mask_and_ack_irq(struct irq_data *d)
> {
> - unsigned int src = irq_map[virq].hwirq;
> + unsigned int src = irq_map[d->irq].hwirq;
> unsigned long bit = 1UL << (src & 0x1f);
> int i = src >> 5;
> unsigned long flags;
> @@ -104,9 +104,9 @@ static void pmac_mask_and_ack_irq(unsigned int virq)
> raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
> }
>
> -static void pmac_ack_irq(unsigned int virq)
> +static void pmac_ack_irq(struct irq_data *d)
> {
> - unsigned int src = irq_map[virq].hwirq;
> + unsigned int src = irq_map[d->irq].hwirq;
> unsigned long bit = 1UL << (src & 0x1f);
> int i = src >> 5;
> unsigned long flags;
> @@ -149,15 +149,15 @@ static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
> /* When an irq gets requested for the first client, if it's an
> * edge interrupt, we clear any previous one on the controller
> */
> -static unsigned int pmac_startup_irq(unsigned int virq)
> +static unsigned int pmac_startup_irq(struct irq_data *d)
> {
> unsigned long flags;
> - unsigned int src = irq_map[virq].hwirq;
> + unsigned int src = irq_map[d->irq].hwirq;
> unsigned long bit = 1UL << (src & 0x1f);
> int i = src >> 5;
>
> raw_spin_lock_irqsave(&pmac_pic_lock, flags);
> - if ((irq_to_desc(virq)->status & IRQ_LEVEL) == 0)
> + if ((irq_to_desc(d->irq)->status & IRQ_LEVEL) == 0)
> out_le32(&pmac_irq_hw[i]->ack, bit);
> __set_bit(src, ppc_cached_irq_mask);
> __pmac_set_irq_mask(src, 0);
> @@ -166,10 +166,10 @@ static unsigned int pmac_startup_irq(unsigned int virq)
> return 0;
> }
>
> -static void pmac_mask_irq(unsigned int virq)
> +static void pmac_mask_irq(struct irq_data *d)
> {
> unsigned long flags;
> - unsigned int src = irq_map[virq].hwirq;
> + unsigned int src = irq_map[d->irq].hwirq;
>
> raw_spin_lock_irqsave(&pmac_pic_lock, flags);
> __clear_bit(src, ppc_cached_irq_mask);
> @@ -177,10 +177,10 @@ static void pmac_mask_irq(unsigned int virq)
> raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
> }
>
> -static void pmac_unmask_irq(unsigned int virq)
> +static void pmac_unmask_irq(struct irq_data *d)
> {
> unsigned long flags;
> - unsigned int src = irq_map[virq].hwirq;
> + unsigned int src = irq_map[d->irq].hwirq;
>
> raw_spin_lock_irqsave(&pmac_pic_lock, flags);
> __set_bit(src, ppc_cached_irq_mask);
> @@ -188,24 +188,24 @@ static void pmac_unmask_irq(unsigned int virq)
> raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
> }
>
> -static int pmac_retrigger(unsigned int virq)
> +static int pmac_retrigger(struct irq_data *d)
> {
> unsigned long flags;
>
> raw_spin_lock_irqsave(&pmac_pic_lock, flags);
> - __pmac_retrigger(irq_map[virq].hwirq);
> + __pmac_retrigger(irq_map[d->irq].hwirq);
> raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
> return 1;
> }
>
> static struct irq_chip pmac_pic = {
> .name = "PMAC-PIC",
> - .startup = pmac_startup_irq,
> - .mask = pmac_mask_irq,
> - .ack = pmac_ack_irq,
> - .mask_ack = pmac_mask_and_ack_irq,
> - .unmask = pmac_unmask_irq,
> - .retrigger = pmac_retrigger,
> + .irq_startup = pmac_startup_irq,
> + .irq_mask = pmac_mask_irq,
> + .irq_ack = pmac_ack_irq,
> + .irq_mask_ack = pmac_mask_and_ack_irq,
> + .irq_unmask = pmac_unmask_irq,
> + .irq_retrigger = pmac_retrigger,
> };
>
> static irqreturn_t gatwick_action(int cpl, void *dev_id)
> @@ -472,12 +472,14 @@ int of_irq_map_oldworld(struct device_node *device, int index,
>
> static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
> {
> - struct mpic *mpic = desc->handler_data;
> -
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> + struct mpic *mpic = get_irq_desc_data(desc);
> unsigned int cascade_irq = mpic_get_one_irq(mpic);
> +
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
> - desc->chip->eoi(irq);
> +
> + chip->irq_eoi(&desc->irq_data);
> }
>
> static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
> @@ -707,7 +709,7 @@ static int pmacpic_resume(struct sys_device *sysdev)
> mb();
> for (i = 0; i < max_real_irqs; ++i)
> if (test_bit(i, sleep_save_mask))
> - pmac_unmask_irq(i);
> + pmac_unmask_irq(irq_get_irq_data(i));
>
> return 0;
> }
> diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
> index 92290ff..4b3cc34 100644
> --- a/arch/powerpc/platforms/ps3/interrupt.c
> +++ b/arch/powerpc/platforms/ps3/interrupt.c
> @@ -99,16 +99,16 @@ static DEFINE_PER_CPU(struct ps3_private, ps3_private);
> * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
> */
>
> -static void ps3_chip_mask(unsigned int virq)
> +static void ps3_chip_mask(struct irq_data *d)
> {
> - struct ps3_private *pd = get_irq_chip_data(virq);
> + struct ps3_private *pd = get_irq_chip_data(d->irq);
> unsigned long flags;
>
> pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
> - pd->thread_id, virq);
> + pd->thread_id, d->irq);
>
> local_irq_save(flags);
> - clear_bit(63 - virq, &pd->bmp.mask);
> + clear_bit(63 - d->irq, &pd->bmp.mask);
> lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
> local_irq_restore(flags);
> }
> @@ -120,16 +120,16 @@ static void ps3_chip_mask(unsigned int virq)
> * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
> */
>
> -static void ps3_chip_unmask(unsigned int virq)
> +static void ps3_chip_unmask(struct irq_data *d)
> {
> - struct ps3_private *pd = get_irq_chip_data(virq);
> + struct ps3_private *pd = get_irq_chip_data(d->irq);
> unsigned long flags;
>
> pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
> - pd->thread_id, virq);
> + pd->thread_id, d->irq);
>
> local_irq_save(flags);
> - set_bit(63 - virq, &pd->bmp.mask);
> + set_bit(63 - d->irq, &pd->bmp.mask);
> lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
> local_irq_restore(flags);
> }
> @@ -141,10 +141,10 @@ static void ps3_chip_unmask(unsigned int virq)
> * Calls lv1_end_of_interrupt_ext().
> */
>
> -static void ps3_chip_eoi(unsigned int virq)
> +static void ps3_chip_eoi(struct irq_data *d)
> {
> - const struct ps3_private *pd = get_irq_chip_data(virq);
> - lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq);
> + const struct ps3_private *pd = get_irq_chip_data(d->irq);
> + lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
> }
>
> /**
> @@ -153,9 +153,9 @@ static void ps3_chip_eoi(unsigned int virq)
>
> static struct irq_chip ps3_irq_chip = {
> .name = "ps3",
> - .mask = ps3_chip_mask,
> - .unmask = ps3_chip_unmask,
> - .eoi = ps3_chip_eoi,
> + .irq_mask = ps3_chip_mask,
> + .irq_unmask = ps3_chip_unmask,
> + .irq_eoi = ps3_chip_eoi,
> };
>
> /**
> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
> index d345bfd..2a0089a 100644
> --- a/arch/powerpc/platforms/pseries/setup.c
> +++ b/arch/powerpc/platforms/pseries/setup.c
> @@ -114,10 +114,13 @@ static void __init fwnmi_init(void)
>
> static void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> unsigned int cascade_irq = i8259_irq();
> +
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
> - desc->chip->eoi(irq);
> +
> + chip->irq_eoi(&desc->irq_data);
> }
>
> static void __init pseries_setup_i8259_cascade(void)
> diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
> index 7b96e5a..7e8ad8e 100644
> --- a/arch/powerpc/platforms/pseries/xics.c
> +++ b/arch/powerpc/platforms/pseries/xics.c
> @@ -202,20 +202,20 @@ static int get_irq_server(unsigned int virq, const struct cpumask *cpumask,
> #define get_irq_server(virq, cpumask, strict_check) (default_server)
> #endif
>
> -static void xics_unmask_irq(unsigned int virq)
> +static void xics_unmask_irq(struct irq_data *d)
> {
> unsigned int irq;
> int call_status;
> int server;
>
> - pr_devel("xics: unmask virq %d\n", virq);
> + pr_devel("xics: unmask virq %d\n", d->irq);
>
> - irq = (unsigned int)irq_map[virq].hwirq;
> + irq = (unsigned int)irq_map[d->irq].hwirq;
> pr_devel(" -> map to hwirq 0x%x\n", irq);
> if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
> return;
>
> - server = get_irq_server(virq, irq_to_desc(virq)->affinity, 0);
> + server = get_irq_server(d->irq, irq_to_desc(d->irq)->affinity, 0);
>
> call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
> DEFAULT_PRIORITY);
> @@ -235,22 +235,22 @@ static void xics_unmask_irq(unsigned int virq)
> }
> }
>
> -static unsigned int xics_startup(unsigned int virq)
> +static unsigned int xics_startup(struct irq_data *d)
> {
> /*
> * The generic MSI code returns with the interrupt disabled on the
> * card, using the MSI mask bits. Firmware doesn't appear to unmask
> * at that level, so we do it here by hand.
> */
> - if (irq_to_desc(virq)->msi_desc)
> - unmask_msi_irq(irq_get_irq_data(virq));
> + if (irq_to_desc(d->irq)->msi_desc)
> + unmask_msi_irq(d);
>
> /* unmask it */
> - xics_unmask_irq(virq);
> + xics_unmask_irq(d);
> return 0;
> }
>
> -static void xics_mask_real_irq(unsigned int irq)
> +static void xics_mask_real_irq(struct irq_data *d)
> {
> int call_status;
>
> @@ -274,13 +274,13 @@ static void xics_mask_real_irq(unsigned int irq)
> }
> }
>
> -static void xics_mask_irq(unsigned int virq)
> +static void xics_mask_irq(struct irq_data *d)
> {
> unsigned int irq;
>
> - pr_devel("xics: mask virq %d\n", virq);
> + pr_devel("xics: mask virq %d\n", d->irq);
>
> - irq = (unsigned int)irq_map[virq].hwirq;
> + irq = (unsigned int)irq_map[d->irq].hwirq;
> if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
> return;
> xics_mask_real_irq(irq);
> @@ -371,30 +371,31 @@ static unsigned char pop_cppr(void)
> return os_cppr->stack[--os_cppr->index];
> }
>
> -static void xics_eoi_direct(unsigned int virq)
> +static void xics_eoi_direct(struct irq_data *d)
> {
> - unsigned int irq = (unsigned int)irq_map[virq].hwirq;
> + unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
>
> iosync();
> direct_xirr_info_set((pop_cppr() << 24) | irq);
> }
>
> -static void xics_eoi_lpar(unsigned int virq)
> +static void xics_eoi_lpar(struct irq_data *d)
> {
> - unsigned int irq = (unsigned int)irq_map[virq].hwirq;
> + unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
>
> iosync();
> lpar_xirr_info_set((pop_cppr() << 24) | irq);
> }
>
> -static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
> +static int
> +xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force)
> {
> unsigned int irq;
> int status;
> int xics_status[2];
> int irq_server;
>
> - irq = (unsigned int)irq_map[virq].hwirq;
> + irq = (unsigned int)irq_map[d->irq].hwirq;
> if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
> return -1;
>
> @@ -406,13 +407,13 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
> return -1;
> }
>
> - irq_server = get_irq_server(virq, cpumask, 1);
> + irq_server = get_irq_server(d->irq, cpumask, 1);
> if (irq_server == -1) {
> char cpulist[128];
> cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
> printk(KERN_WARNING
> "%s: No online cpus in the mask %s for irq %d\n",
> - __func__, cpulist, virq);
> + __func__, cpulist, d->irq);
> return -1;
> }
>
> @@ -430,20 +431,20 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
>
> static struct irq_chip xics_pic_direct = {
> .name = "XICS",
> - .startup = xics_startup,
> - .mask = xics_mask_irq,
> - .unmask = xics_unmask_irq,
> - .eoi = xics_eoi_direct,
> - .set_affinity = xics_set_affinity
> + .irq_startup = xics_startup,
> + .irq_mask = xics_mask_irq,
> + .irq_unmask = xics_unmask_irq,
> + .irq_eoi = xics_eoi_direct,
> + .irq_set_affinity = xics_set_affinity
> };
>
> static struct irq_chip xics_pic_lpar = {
> .name = "XICS",
> - .startup = xics_startup,
> - .mask = xics_mask_irq,
> - .unmask = xics_unmask_irq,
> - .eoi = xics_eoi_lpar,
> - .set_affinity = xics_set_affinity
> + .irq_startup = xics_startup,
> + .irq_mask = xics_mask_irq,
> + .irq_unmask = xics_unmask_irq,
> + .irq_eoi = xics_eoi_lpar,
> + .irq_set_affinity = xics_set_affinity
> };
>
>
> @@ -890,6 +891,7 @@ void xics_migrate_irqs_away(void)
>
> for_each_irq(virq) {
> struct irq_desc *desc;
> + struct irq_chip *chip;
> int xics_status[2];
> int status;
> unsigned long flags;
> @@ -903,12 +905,15 @@ void xics_migrate_irqs_away(void)
> /* We need to get IPIs still. */
> if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
> continue;
> +
> desc = irq_to_desc(virq);
>
> /* We only need to migrate enabled IRQS */
> - if (desc == NULL || desc->chip == NULL
> - || desc->action == NULL
> - || desc->chip->set_affinity == NULL)
> + if (desc == NULL || desc->action == NULL)
> + continue;
> +
> + chip = get_irq_desc_chip(desc);
> + if (chip == NULL || chip->irq_set_affinity == NULL)
> continue;
>
> raw_spin_lock_irqsave(&desc->lock, flags);
> @@ -934,8 +939,8 @@ void xics_migrate_irqs_away(void)
> virq, cpu);
>
> /* Reset affinity to all cpus */
> - cpumask_setall(irq_to_desc(virq)->affinity);
> - desc->chip->set_affinity(virq, cpu_all_mask);
> + cpumask_setall(desc->irq_data.affinity);
> + chip->irq_set_affinity(&desc->irq_data, cpu_all_mask, true);
> unlock:
> raw_spin_unlock_irqrestore(&desc->lock, flags);
> }
> diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
> index 0085212..0476bcc 100644
> --- a/arch/powerpc/sysdev/cpm1.c
> +++ b/arch/powerpc/sysdev/cpm1.c
> @@ -56,32 +56,32 @@ static cpic8xx_t __iomem *cpic_reg;
>
> static struct irq_host *cpm_pic_host;
>
> -static void cpm_mask_irq(unsigned int irq)
> +static void cpm_mask_irq(struct irq_data *d)
> {
> - unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
> + unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
>
> clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
> }
>
> -static void cpm_unmask_irq(unsigned int irq)
> +static void cpm_unmask_irq(struct irq_data *d)
> {
> - unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
> + unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
>
> setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
> }
>
> -static void cpm_end_irq(unsigned int irq)
> +static void cpm_end_irq(struct irq_data *d)
> {
> - unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
> + unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
>
> out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
> }
>
> static struct irq_chip cpm_pic = {
> .name = "CPM PIC",
> - .mask = cpm_mask_irq,
> - .unmask = cpm_unmask_irq,
> - .eoi = cpm_end_irq,
> + .irq_mask = cpm_mask_irq,
> + .irq_unmask = cpm_unmask_irq,
> + .irq_eoi = cpm_end_irq,
> };
>
> int cpm_get_irq(void)
> diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
> index fcea4ff..4730325 100644
> --- a/arch/powerpc/sysdev/cpm2_pic.c
> +++ b/arch/powerpc/sysdev/cpm2_pic.c
> @@ -78,10 +78,10 @@ static const u_char irq_to_siubit[] = {
> 24, 25, 26, 27, 28, 29, 30, 31,
> };
>
> -static void cpm2_mask_irq(unsigned int virq)
> +static void cpm2_mask_irq(struct irq_data *d)
> {
> int bit, word;
> - unsigned int irq_nr = virq_to_hw(virq);
> + unsigned int irq_nr = virq_to_hw(d->irq);
>
> bit = irq_to_siubit[irq_nr];
> word = irq_to_siureg[irq_nr];
> @@ -90,10 +90,10 @@ static void cpm2_mask_irq(unsigned int virq)
> out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
> }
>
> -static void cpm2_unmask_irq(unsigned int virq)
> +static void cpm2_unmask_irq(struct irq_data *d)
> {
> int bit, word;
> - unsigned int irq_nr = virq_to_hw(virq);
> + unsigned int irq_nr = virq_to_hw(d->irq);
>
> bit = irq_to_siubit[irq_nr];
> word = irq_to_siureg[irq_nr];
> @@ -102,10 +102,10 @@ static void cpm2_unmask_irq(unsigned int virq)
> out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
> }
>
> -static void cpm2_ack(unsigned int virq)
> +static void cpm2_ack(struct irq_data *d)
> {
> int bit, word;
> - unsigned int irq_nr = virq_to_hw(virq);
> + unsigned int irq_nr = virq_to_hw(d->irq);
>
> bit = irq_to_siubit[irq_nr];
> word = irq_to_siureg[irq_nr];
> @@ -113,11 +113,11 @@ static void cpm2_ack(unsigned int virq)
> out_be32(&cpm2_intctl->ic_sipnrh + word, 1 << bit);
> }
>
> -static void cpm2_end_irq(unsigned int virq)
> +static void cpm2_end_irq(struct irq_data *d)
> {
> struct irq_desc *desc;
> int bit, word;
> - unsigned int irq_nr = virq_to_hw(virq);
> + unsigned int irq_nr = virq_to_hw(d->irq);
>
> desc = irq_to_desc(irq_nr);
> if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))
> @@ -137,10 +137,10 @@ static void cpm2_end_irq(unsigned int virq)
> }
> }
>
> -static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
> +static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
> {
> - unsigned int src = virq_to_hw(virq);
> - struct irq_desc *desc = irq_to_desc(virq);
> + unsigned int src = virq_to_hw(d->irq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
> unsigned int vold, vnew, edibit;
>
> /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
> @@ -199,11 +199,11 @@ err_sense:
>
> static struct irq_chip cpm2_pic = {
> .name = "CPM2 SIU",
> - .mask = cpm2_mask_irq,
> - .unmask = cpm2_unmask_irq,
> - .ack = cpm2_ack,
> - .eoi = cpm2_end_irq,
> - .set_type = cpm2_set_irq_type,
> + .irq_mask = cpm2_mask_irq,
> + .irq_unmask = cpm2_unmask_irq,
> + .irq_ack = cpm2_ack,
> + .irq_eoi = cpm2_end_irq,
> + .irq_set_type = cpm2_set_irq_type,
> };
>
> unsigned int cpm2_get_irq(void)
> diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
> index 108d76f..f6051d7 100644
> --- a/arch/powerpc/sysdev/fsl_msi.c
> +++ b/arch/powerpc/sysdev/fsl_msi.c
> @@ -47,14 +47,14 @@ static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg)
> * We do not need this actually. The MSIR register has been read once
> * in the cascade interrupt. So, this MSI interrupt has been acked
> */
> -static void fsl_msi_end_irq(unsigned int virq)
> +static void fsl_msi_end_irq(struct irq_data *d)
> {
> }
>
> static struct irq_chip fsl_msi_chip = {
> .irq_mask = mask_msi_irq,
> .irq_unmask = unmask_msi_irq,
> - .ack = fsl_msi_end_irq,
> + .irq_ack = fsl_msi_end_irq,
> .name = "FSL-MSI",
> };
>
> @@ -183,6 +183,7 @@ out_free:
>
> static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> unsigned int cascade_irq;
> struct fsl_msi *msi_data;
> int msir_index = -1;
> @@ -196,11 +197,11 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
>
> raw_spin_lock(&desc->lock);
> if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
> - if (desc->chip->mask_ack)
> - desc->chip->mask_ack(irq);
> + if (chip->irq_mask_ack)
> + chip->irq_mask_ack(&desc->irq_data);
> else {
> - desc->chip->mask(irq);
> - desc->chip->ack(irq);
> + chip->irq_mask(&desc->irq_data);
> + chip->irq_ack(&desc->irq_data);
> }
> }
>
> @@ -238,11 +239,11 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
>
> switch (msi_data->feature & FSL_PIC_IP_MASK) {
> case FSL_PIC_IP_MPIC:
> - desc->chip->eoi(irq);
> + chip->irq_eoi(&desc->irq_data);
> break;
> case FSL_PIC_IP_IPIC:
> - if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
> - desc->chip->unmask(irq);
> + if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
> + chip->irq_unmask(&desc->irq_data);
> break;
> }
> unlock:
> diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
> index 6323e70..aeda4c8 100644
> --- a/arch/powerpc/sysdev/i8259.c
> +++ b/arch/powerpc/sysdev/i8259.c
> @@ -78,19 +78,19 @@ unsigned int i8259_irq(void)
> return irq;
> }
>
> -static void i8259_mask_and_ack_irq(unsigned int irq_nr)
> +static void i8259_mask_and_ack_irq(struct irq_data *d)
> {
> unsigned long flags;
>
> raw_spin_lock_irqsave(&i8259_lock, flags);
> - if (irq_nr > 7) {
> - cached_A1 |= 1 << (irq_nr-8);
> + if (d->irq > 7) {
> + cached_A1 |= 1 << (d->irq-8);
> inb(0xA1); /* DUMMY */
> outb(cached_A1, 0xA1);
> outb(0x20, 0xA0); /* Non-specific EOI */
> outb(0x20, 0x20); /* Non-specific EOI to cascade */
> } else {
> - cached_21 |= 1 << irq_nr;
> + cached_21 |= 1 << d->irq;
> inb(0x21); /* DUMMY */
> outb(cached_21, 0x21);
> outb(0x20, 0x20); /* Non-specific EOI */
> @@ -104,42 +104,42 @@ static void i8259_set_irq_mask(int irq_nr)
> outb(cached_21,0x21);
> }
>
> -static void i8259_mask_irq(unsigned int irq_nr)
> +static void i8259_mask_irq(struct irq_data *d)
> {
> unsigned long flags;
>
> - pr_debug("i8259_mask_irq(%d)\n", irq_nr);
> + pr_debug("i8259_mask_irq(%d)\n", d->irq);
>
> raw_spin_lock_irqsave(&i8259_lock, flags);
> - if (irq_nr < 8)
> - cached_21 |= 1 << irq_nr;
> + if (d->irq < 8)
> + cached_21 |= 1 << d->irq;
> else
> - cached_A1 |= 1 << (irq_nr-8);
> - i8259_set_irq_mask(irq_nr);
> + cached_A1 |= 1 << (d->irq-8);
> + i8259_set_irq_mask(d->irq);
> raw_spin_unlock_irqrestore(&i8259_lock, flags);
> }
>
> -static void i8259_unmask_irq(unsigned int irq_nr)
> +static void i8259_unmask_irq(struct irq_data *d)
> {
> unsigned long flags;
>
> - pr_debug("i8259_unmask_irq(%d)\n", irq_nr);
> + pr_debug("i8259_unmask_irq(%d)\n", d->irq);
>
> raw_spin_lock_irqsave(&i8259_lock, flags);
> - if (irq_nr < 8)
> - cached_21 &= ~(1 << irq_nr);
> + if (d->irq < 8)
> + cached_21 &= ~(1 << d->irq);
> else
> - cached_A1 &= ~(1 << (irq_nr-8));
> - i8259_set_irq_mask(irq_nr);
> + cached_A1 &= ~(1 << (d->irq-8));
> + i8259_set_irq_mask(d->irq);
> raw_spin_unlock_irqrestore(&i8259_lock, flags);
> }
>
> static struct irq_chip i8259_pic = {
> .name = "i8259",
> - .mask = i8259_mask_irq,
> - .disable = i8259_mask_irq,
> - .unmask = i8259_unmask_irq,
> - .mask_ack = i8259_mask_and_ack_irq,
> + .irq_mask = i8259_mask_irq,
> + .irq_disable = i8259_mask_irq,
> + .irq_unmask = i8259_unmask_irq,
> + .irq_mask_ack = i8259_mask_and_ack_irq,
> };
>
> static struct resource pic1_iores = {
> @@ -188,7 +188,7 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
> static void i8259_host_unmap(struct irq_host *h, unsigned int virq)
> {
> /* Make sure irq is masked in hardware */
> - i8259_mask_irq(virq);
> + i8259_mask_irq(irq_get_irq_data(virq));
>
> /* remove chip and handler */
> set_irq_chip_and_handler(virq, NULL, NULL);
> diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
> index d7b9b9c..497047d 100644
> --- a/arch/powerpc/sysdev/ipic.c
> +++ b/arch/powerpc/sysdev/ipic.c
> @@ -523,10 +523,10 @@ static inline struct ipic * ipic_from_irq(unsigned int virq)
>
> #define ipic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
>
> -static void ipic_unmask_irq(unsigned int virq)
> +static void ipic_unmask_irq(struct irq_data *d)
> {
> - struct ipic *ipic = ipic_from_irq(virq);
> - unsigned int src = ipic_irq_to_hw(virq);
> + struct ipic *ipic = ipic_from_irq(d->irq);
> + unsigned int src = ipic_irq_to_hw(d->irq);
> unsigned long flags;
> u32 temp;
>
> @@ -539,10 +539,10 @@ static void ipic_unmask_irq(unsigned int virq)
> raw_spin_unlock_irqrestore(&ipic_lock, flags);
> }
>
> -static void ipic_mask_irq(unsigned int virq)
> +static void ipic_mask_irq(struct irq_data *d)
> {
> - struct ipic *ipic = ipic_from_irq(virq);
> - unsigned int src = ipic_irq_to_hw(virq);
> + struct ipic *ipic = ipic_from_irq(d->irq);
> + unsigned int src = ipic_irq_to_hw(d->irq);
> unsigned long flags;
> u32 temp;
>
> @@ -559,10 +559,10 @@ static void ipic_mask_irq(unsigned int virq)
> raw_spin_unlock_irqrestore(&ipic_lock, flags);
> }
>
> -static void ipic_ack_irq(unsigned int virq)
> +static void ipic_ack_irq(struct irq_data *d)
> {
> - struct ipic *ipic = ipic_from_irq(virq);
> - unsigned int src = ipic_irq_to_hw(virq);
> + struct ipic *ipic = ipic_from_irq(d->irq);
> + unsigned int src = ipic_irq_to_hw(d->irq);
> unsigned long flags;
> u32 temp;
>
> @@ -578,10 +578,10 @@ static void ipic_ack_irq(unsigned int virq)
> raw_spin_unlock_irqrestore(&ipic_lock, flags);
> }
>
> -static void ipic_mask_irq_and_ack(unsigned int virq)
> +static void ipic_mask_irq_and_ack(struct irq_data *d)
> {
> - struct ipic *ipic = ipic_from_irq(virq);
> - unsigned int src = ipic_irq_to_hw(virq);
> + struct ipic *ipic = ipic_from_irq(d->irq);
> + unsigned int src = ipic_irq_to_hw(d->irq);
> unsigned long flags;
> u32 temp;
>
> @@ -601,11 +601,11 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
> raw_spin_unlock_irqrestore(&ipic_lock, flags);
> }
>
> -static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
> +static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
> {
> - struct ipic *ipic = ipic_from_irq(virq);
> - unsigned int src = ipic_irq_to_hw(virq);
> - struct irq_desc *desc = irq_to_desc(virq);
> + struct ipic *ipic = ipic_from_irq(d->irq);
> + unsigned int src = ipic_irq_to_hw(d->irq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
> unsigned int vold, vnew, edibit;
>
> if (flow_type == IRQ_TYPE_NONE)
> @@ -630,10 +630,10 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
> if (flow_type & IRQ_TYPE_LEVEL_LOW) {
> desc->status |= IRQ_LEVEL;
> desc->handle_irq = handle_level_irq;
> - desc->chip = &ipic_level_irq_chip;
> + desc->irq_data.chip = &ipic_level_irq_chip;
> } else {
> desc->handle_irq = handle_edge_irq;
> - desc->chip = &ipic_edge_irq_chip;
> + desc->irq_data.chip = &ipic_edge_irq_chip;
> }
>
> /* only EXT IRQ senses are programmable on ipic
> @@ -661,19 +661,19 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
> /* level interrupts and edge interrupts have different ack operations */
> static struct irq_chip ipic_level_irq_chip = {
> .name = "IPIC",
> - .unmask = ipic_unmask_irq,
> - .mask = ipic_mask_irq,
> - .mask_ack = ipic_mask_irq,
> - .set_type = ipic_set_irq_type,
> + .irq_unmask = ipic_unmask_irq,
> + .irq_mask = ipic_mask_irq,
> + .irq_mask_ack = ipic_mask_irq,
> + .irq_set_type = ipic_set_irq_type,
> };
>
> static struct irq_chip ipic_edge_irq_chip = {
> .name = "IPIC",
> - .unmask = ipic_unmask_irq,
> - .mask = ipic_mask_irq,
> - .mask_ack = ipic_mask_irq_and_ack,
> - .ack = ipic_ack_irq,
> - .set_type = ipic_set_irq_type,
> + .irq_unmask = ipic_unmask_irq,
> + .irq_mask = ipic_mask_irq,
> + .irq_mask_ack = ipic_mask_irq_and_ack,
> + .irq_ack = ipic_ack_irq,
> + .irq_set_type = ipic_set_irq_type,
> };
>
> static int ipic_host_match(struct irq_host *h, struct device_node *node)
> diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
> index 8c27d26..1a75a7f 100644
> --- a/arch/powerpc/sysdev/mpc8xx_pic.c
> +++ b/arch/powerpc/sysdev/mpc8xx_pic.c
> @@ -25,10 +25,10 @@ static sysconf8xx_t __iomem *siu_reg;
>
> int cpm_get_irq(struct pt_regs *regs);
>
> -static void mpc8xx_unmask_irq(unsigned int virq)
> +static void mpc8xx_unmask_irq(struct irq_data *d)
> {
> int bit, word;
> - unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
> + unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
>
> bit = irq_nr & 0x1f;
> word = irq_nr >> 5;
> @@ -37,10 +37,10 @@ static void mpc8xx_unmask_irq(unsigned int virq)
> out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
> }
>
> -static void mpc8xx_mask_irq(unsigned int virq)
> +static void mpc8xx_mask_irq(struct irq_data *d)
> {
> int bit, word;
> - unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
> + unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
>
> bit = irq_nr & 0x1f;
> word = irq_nr >> 5;
> @@ -49,19 +49,19 @@ static void mpc8xx_mask_irq(unsigned int virq)
> out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
> }
>
> -static void mpc8xx_ack(unsigned int virq)
> +static void mpc8xx_ack(struct irq_data *d)
> {
> int bit;
> - unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
> + unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
>
> bit = irq_nr & 0x1f;
> out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
> }
>
> -static void mpc8xx_end_irq(unsigned int virq)
> +static void mpc8xx_end_irq(struct irq_data *d)
> {
> int bit, word;
> - unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
> + unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
>
> bit = irq_nr & 0x1f;
> word = irq_nr >> 5;
> @@ -70,9 +70,9 @@ static void mpc8xx_end_irq(unsigned int virq)
> out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
> }
>
> -static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
> +static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
> {
> - struct irq_desc *desc = irq_to_desc(virq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
>
> desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
> desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
> @@ -80,7 +80,7 @@ static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
> desc->status |= IRQ_LEVEL;
>
> if (flow_type & IRQ_TYPE_EDGE_FALLING) {
> - irq_hw_number_t hw = (unsigned int)irq_map[virq].hwirq;
> + irq_hw_number_t hw = (unsigned int)irq_map[d->irq].hwirq;
> unsigned int siel = in_be32(&siu_reg->sc_siel);
>
> /* only external IRQ senses are programmable */
> @@ -95,11 +95,11 @@ static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
>
> static struct irq_chip mpc8xx_pic = {
> .name = "MPC8XX SIU",
> - .unmask = mpc8xx_unmask_irq,
> - .mask = mpc8xx_mask_irq,
> - .ack = mpc8xx_ack,
> - .eoi = mpc8xx_end_irq,
> - .set_type = mpc8xx_set_irq_type,
> + .irq_unmask = mpc8xx_unmask_irq,
> + .irq_mask = mpc8xx_mask_irq,
> + .irq_ack = mpc8xx_ack,
> + .irq_eoi = mpc8xx_end_irq,
> + .irq_set_type = mpc8xx_set_irq_type,
> };
>
> unsigned int mpc8xx_get_irq(void)
> diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
> index c48cd81..519a877 100644
> --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
> +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c
> @@ -155,43 +155,43 @@ static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
> 32 - ffs(mask)));
> }
>
> -static void mpc8xxx_irq_unmask(unsigned int virq)
> +static void mpc8xxx_irq_unmask(struct irq_data *d)
> {
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(d->irq);
> struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> unsigned long flags;
>
> spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
>
> - setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq)));
> + setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
>
> spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> }
>
> -static void mpc8xxx_irq_mask(unsigned int virq)
> +static void mpc8xxx_irq_mask(struct irq_data *d)
> {
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(d->irq);
> struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> unsigned long flags;
>
> spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
>
> - clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq)));
> + clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
>
> spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> }
>
> -static void mpc8xxx_irq_ack(unsigned int virq)
> +static void mpc8xxx_irq_ack(struct irq_data *d)
> {
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(d->irq);
> struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
>
> - out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(virq)));
> + out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
> }
>
> -static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
> +static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
> {
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(d->irq);
> struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> unsigned long flags;
>
> @@ -199,14 +199,14 @@ static int mpc8xxx_irq_set_type(unsigned int virq, 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(virq)));
> + mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
> 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(virq)));
> + mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
> spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> break;
>
> @@ -217,11 +217,11 @@ static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
> return 0;
> }
>
> -static int mpc512x_irq_set_type(unsigned int virq, unsigned int flow_type)
> +static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
> {
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(d->irq);
> struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> - unsigned long gpio = virq_to_hw(virq);
> + unsigned long gpio = virq_to_hw(d->irq);
> void __iomem *reg;
> unsigned int shift;
> unsigned long flags;
> @@ -264,10 +264,10 @@ static int mpc512x_irq_set_type(unsigned int virq, unsigned int flow_type)
>
> static struct irq_chip mpc8xxx_irq_chip = {
> .name = "mpc8xxx-gpio",
> - .unmask = mpc8xxx_irq_unmask,
> - .mask = mpc8xxx_irq_mask,
> - .ack = mpc8xxx_irq_ack,
> - .set_type = mpc8xxx_irq_set_type,
> + .irq_unmask = mpc8xxx_irq_unmask,
> + .irq_mask = mpc8xxx_irq_mask,
> + .irq_ack = mpc8xxx_irq_ack,
> + .irq_set_type = mpc8xxx_irq_set_type,
> };
>
> static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
> @@ -276,7 +276,7 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
> struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
>
> if (mpc8xxx_gc->of_dev_id_data)
> - mpc8xxx_irq_chip.set_type = mpc8xxx_gc->of_dev_id_data;
> + mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
>
> set_irq_chip_data(virq, h->host_data);
> set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> index b0c8469..83b34eb 100644
> --- a/arch/powerpc/sysdev/mpic.c
> +++ b/arch/powerpc/sysdev/mpic.c
> @@ -611,7 +611,7 @@ static struct mpic *mpic_find(unsigned int irq)
> if (irq < NUM_ISA_INTERRUPTS)
> return NULL;
>
> - return irq_to_desc(irq)->chip_data;
> + return get_irq_chip_data(irq);
> }
>
> /* Determine if the linux irq is an IPI */
> @@ -645,7 +645,7 @@ static inline struct mpic * mpic_from_ipi(unsigned int ipi)
> /* Get the mpic structure from the irq number */
> static inline struct mpic * mpic_from_irq(unsigned int irq)
> {
> - return irq_to_desc(irq)->chip_data;
> + return get_irq_chip_data(irq);
> }
>
> /* Send an EOI */
> @@ -660,13 +660,13 @@ static inline void mpic_eoi(struct mpic *mpic)
> */
>
>
> -void mpic_unmask_irq(unsigned int irq)
> +void mpic_unmask_irq(struct irq_data *d)
> {
> unsigned int loops = 100000;
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
> + DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, d->irq, src);
>
> mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
> @@ -681,13 +681,13 @@ void mpic_unmask_irq(unsigned int irq)
> } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
> }
>
> -void mpic_mask_irq(unsigned int irq)
> +void mpic_mask_irq(struct irq_data *d)
> {
> unsigned int loops = 100000;
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
> + DBG("%s: disable_irq: %d (src %d)\n", mpic->name, d->irq, src);
>
> mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
> @@ -703,12 +703,12 @@ void mpic_mask_irq(unsigned int irq)
> } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
> }
>
> -void mpic_end_irq(unsigned int irq)
> +void mpic_end_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
>
> #ifdef DEBUG_IRQ
> - DBG("%s: end_irq: %d\n", mpic->name, irq);
> + DBG("%s: end_irq: %d\n", mpic->name, d->irq);
> #endif
> /* We always EOI on end_irq() even for edge interrupts since that
> * should only lower the priority, the MPIC should have properly
> @@ -720,51 +720,51 @@ void mpic_end_irq(unsigned int irq)
>
> #ifdef CONFIG_MPIC_U3_HT_IRQS
>
> -static void mpic_unmask_ht_irq(unsigned int irq)
> +static void mpic_unmask_ht_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - mpic_unmask_irq(irq);
> + mpic_unmask_irq(d);
>
> - if (irq_to_desc(irq)->status & IRQ_LEVEL)
> + if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
> mpic_ht_end_irq(mpic, src);
> }
>
> -static unsigned int mpic_startup_ht_irq(unsigned int irq)
> +static unsigned int mpic_startup_ht_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - mpic_unmask_irq(irq);
> - mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
> + mpic_unmask_irq(d);
> + mpic_startup_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
>
> return 0;
> }
>
> -static void mpic_shutdown_ht_irq(unsigned int irq)
> +static void mpic_shutdown_ht_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> - mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
> - mpic_mask_irq(irq);
> + mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
> + mpic_mask_irq(d);
> }
>
> -static void mpic_end_ht_irq(unsigned int irq)
> +static void mpic_end_ht_irq(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> #ifdef DEBUG_IRQ
> - DBG("%s: end_irq: %d\n", mpic->name, irq);
> + DBG("%s: end_irq: %d\n", mpic->name, d->irq);
> #endif
> /* We always EOI on end_irq() even for edge interrupts since that
> * should only lower the priority, the MPIC should have properly
> * latched another edge interrupt coming in anyway
> */
>
> - if (irq_to_desc(irq)->status & IRQ_LEVEL)
> + if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
> mpic_ht_end_irq(mpic, src);
> mpic_eoi(mpic);
> }
> @@ -772,23 +772,23 @@ static void mpic_end_ht_irq(unsigned int irq)
>
> #ifdef CONFIG_SMP
>
> -static void mpic_unmask_ipi(unsigned int irq)
> +static void mpic_unmask_ipi(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_ipi(irq);
> - unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
> + struct mpic *mpic = mpic_from_ipi(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq) - mpic->ipi_vecs[0];
>
> - DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src);
> + DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, d->irq, src);
> mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
> }
>
> -static void mpic_mask_ipi(unsigned int irq)
> +static void mpic_mask_ipi(struct irq_data *d)
> {
> /* NEVER disable an IPI... that's just plain wrong! */
> }
>
> -static void mpic_end_ipi(unsigned int irq)
> +static void mpic_end_ipi(struct irq_data *d)
> {
> - struct mpic *mpic = mpic_from_ipi(irq);
> + struct mpic *mpic = mpic_from_ipi(d->irq);
>
> /*
> * IPIs are marked IRQ_PER_CPU. This has the side effect of
> @@ -802,10 +802,11 @@ static void mpic_end_ipi(unsigned int irq)
>
> #endif /* CONFIG_SMP */
>
> -int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
> +int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
> + bool force)
> {
> - struct mpic *mpic = mpic_from_irq(irq);
> - unsigned int src = mpic_irq_to_hw(irq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
>
> if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
> int cpuid = irq_choose_cpu(cpumask);
> @@ -848,15 +849,15 @@ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
> }
> }
>
> -int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
> +int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
> {
> - struct mpic *mpic = mpic_from_irq(virq);
> - unsigned int src = mpic_irq_to_hw(virq);
> - struct irq_desc *desc = irq_to_desc(virq);
> + struct mpic *mpic = mpic_from_irq(d->irq);
> + unsigned int src = mpic_irq_to_hw(d->irq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
> unsigned int vecpri, vold, vnew;
>
> DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
> - mpic, virq, src, flow_type);
> + mpic, d->irq, src, flow_type);
>
> if (src >= mpic->irq_count)
> return -EINVAL;
> @@ -907,28 +908,28 @@ void mpic_set_vector(unsigned int virq, unsigned int vector)
> }
>
> static struct irq_chip mpic_irq_chip = {
> - .mask = mpic_mask_irq,
> - .unmask = mpic_unmask_irq,
> - .eoi = mpic_end_irq,
> - .set_type = mpic_set_irq_type,
> + .irq_mask = mpic_mask_irq,
> + .irq_unmask = mpic_unmask_irq,
> + .irq_eoi = mpic_end_irq,
> + .irq_set_type = mpic_set_irq_type,
> };
>
> #ifdef CONFIG_SMP
> static struct irq_chip mpic_ipi_chip = {
> - .mask = mpic_mask_ipi,
> - .unmask = mpic_unmask_ipi,
> - .eoi = mpic_end_ipi,
> + .irq_mask = mpic_mask_ipi,
> + .irq_unmask = mpic_unmask_ipi,
> + .irq_eoi = mpic_end_ipi,
> };
> #endif /* CONFIG_SMP */
>
> #ifdef CONFIG_MPIC_U3_HT_IRQS
> static struct irq_chip mpic_irq_ht_chip = {
> - .startup = mpic_startup_ht_irq,
> - .shutdown = mpic_shutdown_ht_irq,
> - .mask = mpic_mask_irq,
> - .unmask = mpic_unmask_ht_irq,
> - .eoi = mpic_end_ht_irq,
> - .set_type = mpic_set_irq_type,
> + .irq_startup = mpic_startup_ht_irq,
> + .irq_shutdown = mpic_shutdown_ht_irq,
> + .irq_mask = mpic_mask_irq,
> + .irq_unmask = mpic_unmask_ht_irq,
> + .irq_eoi = mpic_end_ht_irq,
> + .irq_set_type = mpic_set_irq_type,
> };
> #endif /* CONFIG_MPIC_U3_HT_IRQS */
>
> @@ -1060,12 +1061,12 @@ struct mpic * __init mpic_alloc(struct device_node *node,
> mpic->hc_irq = mpic_irq_chip;
> mpic->hc_irq.name = name;
> if (flags & MPIC_PRIMARY)
> - mpic->hc_irq.set_affinity = mpic_set_affinity;
> + mpic->hc_irq.irq_set_affinity = mpic_set_affinity;
> #ifdef CONFIG_MPIC_U3_HT_IRQS
> mpic->hc_ht_irq = mpic_irq_ht_chip;
> mpic->hc_ht_irq.name = name;
> if (flags & MPIC_PRIMARY)
> - mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
> + mpic->hc_ht_irq.irq_set_affinity = mpic_set_affinity;
> #endif /* CONFIG_MPIC_U3_HT_IRQS */
>
> #ifdef CONFIG_SMP
> diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
> index e4a6df7..13f3e89 100644
> --- a/arch/powerpc/sysdev/mpic.h
> +++ b/arch/powerpc/sysdev/mpic.h
> @@ -34,9 +34,10 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
> }
> #endif
>
> -extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
> +extern int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type);
> extern void mpic_set_vector(unsigned int virq, unsigned int vector);
> -extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
> +extern int mpic_set_affinity(struct irq_data *d,
> + const struct cpumask *cpumask, bool force);
> extern void mpic_reset_core(int cpu);
>
> #endif /* _POWERPC_SYSDEV_MPIC_H */
> diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
> index 320ad5a..0b7794a 100644
> --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
> +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
> @@ -43,24 +43,24 @@ static void mpic_pasemi_msi_mask_irq(struct irq_data *data)
> {
> pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq);
> mask_msi_irq(data);
> - mpic_mask_irq(data->irq);
> + mpic_mask_irq(data);
> }
>
> static void mpic_pasemi_msi_unmask_irq(struct irq_data *data)
> {
> pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq);
> - mpic_unmask_irq(data->irq);
> + mpic_unmask_irq(data);
> unmask_msi_irq(data);
> }
>
> static struct irq_chip mpic_pasemi_msi_chip = {
> - .irq_shutdown = mpic_pasemi_msi_mask_irq,
> - .irq_mask = mpic_pasemi_msi_mask_irq,
> - .irq_unmask = mpic_pasemi_msi_unmask_irq,
> - .eoi = mpic_end_irq,
> - .set_type = mpic_set_irq_type,
> - .set_affinity = mpic_set_affinity,
> - .name = "PASEMI-MSI",
> + .irq_shutdown = mpic_pasemi_msi_mask_irq,
> + .irq_mask = mpic_pasemi_msi_mask_irq,
> + .irq_unmask = mpic_pasemi_msi_unmask_irq,
> + .irq_eoi = mpic_end_irq,
> + .irq_set_type = mpic_set_irq_type,
> + .irq_set_affinity = mpic_set_affinity,
> + .name = "PASEMI-MSI",
> };
>
> static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
> diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
> index a2b028b..71900ac 100644
> --- a/arch/powerpc/sysdev/mpic_u3msi.c
> +++ b/arch/powerpc/sysdev/mpic_u3msi.c
> @@ -26,23 +26,23 @@ static struct mpic *msi_mpic;
> static void mpic_u3msi_mask_irq(struct irq_data *data)
> {
> mask_msi_irq(data);
> - mpic_mask_irq(data->irq);
> + mpic_mask_irq(data);
> }
>
> static void mpic_u3msi_unmask_irq(struct irq_data *data)
> {
> - mpic_unmask_irq(data->irq);
> + mpic_unmask_irq(data);
> unmask_msi_irq(data);
> }
>
> static struct irq_chip mpic_u3msi_chip = {
> - .irq_shutdown = mpic_u3msi_mask_irq,
> - .irq_mask = mpic_u3msi_mask_irq,
> - .irq_unmask = mpic_u3msi_unmask_irq,
> - .eoi = mpic_end_irq,
> - .set_type = mpic_set_irq_type,
> - .set_affinity = mpic_set_affinity,
> - .name = "MPIC-U3MSI",
> + .irq_shutdown = mpic_u3msi_mask_irq,
> + .irq_mask = mpic_u3msi_mask_irq,
> + .irq_unmask = mpic_u3msi_unmask_irq,
> + .irq_eoi = mpic_end_irq,
> + .irq_set_type = mpic_set_irq_type,
> + .irq_set_affinity = mpic_set_affinity,
> + .name = "MPIC-U3MSI",
> };
>
> static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
> diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
> index 485b924..bc61ebb 100644
> --- a/arch/powerpc/sysdev/mv64x60_pic.c
> +++ b/arch/powerpc/sysdev/mv64x60_pic.c
> @@ -76,9 +76,9 @@ static struct irq_host *mv64x60_irq_host;
> * mv64x60_chip_low functions
> */
>
> -static void mv64x60_mask_low(unsigned int virq)
> +static void mv64x60_mask_low(struct irq_data *d)
> {
> - int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
> + int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
> unsigned long flags;
>
> spin_lock_irqsave(&mv64x60_lock, flags);
> @@ -89,9 +89,9 @@ static void mv64x60_mask_low(unsigned int virq)
> (void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
> }
>
> -static void mv64x60_unmask_low(unsigned int virq)
> +static void mv64x60_unmask_low(struct irq_data *d)
> {
> - int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
> + int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
> unsigned long flags;
>
> spin_lock_irqsave(&mv64x60_lock, flags);
> @@ -104,18 +104,18 @@ static void mv64x60_unmask_low(unsigned int virq)
>
> static struct irq_chip mv64x60_chip_low = {
> .name = "mv64x60_low",
> - .mask = mv64x60_mask_low,
> - .mask_ack = mv64x60_mask_low,
> - .unmask = mv64x60_unmask_low,
> + .irq_mask = mv64x60_mask_low,
> + .irq_mask_ack = mv64x60_mask_low,
> + .irq_unmask = mv64x60_unmask_low,
> };
>
> /*
> * mv64x60_chip_high functions
> */
>
> -static void mv64x60_mask_high(unsigned int virq)
> +static void mv64x60_mask_high(struct irq_data *d)
> {
> - int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
> + int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
> unsigned long flags;
>
> spin_lock_irqsave(&mv64x60_lock, flags);
> @@ -126,9 +126,9 @@ static void mv64x60_mask_high(unsigned int virq)
> (void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
> }
>
> -static void mv64x60_unmask_high(unsigned int virq)
> +static void mv64x60_unmask_high(struct irq_data *d)
> {
> - int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
> + int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
> unsigned long flags;
>
> spin_lock_irqsave(&mv64x60_lock, flags);
> @@ -141,18 +141,18 @@ static void mv64x60_unmask_high(unsigned int virq)
>
> static struct irq_chip mv64x60_chip_high = {
> .name = "mv64x60_high",
> - .mask = mv64x60_mask_high,
> - .mask_ack = mv64x60_mask_high,
> - .unmask = mv64x60_unmask_high,
> + .irq_mask = mv64x60_mask_high,
> + .irq_mask_ack = mv64x60_mask_high,
> + .irq_unmask = mv64x60_unmask_high,
> };
>
> /*
> * mv64x60_chip_gpp functions
> */
>
> -static void mv64x60_mask_gpp(unsigned int virq)
> +static void mv64x60_mask_gpp(struct irq_data *d)
> {
> - int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
> + int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
> unsigned long flags;
>
> spin_lock_irqsave(&mv64x60_lock, flags);
> @@ -163,9 +163,9 @@ static void mv64x60_mask_gpp(unsigned int virq)
> (void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
> }
>
> -static void mv64x60_mask_ack_gpp(unsigned int virq)
> +static void mv64x60_mask_ack_gpp(struct irq_data *d)
> {
> - int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
> + int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
> unsigned long flags;
>
> spin_lock_irqsave(&mv64x60_lock, flags);
> @@ -178,9 +178,9 @@ static void mv64x60_mask_ack_gpp(unsigned int virq)
> (void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE);
> }
>
> -static void mv64x60_unmask_gpp(unsigned int virq)
> +static void mv64x60_unmask_gpp(struct irq_data *d)
> {
> - int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
> + int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
> unsigned long flags;
>
> spin_lock_irqsave(&mv64x60_lock, flags);
> @@ -193,9 +193,9 @@ static void mv64x60_unmask_gpp(unsigned int virq)
>
> static struct irq_chip mv64x60_chip_gpp = {
> .name = "mv64x60_gpp",
> - .mask = mv64x60_mask_gpp,
> - .mask_ack = mv64x60_mask_ack_gpp,
> - .unmask = mv64x60_unmask_gpp,
> + .irq_mask = mv64x60_mask_gpp,
> + .irq_mask_ack = mv64x60_mask_ack_gpp,
> + .irq_unmask = mv64x60_unmask_gpp,
> };
>
> /*
> diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
> index 541ba98..24bfc1e 100644
> --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
> +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
> @@ -189,15 +189,15 @@ static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg
>
> static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
> {
> - return irq_to_desc(virq)->chip_data;
> + return get_irq_chip_data(virq);
> }
>
> #define virq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
>
> -static void qe_ic_unmask_irq(unsigned int virq)
> +static void qe_ic_unmask_irq(struct irq_data *d)
> {
> - struct qe_ic *qe_ic = qe_ic_from_irq(virq);
> - unsigned int src = virq_to_hw(virq);
> + struct qe_ic *qe_ic = qe_ic_from_irq(d->irq);
> + unsigned int src = virq_to_hw(d->irq);
> unsigned long flags;
> u32 temp;
>
> @@ -210,10 +210,10 @@ static void qe_ic_unmask_irq(unsigned int virq)
> raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
> }
>
> -static void qe_ic_mask_irq(unsigned int virq)
> +static void qe_ic_mask_irq(struct irq_data *d)
> {
> - struct qe_ic *qe_ic = qe_ic_from_irq(virq);
> - unsigned int src = virq_to_hw(virq);
> + struct qe_ic *qe_ic = qe_ic_from_irq(d->irq);
> + unsigned int src = virq_to_hw(d->irq);
> unsigned long flags;
> u32 temp;
>
> @@ -238,9 +238,9 @@ static void qe_ic_mask_irq(unsigned int virq)
>
> static struct irq_chip qe_ic_irq_chip = {
> .name = "QEIC",
> - .unmask = qe_ic_unmask_irq,
> - .mask = qe_ic_mask_irq,
> - .mask_ack = qe_ic_mask_irq,
> + .irq_unmask = qe_ic_unmask_irq,
> + .irq_mask = qe_ic_mask_irq,
> + .irq_mask_ack = qe_ic_mask_irq,
> };
>
> static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
> diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
> index 0ab9281..02c91db 100644
> --- a/arch/powerpc/sysdev/tsi108_pci.c
> +++ b/arch/powerpc/sysdev/tsi108_pci.c
> @@ -343,24 +343,9 @@ static inline unsigned int get_pci_source(void)
> * Linux descriptor level callbacks
> */
>
> -static void tsi108_pci_irq_enable(u_int irq)
> +static void tsi108_pci_irq_unmask(struct irq_data *d)
> {
> - tsi108_pci_int_unmask(irq);
> -}
> -
> -static void tsi108_pci_irq_disable(u_int irq)
> -{
> - tsi108_pci_int_mask(irq);
> -}
> -
> -static void tsi108_pci_irq_ack(u_int irq)
> -{
> - tsi108_pci_int_mask(irq);
> -}
> -
> -static void tsi108_pci_irq_end(u_int irq)
> -{
> - tsi108_pci_int_unmask(irq);
> + tsi108_pci_int_unmask(d->irq);
>
> /* Enable interrupts from PCI block */
> tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
> @@ -370,16 +355,25 @@ static void tsi108_pci_irq_end(u_int irq)
> mb();
> }
>
> +static void tsi108_pci_irq_mask(struct irq_data *d)
> +{
> + tsi108_pci_int_mask(d->irq);
> +}
> +
> +static void tsi108_pci_irq_ack(struct irq_data *d)
> +{
> + tsi108_pci_int_mask(d->irq);
> +}
> +
> /*
> * Interrupt controller descriptor for cascaded PCI interrupt controller.
> */
>
> static struct irq_chip tsi108_pci_irq = {
> .name = "tsi108_PCI_int",
> - .mask = tsi108_pci_irq_disable,
> - .ack = tsi108_pci_irq_ack,
> - .end = tsi108_pci_irq_end,
> - .unmask = tsi108_pci_irq_enable,
> + .irq_mask = tsi108_pci_irq_mask,
> + .irq_ack = tsi108_pci_irq_ack,
> + .irq_unmask = tsi108_pci_irq_unmask,
> };
>
> static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
> @@ -437,8 +431,11 @@ void __init tsi108_pci_int_init(struct device_node *node)
>
> void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> unsigned int cascade_irq = get_pci_source();
> +
> if (cascade_irq != NO_IRQ)
> generic_handle_irq(cascade_irq);
> - desc->chip->eoi(irq);
> +
> + chip->irq_eoi(&desc->irq_data);
> }
> diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
> index 0038fb7..1fb46fe 100644
> --- a/arch/powerpc/sysdev/uic.c
> +++ b/arch/powerpc/sysdev/uic.c
> @@ -55,11 +55,11 @@ struct uic {
> struct irq_host *irqhost;
> };
>
> -static void uic_unmask_irq(unsigned int virq)
> +static void uic_unmask_irq(struct irq_data *d)
> {
> - struct irq_desc *desc = irq_to_desc(virq);
> - struct uic *uic = get_irq_chip_data(virq);
> - unsigned int src = uic_irq_to_hw(virq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
> + struct uic *uic = get_irq_chip_data(d->irq);
> + unsigned int src = uic_irq_to_hw(d->irq);
> unsigned long flags;
> u32 er, sr;
>
> @@ -74,10 +74,10 @@ static void uic_unmask_irq(unsigned int virq)
> spin_unlock_irqrestore(&uic->lock, flags);
> }
>
> -static void uic_mask_irq(unsigned int virq)
> +static void uic_mask_irq(struct irq_data *d)
> {
> - struct uic *uic = get_irq_chip_data(virq);
> - unsigned int src = uic_irq_to_hw(virq);
> + struct uic *uic = get_irq_chip_data(d->irq);
> + unsigned int src = uic_irq_to_hw(d->irq);
> unsigned long flags;
> u32 er;
>
> @@ -88,10 +88,10 @@ static void uic_mask_irq(unsigned int virq)
> spin_unlock_irqrestore(&uic->lock, flags);
> }
>
> -static void uic_ack_irq(unsigned int virq)
> +static void uic_ack_irq(struct irq_data *d)
> {
> - struct uic *uic = get_irq_chip_data(virq);
> - unsigned int src = uic_irq_to_hw(virq);
> + struct uic *uic = get_irq_chip_data(d->irq);
> + unsigned int src = uic_irq_to_hw(d->irq);
> unsigned long flags;
>
> spin_lock_irqsave(&uic->lock, flags);
> @@ -99,11 +99,11 @@ static void uic_ack_irq(unsigned int virq)
> spin_unlock_irqrestore(&uic->lock, flags);
> }
>
> -static void uic_mask_ack_irq(unsigned int virq)
> +static void uic_mask_ack_irq(struct irq_data *d)
> {
> - struct irq_desc *desc = irq_to_desc(virq);
> - struct uic *uic = get_irq_chip_data(virq);
> - unsigned int src = uic_irq_to_hw(virq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
> + struct uic *uic = get_irq_chip_data(d->irq);
> + unsigned int src = uic_irq_to_hw(d->irq);
> unsigned long flags;
> u32 er, sr;
>
> @@ -125,18 +125,18 @@ static void uic_mask_ack_irq(unsigned int virq)
> spin_unlock_irqrestore(&uic->lock, flags);
> }
>
> -static int uic_set_irq_type(unsigned int virq, unsigned int flow_type)
> +static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)
> {
> - struct uic *uic = get_irq_chip_data(virq);
> - unsigned int src = uic_irq_to_hw(virq);
> - struct irq_desc *desc = irq_to_desc(virq);
> + struct uic *uic = get_irq_chip_data(d->irq);
> + unsigned int src = uic_irq_to_hw(d->irq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
> unsigned long flags;
> int trigger, polarity;
> u32 tr, pr, mask;
>
> switch (flow_type & IRQ_TYPE_SENSE_MASK) {
> case IRQ_TYPE_NONE:
> - uic_mask_irq(virq);
> + uic_mask_irq(d);
> return 0;
>
> case IRQ_TYPE_EDGE_RISING:
> @@ -178,11 +178,11 @@ static int uic_set_irq_type(unsigned int virq, unsigned int flow_type)
>
> static struct irq_chip uic_irq_chip = {
> .name = "UIC",
> - .unmask = uic_unmask_irq,
> - .mask = uic_mask_irq,
> - .mask_ack = uic_mask_ack_irq,
> - .ack = uic_ack_irq,
> - .set_type = uic_set_irq_type,
> + .irq_unmask = uic_unmask_irq,
> + .irq_mask = uic_mask_irq,
> + .irq_mask_ack = uic_mask_ack_irq,
> + .irq_ack = uic_ack_irq,
> + .irq_set_type = uic_set_irq_type,
> };
>
> static int uic_host_map(struct irq_host *h, unsigned int virq,
> @@ -220,6 +220,7 @@ static struct irq_host_ops uic_host_ops = {
>
> void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> struct uic *uic = get_irq_data(virq);
> u32 msr;
> int src;
> @@ -227,9 +228,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
>
> raw_spin_lock(&desc->lock);
> if (desc->status & IRQ_LEVEL)
> - desc->chip->mask(virq);
> + chip->irq_mask(&desc->irq_data);
> else
> - desc->chip->mask_ack(virq);
> + chip->irq_mask_ack(&desc->irq_data);
> raw_spin_unlock(&desc->lock);
>
> msr = mfdcr(uic->dcrbase + UIC_MSR);
> @@ -244,9 +245,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
> uic_irq_ret:
> raw_spin_lock(&desc->lock);
> if (desc->status & IRQ_LEVEL)
> - desc->chip->ack(virq);
> - if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
> - desc->chip->unmask(virq);
> + chip->irq_ack(&desc->irq_data);
> + if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
> + chip->irq_unmask(&desc->irq_data);
> raw_spin_unlock(&desc->lock);
> }
>
> diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
> index 1e0ccfa..0512f58 100644
> --- a/arch/powerpc/sysdev/xilinx_intc.c
> +++ b/arch/powerpc/sysdev/xilinx_intc.c
> @@ -69,17 +69,17 @@ static unsigned char xilinx_intc_map_senses[] = {
> *
> * IRQ Chip common (across level and edge) operations
> */
> -static void xilinx_intc_mask(unsigned int virq)
> +static void xilinx_intc_mask(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void * regs = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void * regs = get_irq_chip_data(d->irq);
> pr_debug("mask: %d\n", irq);
> out_be32(regs + XINTC_CIE, 1 << irq);
> }
>
> -static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
> +static int xilinx_intc_set_type(struct irq_data *d, unsigned int flow_type)
> {
> - struct irq_desc *desc = irq_to_desc(virq);
> + struct irq_desc *desc = irq_to_desc(d->irq);
>
> desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
> desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
> @@ -91,10 +91,10 @@ static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
> /*
> * IRQ Chip level operations
> */
> -static void xilinx_intc_level_unmask(unsigned int virq)
> +static void xilinx_intc_level_unmask(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void * regs = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void * regs = get_irq_chip_data(d->irq);
> pr_debug("unmask: %d\n", irq);
> out_be32(regs + XINTC_SIE, 1 << irq);
>
> @@ -107,37 +107,37 @@ static void xilinx_intc_level_unmask(unsigned int virq)
>
> static struct irq_chip xilinx_intc_level_irqchip = {
> .name = "Xilinx Level INTC",
> - .mask = xilinx_intc_mask,
> - .mask_ack = xilinx_intc_mask,
> - .unmask = xilinx_intc_level_unmask,
> - .set_type = xilinx_intc_set_type,
> + .irq_mask = xilinx_intc_mask,
> + .irq_mask_ack = xilinx_intc_mask,
> + .irq_unmask = xilinx_intc_level_unmask,
> + .irq_set_type = xilinx_intc_set_type,
> };
>
> /*
> * IRQ Chip edge operations
> */
> -static void xilinx_intc_edge_unmask(unsigned int virq)
> +static void xilinx_intc_edge_unmask(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void *regs = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void *regs = get_irq_chip_data(d->irq);
> pr_debug("unmask: %d\n", irq);
> out_be32(regs + XINTC_SIE, 1 << irq);
> }
>
> -static void xilinx_intc_edge_ack(unsigned int virq)
> +static void xilinx_intc_edge_ack(struct irq_data *d)
> {
> - int irq = virq_to_hw(virq);
> - void * regs = get_irq_chip_data(virq);
> + int irq = virq_to_hw(d->irq);
> + void * regs = get_irq_chip_data(d->irq);
> pr_debug("ack: %d\n", irq);
> out_be32(regs + XINTC_IAR, 1 << irq);
> }
>
> static struct irq_chip xilinx_intc_edge_irqchip = {
> .name = "Xilinx Edge INTC",
> - .mask = xilinx_intc_mask,
> - .unmask = xilinx_intc_edge_unmask,
> - .ack = xilinx_intc_edge_ack,
> - .set_type = xilinx_intc_set_type,
> + .irq_mask = xilinx_intc_mask,
> + .irq_unmask = xilinx_intc_edge_unmask,
> + .irq_ack = xilinx_intc_edge_ack,
> + .irq_set_type = xilinx_intc_set_type,
> };
>
> /*
> @@ -229,12 +229,14 @@ int xilinx_intc_get_irq(void)
> */
> static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
> {
> + struct irq_chip *chip = get_irq_desc_chip(desc);
> unsigned int cascade_irq = i8259_irq();
> +
> if (cascade_irq)
> generic_handle_irq(cascade_irq);
>
> /* Let xilinx_intc end the interrupt */
> - desc->chip->unmask(irq);
> + chip->irq_unmask(&desc->irq_data);
> }
>
> static void __init xilinx_i8259_setup_cascade(void)
> --
> 1.7.1
^ permalink raw reply
* Re: [RFC] Inter-processor Mailboxes Drivers
From: Ira W. Snyder @ 2011-02-14 16:53 UTC (permalink / raw)
To: Ohad Ben-Cohen
Cc: Meador Inge, Hiroshi DOYU, Blanchard, Hollis, openmcapi-dev,
Jamie Iles, linuxppc-dev, linux-arm-kernel
In-Reply-To: <AANLkTinu9VMuFgHeFZGXptDYZyJL6P4qxAA9MA8UewpU@mail.gmail.com>
On Mon, Feb 14, 2011 at 12:03:59PM +0200, Ohad Ben-Cohen wrote:
> On Mon, Feb 14, 2011 at 12:01 PM, Jamie Iles <jamie@jamieiles.com> wrote:
> > On Fri, Feb 11, 2011 at 03:19:51PM -0600, Meador Inge wrote:
> >> 1. Hardware specific bits somewhere under '.../arch/*'. Drivers
> >> for the MPIC message registers on Power and OMAP4 mailboxes, for
> >> example.
> >> 2. A higher level driver under '.../drivers/mailbox/*'. That the
> >> pieces in (1) would register with. This piece would expose the
> >> main kernel API.
> >> 3. Userspace interfaces for accessing the mailboxes. A
> >> '/dev/mailbox1', '/dev/mailbox2', etc... mapping, for example.
> >
> > How about using virtio for all of this and having the mailbox as a
> > notification/message passing driver for the virtio backend?
>
> This is exactly what we are doing now, and it looks promising. expect
> patches soon.
I'll be happy to examine the feasibility of doing a port to mpc83xx as
soon as I see the code. :-) I have been using the message registers to
create a software "network card" over PCI (between a host system and an
mpc83xx in a PCI slot). I have wanted to use virtio for this task for a
long time.
I think a uniform interface for the mailbox registers would be a very
useful API.
Thanks,
Ira
^ permalink raw reply
* Re: [PATCH V8 03/10] USB/ppc4xx: Add Synopsys DWC OTG Core InterfaceLayer
From: Alexander Gordeev @ 2011-02-14 11:34 UTC (permalink / raw)
To: David Laight
Cc: Tirumala Marri, Greg KH, linux-usb, Mark Miesfeld, linuxppc-dev,
Fushen Chen
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6D8AC4D@saturn3.aculab.com>
[-- Attachment #1: Type: text/plain, Size: 724 bytes --]
В Mon, 14 Feb 2011 08:53:21 -0000
"David Laight" <David.Laight@ACULAB.COM> пишет:
>
> > > Sorry, I don't understand that. I think u32 is always 32bit
> > > 4byte on all archs. Right?
> >
> > Yes.
> >
> > Use an unsigned long if you want to hold a pointer correctly on all
> > arches.
>
> Although that is true for many systems (and probably all ppc Linux)
> it isn't necessarily true (eg 64 bit Microsoft Windows).
> C99 inttypes.h should define uintptr_t as an unsigned integer
> type that is large enough to hold a (data) pointer.
> I'm not sure if this is defined for the Linux kernel.
I think, the most reasonable option is to use a pointer type to hold
pointer. :)
--
Alexander
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* Re: [PATCH v3 3/3] tcm ibmvscsis driver
From: Nicholas A. Bellinger @ 2011-02-14 10:29 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: brking, linuxppc-dev, linux-scsi
In-Reply-To: <20110214192600L.fujita.tomonori@lab.ntt.co.jp>
On Mon, 2011-02-14 at 19:25 +0900, FUJITA Tomonori wrote:
> This is the third version of tcm ibmvscsis driver. You can find the
> first version at:
>
> http://marc.info/?t=129734085600004&r=1&w=2
>
> The changes are:
> v3:
> - fix task attribute (convert MSG_* to TASK_ATTR_*)
> v2:
> - send VIOSRP_MAD_NOT_SUPPORTED for unknown mad type requests.
> - fix inquiry typo
> - sends task management response (for now, 'NOT SUPPORTED').
> - remove dead code.
>
> =
> From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
> Subject: [PATCH v3 3/3] tcm ibmvscsis driver
>
> This replaces ibmvstgt driver that uses the old target framework.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
> ---
> drivers/scsi/ibmvscsi/Makefile | 4 +-
> drivers/scsi/ibmvscsi/ibmvscsis.c | 1761 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 1764 insertions(+), 1 deletions(-)
> create mode 100644 drivers/scsi/ibmvscsi/ibmvscsis.c
>
Merged and pushed your rev3 changes into lio-core-2.6.git/tcm_ibmvscsis
Thanks again Tomo-san!
--nab
^ permalink raw reply
* [PATCH v3 3/3] tcm ibmvscsis driver
From: FUJITA Tomonori @ 2011-02-14 10:25 UTC (permalink / raw)
To: linux-scsi; +Cc: brking, linuxppc-dev, nab
This is the third version of tcm ibmvscsis driver. You can find the
first version at:
http://marc.info/?t=129734085600004&r=1&w=2
The changes are:
v3:
- fix task attribute (convert MSG_* to TASK_ATTR_*)
v2:
- send VIOSRP_MAD_NOT_SUPPORTED for unknown mad type requests.
- fix inquiry typo
- sends task management response (for now, 'NOT SUPPORTED').
- remove dead code.
=
From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Subject: [PATCH v3 3/3] tcm ibmvscsis driver
This replaces ibmvstgt driver that uses the old target framework.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
---
drivers/scsi/ibmvscsi/Makefile | 4 +-
drivers/scsi/ibmvscsi/ibmvscsis.c | 1761 +++++++++++++++++++++++++++++++++++++
2 files changed, 1764 insertions(+), 1 deletions(-)
create mode 100644 drivers/scsi/ibmvscsi/ibmvscsis.c
diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile
index a423d96..a615ea5 100644
--- a/drivers/scsi/ibmvscsi/Makefile
+++ b/drivers/scsi/ibmvscsi/Makefile
@@ -1,8 +1,10 @@
+EXTRA_CFLAGS += -I$(srctree)/drivers/target/
+
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o
ibmvscsic-y += ibmvscsi.o
ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o
ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o
-obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o
+obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsis.o
obj-$(CONFIG_SCSI_IBMVFC) += ibmvfc.o
diff --git a/drivers/scsi/ibmvscsi/ibmvscsis.c b/drivers/scsi/ibmvscsi/ibmvscsis.c
new file mode 100644
index 0000000..189c3a3
--- /dev/null
+++ b/drivers/scsi/ibmvscsi/ibmvscsis.c
@@ -0,0 +1,1761 @@
+/*
+ * IBM eServer i/pSeries Virtual SCSI Target Driver
+ * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp.
+ * Santiago Leon (santil@us.ibm.com) IBM Corp.
+ * Linda Xie (lxie@us.ibm.com) IBM Corp.
+ *
+ * Copyright (C) 2005-2011 FUJITA Tomonori <tomof@acm.org>
+ * Copyright (C) 2010 Nicholas A. Bellinger <nab@kernel.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/utsname.h>
+#include <asm/unaligned.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/libsrp.h>
+#include <scsi/libsas.h> /* For TASK_ATTR_* */
+#include <generated/utsrelease.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_transport.h>
+#include <target/target_core_fabric_ops.h>
+#include <target/target_core_fabric_lib.h>
+#include <target/target_core_fabric_configfs.h>
+#include <target/target_core_device.h>
+#include <target/target_core_tpg.h>
+#include <target/target_core_configfs.h>
+
+#include <asm/hvcall.h>
+#include <asm/iommu.h>
+#include <asm/prom.h>
+#include <asm/vio.h>
+
+#include "ibmvscsi.h"
+#include "viosrp.h"
+
+#define IBMVSCSIS_VERSION "v0.1"
+#define IBMVSCSIS_NAMELEN 32
+
+#define INITIAL_SRP_LIMIT 16
+#define DEFAULT_MAX_SECTORS 256
+
+/*
+ * Hypervisor calls.
+ */
+#define h_copy_rdma(l, sa, sb, da, db) \
+ plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db)
+#define h_send_crq(ua, l, h) \
+ plpar_hcall_norets(H_SEND_CRQ, ua, l, h)
+#define h_reg_crq(ua, tok, sz)\
+ plpar_hcall_norets(H_REG_CRQ, ua, tok, sz);
+#define h_free_crq(ua) \
+ plpar_hcall_norets(H_FREE_CRQ, ua);
+
+#define GETTARGET(x) ((int)((((u64)(x)) >> 56) & 0x003f))
+#define GETBUS(x) ((int)((((u64)(x)) >> 53) & 0x0007))
+#define GETLUN(x) ((int)((((u64)(x)) >> 48) & 0x001f))
+
+/*
+ * These are fixed for the system and come from the Open Firmware device tree.
+ * We just store them here to save getting them every time.
+ */
+static char system_id[64] = "";
+static char partition_name[97] = "UNKNOWN";
+static unsigned int partition_number = -1;
+
+static LIST_HEAD(tpg_list);
+static DEFINE_SPINLOCK(tpg_lock);
+
+struct ibmvscsis_adapter {
+ struct vio_dev *dma_dev;
+ struct list_head siblings;
+
+ struct crq_queue crq_queue;
+
+ struct work_struct crq_work;
+
+ unsigned long liobn;
+ unsigned long riobn;
+
+ /* todo: remove */
+ struct srp_target srpt;
+
+ /* SRP port target portal group tag for TCM */
+ unsigned long tport_tpgt;
+
+ /* Returned by ibmvscsis_make_tpg() */
+ struct se_portal_group se_tpg;
+
+ struct se_session *se_sess;
+
+
+ /* SCSI protocol the tport is providing */
+ u8 tport_proto_id;
+ /* Binary World Wide unique Port Name for SRP Target port */
+ u64 tport_wwpn;
+ /* ASCII formatted WWPN for SRP Target port */
+ char tport_name[IBMVSCSIS_NAMELEN];
+ /* Returned by ibmvscsis_make_tport() */
+ struct se_wwn tport_wwn;
+};
+
+struct ibmvscsis_cmnd {
+ /* Used for libsrp processing callbacks */
+ struct scsi_cmnd sc;
+ /* Used for TCM Core operations */
+ struct se_cmd se_cmd;
+ /* Sense buffer that will be mapped into outgoing status */
+ unsigned char sense_buf[TRANSPORT_SENSE_BUFFER];
+};
+
+static int ibmvscsis_check_true(struct se_portal_group *se_tpg)
+{
+ return 1;
+}
+
+static int ibmvscsis_check_false(struct se_portal_group *se_tpg)
+{
+ return 0;
+}
+
+static char *ibmvscsis_get_fabric_name(void)
+{
+ return "ibmvscsis";
+}
+
+static u8 ibmvscsis_get_fabric_proto_ident(struct se_portal_group *se_tpg)
+{
+ return 4;
+}
+
+static char *ibmvscsis_get_fabric_wwn(struct se_portal_group *se_tpg)
+{
+ struct ibmvscsis_adapter *adapter =
+ container_of(se_tpg, struct ibmvscsis_adapter, se_tpg);
+
+ return adapter->tport_name;
+}
+
+static u16 ibmvscsis_get_tag(struct se_portal_group *se_tpg)
+{
+ struct ibmvscsis_adapter *adapter =
+ container_of(se_tpg, struct ibmvscsis_adapter, se_tpg);
+ return adapter->tport_tpgt;
+}
+
+static u32 ibmvscsis_get_default_depth(struct se_portal_group *se_tpg)
+{
+ return 1;
+}
+
+/* we don't care about the transport id since we never use pr. */
+static u32 ibmvscsis_get_pr_transport_id(struct se_portal_group *se_tpg,
+ struct se_node_acl *se_nacl,
+ struct t10_pr_registration *pr_reg,
+ int *format_code,
+ unsigned char *buf)
+{
+ return 24;
+}
+
+static u32 ibmvscsis_get_pr_transport_id_len(struct se_portal_group *se_tpg,
+ struct se_node_acl *se_nacl,
+ struct t10_pr_registration *pr_reg,
+ int *format_code)
+{
+ return 24;
+}
+
+static char *ibmvscsis_parse_pr_out_transport_id(struct se_portal_group *se_tpg,
+ const char *buf,
+ u32 *out_tid_len,
+ char **port_nexus_ptr)
+{
+ return NULL;
+}
+
+struct ibmvscsis_nacl {
+ /* Binary World Wide unique Port Name for SRP Initiator port */
+ u64 iport_wwpn;
+ /* ASCII formatted WWPN for Sas Initiator port */
+ char iport_name[IBMVSCSIS_NAMELEN];
+ /* Returned by ibmvscsis_make_nodeacl() */
+ struct se_node_acl se_node_acl;
+};
+
+static struct se_node_acl *ibmvscsis_alloc_fabric_acl(struct se_portal_group *se_tpg)
+{
+ struct ibmvscsis_nacl *nacl;
+
+ nacl = kzalloc(sizeof(struct ibmvscsis_nacl), GFP_KERNEL);
+ if (!(nacl)) {
+ printk(KERN_ERR "Unable to alocate struct ibmvscsis_nacl\n");
+ return NULL;
+ }
+
+ return &nacl->se_node_acl;
+}
+
+static void ibmvscsis_release_fabric_acl(struct se_portal_group *se_tpg,
+ struct se_node_acl *se_nacl)
+{
+ struct ibmvscsis_nacl *nacl = container_of(se_nacl,
+ struct ibmvscsis_nacl, se_node_acl);
+ kfree(nacl);
+}
+
+static u32 ibmvscsis_tpg_get_inst_index(struct se_portal_group *se_tpg)
+{
+ return 1;
+}
+
+static void ibmvscsis_release_cmd(struct se_cmd *se_cmd)
+{
+ struct ibmvscsis_cmnd *cmd =
+ container_of(se_cmd, struct ibmvscsis_cmnd, se_cmd);
+ kfree(cmd);
+ return;
+}
+
+static int ibmvscsis_shutdown_session(struct se_session *se_sess)
+{
+ return 0;
+}
+
+static void ibmvscsis_close_session(struct se_session *se_sess)
+{
+ return;
+}
+
+static void ibmvscsis_stop_session(struct se_session *se_sess,
+ int sess_sleep , int conn_sleep)
+{
+ return;
+}
+
+static void ibmvscsis_reset_nexus(struct se_session *se_sess)
+{
+ return;
+}
+
+static int ibmvscsis_sess_logged_in(struct se_session *se_sess)
+{
+ return 0;
+}
+
+static u32 ibmvscsis_sess_get_index(struct se_session *se_sess)
+{
+ return 0;
+}
+
+static int ibmvscsis_write_pending_status(struct se_cmd *se_cmd)
+{
+ return 0;
+}
+
+static void ibmvscsis_set_default_node_attrs(struct se_node_acl *nacl)
+{
+ return;
+}
+
+static u32 ibmvscsis_get_task_tag(struct se_cmd *se_cmd)
+{
+ return 0;
+}
+
+static int ibmvscsis_get_cmd_state(struct se_cmd *se_cmd)
+{
+ return 0;
+}
+
+static void ibmvscsis_new_cmd_failure(struct se_cmd *se_cmd)
+{
+ return;
+}
+
+static int ibmvscsis_queue_tm_rsp(struct se_cmd *se_cmd)
+{
+ return 0;
+}
+
+static u16 ibmvscsis_set_fabric_sense_len(struct se_cmd *se_cmd,
+ u32 sense_length)
+{
+ return 0;
+}
+
+static u16 ibmvscsis_get_fabric_sense_len(void)
+{
+ return 0;
+}
+
+static int ibmvscsis_is_state_remove(struct se_cmd *se_cmd)
+{
+ return 0;
+}
+
+static u64 make_lun(unsigned int bus, unsigned int target, unsigned int lun);
+
+static u64 ibmvscsis_pack_lun(unsigned int lun)
+{
+ return make_lun(0, lun & 0x003f, 0);
+}
+
+/* Local pointer to allocated TCM configfs fabric module */
+static struct target_fabric_configfs *ibmvscsis_fabric_configfs;
+
+static struct se_portal_group *ibmvscsis_make_tpg(struct se_wwn *wwn,
+ struct config_group *group,
+ const char *name)
+{
+ struct ibmvscsis_adapter *adapter =
+ container_of(wwn, struct ibmvscsis_adapter, tport_wwn);
+ struct se_node_acl *acl;
+ int ret;
+ char *dname = (char *)dev_name(&adapter->dma_dev->dev);
+
+ if (strncmp(name, "tpgt_1", 6))
+ return ERR_PTR(-EINVAL);
+
+ ret = core_tpg_register(&ibmvscsis_fabric_configfs->tf_ops, wwn,
+ &adapter->se_tpg, (void *)adapter,
+ TRANSPORT_TPG_TYPE_NORMAL);
+ if (ret)
+ return ERR_PTR(-ENOMEM);
+
+ adapter->se_sess = transport_init_session();
+ if (!adapter->se_sess) {
+ core_tpg_deregister(&adapter->se_tpg);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ acl = core_tpg_check_initiator_node_acl(&adapter->se_tpg, dname);
+ if (!acl) {
+ transport_free_session(adapter->se_sess);
+ adapter->se_sess = NULL;
+ return ERR_PTR(-ENOMEM);
+ }
+ adapter->se_sess->se_node_acl = acl;
+
+ transport_register_session(&adapter->se_tpg,
+ adapter->se_sess->se_node_acl,
+ adapter->se_sess, adapter);
+
+ return &adapter->se_tpg;
+}
+
+static void ibmvscsis_drop_tpg(struct se_portal_group *se_tpg)
+{
+ struct ibmvscsis_adapter *adapter =
+ container_of(se_tpg, struct ibmvscsis_adapter, se_tpg);
+ unsigned long flags;
+
+
+ transport_deregister_session_configfs(adapter->se_sess);
+ transport_free_session(adapter->se_sess);
+ core_tpg_deregister(se_tpg);
+
+ spin_lock_irqsave(&tpg_lock, flags);
+ adapter->se_sess = NULL;
+ spin_unlock_irqrestore(&tpg_lock, flags);
+}
+
+static struct se_wwn *ibmvscsis_make_tport(struct target_fabric_configfs *tf,
+ struct config_group *group,
+ const char *name)
+{
+ struct ibmvscsis_adapter *adapter;
+ unsigned long tpgt, flags;
+
+ if (strict_strtoul(name, 10, &tpgt))
+ return NULL;
+
+ spin_lock_irqsave(&tpg_lock, flags);
+ list_for_each_entry(adapter, &tpg_list, siblings) {
+ if (tpgt == adapter->tport_tpgt)
+ goto found;
+ }
+
+ spin_unlock_irqrestore(&tpg_lock, flags);
+ return NULL;
+found:
+ spin_unlock_irqrestore(&tpg_lock, flags);
+
+ return &adapter->tport_wwn;
+}
+
+static void ibmvscsis_drop_tport(struct se_wwn *wwn)
+{
+}
+
+static ssize_t ibmvscsis_wwn_show_attr_version(struct target_fabric_configfs *tf,
+ char *page)
+{
+ return sprintf(page, "IBMVSCSIS fabric module %s on %s/%s"
+ "on "UTS_RELEASE"\n", IBMVSCSIS_VERSION, utsname()->sysname,
+ utsname()->machine);
+}
+
+TF_WWN_ATTR_RO(ibmvscsis, version);
+
+static struct configfs_attribute *ibmvscsis_wwn_attrs[] = {
+ &ibmvscsis_wwn_version.attr,
+ NULL,
+};
+
+static int ibmvscsis_write_pending(struct se_cmd *se_cmd);
+static int ibmvscsis_queue_data_in(struct se_cmd *se_cmd);
+static int ibmvscsis_queue_status(struct se_cmd *se_cmd);
+static int ibmvscsis_new_cmd_map(struct se_cmd *se_cmd);
+static void ibmvscsis_check_stop_free(struct se_cmd *se_cmd);
+
+static struct target_core_fabric_ops ibmvscsis_ops = {
+ .task_sg_chaining = 1,
+ .get_fabric_name = ibmvscsis_get_fabric_name,
+ .get_fabric_proto_ident = ibmvscsis_get_fabric_proto_ident,
+ .tpg_get_wwn = ibmvscsis_get_fabric_wwn,
+ .tpg_get_tag = ibmvscsis_get_tag,
+ .tpg_get_default_depth = ibmvscsis_get_default_depth,
+ .tpg_get_pr_transport_id = ibmvscsis_get_pr_transport_id,
+ .tpg_get_pr_transport_id_len = ibmvscsis_get_pr_transport_id_len,
+ .tpg_parse_pr_out_transport_id = ibmvscsis_parse_pr_out_transport_id,
+ .tpg_check_demo_mode = ibmvscsis_check_true,
+ .tpg_check_demo_mode_cache = ibmvscsis_check_true,
+ .tpg_check_demo_mode_write_protect = ibmvscsis_check_false,
+ .tpg_check_prod_mode_write_protect = ibmvscsis_check_false,
+ .tpg_alloc_fabric_acl = ibmvscsis_alloc_fabric_acl,
+ .tpg_release_fabric_acl = ibmvscsis_release_fabric_acl,
+ .tpg_get_inst_index = ibmvscsis_tpg_get_inst_index,
+ .new_cmd_map = ibmvscsis_new_cmd_map,
+ .check_stop_free = ibmvscsis_check_stop_free,
+ .release_cmd_to_pool = ibmvscsis_release_cmd,
+ .release_cmd_direct = ibmvscsis_release_cmd,
+ .shutdown_session = ibmvscsis_shutdown_session,
+ .close_session = ibmvscsis_close_session,
+ .stop_session = ibmvscsis_stop_session,
+ .fall_back_to_erl0 = ibmvscsis_reset_nexus,
+ .sess_logged_in = ibmvscsis_sess_logged_in,
+ .sess_get_index = ibmvscsis_sess_get_index,
+ .sess_get_initiator_sid = NULL,
+ .write_pending = ibmvscsis_write_pending,
+ .write_pending_status = ibmvscsis_write_pending_status,
+ .set_default_node_attributes = ibmvscsis_set_default_node_attrs,
+ .get_task_tag = ibmvscsis_get_task_tag,
+ .get_cmd_state = ibmvscsis_get_cmd_state,
+ .new_cmd_failure = ibmvscsis_new_cmd_failure,
+ .queue_data_in = ibmvscsis_queue_data_in,
+ .queue_status = ibmvscsis_queue_status,
+ .queue_tm_rsp = ibmvscsis_queue_tm_rsp,
+ .get_fabric_sense_len = ibmvscsis_get_fabric_sense_len,
+ .set_fabric_sense_len = ibmvscsis_set_fabric_sense_len,
+ .is_state_remove = ibmvscsis_is_state_remove,
+ .pack_lun = ibmvscsis_pack_lun,
+ .fabric_make_wwn = ibmvscsis_make_tport,
+ .fabric_drop_wwn = ibmvscsis_drop_tport,
+ .fabric_make_tpg = ibmvscsis_make_tpg,
+ .fabric_drop_tpg = ibmvscsis_drop_tpg,
+ .fabric_post_link = NULL,
+ .fabric_pre_unlink = NULL,
+ .fabric_make_np = NULL,
+ .fabric_drop_np = NULL,
+ .fabric_make_nodeacl = NULL,
+ .fabric_drop_nodeacl = NULL,
+};
+
+static inline union viosrp_iu *vio_iu(struct iu_entry *iue)
+{
+ return (union viosrp_iu *)(iue->sbuf->buf);
+}
+
+static int send_iu(struct iu_entry *iue, u64 length, u8 format)
+{
+ struct srp_target *target = iue->target;
+ struct ibmvscsis_adapter *adapter = target->ldata;
+ long rc, rc1;
+ union {
+ struct viosrp_crq cooked;
+ u64 raw[2];
+ } crq;
+
+ /* First copy the SRP */
+ rc = h_copy_rdma(length, adapter->liobn, iue->sbuf->dma,
+ adapter->riobn, iue->remote_token);
+
+ if (rc)
+ printk(KERN_ERR "Error %ld transferring data\n", rc);
+
+ crq.cooked.valid = 0x80;
+ crq.cooked.format = format;
+ crq.cooked.reserved = 0x00;
+ crq.cooked.timeout = 0x00;
+ crq.cooked.IU_length = length;
+ crq.cooked.IU_data_ptr = vio_iu(iue)->srp.rsp.tag;
+
+ if (rc == 0)
+ crq.cooked.status = 0x99; /* Just needs to be non-zero */
+ else
+ crq.cooked.status = 0x00;
+
+ rc1 = h_send_crq(adapter->dma_dev->unit_address, crq.raw[0],
+ crq.raw[1]);
+ if (rc1) {
+ printk(KERN_ERR "%ld sending response\n", rc1);
+ return rc1;
+ }
+
+ return rc;
+}
+
+#define SRP_RSP_SENSE_DATA_LEN 18
+
+static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc,
+ unsigned char status, unsigned char asc)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ uint64_t tag = iu->srp.rsp.tag;
+
+ /* If the linked bit is on and status is good */
+ if (test_bit(V_LINKED, &iue->flags) && (status == NO_SENSE))
+ status = 0x10;
+
+ memset(iu, 0, sizeof(struct srp_rsp));
+ iu->srp.rsp.opcode = SRP_RSP;
+ iu->srp.rsp.req_lim_delta = 1;
+ iu->srp.rsp.tag = tag;
+
+ if (test_bit(V_DIOVER, &iue->flags))
+ iu->srp.rsp.flags |= SRP_RSP_FLAG_DIOVER;
+
+ iu->srp.rsp.data_in_res_cnt = 0;
+ iu->srp.rsp.data_out_res_cnt = 0;
+
+ iu->srp.rsp.flags &= ~SRP_RSP_FLAG_RSPVALID;
+
+ iu->srp.rsp.resp_data_len = 0;
+ iu->srp.rsp.status = status;
+ if (status) {
+ uint8_t *sense = iu->srp.rsp.data;
+
+ if (sc) {
+ iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
+ iu->srp.rsp.sense_data_len = SCSI_SENSE_BUFFERSIZE;
+ memcpy(sense, sc->sense_buffer, SCSI_SENSE_BUFFERSIZE);
+ } else {
+ iu->srp.rsp.status = SAM_STAT_CHECK_CONDITION;
+ iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
+ iu->srp.rsp.sense_data_len = SRP_RSP_SENSE_DATA_LEN;
+
+ /* Valid bit and 'current errors' */
+ sense[0] = (0x1 << 7 | 0x70);
+ /* Sense key */
+ sense[2] = status;
+ /* Additional sense length */
+ sense[7] = 0xa; /* 10 bytes */
+ /* Additional sense code */
+ sense[12] = asc;
+ }
+ }
+
+ send_iu(iue, sizeof(iu->srp.rsp) + SRP_RSP_SENSE_DATA_LEN,
+ VIOSRP_SRP_FORMAT);
+
+ return 0;
+}
+
+static int send_adapter_info(struct iu_entry *iue,
+ dma_addr_t remote_buffer, u16 length)
+{
+ struct srp_target *target = iue->target;
+ struct ibmvscsis_adapter *adapter = target->ldata;
+ dma_addr_t data_token;
+ struct mad_adapter_info_data *info;
+ int err;
+
+ info = dma_alloc_coherent(&adapter->dma_dev->dev, sizeof(*info),
+ &data_token, GFP_KERNEL);
+ if (!info) {
+ printk(KERN_ERR "bad dma_alloc_coherent %p\n", target);
+ return 1;
+ }
+
+ /* Get remote info */
+ err = h_copy_rdma(sizeof(*info), adapter->riobn, remote_buffer,
+ adapter->liobn, data_token);
+ if (err == H_SUCCESS) {
+ printk(KERN_INFO "Client connect: %s (%d)\n",
+ info->partition_name, info->partition_number);
+ }
+
+ memset(info, 0, sizeof(*info));
+
+ strcpy(info->srp_version, "16.a");
+ strncpy(info->partition_name, partition_name,
+ sizeof(info->partition_name));
+ info->partition_number = partition_number;
+ info->mad_version = 1;
+ info->os_type = 2;
+ info->port_max_txu[0] = DEFAULT_MAX_SECTORS << 9;
+
+ /* Send our info to remote */
+ err = h_copy_rdma(sizeof(*info), adapter->liobn, data_token,
+ adapter->riobn, remote_buffer);
+
+ dma_free_coherent(&adapter->dma_dev->dev, sizeof(*info), info,
+ data_token);
+ if (err != H_SUCCESS) {
+ printk(KERN_INFO "Error sending adapter info %d\n", err);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int process_mad_iu(struct iu_entry *iue)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ struct viosrp_adapter_info *info;
+ struct viosrp_host_config *conf;
+
+ switch (iu->mad.empty_iu.common.type) {
+ case VIOSRP_EMPTY_IU_TYPE:
+ printk(KERN_ERR "%s\n", "Unsupported EMPTY MAD IU");
+ break;
+ case VIOSRP_ERROR_LOG_TYPE:
+ printk(KERN_ERR "%s\n", "Unsupported ERROR LOG MAD IU");
+ iu->mad.error_log.common.status = 1;
+ send_iu(iue, sizeof(iu->mad.error_log), VIOSRP_MAD_FORMAT);
+ break;
+ case VIOSRP_ADAPTER_INFO_TYPE:
+ info = &iu->mad.adapter_info;
+ info->common.status = send_adapter_info(iue, info->buffer,
+ info->common.length);
+ send_iu(iue, sizeof(*info), VIOSRP_MAD_FORMAT);
+ break;
+ case VIOSRP_HOST_CONFIG_TYPE:
+ conf = &iu->mad.host_config;
+ conf->common.status = 1;
+ send_iu(iue, sizeof(*conf), VIOSRP_MAD_FORMAT);
+ break;
+ default:
+ printk(KERN_ERR "Unknown type %u\n", iu->srp.rsp.opcode);
+ iu->mad.empty_iu.common.status = VIOSRP_MAD_NOT_SUPPORTED;
+ send_iu(iue, sizeof(iu->mad), VIOSRP_MAD_FORMAT);
+ break;
+ }
+
+ return 1;
+}
+
+static void process_login(struct iu_entry *iue)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ struct srp_login_rsp *rsp = &iu->srp.login_rsp;
+ u64 tag = iu->srp.rsp.tag;
+
+ /*
+ * TODO handle case that requested size is wrong and buffer
+ * format is wrong
+ */
+ memset(iu, 0, sizeof(struct srp_login_rsp));
+ rsp->opcode = SRP_LOGIN_RSP;
+ rsp->req_lim_delta = INITIAL_SRP_LIMIT;
+ rsp->tag = tag;
+ rsp->max_it_iu_len = sizeof(union srp_iu);
+ rsp->max_ti_iu_len = sizeof(union srp_iu);
+ /* direct and indirect */
+ rsp->buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT;
+
+ send_iu(iue, sizeof(*rsp), VIOSRP_SRP_FORMAT);
+}
+
+static void process_tsk_mgmt(struct iu_entry *iue)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ uint64_t tag = iu->srp.rsp.tag;
+ uint8_t *resp_data = iu->srp.rsp.data;
+
+ memset(iu, 0, sizeof(struct srp_rsp));
+ iu->srp.rsp.opcode = SRP_RSP;
+ iu->srp.rsp.req_lim_delta = 1;
+ iu->srp.rsp.tag = tag;
+
+ iu->srp.rsp.data_in_res_cnt = 0;
+ iu->srp.rsp.data_out_res_cnt = 0;
+
+ iu->srp.rsp.flags &= ~SRP_RSP_FLAG_RSPVALID;
+
+ iu->srp.rsp.resp_data_len = 4;
+ /* TASK MANAGEMENT FUNCTION NOT SUPPORTED for now */
+ resp_data[3] = 4;
+
+ send_iu(iue, sizeof(iu->srp.rsp) + iu->srp.rsp.resp_data_len,
+ VIOSRP_SRP_FORMAT);
+}
+
+static int process_srp_iu(struct iu_entry *iue)
+{
+ union viosrp_iu *iu = vio_iu(iue);
+ struct srp_target *target = iue->target;
+ int done = 1;
+ u8 opcode = iu->srp.rsp.opcode;
+ unsigned long flags;
+
+ switch (opcode) {
+ case SRP_LOGIN_REQ:
+ process_login(iue);
+ break;
+ case SRP_TSK_MGMT:
+ process_tsk_mgmt(iue);
+ break;
+ case SRP_CMD:
+ spin_lock_irqsave(&target->lock, flags);
+ list_add_tail(&iue->ilist, &target->cmd_queue);
+ spin_unlock_irqrestore(&target->lock, flags);
+ done = 0;
+ break;
+ case SRP_LOGIN_RSP:
+ case SRP_I_LOGOUT:
+ case SRP_T_LOGOUT:
+ case SRP_RSP:
+ case SRP_CRED_REQ:
+ case SRP_CRED_RSP:
+ case SRP_AER_REQ:
+ case SRP_AER_RSP:
+ printk(KERN_ERR "Unsupported type %u\n", opcode);
+ break;
+ default:
+ printk(KERN_ERR "Unknown type %u\n", opcode);
+ }
+
+ return done;
+}
+
+static void process_iu(struct viosrp_crq *crq,
+ struct ibmvscsis_adapter *adapter)
+{
+ struct iu_entry *iue;
+ long err;
+ int done = 1;
+
+ iue = srp_iu_get(&adapter->srpt);
+ if (!iue) {
+ printk(KERN_ERR "Error getting IU from pool\n");
+ return;
+ }
+
+ iue->remote_token = crq->IU_data_ptr;
+
+ err = h_copy_rdma(crq->IU_length, adapter->riobn,
+ iue->remote_token, adapter->liobn, iue->sbuf->dma);
+
+ if (err != H_SUCCESS) {
+ printk(KERN_ERR "%ld transferring data error %p\n", err, iue);
+ goto out;
+ }
+
+ if (crq->format == VIOSRP_MAD_FORMAT)
+ done = process_mad_iu(iue);
+ else
+ done = process_srp_iu(iue);
+out:
+ if (done)
+ srp_iu_put(iue);
+}
+
+static void process_crq(struct viosrp_crq *crq,
+ struct ibmvscsis_adapter *adapter)
+{
+ switch (crq->valid) {
+ case 0xC0:
+ /* initialization */
+ switch (crq->format) {
+ case 0x01:
+ h_send_crq(adapter->dma_dev->unit_address,
+ 0xC002000000000000, 0);
+ break;
+ case 0x02:
+ break;
+ default:
+ printk(KERN_ERR "Unknown format %u\n", crq->format);
+ }
+ break;
+ case 0xFF:
+ /* transport event */
+ break;
+ case 0x80:
+ /* real payload */
+ switch (crq->format) {
+ case VIOSRP_SRP_FORMAT:
+ case VIOSRP_MAD_FORMAT:
+ process_iu(crq, adapter);
+ break;
+ case VIOSRP_OS400_FORMAT:
+ case VIOSRP_AIX_FORMAT:
+ case VIOSRP_LINUX_FORMAT:
+ case VIOSRP_INLINE_FORMAT:
+ printk(KERN_ERR "Unsupported format %u\n", crq->format);
+ break;
+ default:
+ printk(KERN_ERR "Unknown format %u\n", crq->format);
+ }
+ break;
+ default:
+ printk(KERN_ERR "unknown message type 0x%02x!?\n", crq->valid);
+ }
+}
+
+static inline struct viosrp_crq *next_crq(struct crq_queue *queue)
+{
+ struct viosrp_crq *crq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&queue->lock, flags);
+ crq = &queue->msgs[queue->cur];
+ if (crq->valid & 0x80) {
+ if (++queue->cur == queue->size)
+ queue->cur = 0;
+ } else
+ crq = NULL;
+ spin_unlock_irqrestore(&queue->lock, flags);
+
+ return crq;
+}
+
+static int tcm_queuecommand(struct ibmvscsis_adapter *adapter,
+ struct ibmvscsis_cmnd *vsc,
+ struct srp_cmd *cmd)
+{
+ struct se_cmd *se_cmd;
+ int attr;
+ int data_len;
+ int ret;
+
+ switch (cmd->task_attr) {
+ case SRP_SIMPLE_TASK:
+ attr = TASK_ATTR_SIMPLE;
+ break;
+ case SRP_ORDERED_TASK:
+ attr = TASK_ATTR_ORDERED;
+ break;
+ case SRP_HEAD_TASK:
+ attr = TASK_ATTR_HOQ;
+ break;
+ default:
+ printk(KERN_WARNING "Task attribute %d not supported\n",
+ cmd->task_attr);
+ attr = TASK_ATTR_SIMPLE;
+ }
+
+ data_len = srp_data_length(cmd, srp_cmd_direction(cmd));
+
+ se_cmd = &vsc->se_cmd;
+
+ transport_init_se_cmd(se_cmd,
+ adapter->se_tpg.se_tpg_tfo,
+ adapter->se_sess, data_len,
+ srp_cmd_direction(cmd),
+ attr, vsc->sense_buf);
+
+ ret = transport_get_lun_for_cmd(se_cmd, NULL, cmd->lun);
+ if (ret) {
+ printk(KERN_ERR "invalid lun %u\n", GETLUN(cmd->lun));
+ transport_send_check_condition_and_sense(se_cmd,
+ se_cmd->scsi_sense_reason,
+ 0);
+ return ret;
+ }
+
+ transport_device_setup_cmd(se_cmd);
+ transport_generic_handle_cdb_map(se_cmd);
+
+ return 0;
+}
+
+static int ibmvscsis_new_cmd_map(struct se_cmd *se_cmd)
+{
+ struct ibmvscsis_cmnd *cmd =
+ container_of(se_cmd, struct ibmvscsis_cmnd, se_cmd);
+ struct scsi_cmnd *sc = &cmd->sc;
+ struct iu_entry *iue = (struct iu_entry *)sc->SCp.ptr;
+ struct srp_cmd *scmd = iue->sbuf->buf;
+ int ret;
+
+ /*
+ * Allocate the necessary tasks to complete the received CDB+data
+ */
+ ret = transport_generic_allocate_tasks(se_cmd, scmd->cdb);
+ if (ret == -1) {
+ /* Out of Resources */
+ return PYX_TRANSPORT_LU_COMM_FAILURE;
+ } else if (ret == -2) {
+ /*
+ * Handle case for SAM_STAT_RESERVATION_CONFLICT
+ */
+ if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
+ return PYX_TRANSPORT_RESERVATION_CONFLICT;
+ /*
+ * Otherwise, return SAM_STAT_CHECK_CONDITION and return
+ * sense data
+ */
+ return PYX_TRANSPORT_USE_SENSE_REASON;
+ }
+
+ return 0;
+}
+
+static void ibmvscsis_check_stop_free(struct se_cmd *se_cmd)
+{
+ if (se_cmd->se_tmr_req)
+ return;
+ transport_generic_free_cmd(se_cmd, 0, 1, 0);
+}
+
+static u64 scsi_lun_to_int(u64 lun)
+{
+ if (GETBUS(lun) || GETLUN(lun))
+ return ~0UL;
+ else
+ return GETTARGET(lun);
+}
+
+struct inquiry_data {
+ u8 qual_type;
+ u8 rmb_reserve;
+ u8 version;
+ u8 aerc_naca_hisup_format;
+ u8 addl_len;
+ u8 sccs_reserved;
+ u8 bque_encserv_vs_multip_mchngr_reserved;
+ u8 reladr_reserved_linked_cmdqueue_vs;
+ char vendor[8];
+ char product[16];
+ char revision[4];
+ char vendor_specific[20];
+ char reserved1[2];
+ char version_descriptor[16];
+ char reserved2[22];
+ char unique[158];
+};
+
+static u64 make_lun(unsigned int bus, unsigned int target, unsigned int lun)
+{
+ u16 result = (0x8000 |
+ ((target & 0x003f) << 8) |
+ ((bus & 0x0007) << 5) |
+ (lun & 0x001f));
+ return ((u64) result) << 48;
+}
+
+static int ibmvscsis_inquiry(struct ibmvscsis_adapter *adapter,
+ struct srp_cmd *cmd, char *data)
+{
+ struct se_portal_group *se_tpg = &adapter->se_tpg;
+ struct inquiry_data *id = (struct inquiry_data *)data;
+ u64 unpacked_lun, lun = cmd->lun;
+ u8 *cdb = cmd->cdb;
+ int len;
+
+ if (!data)
+ printk(KERN_INFO "%s %d: oomu\n", __func__, __LINE__);
+
+ if (((cdb[1] & 0x3) == 0x3) || (!(cdb[1] & 0x3) && cdb[2])) {
+ printk(KERN_INFO "%s %d: invalid req\n", __func__, __LINE__);
+ return 0;
+ }
+
+ if (cdb[1] & 0x3)
+ printk(KERN_INFO "%s %d: needs the normal path\n",
+ __func__, __LINE__);
+ else {
+ id->qual_type = TYPE_DISK;
+ id->rmb_reserve = 0x00;
+ id->version = 0x84; /* ISO/IE */
+ id->aerc_naca_hisup_format = 0x22; /* naca & fmt 0x02 */
+ id->addl_len = sizeof(*id) - 4;
+ id->bque_encserv_vs_multip_mchngr_reserved = 0x00;
+ id->reladr_reserved_linked_cmdqueue_vs = 0x02; /* CMDQ */
+ memcpy(id->vendor, "IBM ", 8);
+ /*
+ * Don't even ask about the next bit. AIX uses
+ * hardcoded device naming to recognize device types
+ * and their client won't work unless we use VOPTA and
+ * VDASD.
+ */
+ if (id->qual_type == TYPE_ROM)
+ memcpy(id->product, "VOPTA blkdev ", 16);
+ else
+ memcpy(id->product, "VDASD blkdev ", 16);
+
+ memcpy(id->revision, "0001", 4);
+
+ snprintf(id->unique, sizeof(id->unique),
+ "IBM-VSCSI-%s-P%d-%x-%d-%d-%d\n",
+ system_id,
+ partition_number,
+ adapter->dma_dev->unit_address,
+ GETBUS(lun),
+ GETTARGET(lun),
+ GETLUN(lun));
+ }
+
+ len = min_t(int, sizeof(*id), cdb[4]);
+
+ unpacked_lun = scsi_lun_to_int(cmd->lun);
+
+ spin_lock(&se_tpg->tpg_lun_lock);
+
+ if (unpacked_lun < TRANSPORT_MAX_LUNS_PER_TPG &&
+ se_tpg->tpg_lun_list[unpacked_lun].lun_status ==
+ TRANSPORT_LUN_STATUS_ACTIVE)
+ ;
+ else
+ data[0] = TYPE_NO_LUN;
+
+ spin_unlock(&se_tpg->tpg_lun_lock);
+
+ return len;
+}
+
+static int ibmvscsis_mode_sense(struct ibmvscsis_adapter *adapter,
+ struct srp_cmd *cmd, char *mode)
+{
+ int bytes;
+ struct se_portal_group *se_tpg = &adapter->se_tpg;
+ u64 unpacked_lun;
+ struct se_lun *lun;
+ u32 blocks;
+
+ unpacked_lun = scsi_lun_to_int(cmd->lun);
+
+ spin_lock(&se_tpg->tpg_lun_lock);
+
+ lun = &se_tpg->tpg_lun_list[unpacked_lun];
+
+ blocks = TRANSPORT(lun->lun_se_dev)->get_blocks(lun->lun_se_dev);
+
+ spin_unlock(&se_tpg->tpg_lun_lock);
+
+ switch (cmd->cdb[2]) {
+ case 0:
+ case 0x3f:
+ mode[1] = 0x00; /* Default medium */
+ /* if (iue->req.vd->b.ro) */
+ if (0)
+ mode[2] = 0x80; /* device specific */
+ else
+ mode[2] = 0x00; /* device specific */
+
+ /* note the DPOFUA bit is set to zero! */
+ mode[3] = 0x08; /* block descriptor length */
+ *((u32 *) &mode[4]) = blocks - 1;
+ *((u32 *) &mode[8]) = 512;
+ bytes = mode[0] = 12; /* length */
+ break;
+
+ case 0x08: /* Cache page */
+ mode[1] = 0x00; /* Default medium */
+ if (0)
+ mode[2] = 0x80; /* device specific */
+ else
+ mode[2] = 0x00; /* device specific */
+
+ /* note the DPOFUA bit is set to zero! */
+ mode[3] = 0x08; /* block descriptor length */
+ *((u32 *) &mode[4]) = blocks - 1;
+ *((u32 *) &mode[8]) = 512;
+
+ /* Cache page */
+ mode[12] = 0x08; /* page */
+ mode[13] = 0x12; /* page length */
+ mode[14] = 0x01; /* no cache (0x04 for read/write cache) */
+
+ bytes = mode[0] = 12 + mode[13]; /* length */
+ break;
+ }
+
+ return bytes;
+}
+
+static int ibmvscsis_report_luns(struct ibmvscsis_adapter *adapter,
+ struct srp_cmd *cmd, u64 *data)
+{
+ u64 lun;
+ struct se_portal_group *se_tpg = &adapter->se_tpg;
+ int i, idx;
+ int alen, oalen, nr_luns, rbuflen = 4096;
+
+ alen = get_unaligned_be32(&cmd->cdb[6]);
+
+ alen &= ~(8 - 1);
+ oalen = alen;
+
+ if (cmd->lun) {
+ nr_luns = 1;
+ goto done;
+ }
+
+ alen -= 8;
+ rbuflen -= 8; /* FIXME */
+ idx = 2;
+ nr_luns = 1;
+
+ spin_lock(&se_tpg->tpg_lun_lock);
+ for (i = 0; i < 255; i++) {
+ if (se_tpg->tpg_lun_list[i].lun_status !=
+ TRANSPORT_LUN_STATUS_ACTIVE)
+ continue;
+
+ lun = make_lun(0, i & 0x003f, 0);
+ data[idx++] = cpu_to_be64(lun);
+ alen -= 8;
+ if (!alen)
+ break;
+ rbuflen -= 8;
+ if (!rbuflen)
+ break;
+
+ nr_luns++;
+ }
+ spin_unlock(&se_tpg->tpg_lun_lock);
+done:
+ put_unaligned_be32(nr_luns * 8, data);
+ return min(oalen, nr_luns * 8 + 8);
+}
+
+static int ibmvscsis_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg,
+ struct srp_direct_buf *md, int nmd,
+ enum dma_data_direction dir, unsigned int rest)
+{
+ struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
+ struct srp_target *target = iue->target;
+ struct ibmvscsis_adapter *adapter = target->ldata;
+ dma_addr_t token;
+ long err;
+ unsigned int done = 0;
+ int i, sidx, soff;
+
+ sidx = soff = 0;
+ token = sg_dma_address(sg + sidx);
+
+ for (i = 0; i < nmd && rest; i++) {
+ unsigned int mdone, mlen;
+
+ mlen = min(rest, md[i].len);
+ for (mdone = 0; mlen;) {
+ int slen = min(sg_dma_len(sg + sidx) - soff, mlen);
+
+ if (dir == DMA_TO_DEVICE)
+ err = h_copy_rdma(slen,
+ adapter->riobn,
+ md[i].va + mdone,
+ adapter->liobn,
+ token + soff);
+ else
+ err = h_copy_rdma(slen,
+ adapter->liobn,
+ token + soff,
+ adapter->riobn,
+ md[i].va + mdone);
+
+ if (err != H_SUCCESS) {
+ printk(KERN_ERR "rdma error %d %d %ld\n",
+ dir, slen, err);
+ return -EIO;
+ }
+
+ mlen -= slen;
+ mdone += slen;
+ soff += slen;
+ done += slen;
+
+ if (soff == sg_dma_len(sg + sidx)) {
+ sidx++;
+ soff = 0;
+ token = sg_dma_address(sg + sidx);
+
+ if (sidx > nsg) {
+ printk(KERN_ERR "out of sg %p %d %d\n",
+ iue, sidx, nsg);
+ return -EIO;
+ }
+ }
+ };
+
+ rest -= mlen;
+ }
+ return 0;
+}
+
+static int ibmvscsis_cmd_done(struct scsi_cmnd *sc)
+{
+ unsigned long flags;
+ struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
+ struct srp_target *target = iue->target;
+ int err = 0;
+
+ if (scsi_sg_count(sc))
+ err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd,
+ ibmvscsis_rdma, 1, 1);
+
+ spin_lock_irqsave(&target->lock, flags);
+ list_del(&iue->ilist);
+ spin_unlock_irqrestore(&target->lock, flags);
+
+ if (err || sc->result != SAM_STAT_GOOD) {
+ printk(KERN_ERR "operation failed %p %d %x\n",
+ iue, sc->result, vio_iu(iue)->srp.cmd.cdb[0]);
+ send_rsp(iue, sc, HARDWARE_ERROR, 0x00);
+ } else
+ send_rsp(iue, sc, NO_SENSE, 0x00);
+
+ /* done(sc); */
+ srp_iu_put(iue);
+ return 0;
+}
+
+struct ibmvscsis_cmd {
+ /* Used for libsrp processing callbacks */
+ struct scsi_cmnd sc;
+ /* Used for TCM Core operations */
+ struct se_cmd se_cmd;
+ /* Sense buffer that will be mapped into outgoing status */
+ unsigned char sense_buf[TRANSPORT_SENSE_BUFFER];
+};
+
+static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
+{
+ struct ibmvscsis_cmnd *cmd = container_of(se_cmd,
+ struct ibmvscsis_cmnd, se_cmd);
+ struct scsi_cmnd *sc = &cmd->sc;
+ struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
+ int ret;
+
+ sc->sdb.length = se_cmd->data_length;
+
+ if ((se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) ||
+ (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) {
+ transport_do_task_sg_chain(se_cmd);
+
+ sc->sdb.table.nents = T_TASK(se_cmd)->t_tasks_sg_chained_no;
+ sc->sdb.table.sgl = T_TASK(se_cmd)->t_tasks_sg_chained;
+ } else if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB) {
+ /*
+ * Use T_TASK(se_cmd)->t_tasks_sg_bounce for control CDBs
+ * using a contigious buffer
+ */
+ sg_init_table(&T_TASK(se_cmd)->t_tasks_sg_bounce, 1);
+ sg_set_buf(&T_TASK(se_cmd)->t_tasks_sg_bounce,
+ T_TASK(se_cmd)->t_task_buf, se_cmd->data_length);
+
+ sc->sdb.table.nents = 1;
+ sc->sdb.table.sgl = &T_TASK(se_cmd)->t_tasks_sg_bounce;
+ }
+
+ ret = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd,
+ ibmvscsis_rdma, 1, 1);
+ if (ret) {
+ printk(KERN_ERR "srp_transfer_data() failed: %d\n", ret);
+ return PYX_TRANSPORT_LU_COMM_FAILURE;
+ }
+ /*
+ * We now tell TCM to add this WRITE CDB directly into the TCM storage
+ * object execution queue.
+ */
+ transport_generic_process_write(se_cmd);
+ return 0;
+}
+
+static int ibmvscsis_queue_data_in(struct se_cmd *se_cmd)
+{
+ struct ibmvscsis_cmnd *cmd = container_of(se_cmd,
+ struct ibmvscsis_cmnd, se_cmd);
+ struct scsi_cmnd *sc = &cmd->sc;
+ /*
+ * Check for overflow residual count
+ */
+ if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT)
+ scsi_set_resid(sc, se_cmd->residual_count);
+
+ sc->sdb.length = se_cmd->data_length;
+
+ /*
+ * Setup the struct se_task->task_sg[] chained SG list
+ */
+ if ((se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) ||
+ (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) {
+ transport_do_task_sg_chain(se_cmd);
+
+ sc->sdb.table.nents = T_TASK(se_cmd)->t_tasks_sg_chained_no;
+ sc->sdb.table.sgl = T_TASK(se_cmd)->t_tasks_sg_chained;
+ } else if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB) {
+ /*
+ * Use T_TASK(se_cmd)->t_tasks_sg_bounce for control CDBs
+ * using a contigious buffer
+ */
+ sg_init_table(&T_TASK(se_cmd)->t_tasks_sg_bounce, 1);
+ sg_set_buf(&T_TASK(se_cmd)->t_tasks_sg_bounce,
+ T_TASK(se_cmd)->t_task_buf, se_cmd->data_length);
+
+ sc->sdb.table.nents = 1;
+ sc->sdb.table.sgl = &T_TASK(se_cmd)->t_tasks_sg_bounce;
+ }
+ /*
+ * This will call srp_transfer_data() and post the response
+ * to VIO via libsrp.
+ */
+ ibmvscsis_cmd_done(sc);
+ return 0;
+}
+
+static int ibmvscsis_queue_status(struct se_cmd *se_cmd)
+{
+ struct ibmvscsis_cmnd *cmd = container_of(se_cmd,
+ struct ibmvscsis_cmnd, se_cmd);
+ struct scsi_cmnd *sc = &cmd->sc;
+ /*
+ * Copy any generated SENSE data into sc->sense_buffer and
+ * set the appropiate sc->result to be translated by
+ * ibmvscsis_cmd_done()
+ */
+ if (se_cmd->sense_buffer &&
+ ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
+ (se_cmd->se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
+ memcpy((void *)sc->sense_buffer, (void *)se_cmd->sense_buffer,
+ SCSI_SENSE_BUFFERSIZE);
+ sc->result = host_byte(DID_OK) | driver_byte(DRIVER_SENSE) |
+ SAM_STAT_CHECK_CONDITION;
+ } else
+ sc->result = host_byte(DID_OK) | se_cmd->scsi_status;
+ /*
+ * Finally post the response to VIO via libsrp.
+ */
+ ibmvscsis_cmd_done(sc);
+ return 0;
+}
+
+static int ibmvscsis_queuecommand(struct ibmvscsis_adapter *adapter,
+ struct iu_entry *iue)
+{
+ int data_len;
+ struct srp_cmd *cmd = iue->sbuf->buf;
+ struct scsi_cmnd *sc;
+ struct page *pg;
+ struct ibmvscsis_cmnd *vsc;
+
+ data_len = srp_data_length(cmd, srp_cmd_direction(cmd));
+
+ vsc = kzalloc(sizeof(*vsc), GFP_KERNEL);
+ sc = &vsc->sc;
+ sc->sense_buffer = vsc->sense_buf;
+ sc->cmnd = cmd->cdb;
+ sc->SCp.ptr = (char *)iue;
+
+ switch (cmd->cdb[0]) {
+ case INQUIRY:
+ sg_alloc_table(&sc->sdb.table, 1, GFP_KERNEL);
+ pg = alloc_page(GFP_KERNEL|__GFP_ZERO);
+ sc->sdb.length = ibmvscsis_inquiry(adapter, cmd,
+ page_address(pg));
+ sg_set_page(sc->sdb.table.sgl, pg, sc->sdb.length, 0);
+ ibmvscsis_cmd_done(sc);
+ sg_free_table(&sc->sdb.table);
+ __free_page(pg);
+ kfree(vsc);
+ break;
+ case REPORT_LUNS:
+ sg_alloc_table(&sc->sdb.table, 1, GFP_KERNEL);
+ pg = alloc_page(GFP_KERNEL|__GFP_ZERO);
+ sc->sdb.length = ibmvscsis_report_luns(adapter, cmd,
+ page_address(pg));
+ sg_set_page(sc->sdb.table.sgl, pg, sc->sdb.length, 0);
+ ibmvscsis_cmd_done(sc);
+ sg_free_table(&sc->sdb.table);
+ __free_page(pg);
+ kfree(vsc);
+ break;
+ case MODE_SENSE:
+ /* fixme: needs to use tcm */
+ sg_alloc_table(&sc->sdb.table, 1, GFP_KERNEL);
+ pg = alloc_page(GFP_KERNEL|__GFP_ZERO);
+ sc->sdb.length = ibmvscsis_mode_sense(adapter,
+ cmd, page_address(pg));
+ sg_set_page(sc->sdb.table.sgl, pg, sc->sdb.length, 0);
+ ibmvscsis_cmd_done(sc);
+ sg_free_table(&sc->sdb.table);
+ __free_page(pg);
+ kfree(vsc);
+ break;
+ default:
+ tcm_queuecommand(adapter, vsc, cmd);
+ break;
+ }
+
+ return 0;
+}
+
+static void handle_cmd_queue(struct ibmvscsis_adapter *adapter)
+{
+ struct srp_target *target = &adapter->srpt;
+ struct iu_entry *iue;
+ struct srp_cmd *cmd;
+ unsigned long flags;
+ int err;
+
+retry:
+ spin_lock_irqsave(&target->lock, flags);
+
+ list_for_each_entry(iue, &target->cmd_queue, ilist) {
+ if (!test_and_set_bit(V_FLYING, &iue->flags)) {
+ spin_unlock_irqrestore(&target->lock, flags);
+ err = ibmvscsis_queuecommand(adapter, iue);
+ if (err) {
+ printk(KERN_ERR "cannot queue cmd %p %d\n",
+ cmd, err);
+ srp_iu_put(iue);
+ }
+ goto retry;
+ }
+ }
+
+ spin_unlock_irqrestore(&target->lock, flags);
+}
+
+static void handle_crq(struct work_struct *work)
+{
+ struct ibmvscsis_adapter *adapter =
+ container_of(work, struct ibmvscsis_adapter, crq_work);
+ struct viosrp_crq *crq;
+ int done = 0;
+
+ while (!done) {
+ while ((crq = next_crq(&adapter->crq_queue)) != NULL) {
+ process_crq(crq, adapter);
+ crq->valid = 0x00;
+ }
+
+ vio_enable_interrupts(adapter->dma_dev);
+
+ crq = next_crq(&adapter->crq_queue);
+ if (crq) {
+ vio_disable_interrupts(adapter->dma_dev);
+ process_crq(crq, adapter);
+ crq->valid = 0x00;
+ } else
+ done = 1;
+ }
+
+ handle_cmd_queue(adapter);
+}
+
+static irqreturn_t ibmvscsis_interrupt(int dummy, void *data)
+{
+ struct ibmvscsis_adapter *adapter = data;
+
+ vio_disable_interrupts(adapter->dma_dev);
+ schedule_work(&adapter->crq_work);
+
+ return IRQ_HANDLED;
+}
+
+static int crq_queue_create(struct crq_queue *queue,
+ struct ibmvscsis_adapter *adapter)
+{
+ int err;
+ struct vio_dev *vdev = adapter->dma_dev;
+
+ queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL);
+ if (!queue->msgs)
+ goto malloc_failed;
+ queue->size = PAGE_SIZE / sizeof(*queue->msgs);
+
+ queue->msg_token = dma_map_single(&vdev->dev, queue->msgs,
+ queue->size * sizeof(*queue->msgs),
+ DMA_BIDIRECTIONAL);
+
+ if (dma_mapping_error(&vdev->dev, queue->msg_token))
+ goto map_failed;
+
+ err = h_reg_crq(vdev->unit_address, queue->msg_token,
+ PAGE_SIZE);
+
+ /* If the adapter was left active for some reason (like kexec)
+ * try freeing and re-registering
+ */
+ if (err == H_RESOURCE) {
+ do {
+ err = h_free_crq(vdev->unit_address);
+ } while (err == H_BUSY || H_IS_LONG_BUSY(err));
+
+ err = h_reg_crq(vdev->unit_address, queue->msg_token,
+ PAGE_SIZE);
+ }
+
+ if (err != H_SUCCESS && err != 2) {
+ printk(KERN_ERR "Error 0x%x opening virtual adapter\n", err);
+ goto reg_crq_failed;
+ }
+
+ err = request_irq(vdev->irq, &ibmvscsis_interrupt,
+ IRQF_DISABLED, "ibmvscsis", adapter);
+ if (err)
+ goto req_irq_failed;
+
+ vio_enable_interrupts(vdev);
+
+ h_send_crq(vdev->unit_address, 0xC001000000000000, 0);
+
+ queue->cur = 0;
+ spin_lock_init(&queue->lock);
+
+ return 0;
+
+req_irq_failed:
+ do {
+ err = h_free_crq(vdev->unit_address);
+ } while (err == H_BUSY || H_IS_LONG_BUSY(err));
+
+reg_crq_failed:
+ dma_unmap_single(&vdev->dev, queue->msg_token,
+ queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
+map_failed:
+ free_page((unsigned long) queue->msgs);
+
+malloc_failed:
+ return -ENOMEM;
+}
+
+static void crq_queue_destroy(struct ibmvscsis_adapter *adapter)
+{
+ struct crq_queue *queue = &adapter->crq_queue;
+ int err;
+
+ free_irq(adapter->dma_dev->irq, adapter);
+ flush_work_sync(&adapter->crq_work);
+ do {
+ err = h_free_crq(adapter->dma_dev->unit_address);
+ } while (err == H_BUSY || H_IS_LONG_BUSY(err));
+
+ dma_unmap_single(&adapter->dma_dev->dev, queue->msg_token,
+ queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
+
+ free_page((unsigned long)queue->msgs);
+}
+
+static int ibmvscsis_probe(struct vio_dev *dev, const struct vio_device_id *id)
+{
+ unsigned int *dma, dma_size;
+ unsigned long flags;
+ int ret;
+ struct ibmvscsis_adapter *adapter;
+
+ adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
+ if (!adapter)
+ return -ENOMEM;
+
+ adapter->dma_dev = dev;
+
+ dma = (unsigned int *)vio_get_attribute(dev, "ibm,my-dma-window",
+ &dma_size);
+ if (!dma || dma_size != 40) {
+ printk(KERN_ERR "Couldn't get window property %d\n", dma_size);
+ kfree(adapter);
+ return -EIO;
+ }
+
+ adapter->liobn = dma[0];
+ adapter->riobn = dma[5];
+ ret = strict_strtoul(dev_name(&dev->dev), 10, &adapter->tport_tpgt);
+
+ spin_lock_irqsave(&tpg_lock, flags);
+ list_add(&adapter->siblings, &tpg_list);
+ spin_unlock_irqrestore(&tpg_lock, flags);
+
+ INIT_WORK(&adapter->crq_work, handle_crq);
+
+ dev_set_drvdata(&dev->dev, adapter);
+
+ ret = srp_target_alloc(&adapter->srpt, &dev->dev, INITIAL_SRP_LIMIT,
+ SRP_MAX_IU_LEN);
+
+ adapter->srpt.ldata = adapter;
+
+ ret = crq_queue_create(&adapter->crq_queue, adapter);
+
+ return 0;
+}
+
+static int ibmvscsis_remove(struct vio_dev *dev)
+{
+ struct ibmvscsis_adapter *adapter = dev_get_drvdata(&dev->dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&tpg_lock, flags);
+ list_del(&adapter->siblings);
+ spin_unlock_irqrestore(&tpg_lock, flags);
+
+ crq_queue_destroy(adapter);
+
+ srp_target_free(&adapter->srpt);
+
+ kfree(adapter);
+ return 0;
+}
+
+static struct vio_device_id ibmvscsis_device_table[] __devinitdata = {
+ {"v-scsi-host", "IBM,v-scsi-host"},
+ {"", ""}
+};
+
+MODULE_DEVICE_TABLE(vio, ibmvscsis_device_table);
+
+static struct vio_driver ibmvscsis_driver = {
+ .id_table = ibmvscsis_device_table,
+ .probe = ibmvscsis_probe,
+ .remove = ibmvscsis_remove,
+ .driver = {
+ .name = "ibmvscsis",
+ .owner = THIS_MODULE,
+ }
+};
+
+static int get_system_info(void)
+{
+ struct device_node *rootdn;
+ const char *id, *model, *name;
+ const unsigned int *num;
+
+ rootdn = of_find_node_by_path("/");
+ if (!rootdn)
+ return -ENOENT;
+
+ model = of_get_property(rootdn, "model", NULL);
+ id = of_get_property(rootdn, "system-id", NULL);
+ if (model && id)
+ snprintf(system_id, sizeof(system_id), "%s-%s", model, id);
+
+ name = of_get_property(rootdn, "ibm,partition-name", NULL);
+ if (name)
+ strncpy(partition_name, name, sizeof(partition_name));
+
+ num = of_get_property(rootdn, "ibm,partition-no", NULL);
+ if (num)
+ partition_number = *num;
+
+ of_node_put(rootdn);
+ return 0;
+}
+
+static int ibmvscsis_register_configfs(void)
+{
+ struct target_fabric_configfs *fabric;
+ int ret;
+
+ printk(KERN_INFO "IBMVSCSIS fabric module %s on %s/%s"
+ " on "UTS_RELEASE"\n", IBMVSCSIS_VERSION, utsname()->sysname,
+ utsname()->machine);
+ /*
+ * Register the top level struct config_item_type with TCM core
+ */
+ fabric = target_fabric_configfs_init(THIS_MODULE, "ibmvscsis");
+ if (!(fabric)) {
+ printk(KERN_ERR "target_fabric_configfs_init() failed\n");
+ return -ENOMEM;
+ }
+ /*
+ * Setup fabric->tf_ops from our local ibmvscsis_ops
+ */
+ fabric->tf_ops = ibmvscsis_ops;
+ /*
+ * Setup default attribute lists for various fabric->tf_cit_tmpl
+ */
+ TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = ibmvscsis_wwn_attrs;
+ TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = NULL;
+ TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;
+ TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;
+ TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;
+ TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL;
+ TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;
+ TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;
+ TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;
+ /*
+ * Register the fabric for use within TCM
+ */
+ ret = target_fabric_configfs_register(fabric);
+ if (ret < 0) {
+ printk(KERN_ERR "target_fabric_configfs_register() failed"
+ " for IBMVSCSIS\n");
+ target_fabric_configfs_deregister(fabric);
+ return ret;
+ }
+ /*
+ * Setup our local pointer to *fabric
+ */
+ ibmvscsis_fabric_configfs = fabric;
+ printk(KERN_INFO "IBMVSCSIS[0] - Set fabric -> ibmvscsis_fabric_configfs\n");
+ return 0;
+};
+
+static void ibmvscsis_deregister_configfs(void)
+{
+ if (!(ibmvscsis_fabric_configfs))
+ return;
+
+ target_fabric_configfs_deregister(ibmvscsis_fabric_configfs);
+ ibmvscsis_fabric_configfs = NULL;
+ printk(KERN_INFO "IBMVSCSIS[0] - Cleared ibmvscsis_fabric_configfs\n");
+};
+
+static int __init ibmvscsis_init(void)
+{
+ int ret;
+
+ ret = get_system_info();
+ if (ret)
+ return ret;
+
+ ret = vio_register_driver(&ibmvscsis_driver);
+ if (ret)
+ return ret;
+
+ ret = ibmvscsis_register_configfs();
+ if (ret < 0)
+ return ret;
+
+ return 0;
+};
+
+static void ibmvscsis_exit(void)
+{
+ vio_unregister_driver(&ibmvscsis_driver);
+ ibmvscsis_deregister_configfs();
+};
+
+MODULE_DESCRIPTION("IBMVSCSIS series fabric driver");
+MODULE_AUTHOR("FUJITA Tomonori");
+MODULE_LICENSE("GPL");
+module_init(ibmvscsis_init);
+module_exit(ibmvscsis_exit);
--
1.7.2.3
^ permalink raw reply related
* Re: [RFC] Inter-processor Mailboxes Drivers
From: Ohad Ben-Cohen @ 2011-02-14 10:03 UTC (permalink / raw)
To: Jamie Iles
Cc: Meador Inge, Hiroshi DOYU, Blanchard, Hollis, openmcapi-dev,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20110214100104.GC4371@pulham.picochip.com>
On Mon, Feb 14, 2011 at 12:01 PM, Jamie Iles <jamie@jamieiles.com> wrote:
> On Fri, Feb 11, 2011 at 03:19:51PM -0600, Meador Inge wrote:
>> =A0 =A0 1. Hardware specific bits somewhere under '.../arch/*'. =A0Drive=
rs
>> =A0 =A0 =A0 =A0for the MPIC message registers on Power and OMAP4 mailbox=
es, for
>> =A0 =A0 =A0 =A0example.
>> =A0 =A0 2. A higher level driver under '.../drivers/mailbox/*'. =A0That =
the
>> =A0 =A0 =A0 =A0pieces in (1) would register with. =A0This piece would ex=
pose the
>> =A0 =A0 =A0 =A0main kernel API.
>> =A0 =A0 3. Userspace interfaces for accessing the mailboxes. =A0A
>> =A0 =A0 =A0 =A0'/dev/mailbox1', '/dev/mailbox2', etc... mapping, for exa=
mple.
>
> How about using virtio for all of this and having the mailbox as a
> notification/message passing driver for the virtio backend?
This is exactly what we are doing now, and it looks promising. expect
patches soon.
^ permalink raw reply
* Re: [RFC] Inter-processor Mailboxes Drivers
From: Jamie Iles @ 2011-02-14 10:01 UTC (permalink / raw)
To: Meador Inge
Cc: openmcapi-dev, Blanchard, Hollis, Hiroshi DOYU, linuxppc-dev,
linux-arm-kernel
In-Reply-To: <4D55A7F7.5090700@mentor.com>
On Fri, Feb 11, 2011 at 03:19:51PM -0600, Meador Inge wrote:
> 1. Hardware specific bits somewhere under '.../arch/*'. Drivers
> for the MPIC message registers on Power and OMAP4 mailboxes, for
> example.
> 2. A higher level driver under '.../drivers/mailbox/*'. That the
> pieces in (1) would register with. This piece would expose the
> main kernel API.
> 3. Userspace interfaces for accessing the mailboxes. A
> '/dev/mailbox1', '/dev/mailbox2', etc... mapping, for example.
How about using virtio for all of this and having the mailbox as a
notification/message passing driver for the virtio backend? There are
already virtio console and network drivers that could be useful for the
userspace part of it. drivers/virtio/virtio_ring.c might be a good
starting point if you thought there was some mileage in this approach.
Jamie
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox