LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 8/9] powerpc: add the mpc837[789]_rdb dts files
From: Kumar Gala @ 2008-01-25 21:24 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev, Joe D'Abbraccio
In-Reply-To: <20080124204718.33a30ab5.kim.phillips@freescale.com>

On Thu, 24 Jan 2008, Kim Phillips wrote:

> Add the dts files for the MPC838xE Reference Development Board (RDB).
>
> The board is a mini-ITX reference board with 256M DDR2, 8M flash,
> 32M NAND, USB, PCI, gigabit ethernet, SATA, and serial.
>
> the difference among the three files is the 8377 has two, the 8378
> none, and the 8379 has four sata controllers.
>
> partially based on the 8379 mds device trees.
>
> Signed-off-by: Joe D'Abbraccio <ljd015@freescale.com>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
>  arch/powerpc/boot/dts/mpc8377_rdb.dts |  296 +++++++++++++++++++++++++++++++
>  arch/powerpc/boot/dts/mpc8378_rdb.dts |  282 ++++++++++++++++++++++++++++++
>  arch/powerpc/boot/dts/mpc8379_rdb.dts |  310 +++++++++++++++++++++++++++++++++

applied.  (fixed spi nodes).

- k

^ permalink raw reply

* Re: [PATCH 7/9] powerpc: add MPC837x RDB platform support
From: Kumar Gala @ 2008-01-25 21:24 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev, Joe D'Abbraccio
In-Reply-To: <20080124204711.02ba14f0.kim.phillips@freescale.com>

On Thu, 24 Jan 2008, Kim Phillips wrote:

> primarily based on mpc837x mds code.
>
> Signed-off-by: Joe D'Abbraccio <ljd015@freescale.com>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
>  arch/powerpc/platforms/83xx/Kconfig       |    8 ++-
>  arch/powerpc/platforms/83xx/Makefile      |    1 +
>  arch/powerpc/platforms/83xx/mpc837x_rdb.c |   99 +++++++++++++++++++++++++++++
>  3 files changed, 107 insertions(+), 1 deletions(-)
>  create mode 100644 arch/powerpc/platforms/83xx/mpc837x_rdb.c
>

applied.

- k

^ permalink raw reply

* Re: [PATCH 5/9] powerpc: ipic: add interrupt vector 94
From: Kumar Gala @ 2008-01-25 21:23 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev, Jerry Huang
In-Reply-To: <20080124204650.48578c7f.kim.phillips@freescale.com>

On Thu, 24 Jan 2008, Kim Phillips wrote:

> this is used on the mpc8315 SoC for DMA error interrupts.
>
> Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
>  arch/powerpc/sysdev/ipic.c |    6 ++++++
>  1 files changed, 6 insertions(+), 0 deletions(-)
>

applied.  (fyi, the irq is for TDM DMA, not general DMA)

- k

^ permalink raw reply

* Re: [PATCH 9/9] powerpc: add the mpc837x rdb defconfig
From: Kumar Gala @ 2008-01-25 21:24 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev, Joe D'Abbraccio
In-Reply-To: <20080124204721.87859a3c.kim.phillips@freescale.com>

On Thu, 24 Jan 2008, Kim Phillips wrote:

> Signed-off-by: Joe D'Abbraccio <ljd015@freescale.com>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
>  arch/powerpc/configs/mpc837x_rdb_defconfig |  887 ++++++++++++++++++++++++++++
>  1 files changed, 887 insertions(+), 0 deletions(-)
>  create mode 100644 arch/powerpc/configs/mpc837x_rdb_defconfig
>

applied.

- k

^ permalink raw reply

* Re: [PATCH 1/5] [POWERPC] qe_lib and users: get rid of most device_types and model
From: Kumar Gala @ 2008-01-25 21:19 UTC (permalink / raw)
  To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20080124153959.GA23246@localhost.localdomain>

On Thu, 24 Jan 2008, Anton Vorontsov wrote:

> Now we're searching for "fsl,qe", "fsl,qe-muram", "fsl,qe-muram-data"
> and "fsl,qe-ic".
>
> Unfortunately it's still impossible to remove device_type = "qe"
> from the existing device trees (except for MPC8360E-RDK), because
> older u-boots are looking for it.
>
> Per http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048388.html
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> ---
>  Documentation/powerpc/booting-without-of.txt |   11 +++--
>  arch/powerpc/boot/dts/mpc832x_mds.dts        |    9 ++--
>  arch/powerpc/boot/dts/mpc832x_rdb.dts        |   10 +++--
>  arch/powerpc/boot/dts/mpc836x_mds.dts        |   10 +++--
>  arch/powerpc/boot/dts/mpc836x_rdk.dts        |    1 -
>  arch/powerpc/boot/dts/mpc8568mds.dts         |   10 +++--
>  arch/powerpc/platforms/83xx/mpc832x_mds.c    |   11 +++--
>  arch/powerpc/platforms/83xx/mpc832x_rdb.c    |   11 +++--
>  arch/powerpc/platforms/83xx/mpc836x_mds.c    |   11 +++--
>  arch/powerpc/platforms/85xx/mpc85xx_mds.c    |   32 ++++++++-----
>  arch/powerpc/sysdev/fsl_soc.c                |    5 ++-
>  arch/powerpc/sysdev/qe_lib/qe.c              |   63 ++++++++++++++++++--------
>  12 files changed, 117 insertions(+), 67 deletions(-)
>

applied, however _rdk will need fixing.

- k

^ permalink raw reply

* Re: [PATCH 4/5] [POWERPC] fsl_spi_init and users: stop using device_type = "spi"
From: Kumar Gala @ 2008-01-25 21:20 UTC (permalink / raw)
  To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20080124154007.GD23246@localhost.localdomain>

On Thu, 24 Jan 2008, Anton Vorontsov wrote:

> Also:
> - rename "fsl_spi" to "fsl,spi";
> - add and use cell-index property, if found;
> - split probing code out of fsl_spi_init, thus we can call
>   it for legacy device_type probing and new "compatible" probing.
>
> Per http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048388.html
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> ---
>  Documentation/powerpc/booting-without-of.txt |    8 +-
>  arch/powerpc/boot/dts/mpc8313erdb.dts        |    4 +-
>  arch/powerpc/boot/dts/mpc832x_mds.dts        |    8 +-
>  arch/powerpc/boot/dts/mpc832x_rdb.dts        |    8 +-
>  arch/powerpc/boot/dts/mpc8349emitx.dts       |    4 +-
>  arch/powerpc/boot/dts/mpc8349emitxgp.dts     |    4 +-
>  arch/powerpc/boot/dts/mpc834x_mds.dts        |    4 +-
>  arch/powerpc/boot/dts/mpc836x_mds.dts        |    8 +-
>  arch/powerpc/boot/dts/mpc836x_rdk.dts        |    6 +-
>  arch/powerpc/boot/dts/mpc8568mds.dts         |    8 +-
>  arch/powerpc/sysdev/fsl_soc.c                |   94 ++++++++++++++++----------
>  11 files changed, 88 insertions(+), 68 deletions(-)
>

applied.  (sans _rdk)

- k

^ permalink raw reply

* Re: [PATCH 1/9] powerpc: fold the mpc8313 platform into the mpc831x platform
From: Kumar Gala @ 2008-01-25 21:21 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev
In-Reply-To: <20080124204551.10cea5fd.kim.phillips@freescale.com>

On Thu, 24 Jan 2008, Kim Phillips wrote:

> prepare for adding support for the mpc8315 rdb,
> since they are identical wrt platform code.
>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
> Kumar, this set of patches is base support for two new boards - the
> mpc8315e rdb and the mpc837xe rdb.  Please consider for 2.6.25.  Thanks.
>
>  arch/powerpc/configs/mpc8313_rdb_defconfig         |    2 +-
>  arch/powerpc/platforms/83xx/Kconfig                |    6 ++--
>  arch/powerpc/platforms/83xx/Makefile               |    2 +-
>  .../83xx/{mpc8313_rdb.c => mpc831x_rdb.c}          |   35 +++++++------------
>  4 files changed, 18 insertions(+), 27 deletions(-)
>  rename arch/powerpc/platforms/83xx/{mpc8313_rdb.c => mpc831x_rdb.c} (70%)
>

applied.

- k

^ permalink raw reply

