Re: [RFC PATCH v2 09/11] powerpc: gamecube/wii: flipper interrupt controller support

2009-12-02 Thread Benjamin Herrenschmidt
On Tue, 2009-12-01 at 20:48 +0100, Albert Herranz wrote:
 
 This -1 should be NO_IRQ too.
 I'll fix this in the next version.

No. The number you pass here is not a linux virq number, but a number in
your HW numbering space that never represents a valid IRQ. In your case
0 (NO_IRQ is deprecated anyways) is a valid HW interrupt number. However
-1 sounds good.

So your existing code is fine.

Cheers,
Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC PATCH v2 09/11] powerpc: gamecube/wii: flipper interrupt controller support

2009-12-02 Thread Albert Herranz
Benjamin Herrenschmidt wrote:
 On Tue, 2009-12-01 at 20:48 +0100, Albert Herranz wrote:
 This -1 should be NO_IRQ too.
 I'll fix this in the next version.
 
 No. The number you pass here is not a linux virq number, but a number in
 your HW numbering space that never represents a valid IRQ. In your case
 0 (NO_IRQ is deprecated anyways) is a valid HW interrupt number. However
 -1 sounds good.
 
 So your existing code is fine.
 

Oh. Good to know.
Then I need to fix the other PIC driver :)

 Cheers,
 Ben.
 

Thanks,
Albert

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [RFC PATCH v2 09/11] powerpc: gamecube/wii: flipper interrupt controller support

2009-12-01 Thread Segher Boessenkool

Add support for the interrupt controller included in the Flipper
chipset of the Nintendo GameCube video game console.
The same interrupt controller is also present in the Hollywood  
chipset

of the Nintendo Wii.

Signed-off-by: Albert Herranz albert_herr...@yahoo.es

Acked-by: Segher Boessenkool seg...@kernel.crashing.org


---
v1 - v2
- Build always Flipper interrupt controller when GAMECUBE_COMMON and
  get rid of FLIPPER_PIC option. Suggestion by Grant Likely.
- Use NO_IRQ instead of -1. Suggestion by Benjamin Herrenschmidt.
- Write 0x instead of ~0 to clear interrupts.
  Suggestion by Segher Boessenkool.
- Use __fls instead of open coded asm. Suggestion by Segher  
Boessenkool.

- Use a write instead of a read/modify/write to ack interrupts.
  Suggestion by Segher Boessenkool and Benjamin Herrenschmidt.
- Use name instead of typename for struct irq_chip.
- Adapt to updated device tree.

 arch/powerpc/platforms/embedded6xx/Makefile  |1 +
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |  263 +++ 
+++

 arch/powerpc/platforms/embedded6xx/flipper-pic.h |   25 ++
 3 files changed, 289 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/platforms/embedded6xx/flipper-pic.c
 create mode 100644 arch/powerpc/platforms/embedded6xx/flipper-pic.h

diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/ 
powerpc/platforms/embedded6xx/Makefile

index 0ab7492..b80f47c 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_PPC_HOLLY) += holly.o
 obj-$(CONFIG_PPC_PRPMC2800)+= prpmc2800.o
 obj-$(CONFIG_PPC_C2K)  += c2k.o
 obj-$(CONFIG_USBGECKO_UDBG)+= usbgecko_udbg.o
+obj-$(CONFIG_GAMECUBE_COMMON)  += flipper-pic.o
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/ 
arch/powerpc/platforms/embedded6xx/flipper-pic.c