* Re: [PATCH 3/5] [POWERPC][SPI] use brg-frequency for SPI in QE
From: Kumar Gala @ 2008-01-25 21:20 UTC (permalink / raw)
  To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20080124154003.GC23246@localhost.localdomain>

On Thu, 24 Jan 2008, Anton Vorontsov wrote:

> In case of QE we can use brg-frequency (which is qeclk/2).
> Thus no need to divide sysclk in the spi_mpc83xx.
>
> This patch also adds code to use get_brgfreq() on QE chips.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> Acked-by: David Brownell <dbrownell@users.sourceforge.net>
> ---
>  arch/powerpc/sysdev/fsl_soc.c |   44 ++++++++++++++++++++++++++++------------
>  drivers/spi/spi_mpc83xx.c     |    6 +----
>  2 files changed, 32 insertions(+), 18 deletions(-)
>

applied

- k

^ permalink raw reply

* Re: [PATCH 3/9] powerpc: Add the MPC8315E RDB dts
From: Kumar Gala @ 2008-01-25 21:22 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev
In-Reply-To: <20080124204606.53bd2a1b.kim.phillips@freescale.com>

On Thu, 24 Jan 2008, Kim Phillips wrote:

> Add the dts for the MPC8315E Reference Development Board (RDB).
>
> The board is a mini-ITX reference board with 128M DDR2, 8M flash,
> 32M NAND, USB, PCI, gigabit ethernet, SATA, and serial.
>
> Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
>  arch/powerpc/boot/dts/mpc8315erdb.dts |  287 +++++++++++++++++++++++++++++++++
>  1 files changed, 287 insertions(+), 0 deletions(-)
>  create mode 100644 arch/powerpc/boot/dts/mpc8315erdb.dts
>

applied.  fixed up spi node

- k

^ permalink raw reply

* Re: [PATCH 2/9] powerpc: add base platform support for the mpc8315 rdb board
From: Kumar Gala @ 2008-01-25 21:21 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev
In-Reply-To: <20080124204600.d16c5142.kim.phillips@freescale.com>

On Thu, 24 Jan 2008, Kim Phillips wrote:

> mpc8315 identical to mpc8313 here, just check compatible.
>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
>  arch/powerpc/platforms/83xx/Kconfig       |    2 +-
>  arch/powerpc/platforms/83xx/mpc831x_rdb.c |    3 ++-
>  2 files changed, 3 insertions(+), 2 deletions(-)
>

applied.

- k

^ permalink raw reply

* Re: [PATCH 6/9] add the mpc8315 rdb defconfig
From: Kumar Gala @ 2008-01-25 21:23 UTC (permalink / raw)
  To: Kim Phillips; +Cc: linuxppc-dev
In-Reply-To: <20080124204705.0e7e5693.kim.phillips@freescale.com>

On Thu, 24 Jan 2008, Kim Phillips wrote:

> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> ---
>  arch/powerpc/configs/mpc8315_rdb_defconfig | 1417 ++++++++++++++++++++++++++++
>  1 files changed, 1417 insertions(+), 0 deletions(-)
>  create mode 100644 arch/powerpc/configs/mpc8315_rdb_defconfig
>

applied.

- k

^ permalink raw reply

* Re: [i2c] [PATCH] mpc i2c driver, compare to NO_IRQ instead of zero
From: Jon Smirl @ 2008-01-25 17:13 UTC (permalink / raw)
  To: i2c, linuxppc-dev
In-Reply-To: <20080121200740.13800.20524.stgit@terra.home>

Any final objections to this patch? When these were changed to 0
instead of NO_IRQ it should have broken polling mode on ppc. ppc would
treat polling mode, NO_IRQ=-1, as an error.

On powerpc this change is a NOP since NO_IRQ=0.

On 1/21/08, Jon Smirl <jonsmirl@gmail.com> wrote:
> Alter the mpc i2c driver to use the NO_IRQ symbol instead of the constant zero when checking for valid interrupts. NO_IRQ=-1 on ppc and NO_IRQ=0 on powerpc so the checks against zero are not correct.
>
> Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
> ---
>
>  drivers/i2c/busses/i2c-mpc.c |   10 +++++-----
>  1 files changed, 5 insertions(+), 5 deletions(-)
>
>
> diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
> index bbe787b..d20959d 100644
> --- a/drivers/i2c/busses/i2c-mpc.c
> +++ b/drivers/i2c/busses/i2c-mpc.c
> @@ -99,7 +99,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
>         u32 x;
>         int result = 0;
>
> -       if (i2c->irq == 0)
> +       if (i2c->irq == NO_IRQ)
>         {
>                 while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
>                         schedule();
> @@ -329,7 +329,7 @@ static int fsl_i2c_probe(struct platform_device *pdev)
>                 return -ENOMEM;
>
>         i2c->irq = platform_get_irq(pdev, 0);
> -       if (i2c->irq < 0) {
> +       if (i2c->irq < NO_IRQ) {
>                 result = -ENXIO;
>                 goto fail_get_irq;
>         }
> @@ -344,7 +344,7 @@ static int fsl_i2c_probe(struct platform_device *pdev)
>                 goto fail_map;
>         }
>
> -       if (i2c->irq != 0)
> +       if (i2c->irq != NO_IRQ)
>                 if ((result = request_irq(i2c->irq, mpc_i2c_isr,
>                                           IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
>                         printk(KERN_ERR
> @@ -367,7 +367,7 @@ static int fsl_i2c_probe(struct platform_device *pdev)
>         return result;
>
>        fail_add:
> -       if (i2c->irq != 0)
> +       if (i2c->irq != NO_IRQ)
>                 free_irq(i2c->irq, i2c);
>        fail_irq:
>         iounmap(i2c->base);
> @@ -384,7 +384,7 @@ static int fsl_i2c_remove(struct platform_device *pdev)
>         i2c_del_adapter(&i2c->adap);
>         platform_set_drvdata(pdev, NULL);
>
> -       if (i2c->irq != 0)
> +       if (i2c->irq != NO_IRQ)
>                 free_irq(i2c->irq, i2c);
>
>         iounmap(i2c->base);
>
>
> _______________________________________________
> i2c mailing list
> i2c@lm-sensors.org
> http://lists.lm-sensors.org/mailman/listinfo/i2c
>


-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* [PATCH] hide kernel only code in asm-powerpc/elf.h
From: Olaf Hering @ 2008-01-25 18:08 UTC (permalink / raw)
  To: Paul Mackeras, linuxppc-dev


stuff inside CONFIG_* should not be exported via make headers-install

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 include/asm-powerpc/elf.h |    2 ++
 1 file changed, 2 insertions(+)

--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -420,6 +420,7 @@ do {									\
 /* Keep this the last entry.  */
 #define R_PPC64_NUM		107
 
+#ifdef __KERNEL__
 #ifdef CONFIG_SPU_BASE
 /* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
 #define NT_SPU		1
@@ -427,5 +428,6 @@ do {									\
 #define ARCH_HAVE_EXTRA_ELF_NOTES
 
 #endif /* CONFIG_SPU_BASE */
+#endif /* __KERNEL__ */
 
 #endif /* _ASM_POWERPC_ELF_H */

^ permalink raw reply

* Please pull 'for-2.6.25' branch of 4xx tree
From: Josh Boyer @ 2008-01-25 21:19 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

Hi Paul,

Please pull from:

 master.kernel.org:/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git for-2.6.25

to pick up a few more patches for 4xx that should go in for 2.6.25.
Mostly self explanatory in the changelogs.  The diffstat is mostly from
the PIKA Warp board patches that Sean worked quite hard on.

thx,
josh

David Gibson (1):
      [POWERPC] Enable RTC for Ebony and Walnut (v2)

Roel Kluin (1):
      [POWERPC] 4xx: logical/bitand typo in powerpc/boot/4xx.c

Sean MacLennan (5):
      [POWERPC] 4xx: Add PowerPC 440EP Rev C
      [POWERPC] 4xx: PIKA Warp base platform
      [POWERPC] 4xx: PIKA Warp DTS
      [POWERPC] 4xx: PIKA Warp bootwrapper
      [POWERPC] 4xx: PIKA Warp defconfig

Stefan Roese (2):
      [POWERPC] 4xx: Add 405EXr to cputable
      [POWERPC] 4xx: Add AMCC Haleakala (405EXr) dts

 arch/powerpc/Kconfig                   |    2 +-
 arch/powerpc/boot/4xx.c                |    2 +-
 arch/powerpc/boot/Makefile             |    4 +-
 arch/powerpc/boot/cuboot-warp.c        |   39 ++
 arch/powerpc/boot/dts/ebony.dts        |    5 +-
 arch/powerpc/boot/dts/haleakala.dts    |  274 +++++++++
 arch/powerpc/boot/dts/walnut.dts       |    5 +-
 arch/powerpc/boot/dts/warp.dts         |  239 +++++++
 arch/powerpc/configs/warp_defconfig    | 1057 ++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/cputable.c         |   28 +-
 arch/powerpc/platforms/40x/walnut.c    |    1 +
 arch/powerpc/platforms/44x/Kconfig     |   15 +
 arch/powerpc/platforms/44x/Makefile    |    2 +
 arch/powerpc/platforms/44x/ebony.c     |    2 +
 arch/powerpc/platforms/44x/warp-nand.c |  105 ++++
 arch/powerpc/platforms/44x/warp.c      |  153 +++++
 arch/powerpc/platforms/Kconfig         |    6 +
 arch/powerpc/sysdev/Makefile           |    1 +
 arch/powerpc/sysdev/of_rtc.c           |   59 ++
 include/asm-powerpc/of_platform.h      |    2 +
 20 files changed, 1992 insertions(+), 9 deletions(-)

^ permalink raw reply

* [PATCH 1/2] IB/ehca: Update sma_attr also in case of disruptive config change
From: Joachim Fenkes @ 2008-01-25 20:12 UTC (permalink / raw)
  To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier, OF-EWG
  Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200801252111.11915.fenkes@de.ibm.com>

Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
---
 drivers/infiniband/hw/ehca/ehca_irq.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 863b34f..b5ca94c 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -403,6 +403,8 @@ static void parse_ec(struct ehca_shca *shca, u64 eqe)
 			sport->port_state = IB_PORT_ACTIVE;
 			dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE,
 					    "is active");
+			ehca_query_sma_attr(shca, port,
+					    &sport->saved_attr);
 		} else
 			notify_port_conf_change(shca, port);
 		break;
-- 
1.5.2

^ permalink raw reply related

* Re: [PATCH v3] create modalias file in sysfs for bus of_platform
From: Paul Mackerras @ 2008-01-26  0:23 UTC (permalink / raw)
  To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20080122190939.GA14124@aepfle.de>

Olaf Hering writes:

> Create /sys/bus/of_platform/devices/*/modalias file to allow autoloading
> of modules. modalias files are already present for many other bus types.

This one causes various oopses on boot for me, both on a dual G5 and
on a tibook.

Paul.

^ permalink raw reply

* Re: [i2c] [PATCH] Convert pfc8563 i2c driver from old style to new style
From: Jon Smirl @ 2008-01-25 17:16 UTC (permalink / raw)
  To: i2c, linuxppc-dev, Jean Delvare
In-Reply-To: <20080121200901.15517.30253.stgit@terra.home>

Any final objections to this patch? Jean can you pick it up?

On 1/21/08, Jon Smirl <jonsmirl@gmail.com> wrote:
> Convert pfc8563 i2c driver from old style to new style.
>
> Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
> ---
>
>  drivers/rtc/rtc-pcf8563.c |  107 +++++++++++----------------------------------
>  1 files changed, 27 insertions(+), 80 deletions(-)
>
>
> diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
> index b3317fc..8eff549 100644
> --- a/drivers/rtc/rtc-pcf8563.c
> +++ b/drivers/rtc/rtc-pcf8563.c
> @@ -25,10 +25,6 @@
>   * located at 0x51 will pass the validation routine due to
>   * the way the registers are implemented.
>   */
> -static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
> -
> -/* Module parameters */
> -I2C_CLIENT_INSMOD;
>
>  #define PCF8563_REG_ST1                0x00 /* status */
>  #define PCF8563_REG_ST2                0x01
> @@ -72,9 +68,6 @@ struct pcf8563 {
>         int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
>  };
>
> -static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
> -static int pcf8563_detach(struct i2c_client *client);
> -
>  /*
>   * In the routines that deal directly with the pcf8563 hardware, we use
>   * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
> @@ -257,98 +250,52 @@ static const struct rtc_class_ops pcf8563_rtc_ops = {
>         .set_time       = pcf8563_rtc_set_time,
>  };
>
> -static int pcf8563_attach(struct i2c_adapter *adapter)
> +static int pcf8563_remove(struct i2c_client *client)
>  {
> -       return i2c_probe(adapter, &addr_data, pcf8563_probe);
> +       struct rtc_device *rtc = i2c_get_clientdata(client);
> +
> +       if (rtc)
> +               rtc_device_unregister(rtc);
> +
> +       return 0;
>  }
>
> +static struct i2c_device_id pcf8563_id[] = {
> +       {"pcf8563", 0},
> +       {"rtc8564", 0},
> +       {},
> +};
> +MODULE_DEVICE_TABLE(i2c, pcf8563_id);
> +
> +static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id);
> +
>  static struct i2c_driver pcf8563_driver = {
>         .driver         = {
> -               .name   = "pcf8563",
> +               .name   = "rtc-pcf8563",
>         },
>         .id             = I2C_DRIVERID_PCF8563,
> -       .attach_adapter = &pcf8563_attach,
> -       .detach_client  = &pcf8563_detach,
> +       .probe = &pcf8563_probe,
> +       .remove = &pcf8563_remove,
> +       .id_table       = pcf8563_id,
>  };
>
> -static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
> +static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id)
>  {
> -       struct pcf8563 *pcf8563;
> -       struct i2c_client *client;
> +       int result;
>         struct rtc_device *rtc;
>
> -       int err = 0;
> -
> -       dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
> -
> -       if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
> -               err = -ENODEV;
> -               goto exit;
> -       }
> -
> -       if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) {
> -               err = -ENOMEM;
> -               goto exit;
> -       }
> -
> -       client = &pcf8563->client;
> -       client->addr = address;
> -       client->driver = &pcf8563_driver;
> -       client->adapter = adapter;
> -
> -       strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE);
> -
> -       /* Verify the chip is really an PCF8563 */
> -       if (kind < 0) {
> -               if (pcf8563_validate_client(client) < 0) {
> -                       err = -ENODEV;
> -                       goto exit_kfree;
> -               }
> -       }
> -
> -       /* Inform the i2c layer */
> -       if ((err = i2c_attach_client(client)))
> -               goto exit_kfree;
> -
> -       dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
> +       result = pcf8563_validate_client(client);
> +       if (result)
> +               return result;
>
>         rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev,
>                                 &pcf8563_rtc_ops, THIS_MODULE);
> -
> -       if (IS_ERR(rtc)) {
> -               err = PTR_ERR(rtc);
> -               goto exit_detach;
> -       }
> +       if (IS_ERR(rtc))
> +               return PTR_ERR(rtc);
>
>         i2c_set_clientdata(client, rtc);
>
>         return 0;
> -
> -exit_detach:
> -       i2c_detach_client(client);
> -
> -exit_kfree:
> -       kfree(pcf8563);
> -
> -exit:
> -       return err;
> -}
> -
> -static int pcf8563_detach(struct i2c_client *client)
> -{
> -       struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
> -       int err;
> -       struct rtc_device *rtc = i2c_get_clientdata(client);
> -
> -       if (rtc)
> -               rtc_device_unregister(rtc);
> -
> -       if ((err = i2c_detach_client(client)))
> -               return err;
> -
> -       kfree(pcf8563);
> -
> -       return 0;
>  }
>
>  static int __init pcf8563_init(void)
>
>
> _______________________________________________
> i2c mailing list
> i2c@lm-sensors.org
> http://lists.lm-sensors.org/mailman/listinfo/i2c
>


-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: [PATCH 5/5] [POWERPC] fsl_soc, legacy_serial: add support for "soc" compatible matching
From: Anton Vorontsov @ 2008-01-25 18:53 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev list, Yoder Stuart
In-Reply-To: <479A27AF.5080701@freescale.com>

On Fri, Jan 25, 2008 at 12:17:19PM -0600, Scott Wood wrote:
> Anton Vorontsov wrote:
> >Freescale soc register space: "fsl,soc"
> >generic soc device: "soc" (or maybe "linux,soc" better?)
> >
> >I know, Scott Wood is pushing "xxxx-immr" thing forward... but
> >I don't like that name because SOC isn't only device with the
> >Internal Memory Mapped Registers. 
> 
> If you look in the manual for xxxx, you'll find something called 
> "Internal Memory Mapped Registers".  Thus, the name xxxx-immr.

Theory.

> >(Think of QE placed outside of "soc"/"immr" node).
> 
> When is the QE ever placed outside the soc/immr/ccsr node?
> The QE registers are part of the IMMR/CCSR.

Practice.

$ grep qe@ arch/powerpc/boot/dts/*
arch/powerpc/boot/dts/mpc832x_mds.dts:  qe@e0100000 {
arch/powerpc/boot/dts/mpc832x_rdb.dts:  qe@e0100000 {
arch/powerpc/boot/dts/mpc836x_mds.dts:  qe@e0100000 {
arch/powerpc/boot/dts/mpc8568mds.dts:   qe@e0080000 {

^^^ if the practice is wrong, then we should fix it, and then
-immr would be the good name indeed (just as I've said previously).

-- 
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2

^ permalink raw reply

* Re: [PATCH 5/5] [POWERPC] fsl_soc, legacy_serial: add support for "soc" compatible matching
From: Scott Wood @ 2008-01-25 18:17 UTC (permalink / raw)
  To: avorontsov; +Cc: linuxppc-dev list, Yoder Stuart
In-Reply-To: <20080125171355.GA9879@localhost.localdomain>

Anton Vorontsov wrote:
> Freescale soc register space: "fsl,soc"
> generic soc device: "soc" (or maybe "linux,soc" better?)
> 
> I know, Scott Wood is pushing "xxxx-immr" thing forward... but
> I don't like that name because SOC isn't only device with the
> Internal Memory Mapped Registers. 

If you look in the manual for xxxx, you'll find something called 
"Internal Memory Mapped Registers".  Thus, the name xxxx-immr.

>(Think of QE placed outside of "soc"/"immr" node).

When is the QE ever placed outside the soc/immr/ccsr node?
The QE registers are part of the IMMR/CCSR.

-Scott

^ permalink raw reply

* Re: [PATCH 7/9] powerpc: add MPC837x RDB platform support
From: Kim Phillips @ 2008-01-25 17:45 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, Jerry, Huang, Joe D'Abbraccio
In-Reply-To: <ED723035-5E14-44B5-B35C-B94133561D78@kernel.crashing.org>

On Fri, 25 Jan 2008 10:17:14 -0600
Kumar Gala <galak@kernel.crashing.org> wrote:

> 
> On Jan 24, 2008, at 8:47 PM, Kim Phillips wrote:
> 
> > primarily based on mpc837x mds code.
> >
> > Signed-off-by: Joe D'Abbraccio <ljd015@freescale.com>
> > Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> > ---
> 
> Who's the actual other of these patches?  (all 9 of them).

I took Joe's 837x from:

http://ozlabs.org/pipermail/linuxppc-embedded/2007-September/028460.html

and updated them.

831x I took from Jerry Huang's tree and updated them.

Kim

^ permalink raw reply

* RE: Failed to mount rootfs
From: Bizhan Gholikhamseh (bgholikh) @ 2008-01-25 16:47 UTC (permalink / raw)
  To: hs; +Cc: linuxppc-embedded
In-Reply-To: <47998D8B.8050100@denx.de>

=20
Hi Heiko,=20
> "Bizhan Gholikhamseh (bgholikh)" <bgholikh@cisco.com> wrote:
> > Our custom board is leveraged from MPC8541cds from freescale.
> > We have been running Linux 2.6.11 on it recently I have=20
> tried to boot=20
> > the system with the latest Linux 2.6.22-rc4 from PowerPC git tree.
> > =20
> > I did ported the libfdt to our older version of the uboot and were=20
> > able to
>=20
> Hmm... why you didnt use actual code?
>=20
> [...]
> >     chosen {
> >         linux,stdout-path =3D "/soc8541@e0000000/serial@4600";
> >     };
> >     chosen {
> >         name =3D "chosen";
> >         bootargs =3D "root=3D/dev/ram rw console=3DttyS1,115200";
> >         linux,platform =3D <600>;
> >         linux,initrd-start =3D <1ef33000>;
> >         linux,initrd-end =3D <1fe190aa>;
> >         linux,stdout-path =3D "/soc8541@e0000000/serial@4600";
> >     };
> > };
>=20
> Here is your problem, you have 2 choosen nodes:
>=20
> 64k data, 108k bss, 116k init) Mount-cache hash table entries: 512
> device-tree: Duplicate name in /, renamed to "chosen#1"
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> -> Linux didnt find your commandline ...
>=20
> Hmm... do you have CONFIG_OF_FLAT_TREE and CONFIG_OF_LIBFDT defined?
> If so, this would explain, why you have 2 choosen nodes.

Yes I do have both CONFIG_OF_FLAT_TREE and CONFIG_OF_LIBFDT defined. Is
there a document to tell more about these options please?

Thanks,
Bizhan

^ permalink raw reply

* drivers/char/hvc_* and /Documentation/powerpc/hvcs.txt
From: Timur Tabi @ 2008-01-25 22:39 UTC (permalink / raw)
  To: linuxppc-dev

Hi,

I'm working on a console driver for the Freescale hypervisor.  I notice a bunch 
of hvc_* files in the drivers/char directory.  I also noticed 
/Documentation/powerpc/hvcs.txt.

My guess is that hvcs.txt talks about drivers/char/hvcs.c, which is a console 
driver specific to some IBM hypervisor.  The hvc_*.c files are based on that 
code but they're more generic and allow people to write console drivers for 
other hypervisors easliy.  Am I right?

If so, does this mean that I can take hvc_beat.c, modify it to make Freescale 
hypervisor calls instead, and presto, I'm done?

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: [PATCH 5/5] [POWERPC] fsl_soc, legacy_serial: add support for "soc" compatible matching
From: Anton Vorontsov @ 2008-01-25 17:26 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev list, Yoder Stuart
In-Reply-To: <20080125171355.GA9879@localhost.localdomain>

On Fri, Jan 25, 2008 at 08:13:55PM +0300, Anton Vorontsov wrote:
[...]
> My thinking:
> 
> Freescale soc register space: "fsl,soc"
> generic soc device: "soc" (or maybe "linux,soc" better?)
> 
> I know, Scott Wood is pushing "xxxx-immr" thing forward... but
> I don't like that name because SOC isn't only device with the
> Internal Memory Mapped Registers. (Think of QE placed outside
> of "soc"/"immr" node).
> 
> Though, "soc" by itself is fully unfortunate name. QE is the
> part of SOC too, as we used to call it when speaking of hardware.
> But logically we divide things for "core soc" and "core soc's
> companion/communication/offload modules", i.e. QE/CPMs/...
> 
> We can remove that ambiguity by moving QE/CPMs nodes inside
> the soc node. Then indeed -immr would be the best compatible for
> the "soc" node.

Oh, and yes, I'm aware that CPM's IMMRs are relocatable, and
that's [most probably] why we have CPMs outside of soc node.
So, my point is that that -immr name is too vague, so in my
opinion we should avoid using it.

-- 
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2

^ permalink raw reply

* [PATCHv3 2.6.25] i2c: adds support for i2c bus on Freescale CPM1/CPM2 controllers
From: Jochen Friedrich @ 2008-01-25 17:11 UTC (permalink / raw)
  To: Scott Wood; +Cc: Kernel, Linux, linuxppc-dev list, Linux I2C, Jean Delvare

Using the port of 2.4 code from Vitaly Bordug <vitb@kernel.crashing.org>
and the actual algorithm used by the i2c driver of the DBox code on
cvs.tuxboc.org from Tmbinc, Gillem (htoa@gmx.net). Renamed i2c-rpx.c and
i2c-algo-8xx.c to i2c-cpm.c and converted the driver to an
of_platform_driver.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 arch/powerpc/boot/dts/mpc8272ads.dts         |   10 +
 arch/powerpc/boot/dts/mpc866ads.dts          |   10 +
 arch/powerpc/boot/dts/mpc885ads.dts          |   10 +
 arch/powerpc/platforms/8xx/mpc885ads_setup.c |    5 +
 drivers/i2c/busses/Kconfig                   |   10 +
 drivers/i2c/busses/Makefile                  |    1 +
 drivers/i2c/busses/i2c-cpm.c                 |  759 ++++++++++++++++++++++++++
 7 files changed, 805 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-cpm.c

diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 7285ca1..7273996 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -215,6 +215,16 @@
 				linux,network-index = <1>;
 				fsl,cpm-command = <16200300>;
 			};
+
+			i2c@11860 {
+				compatible = "fsl,mpc8248-i2c",
+					     "fsl,cpm2-i2c",
+					     "fsl,cpm-i2c";
+				reg = <11860 20 8afc 2>;
+				interrupts = <1 8>;
+				interrupt-parent = <&PIC>;
+				fsl,cpm-command = <29600000>;
+			};
 		};
 
 		PIC: interrupt-controller@10c00 {
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index daf9433..80c08bf 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -169,6 +169,16 @@
 				fsl,cpm-command = <0000>;
 				linux,network-index = <1>;
 			};
+
+			i2c@860 {
+				compatible = "fsl,mpc866-i2c",
+					     "fsl,cpm1-i2c",
+					     "fsl,cpm-i2c";
+				reg = <860 20 3c80 30>;
+				interrupts = <10 3>;
+				interrupt-parent = <&Cpm_pic>;
+				fsl,cpm-command = <0010>;
+			};
 		};
 	};
 
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 8848e63..fd9c9d7 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -213,6 +213,16 @@
 				fsl,cpm-command = <0080>;
 				linux,network-index = <2>;
 			};
+
+			i2c@860 {
+				compatible = "fsl,mpc885-i2c",
+					     "fsl,cpm1-i2c",
+					     "fsl,cpm-i2c";
+				reg = <860 20 3c80 30>;
+				interrupts = <10>;
+				interrupt-parent = <&CPM_PIC>;
+				fsl,cpm-command = <0010>;
+			};
 		};
 	};
 
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index f39447b..1e7d056 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -157,6 +157,11 @@ static struct cpm_pin mpc885ads_pins[] = {
 	{CPM_PORTE, 28, CPM_PIN_OUTPUT},
 	{CPM_PORTE, 29, CPM_PIN_OUTPUT},
 #endif
+	/* I2C */
+#ifdef CONFIG_I2C_8XX
+	{CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+	{CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+#endif
 };
 
 static void __init init_ioports(void)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index c466c6c..5950172 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -114,6 +114,16 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
 	help
 	  The unit of the TWI clock is kHz.
 
+config I2C_CPM
+	tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
+	depends on (CPM1 || CPM2) && I2C && PPC_OF
+	help
+	  This supports the use of the I2C interface on Freescale
+	  processors with CPM1 or CPM2.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-cpm.
+
 config I2C_DAVINCI
 	tristate "DaVinci I2C driver"
 	depends on ARCH_DAVINCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 81d43c2..a395555 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
 obj-$(CONFIG_I2C_AT91)		+= i2c-at91.o
 obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o
 obj-$(CONFIG_I2C_BLACKFIN_TWI)	+= i2c-bfin-twi.o
+obj-$(CONFIG_I2C_CPM)		+= i2c-cpm.o
 obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
new file mode 100644
index 0000000..7191427
--- /dev/null
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -0,0 +1,759 @@
+/*
+ * Freescale CPM1/CPM2 I2C interface.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
+ *
+ * moved into proper i2c interface;
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * RPX lite specific parts of the i2c interface
+ * Update:  There actually isn't anything RPXLite-specific about this module.
+ * This should work for most any CPM board.  The console messages have been
+ * changed to eliminate RPXLite references.
+ *
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * moved into proper i2c interface; separated out platform specific
+ * parts into i2c-8xx.c
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * Parts from dbox2_i2c.c (cvs.tuxbox.org)
+ * (C) 2000-2001 Tmbinc, Gillem (htoa@gmx.net)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * Converted to of_platform_device. Renamed to i2c-cpm.c.
+ * (C) 2007 Jochen Friedrich <jochen@scram.de>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/time.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/cpm.h>
+
+/*
+ * Wait for patch from Jon Smirl
+ * #include "powerpc-common.h"
+ */
+
+/* Try to define this if you have an older CPU (earlier than rev D4) */
+/* However, better use a GPIO based bitbang driver in this case :/   */
+#undef	I2C_CHIP_ERRATA
+
+#define CPM_MAX_READ    513
+#define CPM_MAXBD       4
+
+#define CPM_CR_INIT_TRX		(0x00)
+#define CPM_CR_CLOSE_RXBD	(0x07)
+
+#define I2C_EB			(0x10) /* Big endian mode */
+
+/* I2C parameter RAM. */
+struct i2c_ram {
+	ushort  rbase;		/* Rx Buffer descriptor base address */
+	ushort  tbase;		/* Tx Buffer descriptor base address */
+	u_char  rfcr;		/* Rx function code */
+	u_char  tfcr;		/* Tx function code */
+	ushort  mrblr;		/* Max receive buffer length */
+	uint    rstate;		/* Internal */
+	uint    rdp;		/* Internal */
+	ushort  rbptr;		/* Rx Buffer descriptor pointer */
+	ushort  rbc;		/* Internal */
+	uint    rxtmp;		/* Internal */
+	uint    tstate;		/* Internal */
+	uint    tdp;		/* Internal */
+	ushort  tbptr;		/* Tx Buffer descriptor pointer */
+	ushort  tbc;		/* Internal */
+	uint    txtmp;		/* Internal */
+	char    res1[4];	/* Reserved */
+	ushort  rpbase;		/* Relocation pointer */
+	char    res2[2];	/* Reserved */
+};
+
+/* I2C Registers */
+struct i2c_reg {
+	u8	i2mod;
+	u8	res1[3];
+	u8	i2add;
+	u8	res2[3];
+	u8	i2brg;
+	u8	res3[3];
+	u8	i2com;
+	u8	res4[3];
+	u8	i2cer;
+	u8	res5[3];
+	u8	i2cmr;
+};
+
+struct cpm_i2c {
+	char *base;
+	struct of_device *ofdev;
+	struct i2c_adapter adap;
+	uint dp_addr;
+	int version; /* CPM1=1, CPM2=2 */
+	int irq;
+	int cp_command;
+	struct i2c_reg __iomem *i2c_reg;
+	struct i2c_ram __iomem *i2c_ram;
+	u16 i2c_addr;
+	wait_queue_head_t i2c_wait;
+	struct mutex i2c_mutex; /* Protects I2C CPM */
+	u_char *txbuf[CPM_MAXBD];
+	u_char *rxbuf[CPM_MAXBD];
+	u32 txdma[CPM_MAXBD];
+	u32 rxdma[CPM_MAXBD];
+};
+
+static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
+{
+	struct cpm_i2c *cpm;
+	struct i2c_reg __iomem *i2c_reg;
+	struct i2c_adapter *adap = dev_id;
+	int i;
+
+	cpm = i2c_get_adapdata(dev_id);
+	i2c_reg = cpm->i2c_reg;
+
+	/* Clear interrupt. */
+	i = in_8(&i2c_reg->i2cer);
+	out_8(&i2c_reg->i2cer, i);
+
+	dev_dbg(&adap->dev, "Interrupt: %x\n", i);
+
+	/* Get 'me going again. */
+	wake_up_interruptible(&cpm->i2c_wait);
+
+	return i ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void cpm_reset_i2c_params(struct cpm_i2c *cpm)
+{
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+
+	/* Set up the IIC parameters in the parameter ram. */
+	out_be16(&i2c_ram->tbase, cpm->dp_addr);
+	out_be16(&i2c_ram->rbase, cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD);
+
+	out_8(&i2c_ram->tfcr, I2C_EB);
+	out_8(&i2c_ram->rfcr, I2C_EB);
+
+	out_be16(&i2c_ram->mrblr, CPM_MAX_READ);
+
+	out_be32(&i2c_ram->rstate, 0);
+	out_be32(&i2c_ram->rdp, 0);
+	out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+	out_be16(&i2c_ram->rbc, 0);
+	out_be32(&i2c_ram->rxtmp, 0);
+	out_be32(&i2c_ram->tstate, 0);
+	out_be32(&i2c_ram->tdp, 0);
+	out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+	out_be16(&i2c_ram->tbc, 0);
+	out_be32(&i2c_ram->txtmp, 0);
+}
+
+static void cpm_i2c_force_close(struct i2c_adapter *adap)
+{
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+
+	dev_dbg(&adap->dev, "cpm_i2c_force_close()\n");
+
+	cpm_command(cpm->cp_command, CPM_CR_CLOSE_RXBD);
+
+	out_8(&i2c_reg->i2cmr, 0x00);	/* Disable all interrupts */
+	out_8(&i2c_reg->i2cer, 0xff);
+}
+
+static void cpm_i2c_parse_message(struct i2c_adapter *adap,
+	struct i2c_msg *pmsg, int num, int tx, int rx)
+{
+	cbd_t *tbdf, *rbdf;
+	u_char addr;
+	u_char *tb;
+	u_char *rb;
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	int i, dscan;
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	/*
+	 * This chip can't do zero length writes. However, the i2c core uses
+	 * them to scan for devices. The best we can do is to convert them
+	 * into 1 byte reads
+	 */
+
+	dscan = ((pmsg->len == 0) && (num == 1));
+
+	addr = pmsg->addr << 1;
+	if ((pmsg->flags & I2C_M_RD) || dscan)
+		addr |= 1;
+
+	tb = cpm->txbuf[tx];
+	rb = cpm->rxbuf[rx];
+
+	/* Align read buffer */
+	rb = (u_char *) (((ulong) rb + 1) & ~1);
+
+	if ((pmsg->flags & I2C_M_RD) || dscan) {
+		/*
+		 * To read, we need an empty buffer of the proper length.
+		 * All that is used is the first byte for address, the remainder
+		 * is just used for timing (and doesn't really have to exist).
+		 */
+		tb[0] = addr;		/* Device address byte w/rw flag */
+
+		dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr);
+
+		if (dscan)
+			tbdf[tx].cbd_datlen = 2;
+		else
+			tbdf[tx].cbd_datlen = pmsg->len + 1;
+
+		tbdf[tx].cbd_sc = 0;
+
+		if (!(pmsg->flags & I2C_M_NOSTART))
+			tbdf[tx].cbd_sc |= BD_I2C_START;
+		if (tx + 1 == num)
+			tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+		rbdf[rx].cbd_datlen = 0;
+		rbdf[rx].cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
+
+		if (rx + 1 == CPM_MAXBD)
+			tbdf[rx].cbd_sc |= BD_SC_WRAP;
+
+		eieio();
+		tbdf[tx].cbd_sc |= BD_SC_READY;
+	} else {
+		tb[0] = addr;		/* Device address byte w/rw flag */
+		for (i = 0; i < pmsg->len; i++)
+			tb[i+1] = pmsg->buf[i];
+
+		dev_dbg(&adap->dev, "cpm_iic_write(abyte=0x%x)\n", addr);
+
+		tbdf[tx].cbd_datlen = pmsg->len + 1;
+		tbdf[tx].cbd_sc = 0;
+
+		if (!(pmsg->flags & I2C_M_NOSTART))
+			tbdf[tx].cbd_sc |= BD_I2C_START;
+
+		if (tx + 1 == num)
+			tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+		eieio();
+		tbdf[tx].cbd_sc |= BD_SC_READY | BD_SC_INTRPT;
+
+		dev_dbg(&adap->dev, "tx sc %d %04x\n",
+			tx, tbdf[tx].cbd_sc);
+	}
+}
+
+static int cpm_i2c_check_message(struct i2c_adapter *adap,
+	struct i2c_msg *pmsg, int tx, int rx)
+{
+	cbd_t *tbdf, *rbdf;
+	u_char *tb;
+	u_char *rb;
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	int i;
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	tb = cpm->txbuf[tx];
+	rb = cpm->rxbuf[rx];
+
+	/* Align read buffer */
+	rb = (u_char *) (((uint) rb + 1) & ~1);
+
+	if (pmsg->flags & I2C_M_RD) {
+		dev_dbg(&adap->dev, "rx sc %04x, rx sc %04x\n",
+			tbdf[tx].cbd_sc, rbdf[rx].cbd_sc);
+
+		if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+			dev_dbg(&adap->dev, "IIC read; No ack\n");
+
+			if (pmsg->flags & I2C_M_IGNORE_NAK)
+				return 0;
+			else
+				return -EIO;
+		}
+		if (rbdf[rx].cbd_sc & BD_SC_EMPTY) {
+			dev_dbg(&adap->dev,
+				"IIC read; complete but rbuf empty\n");
+			return -EREMOTEIO;
+		}
+		if (rbdf[rx].cbd_sc & BD_SC_OV) {
+			dev_dbg(&adap->dev, "IIC read; Overrun\n");
+			return -EREMOTEIO;
+		}
+		for (i = 0; i < pmsg->len; i++)
+			pmsg->buf[i] = rb[i];
+	} else {
+		dev_dbg(&adap->dev, "tx sc %d %04x\n", tx, tbdf[tx].cbd_sc);
+
+		if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+			dev_dbg(&adap->dev, "IIC write; No ack\n");
+
+			if (pmsg->flags & I2C_M_IGNORE_NAK)
+				return 0;
+			else
+				return -EIO;
+		}
+		if (tbdf[tx].cbd_sc & BD_SC_UN) {
+			dev_dbg(&adap->dev, "IIC write; Underrun\n");
+			return -EIO;
+		}
+		if (tbdf[tx].cbd_sc & BD_SC_CL) {
+			dev_dbg(&adap->dev, "IIC write; Collision\n");
+			return -EIO;
+		}
+	}
+	return 0;
+}
+
+static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	struct i2c_msg *pmsg, *rmsg;
+	int ret, i;
+	int tptr;
+	int rptr;
+	cbd_t *tbdf, *rbdf;
+
+	if (num > CPM_MAXBD)
+		return -EINVAL;
+
+	/* Check if we have any oversized READ requests */
+	for (i = 0; i < num; i++) {
+		pmsg = &msgs[i];
+		if (pmsg->len >= CPM_MAX_READ)
+			return -EINVAL;
+	}
+
+	mutex_lock(&cpm->i2c_mutex);
+
+	/* Reset to use first buffer */
+	out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+	out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	tptr = 0;
+	rptr = 0;
+
+	while (tptr < num) {
+		pmsg = &msgs[tptr];
+		dev_dbg(&adap->dev, "i2c-algo-cpm.o: " "R: %d T: %d\n",
+			rptr, tptr);
+
+		cpm_i2c_parse_message(adap, pmsg, num, tptr, rptr);
+		if (pmsg->flags & I2C_M_RD)
+			rptr++;
+		tptr++;
+	}
+	/* Start transfer now */
+	/* Chip bug, set enable here */
+	out_8(&i2c_reg->i2cmr, 0x13);	/* Enable RX/TX/Error interupts */
+	out_8(&i2c_reg->i2cer, 0xff);	/* Clear interrupt status */
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | 1);	/* Enable */
+	/* Begin transmission */
+	out_8(&i2c_reg->i2com, in_8(&i2c_reg->i2com) | 0x80);
+
+	tptr = 0;
+	rptr = 0;
+
+	while (tptr < num) {
+		/* Check for outstanding messages */
+		dev_dbg(&adap->dev, "test ready.\n");
+		if (!(tbdf[tptr].cbd_sc & BD_SC_READY)) {
+			dev_dbg(&adap->dev, "ready.\n");
+			rmsg = &msgs[tptr];
+			ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
+			tptr++;
+			if (rmsg->flags & I2C_M_RD)
+				rptr++;
+			if (ret)
+				goto out_err;
+		} else {
+			dev_dbg(&adap->dev, "not ready.\n");
+			ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+				!(tbdf[tptr].cbd_sc & BD_SC_READY), 1 * HZ);
+			if (ret == 0) {
+				ret = -EREMOTEIO;
+				dev_dbg(&adap->dev, "I2C read: timeout!\n");
+				goto out_err;
+			}
+		}
+	}
+#ifdef I2C_CHIP_ERRATA
+	/*
+	 * Chip errata, clear enable. This is not needed on rev D4 CPUs.
+	 * Disabling I2C too early may cause too short stop condition
+	 */
+	udelay(4);
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+#endif
+	mutex_unlock(&cpm->i2c_mutex);
+	return (num);
+
+out_err:
+	cpm_i2c_force_close(adap);
+#ifdef I2C_CHIP_ERRATA
+	/*
+	 * Chip errata, clear enable. This is not needed on rev D4 CPUs.
+	 */
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+#endif
+	mutex_unlock(&cpm->i2c_mutex);
+	return ret;
+}
+
+static u32 cpm_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static const struct i2c_algorithm cpm_i2c_algo = {
+	.master_xfer = cpm_i2c_xfer,
+	.functionality = cpm_i2c_func,
+};
+
+static const struct i2c_adapter cpm_ops = {
+	.owner		= THIS_MODULE,
+	.name		= "i2c-cpm",
+	.id		= I2C_HW_MPC8XX_EPON,
+	.algo		= &cpm_i2c_algo,
+	.class		= I2C_CLASS_HWMON,
+};
+
+static int cpm_i2c_setup(struct cpm_i2c *cpm)
+{
+	struct of_device *ofdev = cpm->ofdev;
+	const u32 *data;
+	int len, ret, i;
+	void __iomem *i2c_base;
+	cbd_t *tbdf, *rbdf;
+	unsigned char brg;
+
+	pr_debug("i2c-cpm: cpm_i2c_setup()\n");
+
+	init_waitqueue_head(&cpm->i2c_wait);
+	mutex_init(&cpm->i2c_mutex);
+
+	cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL);
+	if (cpm->irq == NO_IRQ)
+		return -EINVAL;
+
+	/* Install interrupt handler. */
+	ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c",
+			  &cpm->adap);
+	if (ret)
+		goto out_irq;
+
+	/* IIC parameter RAM */
+	i2c_base = of_iomap(ofdev->node, 1);
+	if (i2c_base == NULL) {
+		ret = -EINVAL;
+		goto out_irq;
+	}
+
+	if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) {
+
+		/* Check for and use a microcode relocation patch. */
+		cpm->i2c_ram = i2c_base;
+		cpm->i2c_addr = in_be16(&cpm->i2c_ram->rpbase);
+
+		/*
+		 * Maybe should use cpm_muram_alloc instead of hardcoding
+		 * this in micropatch.c
+		 */
+		if (cpm->i2c_addr) {
+			cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+			iounmap(i2c_base);
+		}
+
+		cpm->version = 1;
+
+	} else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) {
+		cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64);
+		cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+		out_be16(i2c_base, cpm->i2c_addr);
+		iounmap(i2c_base);
+
+		cpm->version = 2;
+
+	} else {
+		iounmap(i2c_base);
+		ret = -EINVAL;
+		goto out_irq;
+	}
+
+	/* I2C control/status registers */
+	cpm->i2c_reg = of_iomap(ofdev->node, 0);
+	if (cpm->i2c_reg == NULL) {
+		ret = -EINVAL;
+		goto out_ram;
+	}
+
+	data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
+	if (!data || len != 4) {
+		ret = -EINVAL;
+		goto out_reg;
+	}
+	cpm->cp_command = *data;
+
+	data = of_get_property(ofdev->node, "linux,i2c-class", &len);
+	if (data && len == 4)
+		cpm->adap.class = *data;
+
+	/*
+	 * Allocate space for CPM_MAXBD transmit and receive buffer
+	 * descriptors in the DP ram.
+	 */
+	cpm->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 2 * CPM_MAXBD, 8);
+	if (!cpm->dp_addr) {
+		ret = -ENOMEM;
+		goto out_reg;
+	}
+
+	/* Initialize Tx/Rx parameters. */
+
+	cpm_reset_i2c_params(cpm);
+
+	pr_debug("i2c-cpm: i2c_ram %x, dp_addr 0x%x\n", (uint) cpm->i2c_ram,
+		cpm->dp_addr);
+	pr_debug("i2c-cpm: tbase %d, rbase %d\n",
+		in_be16(&cpm->i2c_ram->tbase), in_be16(&cpm->i2c_ram->rbase));
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->rbase));
+
+	/* Allocate TX and RX buffers */
+
+	for (i = 0; i < CPM_MAXBD; i++) {
+		cpm->rxbuf[i] = dma_alloc_coherent(
+			NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+		if (!cpm->rxbuf[i]) {
+			ret = -ENOMEM;
+			goto out_muram;
+		}
+		rbdf[i].cbd_bufaddr = ((cpm->rxdma[i] + 1) & ~1);
+		cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
+			NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+		if (!cpm->txbuf[i]) {
+			ret = -ENOMEM;
+			goto out_muram;
+		}
+		tbdf[i].cbd_bufaddr = cpm->txdma[i];
+	}
+
+	cpm_command(cpm->cp_command, CPM_CR_INIT_TRX);
+
+	/*
+	 * Select an invalid address. Just make sure we don't use loopback mode
+	 */
+	out_8(&cpm->i2c_reg->i2add, 0xfe);
+
+	/* Make clock run at 60 kHz. */
+
+	brg = get_brgfreq() / (32 * 2 * 60000) - 3;
+	out_8(&cpm->i2c_reg->i2brg, brg);
+
+	out_8(&cpm->i2c_reg->i2mod, 0x00);
+	out_8(&cpm->i2c_reg->i2com, 0x01);	/* Master mode */
+
+	/* Disable interrupts. */
+	out_8(&cpm->i2c_reg->i2cmr, 0);
+	out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+	return 0;
+
+out_muram:
+	for (i = 0; i < CPM_MAXBD; i++) {
+		if (cpm->rxbuf[i])
+			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+				cpm->rxbuf[i], cpm->rxdma[i]);
+		if (cpm->txbuf[i])
+			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+				cpm->txbuf[i], cpm->txdma[i]);
+	}
+	cpm_muram_free(cpm->dp_addr);
+out_reg:
+	iounmap(cpm->i2c_reg);
+out_ram:
+	if ((cpm->version == 1) && (!cpm->i2c_addr))
+		iounmap(cpm->i2c_ram);
+	if (cpm->version == 2)
+		cpm_muram_free(cpm->i2c_addr);
+out_irq:
+	free_irq(cpm->irq, &cpm->adap);
+	return ret;
+}
+
+static void cpm_i2c_shutdown(struct cpm_i2c *cpm)
+{
+	int i;
+
+	/* Shut down I2C. */
+	out_8(&cpm->i2c_reg->i2mod, in_8(&cpm->i2c_reg->i2mod) | ~1);
+
+	/* Disable interrupts */
+	out_8(&cpm->i2c_reg->i2cmr, 0);
+	out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+	free_irq(cpm->irq, &cpm->adap);
+
+	/* Free all memory */
+	for (i = 0; i < CPM_MAXBD; i++) {
+		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			cpm->rxbuf[i], cpm->rxdma[i]);
+		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			cpm->txbuf[i], cpm->txdma[i]);
+	}
+
+	cpm_muram_free(cpm->dp_addr);
+	iounmap(cpm->i2c_reg);
+
+	if ((cpm->version == 1) && (!cpm->i2c_addr))
+		iounmap(cpm->i2c_ram);
+	if (cpm->version == 2)
+		cpm_muram_free(cpm->i2c_addr);
+
+	return;
+}
+
+static int __devinit cpm_i2c_probe(struct of_device *ofdev,
+			 const struct of_device_id *match)
+{
+	int result;
+	struct cpm_i2c *cpm;
+
+	cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL);
+	if (!cpm)
+		return -ENOMEM;
+
+	cpm->ofdev = ofdev;
+
+	dev_set_drvdata(&ofdev->dev, cpm);
+
+	cpm->adap = cpm_ops;
+	i2c_set_adapdata(&cpm->adap, cpm);
+	cpm->adap.dev.parent = &ofdev->dev;
+
+	result = cpm_i2c_setup(cpm);
+	if (result) {
+		printk(KERN_ERR "i2c-cpm: Unable to init hardware\n");
+		goto out;
+	}
+
+	/* register new adapter to i2c module... */
+
+	result = i2c_add_adapter(&cpm->adap);
+	if (result < 0) {
+		printk(KERN_ERR "i2c-cpm: Unable to register with I2C\n");
+		goto out2;
+	}
+
+	pr_debug("i2c-cpm: hw routines for %s registered.\n", cpm->adap.name);
+
+	/*
+	 * Wait for patch from Jon Smirl
+	 * of_register_i2c_devices(&cpm->adap, ofdev->node);
+	 */
+
+	return 0;
+out2:
+	cpm_i2c_shutdown(cpm);
+out:
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(cpm);
+
+	return result;
+}
+
+static int __devexit cpm_i2c_remove(struct of_device *ofdev)
+{
+	struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);
+
+	i2c_del_adapter(&cpm->adap);
+
+	cpm_i2c_shutdown(cpm);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(cpm);
+
+	return 0;
+}
+
+static const struct of_device_id cpm_i2c_match[] = {
+	{
+		.compatible = "fsl,cpm-i2c",
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, cpm_i2c_match);
+
+static struct of_platform_driver cpm_i2c_driver = {
+	.match_table	= cpm_i2c_match,
+	.probe		= cpm_i2c_probe,
+	.remove		= __devexit_p(cpm_i2c_remove),
+	.driver		= {
+		.name	= "fsl-i2c-cpm",
+		.owner	= THIS_MODULE,
+	}
+};
+
+static int __init cpm_i2c_init(void)
+{
+	return of_register_platform_driver(&cpm_i2c_driver);
+}
+
+static void __exit cpm_i2c_exit(void)
+{
+	of_unregister_platform_driver(&cpm_i2c_driver);
+}
+
+module_init(cpm_i2c_init);
+module_exit(cpm_i2c_exit);
+
+MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");
+MODULE_LICENSE("GPL");
-- 
1.5.3.8

^ permalink raw reply related

* [PATCH 2/2] IB/ehca: Add PMA support
From: Joachim Fenkes @ 2008-01-25 20:18 UTC (permalink / raw)
  To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier, OF-EWG
  Cc: Stefan Roscher, Christoph Raisch
In-Reply-To: <200801252111.11915.fenkes@de.ibm.com>

From: Hoang-Nam Nguyen <hnguyen@de.ibm.com>

This patch enables ehca to redirect any PMA queries to the
actual PMA QP.

Signed-off-by: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Reviewed-by: Joachim Fenkes <fenkes@de.ibm.com>
Reviewed-by: Christoph Raisch <raisch@de.ibm.com>
---
 drivers/infiniband/hw/ehca/ehca_classes.h |    1 +
 drivers/infiniband/hw/ehca/ehca_iverbs.h  |    5 ++
 drivers/infiniband/hw/ehca/ehca_main.c    |    2 +-
 drivers/infiniband/hw/ehca/ehca_sqp.c     |   91 +++++++++++++++++++++++++++++
 4 files changed, 98 insertions(+), 1 deletions(-)

diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index f281d16..92cce8a 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -101,6 +101,7 @@ struct ehca_sport {
 	spinlock_t mod_sqp_lock;
 	enum ib_port_state port_state;
 	struct ehca_sma_attr saved_attr;
+	u32 pma_qp_nr;
 };
 
 #define HCA_CAP_MR_PGSIZE_4K  0x80000000
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index c469bfd..a8a2ea5 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -187,6 +187,11 @@ int ehca_dealloc_ucontext(struct ib_ucontext *context);
 
 int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
 
+int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
+		     struct ib_wc *in_wc, struct ib_grh *in_grh,
+		     struct ib_mad *in_mad,
+		     struct ib_mad *out_mad);
+
 void ehca_poll_eqs(unsigned long data);
 
 int ehca_calc_ipd(struct ehca_shca *shca, int port,
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 0fe0c84..33b5bac 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -472,7 +472,7 @@ int ehca_init_device(struct ehca_shca *shca)
 	shca->ib_device.dealloc_fmr	    = ehca_dealloc_fmr;
 	shca->ib_device.attach_mcast	    = ehca_attach_mcast;
 	shca->ib_device.detach_mcast	    = ehca_detach_mcast;
-	/* shca->ib_device.process_mad	    = ehca_process_mad;	    */
+	shca->ib_device.process_mad	    = ehca_process_mad;
 	shca->ib_device.mmap		    = ehca_mmap;
 
 	if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c
index 79e72b2..706d97a 100644
--- a/drivers/infiniband/hw/ehca/ehca_sqp.c
+++ b/drivers/infiniband/hw/ehca/ehca_sqp.c
@@ -39,12 +39,18 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rdma/ib_mad.h>
 
 #include "ehca_classes.h"
 #include "ehca_tools.h"
 #include "ehca_iverbs.h"
 #include "hcp_if.h"
 
+#define IB_MAD_STATUS_REDIRECT		__constant_htons(0x0002)
+#define IB_MAD_STATUS_UNSUP_VERSION	__constant_htons(0x0004)
+#define IB_MAD_STATUS_UNSUP_METHOD	__constant_htons(0x0008)
+
+#define IB_PMA_CLASS_PORT_INFO		__constant_htons(0x0001)
 
 /**
  * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
@@ -83,6 +89,9 @@ u64 ehca_define_sqp(struct ehca_shca *shca,
 				 port, ret);
 			return ret;
 		}
+		shca->sport[port - 1].pma_qp_nr = pma_qp_nr;
+		ehca_dbg(&shca->ib_device, "port=%x pma_qp_nr=%x",
+			 port, pma_qp_nr);
 		break;
 	default:
 		ehca_err(&shca->ib_device, "invalid qp_type=%x",
@@ -109,3 +118,85 @@ u64 ehca_define_sqp(struct ehca_shca *shca,
 
 	return H_SUCCESS;
 }
+
+struct ib_perf {
+	struct ib_mad_hdr mad_hdr;
+	u8 reserved[40];
+	u8 data[192];
+} __attribute__ ((packed));
+
+
+static int ehca_process_perf(struct ib_device *ibdev, u8 port_num,
+			     struct ib_mad *in_mad, struct ib_mad *out_mad)
+{
+	struct ib_perf *in_perf = (struct ib_perf *)in_mad;
+	struct ib_perf *out_perf = (struct ib_perf *)out_mad;
+	struct ib_class_port_info *poi =
+		(struct ib_class_port_info *)out_perf->data;
+	struct ehca_shca *shca =
+		container_of(ibdev, struct ehca_shca, ib_device);
+	struct ehca_sport *sport = &shca->sport[port_num - 1];
+
+	ehca_dbg(ibdev, "method=%x", in_perf->mad_hdr.method);
+
+	*out_mad = *in_mad;
+
+	if (in_perf->mad_hdr.class_version != 1) {
+		ehca_warn(ibdev, "Unsupported class_version=%x",
+			  in_perf->mad_hdr.class_version);
+		out_perf->mad_hdr.status = IB_MAD_STATUS_UNSUP_VERSION;
+		goto perf_reply;
+	}
+
+	switch (in_perf->mad_hdr.method) {
+	case IB_MGMT_METHOD_GET:
+	case IB_MGMT_METHOD_SET:
+		/* set class port info for redirection */
+		out_perf->mad_hdr.attr_id = IB_PMA_CLASS_PORT_INFO;
+		out_perf->mad_hdr.status = IB_MAD_STATUS_REDIRECT;
+		memset(poi, 0, sizeof(*poi));
+		poi->base_version = 1;
+		poi->class_version = 1;
+		poi->resp_time_value = 18;
+		poi->redirect_lid = sport->saved_attr.lid;
+		poi->redirect_qp = sport->pma_qp_nr;
+		poi->redirect_qkey = IB_QP1_QKEY;
+		poi->redirect_pkey = IB_DEFAULT_PKEY_FULL;
+
+		ehca_dbg(ibdev, "ehca_pma_lid=%x ehca_pma_qp=%x",
+			 sport->saved_attr.lid, sport->pma_qp_nr);
+		break;
+
+	case IB_MGMT_METHOD_GET_RESP:
+		return IB_MAD_RESULT_FAILURE;
+
+	default:
+		out_perf->mad_hdr.status = IB_MAD_STATUS_UNSUP_METHOD;
+		break;
+	}
+
+perf_reply:
+	out_perf->mad_hdr.method = IB_MGMT_METHOD_GET_RESP;
+
+	return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
+}
+
+int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
+		     struct ib_wc *in_wc, struct ib_grh *in_grh,
+		     struct ib_mad *in_mad,
+		     struct ib_mad *out_mad)
+{
+	int ret;
+
+	if (!port_num || port_num > ibdev->phys_port_cnt)
+		return IB_MAD_RESULT_FAILURE;
+
+	/* accept only pma request */
+	if (in_mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_PERF_MGMT)
+		return IB_MAD_RESULT_SUCCESS;
+
+	ehca_dbg(ibdev, "port_num=%x src_qp=%x", port_num, in_wc->src_qp);
+	ret = ehca_process_perf(ibdev, port_num, in_mad, out_mad);
+
+	return ret;
+}
-- 
1.5.2

^ permalink raw reply related


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