new file mode 100644
index 000..d596328
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -0,0 +1,263 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/flipper-pic.c
+ *
+ * Nintendo GameCube/Wii Flipper interrupt controller support.
+ * Copyright (C) 2004-2009 The GameCube Linux Team
+ * Copyright (C) 2007,2008,2009 Albert Herranz
+ *
+ * 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.
+ *
+ */
+#define DRV_MODULE_NAME flipper-pic
+#define pr_fmt(fmt) DRV_MODULE_NAME :  fmt
+
+#include linux/kernel.h
+#include linux/init.h
+#include linux/irq.h
+#include linux/of.h
+#include asm/io.h
+
+#include flipper-pic.h
+
+#define FLIPPER_NR_IRQS32
+
+/*
+ * Each interrupt has a corresponding bit in both
+ * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers.
+ *
+ * Enabling/disabling an interrupt line involves setting/clearing
+ * the corresponding bit in IMR.
+ * Except for the RSW interrupt, all interrupts get deasserted  
automatically

+ * when the source deasserts the interrupt.
+ */
+#define FLIPPER_ICR0x00
+#define FLIPPER_ICR_RSS(116) /* reset switch state */
+
+#define FLIPPER_IMR0x04
+
+#define FLIPPER_RESET  0x24
+
+
+/*
+ * IRQ chip hooks.
+ *
+ */
+
+static void flipper_pic_mask_and_ack(unsigned int virq)
+{
+   int irq = virq_to_hw(virq);
+   void __iomem *io_base = get_irq_chip_data(virq);
+   u32 mask = 1  irq;
+
+   clrbits32(io_base + FLIPPER_IMR, mask);
+   /* this is at least needed for RSW */
+   out_be32(io_base + FLIPPER_ICR, mask);
+}
+
+static void flipper_pic_ack(unsigned int virq)
+{
+   int irq = virq_to_hw(virq);
+   void __iomem *io_base = get_irq_chip_data(virq);
+
+   /* this is at least needed for RSW */
+   out_be32(io_base + FLIPPER_ICR, 1  irq);
+}
+
+static void flipper_pic_mask(unsigned int virq)
+{
+   int irq = virq_to_hw(virq);
+   void __iomem *io_base = get_irq_chip_data(virq);
+
+   clrbits32(io_base + FLIPPER_IMR, 1  irq);
+}
+
+static void flipper_pic_unmask(unsigned int virq)
+{
+   int irq = virq_to_hw(virq);
+   void __iomem *io_base = get_irq_chip_data(virq);
+
+   setbits32(io_base + FLIPPER_IMR, 1  irq);
+}
+
+
+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 host hooks.
+ *
+ */
+
+static struct irq_host *flipper_irq_host;
+
+static int flipper_pic_map(struct irq_host *h, unsigned int virq,
+  irq_hw_number_t hwirq)
+{
+   set_irq_chip_data(virq, h-host_data);
+   get_irq_desc(virq)-status |= IRQ_LEVEL;
+   set_irq_chip_and_handler(virq, flipper_pic, handle_level_irq);
+  

Re: [RFC PATCH v2 09/11] powerpc: gamecube/wii: flipper interrupt controller support

2009-12-01 Thread Albert Herranz
Segher Boessenkool wrote:
 Add support for the interrupt controller included in the Flipper
 chipset of the Nintendo GameCube video game console.
 The same interrupt controller is also present in the Hollywood chipset
 of the Nintendo Wii.

 Signed-off-by: Albert Herranz albert_herr...@yahoo.es
 Acked-by: Segher Boessenkool seg...@kernel.crashing.org
 
 ---
 v1 - v2
 - Build always Flipper interrupt controller when GAMECUBE_COMMON and
   get rid of FLIPPER_PIC option. Suggestion by Grant Likely.
 - Use NO_IRQ instead of -1. Suggestion by Benjamin Herrenschmidt.
 - Write 0x instead of ~0 to clear interrupts.
   Suggestion by Segher Boessenkool.
 - Use __fls instead of open coded asm. Suggestion by Segher Boessenkool.
 - Use a write instead of a read/modify/write to ack interrupts.
   Suggestion by Segher Boessenkool and Benjamin Herrenschmidt.
 - Use name instead of typename for struct irq_chip.
 - Adapt to updated device tree.

  arch/powerpc/platforms/embedded6xx/Makefile  |1 +
  arch/powerpc/platforms/embedded6xx/flipper-pic.c |  263
 ++
  arch/powerpc/platforms/embedded6xx/flipper-pic.h |   25 ++
  3 files changed, 289 insertions(+), 0 deletions(-)
  create mode 100644 arch/powerpc/platforms/embedded6xx/flipper-pic.c
  create mode 100644 arch/powerpc/platforms/embedded6xx/flipper-pic.h

 diff --git a/arch/powerpc/platforms/embedded6xx/Makefile
 b/arch/powerpc/platforms/embedded6xx/Makefile
 index 0ab7492..b80f47c 100644
 --- a/arch/powerpc/platforms/embedded6xx/Makefile
 +++ b/arch/powerpc/platforms/embedded6xx/Makefile
 @@ -8,3 +8,4 @@ obj-$(CONFIG_PPC_HOLLY)+= holly.o
  obj-$(CONFIG_PPC_PRPMC2800)+= prpmc2800.o
  obj-$(CONFIG_PPC_C2K)+= c2k.o
  obj-$(CONFIG_USBGECKO_UDBG)+= usbgecko_udbg.o
 +obj-$(CONFIG_GAMECUBE_COMMON)+= flipper-pic.o
 diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
 b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
 new file mode 100644
 index 000..d596328
 --- /dev/null
 +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
 @@ -0,0 +1,263 @@
 +/*
 + * arch/powerpc/platforms/embedded6xx/flipper-pic.c
 + *
 + * Nintendo GameCube/Wii Flipper interrupt controller support.
 + * Copyright (C) 2004-2009 The GameCube Linux Team
 + * Copyright (C) 2007,2008,2009 Albert Herranz
 + *
 + * 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.
 + *
 + */
 +#define DRV_MODULE_NAME flipper-pic
 +#define pr_fmt(fmt) DRV_MODULE_NAME :  fmt
 +
 +#include linux/kernel.h
 +#include linux/init.h
 +#include linux/irq.h
 +#include linux/of.h
 +#include asm/io.h
 +
 +#include flipper-pic.h
 +
 +#define FLIPPER_NR_IRQS32
 +
 +/*
 + * Each interrupt has a corresponding bit in both
 + * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers.
 + *
 + * Enabling/disabling an interrupt line involves setting/clearing
 + * the corresponding bit in IMR.
 + * Except for the RSW interrupt, all interrupts get deasserted
 automatically
 + * when the source deasserts the interrupt.
 + */
 +#define FLIPPER_ICR0x00
 +#define FLIPPER_ICR_RSS(116) /* reset switch state */
 +
 +#define FLIPPER_IMR0x04
 +
 +#define FLIPPER_RESET0x24
 +
 +
 +/*
 + * IRQ chip hooks.
 + *
 + */
 +
 +static void flipper_pic_mask_and_ack(unsigned int virq)
 +{
 +int irq = virq_to_hw(virq);
 +void __iomem *io_base = get_irq_chip_data(virq);
 +u32 mask = 1  irq;
 +
 +clrbits32(io_base + FLIPPER_IMR, mask);
 +/* this is at least needed for RSW */
 +out_be32(io_base + FLIPPER_ICR, mask);
 +}
 +
 +static void flipper_pic_ack(unsigned int virq)
 +{
 +int irq = virq_to_hw(virq);
 +void __iomem *io_base = get_irq_chip_data(virq);
 +
 +/* this is at least needed for RSW */
 +out_be32(io_base + FLIPPER_ICR, 1  irq);
 +}
 +
 +static void flipper_pic_mask(unsigned int virq)
 +{
 +int irq = virq_to_hw(virq);
 +void __iomem *io_base = get_irq_chip_data(virq);
 +
 +clrbits32(io_base + FLIPPER_IMR, 1  irq);
 +}
 +
 +static void flipper_pic_unmask(unsigned int virq)
 +{
 +int irq = virq_to_hw(virq);
 +void __iomem *io_base = get_irq_chip_data(virq);
 +
 +setbits32(io_base + FLIPPER_IMR, 1  irq);
 +}
 +
 +
 +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 host hooks.
 + *
 + */
 +
 +static struct irq_host *flipper_irq_host;
 +
 +static int flipper_pic_map(struct irq_host *h, unsigned int virq,
 +   irq_hw_number_t hwirq)
 +{
 +set_irq_chip_data(virq, h-host_data);
 +get_irq_desc(virq)-status |= IRQ_LEVEL;
 +set_irq_chip_and_handler(virq, 

Re: [RFC PATCH v2 09/11] powerpc: gamecube/wii: flipper interrupt controller support

2009-11-29 Thread Benjamin Herrenschmidt
On Sat, 2009-11-28 at 21:43 +0100, Albert Herranz wrote:

 +static void flipper_pic_mask_and_ack(unsigned int virq)
 +{
 + int irq = virq_to_hw(virq);
 + void __iomem *io_base = get_irq_chip_data(virq);
 + u32 mask = 1  irq;
 +
 + clrbits32(io_base + FLIPPER_IMR, mask);
 + /* this is at least needed for RSW */
 + out_be32(io_base + FLIPPER_ICR, mask);
 +}

That's a lot better. You probably still need to also read back to make
sure the line is properly de-asserted before you return... but if you
don't observe spurrious interrupts then it probably doesn't matter
much. 

No big deal either way though, change it if you want but I'm not going
to nack it if you don't :-)

You can also save cycles by avoiding the read/modify/write by storing a
memory cache of what the mask should be. MMIO reads tend to be slow.

Cheers,
Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[RFC PATCH v2 09/11] powerpc: gamecube/wii: flipper interrupt controller support

2009-11-28 Thread Albert Herranz
Add support for the interrupt controller included in the Flipper
chipset of the Nintendo GameCube video game console.
The same interrupt controller is also present in the Hollywood chipset
of the Nintendo Wii.

Signed-off-by: Albert Herranz albert_herr...@yahoo.es
---
v1 - v2
- Build always Flipper interrupt controller when GAMECUBE_COMMON and
  get rid of FLIPPER_PIC option. Suggestion by Grant Likely.
- Use NO_IRQ instead of -1. Suggestion by Benjamin Herrenschmidt.
- Write 0x instead of ~0 to clear interrupts.
  Suggestion by Segher Boessenkool.
- Use __fls instead of open coded asm. Suggestion by Segher Boessenkool.
- Use a write instead of a read/modify/write to ack interrupts.
  Suggestion by Segher Boessenkool and Benjamin Herrenschmidt.
- Use name instead of typename for struct irq_chip.
- Adapt to updated device tree.

 arch/powerpc/platforms/embedded6xx/Makefile  |1 +
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |  263 ++
 arch/powerpc/platforms/embedded6xx/flipper-pic.h |   25 ++
 3 files changed, 289 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/platforms/embedded6xx/flipper-pic.c
 create mode 100644 arch/powerpc/platforms/embedded6xx/flipper-pic.h

diff --git a/arch/powerpc/platforms/embedded6xx/Makefile 
b/arch/powerpc/platforms/embedded6xx/Makefile
index 0ab7492..b80f47c 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_PPC_HOLLY) += holly.o
 obj-$(CONFIG_PPC_PRPMC2800)+= prpmc2800.o
 obj-$(CONFIG_PPC_C2K)  += c2k.o
 obj-$(CONFIG_USBGECKO_UDBG)+= usbgecko_udbg.o
+obj-$(CONFIG_GAMECUBE_COMMON)  += flipper-pic.o
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c 
b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
new file mode 100644
index 000..d596328
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -0,0 +1,263 @@
+/*
+ * arch/powerpc/platforms/embedded6xx/flipper-pic.c
+ *
+ * Nintendo GameCube/Wii Flipper interrupt controller support.
+ * Copyright (C) 2004-2009 The GameCube Linux Team
+ * Copyright (C) 2007,2008,2009 Albert Herranz
+ *
+ * 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.
+ *
+ */
+#define DRV_MODULE_NAME flipper-pic
+#define pr_fmt(fmt) DRV_MODULE_NAME :  fmt
+
+#include linux/kernel.h
+#include linux/init.h
+#include linux/irq.h
+#include linux/of.h
+#include asm/io.h
+
+#include flipper-pic.h
+
+#define FLIPPER_NR_IRQS32
+
+/*
+ * Each interrupt has a corresponding bit in both
+ * the Interrupt Cause (ICR) and Interrupt Mask (IMR) registers.
+ *
+ * Enabling/disabling an interrupt line involves setting/clearing
+ * the corresponding bit in IMR.
+ * Except for the RSW interrupt, all interrupts get deasserted automatically
+ * when the source deasserts the interrupt.
+ */
+#define FLIPPER_ICR0x00
+#define FLIPPER_ICR_RSS(116) /* reset switch state */
+
+#define FLIPPER_IMR0x04
+
+#define FLIPPER_RESET  0x24
+
+
+/*
+ * IRQ chip hooks.
+ *
+ */
+
+static void flipper_pic_mask_and_ack(unsigned int virq)
+{
+   int irq = virq_to_hw(virq);
+   void __iomem *io_base = get_irq_chip_data(virq);
+   u32 mask = 1  irq;
+
+   clrbits32(io_base + FLIPPER_IMR, mask);
+   /* this is at least needed for RSW */
+   out_be32(io_base + FLIPPER_ICR, mask);
+}
+
+static void flipper_pic_ack(unsigned int virq)
+{
+   int irq = virq_to_hw(virq);
+   void __iomem *io_base = get_irq_chip_data(virq);
+
+   /* this is at least needed for RSW */
+   out_be32(io_base + FLIPPER_ICR, 1  irq);
+}
+
+static void flipper_pic_mask(unsigned int virq)
+{
+   int irq = virq_to_hw(virq);
+   void __iomem *io_base = get_irq_chip_data(virq);
+
+   clrbits32(io_base + FLIPPER_IMR, 1  irq);
+}
+
+static void flipper_pic_unmask(unsigned int virq)
+{
+   int irq = virq_to_hw(virq);
+   void __iomem *io_base = get_irq_chip_data(virq);
+
+   setbits32(io_base + FLIPPER_IMR, 1  irq);
+}
+
+
+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 host hooks.
+ *
+ */
+
+static struct irq_host *flipper_irq_host;
+
+static int flipper_pic_map(struct irq_host *h, unsigned int virq,
+  irq_hw_number_t hwirq)
+{
+   set_irq_chip_data(virq, h-host_data);
+   get_irq_desc(virq)-status |= IRQ_LEVEL;
+   set_irq_chip_and_handler(virq, flipper_pic, handle_level_irq);
+   return 0;
+}
+
+static void flipper_pic_unmap(struct irq_host *h,