* Re: [patch v4 0/4] Cypress c67x00 (EZ-Host/EZ-OTG) support
From: Grant Likely @ 2008-01-21 17:11 UTC (permalink / raw)
To: Peter Korsgaard; +Cc: linuxppc-dev, dbrownell, linux-usb
In-Reply-To: <20080121103434.397382000@sunsite.dk>
On 1/21/08, Peter Korsgaard <jacmet@sunsite.dk> wrote:
> The Cypress c67x00 (EZ-Host/EZ-OTG) controllers are multi-role low/fullspeed
> USB controllers. This patch series implements a HCD driver and shows the
> work-in-progress status of a gadget driver.
>
> I believe patch 1..3 are ready, and I would like to see queued up for 2.6.25.
>
> Changes since v3:
> - Lots of cleanups: checkpatch, interrupt handling, c67x00_ prefixes, ..
> - The dummy platform_device's created per serial engine are gone.
> - Gadget driver (WIP)
Can you please post/publish the diff between v3 and this series?
Thanks,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [MPC5200] problem running FEC and ATA
From: Juergen Beisert @ 2008-01-21 16:28 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mehlan, Markus (Ritter Elektronik)
In-Reply-To: <FACFFB02D783C64FB2CEF2D6825F6FC206EEF1C0@SRVEXC01.sts.saurer.vpn>
On Monday 21 January 2008 14:01, Mehlan, Markus (Ritter Elektronik) wrote:
> > -----Urspr=FCngliche Nachricht-----
> > Von: Juergen Beisert [mailto:jbe@pengutronix.de]
> > Gesendet: Montag, 21. Januar 2008 09:58
> > An: linuxppc-dev@ozlabs.org
> > Cc: Mehlan, Markus (Ritter Elektronik)
> > Betreff: Re: [MPC5200] problem running FEC and ATA
> >
> > Markus,
> >
> > On Monday 21 January 2008 08:10, Mehlan, Markus (Ritter
> >
> > Elektronik) wrote:
> > > i have the same problem with the fec driver. See my posting at
> >
> > http://ozlabs.org/pipermail/linuxppc-embedded/2008-January/029466.html
> >
> > > Arnon, have you already fixed the FEC problem?
> >
> > Can you check this?
> >
> > http://ozlabs.org/pipermail/linuxppc-embedded/2007-May/027046.html
>
> I have checked the article. To set the BSDIS bit in the XLB config regist=
er
> during initialization fixes my problem:
>
> xlb =3D (struct mpc52xx_xlb *)MPC5xxx_XLB;
> out_be32(&xlb->config, in_be32(&xlb->config) |
> MPC52xx_XLB_CFG_BSDIS);
Is anybody out there with more MPC5200B experience? Can someone tell me why=
=20
some MPC5200B are need this patch and others not? We have two different=20
systems here (cards from different vendors) with the same processor, one=20
needs this BSDIS-patch and the other not. ???????????????
Juergen
=2D-=20
Dipl.-Ing. Juergen Beisert | http://www.pengutronix.de
=A0Pengutronix - Linux Solutions for Science and Industry
=A0 Handelsregister: Amtsgericht Hildesheim, HRA 2686
=A0 =A0 =A0 Vertretung Sued/Muenchen, Germany
Phone: +49-8766-939 228 | Fax: +49-5121-206917-9
^ permalink raw reply
* Re: Endian problem when accessing internel regs on 8347
From: Scott Wood @ 2008-01-21 16:40 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-embedded
In-Reply-To: <OFE90E4633.93F2906B-ON882573D7.002448B6-882573D7.00287256@selinc.com>
On Sun, Jan 20, 2008 at 11:21:48PM -0800, Bruce_Leonard@selinc.com wrote:
> Okay, after much digging and experimenting, I'll agree that the memory
> operand makes sense. When I first said that I was thinking of direct
> manipulation of memory, which the PPC doesn't support. (Don't ask, my
> brain sometimes goes off into la-la land without me :-> ) Also, update
> mode is applicable and makes sense. But I do still have a problem with
> the index mode, though it could be compiler magic. Here's why: the index
> mode of the 'lwz' instruction requires three operands, i.e., 'lwzx
> rD,rA,rB', and there's only place holders for two operands. Is the
> compiler smart enough to add the third operand for the index mode? If so,
> what does it put for the third operand?
When the compiler decides to use index mode, the second "operand" is a
string containing "rX, rY", just as when it decides not to, the second
operand is a string containing "offset(rX)".
> Another question is how does the compiler know which mode to pick?
The same way it decides which mode to use for internally generated loads
and stores. Compiler optimization implementation is beyond the scope of
this list. :-)
> And what is the significance of the trailing number? Some places in
> the code have %U1%X1 and others have %U2%X2? I've found documentation
> for the # and ## tokens, but I can't find anything for the %U or %X
> tokens.
The number is an index into the operand list at the end of the asm
statement.
> Now this has all been very interesting to learn but doesn't solve my
> underlying problem which I've finally drilled down to. At first I thought
> in_be32() might be broken because I wasn't getting back the value I knew
> to be in the internal register. I knew I had the address and the mapping
> to kernel space correct because I could use in_le32 and get the right
> value though it was byte swapped.
Are you absolutely sure that in_le32 to in_be32 is the only thing that
changed? If you change it back now, does it resume returning a byte-swap
of the correct value?
If that is indeed what is making the difference, then perhaps it's some
subtle timing (or memory corruption) difference caused by different code
generation because the compiler is forced to use index mode for in_le32
(though it appears that the same operand list is given to GCC in either
case -- is GCC smart enough to optimize away preperation of inputs that
aren't actually referenced in the asm statement?). Is there any
difference in the generated assembly besides the specific load
instruction used?
Alternatively, maybe your chip is just fried. :-)
> I don't want to just arbitrarily point to that %U1%X1 parameter list,
So please don't.
> but I get compiler errors if I try to remove them
That's why it's there. :-)
> Can't anyone suggest anything I can try?
Beer.
-Scott
^ permalink raw reply
* Re: [PATCH 2/3] i2c: Convert all new-style drivers to use module aliasing
From: Jon Smirl @ 2008-01-21 16:50 UTC (permalink / raw)
To: Jean Delvare; +Cc: David Brownell, linuxppc-dev, Linux I2C
In-Reply-To: <20080121114139.3aaa111a@hyperion.delvare>
In my version of these patches new style drivers could be loaded with
both the driver_name/name scheme and the modalias. In these patches
new style drivers can only be loaded via modalias. Is that what you
intended? I'm all for making new style driver only use the modalias
scheme.
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* patches for 2.6.25
From: Kumar Gala @ 2008-01-21 16:43 UTC (permalink / raw)
To: linuxppc-dev
I'm sure I missed some patches for 2.6.25, so please point any out that
people would like to see get in.
- k
^ permalink raw reply
* Please pull from 'for-2.6.25' branch
From: Kumar Gala @ 2008-01-21 16:32 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Please pull from 'for-2.6.25' branch of
master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc.git for-2.6.25
to receive the following updates:
Documentation/powerpc/00-INDEX | 3
Documentation/powerpc/booting-without-of.txt | 91 +
Documentation/powerpc/qe_firmware.txt | 295 ++++
arch/powerpc/Kconfig | 3
arch/powerpc/boot/.gitignore | 1
arch/powerpc/boot/Makefile | 7
arch/powerpc/boot/cuboot-83xx.c | 3
arch/powerpc/boot/cuboot-85xx.c | 5
arch/powerpc/boot/devtree.c | 14
arch/powerpc/boot/dts/adder875-redboot.dts | 184 ++
arch/powerpc/boot/dts/adder875-uboot.dts | 183 ++
arch/powerpc/boot/dts/ep8248e.dts | 207 +++
arch/powerpc/boot/dts/mpc8313erdb.dts | 49
arch/powerpc/boot/dts/mpc832x_mds.dts | 51
arch/powerpc/boot/dts/mpc8349emitx.dts | 30
arch/powerpc/boot/dts/mpc8349emitxgp.dts | 1
arch/powerpc/boot/dts/mpc834x_mds.dts | 2
arch/powerpc/boot/dts/mpc836x_mds.dts | 1
arch/powerpc/boot/dts/mpc8377_mds.dts | 279 ++++
arch/powerpc/boot/dts/mpc8378_mds.dts | 265 ++++
arch/powerpc/boot/dts/mpc8379_mds.dts | 293 ++++
arch/powerpc/boot/dts/mpc8544ds.dts | 6
arch/powerpc/boot/dts/mpc8572ds.dts | 7
arch/powerpc/boot/dts/mpc8610_hpcd.dts | 113 +
arch/powerpc/boot/dts/mpc8641_hpcn.dts | 6
arch/powerpc/boot/ep8248e.c | 55
arch/powerpc/boot/ops.h | 14
arch/powerpc/boot/redboot-8xx.c | 58
arch/powerpc/boot/redboot.h | 56
arch/powerpc/boot/wrapper | 2
arch/powerpc/configs/adder875-redboot_defconfig | 798 ++++++++++++
arch/powerpc/configs/adder875-uboot_defconfig | 798 ++++++++++++
arch/powerpc/configs/ep8248e_defconfig | 821 +++++++++++++
arch/powerpc/configs/mpc8313_rdb_defconfig | 46
arch/powerpc/configs/mpc834x_itx_defconfig | 3
arch/powerpc/configs/mpc8610_hpcd_defconfig | 171 ++
arch/powerpc/kernel/head_fsl_booke.S | 20
arch/powerpc/kernel/pci-common.c | 8
arch/powerpc/kernel/pci_32.c | 58
arch/powerpc/math-emu/op-4.h | 40
arch/powerpc/mm/fsl_booke_mmu.c | 6
arch/powerpc/mm/lmb.c | 13
arch/powerpc/mm/mem.c | 20
arch/powerpc/platforms/82xx/Kconfig | 13
arch/powerpc/platforms/82xx/Makefile | 1
arch/powerpc/platforms/82xx/ep8248e.c | 324 +++++
arch/powerpc/platforms/83xx/mpc8313_rdb.c | 13
arch/powerpc/platforms/83xx/mpc832x_mds.c | 5
arch/powerpc/platforms/83xx/mpc832x_rdb.c | 10
arch/powerpc/platforms/83xx/mpc834x_itx.c | 12
arch/powerpc/platforms/83xx/mpc834x_mds.c | 5
arch/powerpc/platforms/83xx/mpc836x_mds.c | 5
arch/powerpc/platforms/83xx/mpc837x_mds.c | 56
arch/powerpc/platforms/83xx/mpc83xx.h | 3
arch/powerpc/platforms/83xx/usb.c | 46
arch/powerpc/platforms/85xx/mpc85xx_ads.c | 18
arch/powerpc/platforms/85xx/mpc85xx_cds.c | 6
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 7
arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 15
arch/powerpc/platforms/8xx/Kconfig | 9
arch/powerpc/platforms/8xx/Makefile | 1
arch/powerpc/platforms/8xx/adder875.c | 118 +
arch/powerpc/platforms/Kconfig | 6
arch/powerpc/sysdev/Makefile | 2
arch/powerpc/sysdev/fsl_pci.c | 139 --
arch/powerpc/sysdev/fsl_soc.c | 103 +
arch/powerpc/sysdev/ipic.c | 62
arch/powerpc/sysdev/mpic.c | 4
arch/powerpc/sysdev/qe_lib/Kconfig | 2
arch/powerpc/sysdev/qe_lib/qe.c | 247 +++
arch/powerpc/sysdev/qe_lib/ucc_slow.c | 10
drivers/net/phy/Kconfig | 32
drivers/net/phy/fixed.c | 445 ++-----
drivers/serial/Kconfig | 10
drivers/serial/Makefile | 1
drivers/serial/ucc_uart.c | 1514 ++++++++++++++++++++++++
include/asm-powerpc/immap_qe.h | 34
include/asm-powerpc/lmb.h | 1
include/asm-powerpc/mpc8260.h | 1
include/asm-powerpc/pci-bridge.h | 3
include/asm-powerpc/qe.h | 61
include/linux/phy_fixed.h | 51
82 files changed, 7840 insertions(+), 641 deletions(-)
Anton Vorontsov (1):
[POWERPC] MPC8349E-mITX: introduce localbus and pata nodes
Becky Bruce (1):
[POWERPC] Fixup use of phys_addr_t in mpic code
Dale Farnsworth (1):
[POWERPC] 85xx: Respect KERNELBASE, PAGE_OFFSET, and PHYSICAL_START on e500
John Rigby (2):
[POWERPC] Add support for mpc512x interrupts to ipic
[POWERPC] Add IPIC Kconfig option
Kumar Gala (10):
[POWERPC] Fix handling of memreserve if the range lands in highmem
[POWERPC] Ensure we only handle PowerMac PCI bus fixup for memory resources
[POWERPC] Fixup transparent P2P resources
[POWERPC] FSL: Rework PCI/PCIe support for 85xx/86xx
[POWERPC] Remove update_bridge_resource
[POWERPC] 85xx: convert boards to use machine_device_initcall
[POWERPC] 83xx: convert boards to use machine_device_initcall
[POWERPC] bootwrapper: Add find_node_by_alias and dt_fixup_mac_address_by_alias
[POWERPC] bootwrapper: convert cuboot-8{3,5}xx to dt_fixup_mac_address_by_alias
[POWERPC] Fix incorrect interrupt map on FSL reference boards
Li Yang (3):
[POWERPC] 83xx: add device trees for MPC837x MDS board
[POWERPC] 83xx: Add MPC837x USB platform support
[POWERPC] 83xx: USB device tree cleanups
Liu Yu (1):
[POWERPC] Fix carry bug in 128-bit unsigned integer adding
Paul Gortmaker (1):
[POWERPC] 85xx: mpc85xx_ads: add in missing of_node_put()
Scott Wood (6):
[POWERPC] fsl_soc: Fix get_immrbase() to use ranges, rather than reg.
[POWERPC] 8xx: Analogue & Micro Adder875 board support.
[POWERPC] 82xx: Embedded Planet EP8248E support
[POWERPC] 83xx: MPC8313e RBD add NAND to device tree
[POWERPC] 83xx: MPC8313e RDB - Add NOR flash to the device tree.
[POWERPC] 83xx: Update MPC8313e RDB defconfig for MTD, NAND, JFFS2.
Timur Tabi (4):
[POWERPC] QE: Add ability to upload QE firmware
[POWERPC] QE: Add support for Freescale QUICCEngine UART
[POWERPC] qe-uart: add support for Freescale QUICCEngine UART
[POWERPC] Update MPC8610 HPCD to support audio drivers
Vitaly Bordug (3):
phy/fixed.c: rework to not duplicate PHY layer functionality
[POWERPC] MPC8349E-mITX: Vitesse 7385 PHY is not connected to the MDIO bus
[POWERPC] fsl_soc: add support to gianfar for fixed-link property
^ permalink raw reply
* Re: [PATCH 2/3] mpc8313erdb: Add NOR flash to the device tree.
From: Kumar Gala @ 2008-01-21 16:22 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080117223755.GB20697@loki.buserror.net>
On Thu, 17 Jan 2008, Scott Wood wrote:
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/boot/dts/mpc8313erdb.dts | 9 +++++++++
> 1 files changed, 9 insertions(+), 0 deletions(-)
>
applied.
- k
^ permalink raw reply
* Re: [PATCH 3/3] Update mpc8313erdb defconfig for MTD, NAND, JFFS2.
From: Kumar Gala @ 2008-01-21 16:21 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080117223811.GC20697@loki.buserror.net>
On Thu, 17 Jan 2008, Scott Wood wrote:
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/configs/mpc8313_rdb_defconfig | 46 ++++++++++++++++++++--------
> 1 files changed, 33 insertions(+), 13 deletions(-)
>
applied.
- k
^ permalink raw reply
* Re: [PATCH 2/2] mpc82xx: Embedded Planet EP8248E support
From: Kumar Gala @ 2008-01-21 16:21 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080117223205.GB17300@loki.buserror.net>
On Thu, 17 Jan 2008, Scott Wood wrote:
> This board is also resold by Freescale under the names
> "QUICCStart MPC8248 Evaluation System" and "CWH-PPC-8248N-VE".
>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> Removed const/initdata combo, and used simple-bus for probing.
>
> Please apply for 2.6.25.
>
> arch/powerpc/boot/Makefile | 3 +-
> arch/powerpc/boot/dts/ep8248e.dts | 207 ++++++++
> arch/powerpc/boot/ep8248e.c | 55 +++
> arch/powerpc/boot/wrapper | 2 +-
> arch/powerpc/configs/ep8248e_defconfig | 821 ++++++++++++++++++++++++++++++++
> arch/powerpc/platforms/82xx/Kconfig | 13 +
> arch/powerpc/platforms/82xx/Makefile | 1 +
> arch/powerpc/platforms/82xx/ep8248e.c | 324 +++++++++++++
> include/asm-powerpc/mpc8260.h | 1 +
> 9 files changed, 1425 insertions(+), 2 deletions(-)
> create mode 100644 arch/powerpc/boot/dts/ep8248e.dts
> create mode 100644 arch/powerpc/boot/ep8248e.c
> create mode 100644 arch/powerpc/configs/ep8248e_defconfig
> create mode 100644 arch/powerpc/platforms/82xx/ep8248e.c
>
applied.
- k
^ permalink raw reply
* Re: [PATCH 1/3] mpc8313erdb: Add NAND to device tree, and call of_platform_bus_probe().
From: Kumar Gala @ 2008-01-21 16:21 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080117223750.GA20697@loki.buserror.net>
On Thu, 17 Jan 2008, Scott Wood wrote:
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> Please apply this series for 2.6.25.
>
> arch/powerpc/boot/dts/mpc8313erdb.dts | 39 +++++++++++++++++++++++++++++
> arch/powerpc/platforms/83xx/mpc8313_rdb.c | 13 +++++++++
> 2 files changed, 52 insertions(+), 0 deletions(-)
>
applied.
- k
^ permalink raw reply
* Re: [PATCH 1/2] 8xx: Analogue & Micro Adder875 board support.
From: Kumar Gala @ 2008-01-21 16:20 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080117223140.GA17300@loki.buserror.net>
On Thu, 17 Jan 2008, Scott Wood wrote:
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> Removed const/initdata combo, added simple-bus to cpm node,
> and used simple-bus for probing.
>
> Please apply for 2.6.25.
>
> arch/powerpc/Kconfig | 3 +
> arch/powerpc/boot/.gitignore | 1 +
> arch/powerpc/boot/Makefile | 6 +-
> arch/powerpc/boot/dts/adder875-redboot.dts | 184 ++++++
> arch/powerpc/boot/dts/adder875-uboot.dts | 183 ++++++
> arch/powerpc/boot/redboot-8xx.c | 58 ++
> arch/powerpc/boot/redboot.h | 56 ++
> arch/powerpc/boot/wrapper | 2 +-
> arch/powerpc/configs/adder875-redboot_defconfig | 798 +++++++++++++++++++++++
> arch/powerpc/configs/adder875-uboot_defconfig | 798 +++++++++++++++++++++++
> arch/powerpc/platforms/8xx/Kconfig | 9 +
> arch/powerpc/platforms/8xx/Makefile | 1 +
> arch/powerpc/platforms/8xx/adder875.c | 118 ++++
> 13 files changed, 2215 insertions(+), 2 deletions(-)
> create mode 100644 arch/powerpc/boot/dts/adder875-redboot.dts
> create mode 100644 arch/powerpc/boot/dts/adder875-uboot.dts
> create mode 100644 arch/powerpc/boot/redboot-8xx.c
> create mode 100644 arch/powerpc/boot/redboot.h
> create mode 100644 arch/powerpc/configs/adder875-redboot_defconfig
> create mode 100644 arch/powerpc/configs/adder875-uboot_defconfig
> create mode 100644 arch/powerpc/platforms/8xx/adder875.c
>
applied.
- k
^ permalink raw reply
* Re: [PATCH 05/10] powerpc: Add crash kernel support for 85xx
From: Kumar Gala @ 2008-01-21 16:19 UTC (permalink / raw)
To: Dale Farnsworth; +Cc: linuxppc-dev
In-Reply-To: <20071122154619.GA26471@xyzzy.farnsworth.org>
On Thu, 22 Nov 2007, Dale Farnsworth wrote:
> Add the ability to build a ppc_85xx kernel to run at a physical
> address of 32MB.
>
> Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
> ---
> arch/powerpc/Kconfig | 2 +-
> arch/powerpc/kernel/head_fsl_booke.S | 23 ++++++++++++++++++-----
> arch/powerpc/mm/fsl_booke_mmu.c | 6 +++---
> 3 files changed, 22 insertions(+), 9 deletions(-)
>
applied. (w/o Kconfig since this is useful for other purposes).
-k
^ permalink raw reply
* Re: [i2c] [PATCH 19 3/5] Clean up error returns
From: Jean Delvare @ 2008-01-21 16:10 UTC (permalink / raw)
To: Jon Smirl; +Cc: i2c, linux-kernel, linuxppc-dev
In-Reply-To: <9e4733910801200739x502d5407x85f0d950ace80bee@mail.gmail.com>
Hi Jon,
On Sun, 20 Jan 2008 10:39:43 -0500, Jon Smirl wrote:
> Here' s a version with the compares to zero switched to NO_IRQ. If I
> understand how NO_IRQ works it is the correct change. My understanding
> is that under ppc IRQ zero was legal and NO_IRQ was -1. But then the
> whole kernel switched to NO_IRQ = zero. Powerpc updated to NO_IRQ=0
> and used virtual IRQs to move a physical IRQ 0 to another IRQ number.
> ppc was not changed. This driver does not appear to have been updated
> to track this global change since it didn't initially use the NO_IRQ
> define everywhere.
As I have already applied the part of this patch that preserves error
values in error paths, can you please send an incremental patch that
only fixes the IRQ issues? These are separate issues so it's better to
have separate patches anyway.
Thanks,
--
Jean Delvare
^ permalink raw reply
* Re: [PATCH] autodetect serial console on efika
From: Andreas Schwab @ 2008-01-21 16:09 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev, Paul Mackeras
In-Reply-To: <20080121152900.GA8664@aepfle.de>
Olaf Hering <olaf@aepfle.de> writes:
> +/*
> + * Per default, input/output-device points to keyboard/screen
> + * If no card is installed, the built-in serial port is used as a fallback.
> + * But unfortunately, the firmware does not connect /chosen/{stdin,stdout}
> + * the the built-in serial node. Instead, a /failsafe node is created.
s/the the/to the/
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* Re: [PATCH] autodetect serial console on efika
From: Geert Uytterhoeven @ 2008-01-21 15:56 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev, Paul Mackeras
In-Reply-To: <20080121152900.GA8664@aepfle.de>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 843 bytes --]
On Mon, 21 Jan 2008, Olaf Hering wrote:
> + * But unfortunately, the firmware does not connect /chosen/{stdin,stdout}
> + * the the built-in serial node. Instead, a /failsafe node is created.
^^^
to
The same typo is in the pegasos2 patch.
With kind regards,
Geert Uytterhoeven
Software Architect
Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
Phone: +32 (0)2 700 8453
Fax: +32 (0)2 700 8622
E-mail: Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/
Sony Network and Software Technology Center Europe
A division of Sony Service Centre (Europe) N.V.
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium
VAT BE 0413.825.160 · RPR Brussels
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619
^ permalink raw reply
* [PATCH] autodetect serial console on pegasos2
From: Olaf Hering @ 2008-01-21 15:37 UTC (permalink / raw)
To: Paul Mackeras, linuxppc-dev
In-Reply-To: <20080121152900.GA8664@aepfle.de>
Autodetect the serial console on Pegasos2.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
arch/powerpc/platforms/chrp/setup.c | 52 ++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -251,6 +251,57 @@ static void briq_restart(char *cmd)
for(;;);
}
+/*
+ * Per default, input/output-device points to the keyboard/screen
+ * If no card is installed, the built-in serial port is used as a fallback.
+ * But unfortunately, the firmware does not connect /chosen/{stdin,stdout}
+ * the the built-in serial node. Instead, a /failsafe node is created.
+ */
+static void chrp_init_early(void)
+{
+ struct device_node *node;
+ const char *property;
+
+ if (strstr(cmd_line, "console="))
+ return;
+ /* find the boot console from /chosen/stdout */
+ if (!of_chosen)
+ return;
+ node = of_find_node_by_path("/");
+ if (!node)
+ return;
+ property = of_get_property(node, "model", NULL);
+ if (!property)
+ goto out_put;
+ if (strcmp(property, "Pegasos2"))
+ goto out_put;
+ /* this is a Pegasos2 */
+ property = of_get_property(of_chosen, "linux,stdout-path", NULL);
+ if (!property)
+ goto out_put;
+ of_node_put(node);
+ node = of_find_node_by_path(property);
+ if (!node)
+ return;
+ property = of_get_property(node, "device_type", NULL);
+ if (!property)
+ goto out_put;
+ if (strcmp(property, "serial"))
+ goto out_put;
+ /*
+ * The 9pin connector is either /failsafe
+ * or /pci@80000000/isa@C/serial@i2F8
+ * The optional graphics card has also type 'serial' in VGA mode.
+ */
+ property = of_get_property(node, "name", NULL);
+ if (!property)
+ goto out_put;
+ if (!strcmp(property, "failsafe") || !strcmp(property, "serial"))
+ add_preferred_console("ttyS", 0, NULL);
+out_put:
+ of_node_put(node);
+}
+
void __init chrp_setup_arch(void)
{
struct device_node *root = of_find_node_by_path("/");
@@ -594,6 +645,7 @@ define_machine(chrp) {
.probe = chrp_probe,
.setup_arch = chrp_setup_arch,
.init = chrp_init2,
+ .init_early = chrp_init_early,
.show_cpuinfo = chrp_show_cpuinfo,
.init_IRQ = chrp_init_IRQ,
.restart = rtas_restart,
^ permalink raw reply
* [PATCH] autodetect serial console on efika
From: Olaf Hering @ 2008-01-21 15:29 UTC (permalink / raw)
To: Paul Mackeras, linuxppc-dev
In-Reply-To: <20070331150823.GA25421@aepfle.de>
Efika boards have to be booted with console=ttyPSC0 unless there is a
graphics card plugged in. Detect if the firmware stdout is the serial
connector.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
arch/powerpc/platforms/52xx/efika.c | 50 ++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -13,6 +13,7 @@
#include <linux/utsrelease.h>
#include <linux/pci.h>
#include <linux/of.h>
+#include <linux/console.h>
#include <asm/prom.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -208,12 +209,61 @@ static int __init efika_probe(void)
return 1;
}
+/*
+ * Per default, input/output-device points to keyboard/screen
+ * If no card is installed, the built-in serial port is used as a fallback.
+ * But unfortunately, the firmware does not connect /chosen/{stdin,stdout}
+ * the the built-in serial node. Instead, a /failsafe node is created.
+ * More advanced hardware configurations cant be detected,
+ * boot with console=xyz123 to point the kernel to the correct device
+ */
+static void __init efika_init_early(void)
+{
+#ifdef CONFIG_SERIAL_MPC52xx
+ struct device_node *stdout_node;
+ const char *property;
+
+ if (strstr(cmd_line, "console="))
+ return;
+ /* find the boot console from /chosen/stdout */
+ if (!of_chosen)
+ return;
+ property = of_get_property(of_chosen, "linux,stdout-path", NULL);
+ if (!property)
+ return;
+ stdout_node = of_find_node_by_path(property);
+ if (!stdout_node)
+ return;
+ property = of_get_property(stdout_node, "device_type", NULL);
+ if (property && strcmp(property, "serial") == 0) {
+ /*
+ * The 9pin connector is either /failsafe or /builtin/serial.
+ * The optional graphics card has also type 'serial' in VGA mode.
+ */
+ property = of_get_property(stdout_node, "name", NULL);
+ if (property) {
+ if (strcmp(property, "failsafe") == 0)
+ add_preferred_console("ttyPSC", 0, NULL);
+ else {
+ if (strcmp(property, "serial") == 0) {
+ property = of_get_property(stdout_node, "model", NULL);
+ if (property && strcmp(property, "mpc5200-serial") == 0)
+ add_preferred_console("ttyPSC", 0, NULL);
+ }
+ }
+ }
+ }
+ of_node_put(stdout_node);
+#endif
+}
+
define_machine(efika)
{
.name = EFIKA_PLATFORM_NAME,
.probe = efika_probe,
.setup_arch = efika_setup_arch,
.init = mpc52xx_declare_of_platform_devices,
+ .init_early = efika_init_early,
.show_cpuinfo = efika_show_cpuinfo,
.init_IRQ = mpc52xx_init_irq,
.get_irq = mpc52xx_get_irq,
^ permalink raw reply
* Re: [PATCH 2/2] mpc82xx: Embedded Planet EP8248E support
From: Sergej Stepanov @ 2008-01-21 15:28 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080118160303.GC15620@ld0162-tx32.am.freescale.net>
Am Freitag, den 18.01.2008, 10:03 -0600 schrieb Scott Wood:
> On Fri, Jan 18, 2008 at 12:07:07PM +0100, Sergej Stepanov wrote:
> >
> > > + /* "Serial" port/SCC1 */
> > > + scc1: serial@11a00 {
> > > + device_type = "serial";
> > > + compatible = "fsl,mpc8248-scc-uart",
> > > + "fsl,cpm2-scc-uart";
> > > + reg = <0x11a00 0x20 0x8000 0x100>;
> > > + interrupts = <40 8>;
> > are you sure with 40 as interrupt? has not it be "28"(hex) here?
>
> This is a version 1 dts file -- the default base is decimal.
>
> -Scott
yes, you are right, sorry.
^ permalink raw reply
* Re: Endian problem when accessing internel regs on 8347
From: Ben Warren @ 2008-01-21 15:16 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: Scott Wood, linuxppc-embedded
In-Reply-To: <OFE90E4633.93F2906B-ON882573D7.002448B6-882573D7.00287256@selinc.com>
Hey Bruce,
Bruce_Leonard@selinc.com wrote:
>>>>> __asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync" : "=r"
>>>>>
> (ret)
>
>>> :
>>>
>>>>> "m" (*addr));
>>>>>
>>>> They allow the compiler to use update and/or index mode for the
>>>>
> memory
>
>>>> operand.
>>>>
>>> Well that makes sense, U for update and X for index, but I'm not sure
>>> they're applicable to this particular instruction and I'm not sure
>>>
> that
>
>>> the memory operand makes sense for PowerPC.
>>>
>> Why not?
>>
>
> Okay, after much digging and experimenting, I'll agree that the memory
> operand makes sense. When I first said that I was thinking of direct
> manipulation of memory, which the PPC doesn't support. (Don't ask, my
> brain sometimes goes off into la-la land without me :-> ) Also, update
> mode is applicable and makes sense. But I do still have a problem with
> the index mode, though it could be compiler magic. Here's why: the index
> mode of the 'lwz' instruction requires three operands, i.e., 'lwzx
> rD,rA,rB', and there's only place holders for two operands. Is the
> compiler smart enough to add the third operand for the index mode? If so,
> what does it put for the third operand?
>
> Another question is how does the compiler know which mode to pick? And
> what is the significance of the trailing number? Some places in the code
> have %U1%X1 and others have %U2%X2? I've found documentation for the #
> and ## tokens, but I can't find anything for the %U or %X tokens.
>
> Now this has all been very interesting to learn but doesn't solve my
> underlying problem which I've finally drilled down to. At first I thought
> in_be32() might be broken because I wasn't getting back the value I knew
> to be in the internal register. I knew I had the address and the mapping
> to kernel space correct because I could use in_le32 and get the right
> value though it was byte swapped. The value in the register was
> 0xFFFFFFE7 but what I was getting from in_be32 was 0xFFFFFFFF. Then I
> started playing and here's what I found:
>
> Register value in_be32 value
> 0x12345678 0x1234567
> 0xff345678 0xff345678
> 0xffff5678 0xffff5678
> 0xfffff678 0xfffff678
> 0xfffffe78 0xffffffff
> 0xffffff78 0xffffffff
>
> This isn't an exhastive list but I tried about twenty values and pretty
> much what I found was that if bits 0 through 22 are set to 1 then in_be32
> reads 0xffffffff. I've also tried it at a variety of addresses and the
> behaviour is the same. in_le32 works fine as does in_be16. I've got no
> ideas as to what may be wrong. I don't want to just arbitrarily point to
> that %U1%X1 parameter list, but I get compiler errors if I try to remove
> them so I can't prove or disprove it and I can't find any documentation on
> it I can't even form a theroy. Has anyone ever seen anything like this?
> Can't anyone suggest anything I can try?
>
Are you sure that all the bits are configured as GPIO? Almost every
peripheral pin on these chips is muxed at least two ways. Maybe some of
the bits that you think are GPIO are configured as some other bus,
possibly explaining goofy behavior and perceived volatility of data.
This is pretty well-vetted code on a reasonably mature product, and in
my experience it's very rarely the tools ...
Just a thought.
regards,
Ben
^ permalink raw reply
* Re: Warp Watchdog
From: Josh Boyer @ 2008-01-21 14:01 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
In-Reply-To: <478FB93A.7040505@pikatech.com>
On Thu, 17 Jan 2008 15:23:22 -0500
Sean MacLennan <smaclennan@pikatech.com> wrote:
> The taco, er warp, has a watchdog timer built into the fpga. The
> watchdog is very trivial and very tied to the warp. I have put it has
> part of the platform code rather than a standalone module.
>
> Two reasons for this: one, once started it can't be stopped. A module
> unload would be fatal ;) Two, it is so closely tied to the taco that it
> really has no use otherwise.
The first isn't much of a reason. The watchdog on the 44x and FSL
Book-E cores have the same behavior.
> The platform always starts the watchdog, assuming you asked for the
> watchdog, but does not enable it until hit from user mode.
>
> What is the general feeling about this implementation? I am not
> submitting this for inclusion in the kernel right now, just feeling out
> what others think.
I'm not thrilled with it being in the platform file itself. It should
really go into drivers/watchdog. It's OK that the watchdog is tied to
Warp, that really isn't an issue. Just make it depend on Warp in the
Kconfig file. And you can select it in your board config so that it's
built in-kernel and not as a module.
The code itself looks pretty clean.
josh
^ permalink raw reply
* Generated xilinx linux 2.6 image sections
From: greenlean @ 2008-01-21 13:05 UTC (permalink / raw)
To: linuxppc-embedded
Hi all,
I'm trying to boot the 2.6 xilinx kernel downloaded from their git server in
the XUPV2P board I'm really having troubles (I can't see anything in the
minicom console terminal). I'm not seeing anything, neither the ucompressing
kernel string nor the prompt with the memory addresses that kernel prompt at
first time, so I have started to distrust of anything.
When I download the kernel using xmd, I see:
XMD% dow imagen_UART16550_ml300.elf
section, .text: 0x00400000-0x0040387b
section, .data: 0x00404000-0x004e6fff
section, .bss: 0x004e7000-0x004e919f
Downloaded Program imagen_UART16550_ml300.elf
Setting PC with Program Start Address 0x00400000
and when I download some of the TestApp generated by EDK I see:
XMD% dow perif.elf
section, .vectors: 0xfffe0000-0xfffe20c3
section, .text: 0x10000000-0x10003b7b
section, .init: 0x10003b7c-0x10003b9f
section, .fini: 0x10003ba0-0x10003bbf
section, .boot0: 0xfffe20c4-0xfffe20d3
section, .boot: 0xfffffffc-0xffffffff
section, .rodata: 0x10003bc0-0x10004111
section, .sdata2: 0x10004114-0x10004113
section, .sbss2: 0x10004114-0x10004113
section, .data: 0x10004114-0x10004243
section, .got: 0x10004244-0x10004243
section, .got1: 0x10004244-0x10004243
section, .got2: 0x10004244-0x1000425f
section, .ctors: 0x10004260-0x10004267
section, .dtors: 0x10004268-0x1000426f
section, .fixup: 0x10004270-0x1000426f
section, .eh_frame: 0x10004270-0x10004277
section, .jcr: 0x10004278-0x1000427b
section, .gcc_except_table: 0x1000427c-0x100042
section, .sdata: 0x1000427c-0x10004293
section, .sbss: 0x10004294-0x100042a3
section, .bss: 0x100042a4-0x10004473
section, .stack: 0x10004474-0x1000647f
section, .heap: 0x10006480-0x1000847f
Downloaded Program perif.elf
Setting PC with Program Start Address 0xfffffffc
Does anybody know why the kernel elf don't have a boot section like the
TestApp generated by EDK?
I suppossed this is because the image kernel is compressed, but despite
beeing compressed it should have a boot section or something similar ???
It's right that the kernel start address is set to the 0x00400000??
Or does the section .text contains all the kernel code to uncompresse the
code of the kernel??
--
View this message in context: http://www.nabble.com/Generated-xilinx-linux-2.6--image-sections-tp14997109p14997109.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* Re: [MPC5200] problem running FEC and ATA
From: Mehlan, Markus (Ritter Elektronik) @ 2008-01-21 13:01 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <200801210957.57761.jbe@pengutronix.de>
Hello Juergen,
> -----Urspr=FCngliche Nachricht-----
> Von: Juergen Beisert [mailto:jbe@pengutronix.de]=20
> Gesendet: Montag, 21. Januar 2008 09:58
> An: linuxppc-dev@ozlabs.org
> Cc: Mehlan, Markus (Ritter Elektronik)
> Betreff: Re: [MPC5200] problem running FEC and ATA
>=20
> Markus,
>=20
> On Monday 21 January 2008 08:10, Mehlan, Markus (Ritter=20
> Elektronik) wrote:
> > i have the same problem with the fec driver. See my posting at=20
> >=20
> http://ozlabs.org/pipermail/linuxppc-embedded/2008-January/029466.html
> >
> > Arnon, have you already fixed the FEC problem?
>=20
> Can you check this?
>=20
> http://ozlabs.org/pipermail/linuxppc-embedded/2007-May/027046.html
I have checked the article. To set the BSDIS bit in the XLB config =
register
during initialization fixes my problem:
xlb =3D (struct mpc52xx_xlb *)MPC5xxx_XLB;
out_be32(&xlb->config, in_be32(&xlb->config) |
MPC52xx_XLB_CFG_BSDIS);
Thank you!
Best regards,
Markus
^ permalink raw reply
* Re: [i2c] [PATCH 0/3] i2c: Use the standard, alias-based device/driver matching scheme
From: Jean Delvare @ 2008-01-21 12:34 UTC (permalink / raw)
To: Rudolf Marek; +Cc: David Brownell, linuxppc-dev, Linux I2C
In-Reply-To: <479478C7.5060807@assembler.cz>
On Mon, 21 Jan 2008 11:49:43 +0100, Rudolf Marek wrote:
> > Note: all the arm and powerpc stuff is untested.
>
> We at http://sysgo.com have some demo server, where you can access embedded
> systems remotely (via VNC to a server with cross tools (ELinOS) + serial console),
> there is 2.6.22 kernel, but I think the i2c core can be replaced. I think some
> PPC and ARMs are connected there. I will ask if you can get access to it if you
> are interested.
Thanks for the proposal, but in general I think it makes more sense
that people who are familiar with these architectures test the patches
themselves. That's less work for me, and they'll do a better job anyway.
--
Jean Delvare
^ permalink raw reply
* [patch v4 2/4] USB: add Cypress c67x00 OTG controller core driver
From: Peter Korsgaard @ 2008-01-21 10:34 UTC (permalink / raw)
To: dbrownell, linux-usb, linuxppc-dev, grant.likely
In-Reply-To: <20080121103434.397382000@sunsite.dk>
This patch add the core driver for the c67x00 USB OTG controller. The core
driver is responsible for the platform bus binding and creating either
USB HCD or USB Gadget instances for each of the serial interface engines
on the chip.
This driver does not directly implement the HCD or gadget behaviours; it
just controls access to the chip.
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
---
MAINTAINERS | 6 +
drivers/usb/c67x00/c67x00-drv.c | 236 ++++++++++++++++++++++++++++++++++++++++
include/linux/usb/c67x00.h | 48 ++++++++
3 files changed, 290 insertions(+)
Index: linux-2.6/drivers/usb/c67x00/c67x00-drv.c
===================================================================
--- /dev/null
+++ linux-2.6/drivers/usb/c67x00/c67x00-drv.c
@@ -0,0 +1,236 @@
+/*
+ * c67x00-drv.c: Cypress C67X00 USB Common infrastructure
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ * Derived from the Cypress cy7c67200/300 ezusb linux driver and
+ * based on multiple host controller drivers inside the linux kernel.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+/*
+ * This file implements the common infrastructure for using the c67x00.
+ * It is both the link between the platform configuration and subdrivers and
+ * the link between the common hardware parts and the subdrivers (e.g.
+ * interrupt handling).
+ *
+ * The c67x00 has 2 SIE's (serial interface engine) wich can be configured
+ * to be host, device or OTG (with some limitations, E.G. only SIE1 can be OTG).
+ *
+ * Depending on the platform configuration, the SIE's are created and
+ * the corresponding subdriver is initialized (c67x00_probe_sie).
+ */
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <linux/usb/c67x00.h>
+#include <asm/io.h>
+
+#include "c67x00.h"
+
+static void c67x00_probe_sie(struct c67x00_sie *sie,
+ struct c67x00_device *dev, int sie_num)
+{
+ spin_lock_init(&sie->lock);
+ sie->dev = dev;
+ sie->sie_num = sie_num;
+ sie->mode = c67x00_sie_config(dev->pdata->sie_config, sie_num);
+
+ switch (sie->mode) {
+ case C67X00_SIE_UNUSED:
+ dev_info(sie_dev(sie),
+ "Not using SIE %d as requested\n", sie->sie_num);
+ break;
+
+ default:
+ dev_err(sie_dev(sie),
+ "Unsupported configuration: 0x%x for SIE %d\n",
+ sie->mode, sie->sie_num);
+ break;
+ }
+}
+
+static void c67x00_remove_sie(struct c67x00_sie *sie)
+{
+}
+
+
+static irqreturn_t c67x00_irq(int irq, void *__dev)
+{
+ struct c67x00_device *c67x00 = __dev;
+ struct c67x00_sie *sie;
+ u16 msg, int_status;
+ int i, count = 8;
+
+ int_status = c67x00_ll_hpi_status(c67x00);
+ if (!int_status)
+ return IRQ_NONE;
+
+ while (int_status != 0 && (count-- >= 0)) {
+ c67x00_ll_irq(c67x00, int_status);
+ for (i = 0; i < C67X00_SIES; i++) {
+ sie = &c67x00->sie[i];
+ msg = 0;
+ if (int_status & SIEMSG_FLG(i)) {
+ msg = c67x00_ll_get_siemsg(sie);
+ /* clear register to allow next message */
+ c67x00_ll_set_siemsg(sie, 0);
+ }
+ if (sie->irq)
+ sie->irq(sie, int_status, msg);
+ }
+ int_status = c67x00_ll_hpi_status(c67x00);
+ }
+
+ if (int_status)
+ dev_warn(&c67x00->pdev->dev, "Not all interrupts handled! "
+ "status = 0x%04x\n", int_status);
+
+ return IRQ_HANDLED;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int __devinit c67x00_drv_probe(struct platform_device *pdev)
+{
+ struct c67x00_device *c67x00;
+ struct c67x00_platform_data *pdata;
+ struct resource *res, *res2;
+ int ret, i;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res2)
+ return -ENODEV;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata)
+ return -ENODEV;
+
+ c67x00 = kzalloc(sizeof(*c67x00), GFP_KERNEL);
+ if (!c67x00)
+ return -ENOMEM;
+
+ if (!request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name)) {
+ dev_err(&pdev->dev, "Memory region busy\n");
+ ret = -EBUSY;
+ goto request_mem_failed;
+ }
+ c67x00->hpi.base = ioremap(res->start, res->end - res->start + 1);
+ if (!c67x00->hpi.base) {
+ dev_err(&pdev->dev, "Unable to map HPI registers\n");
+ ret = -EIO;
+ goto map_failed;
+ }
+
+ spin_lock_init(&c67x00->hpi.lock);
+ c67x00->hpi.regstep = pdata->hpi_regstep;
+ c67x00->pdata = pdev->dev.platform_data;
+ c67x00->pdev = pdev;
+
+ c67x00_ll_init(c67x00);
+ c67x00_ll_hpi_reg_init(c67x00);
+
+ ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, c67x00);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot claim IRQ\n");
+ goto request_irq_failed;
+ }
+
+ ret = c67x00_ll_reset(c67x00);
+ if (ret) {
+ dev_err(&pdev->dev, "Device reset failed\n");
+ goto reset_failed;
+ }
+
+ for (i = 0; i < C67X00_SIES; i++)
+ c67x00_probe_sie(&c67x00->sie[i], c67x00, i);
+
+ platform_set_drvdata(pdev, c67x00);
+
+ return 0;
+
+reset_failed:
+ free_irq(res2->start, c67x00);
+request_irq_failed:
+ iounmap(c67x00->hpi.base);
+map_failed:
+ release_mem_region(res->start, res->end - res->start + 1);
+request_mem_failed:
+ kfree(c67x00);
+
+ return ret;
+}
+
+static int __devexit c67x00_drv_remove(struct platform_device *pdev)
+{
+ struct c67x00_device *c67x00 = platform_get_drvdata(pdev);
+ struct resource *res;
+ int i;
+
+ for (i = 0; i < C67X00_SIES; i++)
+ c67x00_remove_sie(&c67x00->sie[i]);
+
+ c67x00_ll_release(c67x00);
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res)
+ free_irq(res->start, c67x00);
+
+ iounmap(c67x00->hpi.base);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res)
+ release_mem_region(res->start, res->end - res->start + 1);
+
+ kfree(c67x00);
+
+ return 0;
+}
+
+static struct platform_driver c67x00_driver = {
+ .probe = c67x00_drv_probe,
+ .remove = __devexit_p(c67x00_drv_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "c67x00",
+ },
+};
+
+static int __init c67x00_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ return platform_driver_register(&c67x00_driver);
+}
+
+static void __exit c67x00_exit(void)
+{
+ platform_driver_unregister(&c67x00_driver);
+}
+
+module_init(c67x00_init);
+module_exit(c67x00_exit);
+
+MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely");
+MODULE_DESCRIPTION("Cypress C67X00 USB Controller Driver");
+MODULE_LICENSE("GPL");
Index: linux-2.6/include/linux/usb/c67x00.h
===================================================================
--- /dev/null
+++ linux-2.6/include/linux/usb/c67x00.h
@@ -0,0 +1,48 @@
+/*
+ * usb_c67x00.h: platform definitions for the Cypress C67X00 USB chip
+ *
+ * Copyright (C) 2006-2007 Barco N.V.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef _LINUX_USB_C67X00_H
+#define _LINUX_USB_C67X00_H
+
+/* SIE configuration */
+#define C67X00_SIE_UNUSED 0
+#define C67X00_SIE_HOST 1
+#define C67X00_SIE_PERIPHERAL_A 2 /* peripheral on A port */
+#define C67X00_SIE_PERIPHERAL_B 3 /* peripheral on B port */
+
+#define c67x00_sie_config(config, n) (((config)>>(4*(n)))&0x3)
+
+#define C67X00_SIE1_UNUSED (C67X00_SIE_UNUSED << 0)
+#define C67X00_SIE1_HOST (C67X00_SIE_HOST << 0)
+#define C67X00_SIE1_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 0)
+#define C67X00_SIE1_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 0)
+
+#define C67X00_SIE2_UNUSED (C67X00_SIE_UNUSED << 4)
+#define C67X00_SIE2_HOST (C67X00_SIE_HOST << 4)
+#define C67X00_SIE2_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 4)
+#define C67X00_SIE2_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 4)
+
+struct c67x00_platform_data {
+ int sie_config; /* SIEs config (C67X00_SIEx_*) */
+ unsigned long hpi_regstep; /* Step between HPI registers */
+};
+
+#endif /* _LINUX_USB_C67X00_H */
Index: linux-2.6/MAINTAINERS
===================================================================
--- linux-2.6.orig/MAINTAINERS
+++ linux-2.6/MAINTAINERS
@@ -3832,6 +3832,12 @@
S: Maintained
W: http://www.kroah.com/linux-usb/
+USB CYPRESS C67X00 DRIVER
+P: Peter Korsgaard
+M: jacmet@sunsite.dk
+L: linux-usb@vger.kernel.org
+S: Maintained
+
USB DAVICOM DM9601 DRIVER
P: Peter Korsgaard
M: jacmet@sunsite.dk
--
Bye, Peter Korsgaard
^ permalink raw reply
* [patch v4 4/4] USB: add Cypress c67x00 OTG controller gadget driver
From: Peter Korsgaard @ 2008-01-21 10:34 UTC (permalink / raw)
To: dbrownell, linux-usb, linuxppc-dev, grant.likely
In-Reply-To: <20080121103434.397382000@sunsite.dk>
This patch adds USB gadget support for the Cypress c67x00 family of devices.
This is work in progress and not ready to be committed yet. I'm posting this
to show how it fits with the rest of the driver and to collect feedback.
The driver works good enought to use g_serial, but there are still issues
to be solved. The biggest issue is that endpoint 0 is currently handled by
the BIOS inside the c67x00, so the gadget stack never sees the data.
The BIOS also has other deficiencies, E.G. see the patching done in
c67x00_ll_susb_init().
---
drivers/usb/Kconfig | 2
drivers/usb/Makefile | 2
drivers/usb/c67x00/Kconfig | 21
drivers/usb/c67x00/Makefile | 7
drivers/usb/c67x00/c67x00-drv.c | 11
drivers/usb/c67x00/c67x00-ll-hpi.c | 184 +++++++
drivers/usb/c67x00/c67x00-udc.c | 905 +++++++++++++++++++++++++++++++++++++
drivers/usb/c67x00/c67x00-udc.h | 50 ++
drivers/usb/c67x00/c67x00.h | 18
drivers/usb/gadget/Kconfig | 7
drivers/usb/gadget/gadget_chips.h | 8
drivers/usb/host/Kconfig | 12
12 files changed, 1212 insertions(+), 15 deletions(-)
Index: linux-2.6/drivers/usb/c67x00/c67x00-udc.c
===================================================================
--- /dev/null
+++ linux-2.6/drivers/usb/c67x00/c67x00-udc.c
@@ -0,0 +1,905 @@
+/*
+ * c67x00-udc.c: Cypress C67X00 USB device controller
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ * Derived from the Cypress cy7c67200/300 ezusb linux driver and
+ * based on multiple device controller drivers inside the linux kernel.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#include <linux/device.h>
+#include <linux/usb.h>
+#include <linux/usb/c67x00.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/ch9.h>
+
+#include "c67x00.h"
+#include "c67x00-udc.h"
+
+/* Defined in DEVICE n ENDPOINT STATUS REGISTERS */
+#define OVERFLOW_FLG 0x0800 /* Receive overflow */
+#define UNDERFLOW_FLG 0x0400 /* Receive underflow */
+#define OUT_EXCEPTION_FLG 0x0200 /* OUT received when armed for IN */
+#define IN_EXCEPTION_FLG 0x0100 /* IN received when armed for OUT */
+#define STALL_FLG 0x0080 /* Stall sent */
+#define NAK_FLG 0x0040 /* NAK sent */
+#define LENGTH_EXCEPT_FLG 0x0020 /* Overflow or Underflow occured */
+#define SETUP_FLG 0x0010 /* SETUP packet received */
+#define SEQ_STAT 0x0008 /* Last Data Toggle Sequence bit sent
+ or received */
+#define TIMEOUT_FLG 0x0004 /* Last transmission timed out */
+#define ERROR_FLG 0x0002 /* CRC Err detected in last
+ reception*/
+#define ACK_FLG 0x0001 /* Last transaction ACK'D (sent
+ or received) */
+
+/* Defined in DEVICE n ENDPOINT CONTROL REGISTERS */
+#define DIR_SEL_IN 0x0004 /* Last transmission timed out */
+#define EP_ENABLE 0x0002 /* Enable Endpoint */
+
+
+
+struct c67x00_request {
+ struct usb_request req;
+ struct list_head queue;
+};
+
+
+
+struct c67x00_udc_ep {
+ struct usb_ep ep;
+ struct c67x00_udc *udc;
+
+ struct list_head queue;
+ int ep_num;
+ int is_ep_in;
+ int enable;
+ int stopped;
+ int start_io;
+};
+
+#define C67X00_MAX_NB_END_POINTS 8
+
+struct c67x00_udc {
+ spinlock_t lock;
+ struct c67x00_sie *sie;
+ struct usb_gadget gadget;
+ struct usb_gadget_driver *driver;
+ struct c67x00_udc_ep ep[C67X00_MAX_NB_END_POINTS];
+ struct work_struct io_work;
+ int config_nr;
+ /* The highest string descriptor entry
+ (used to retrieve descriptors from gadget driver) */
+ int top_str_id;
+ u16 string_desc_addr;
+};
+
+const static unsigned char get_descriptor_device[] = {
+ USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+ USB_REQ_GET_DESCRIPTOR,
+ 0x00,
+ USB_DT_DEVICE,
+ 0x00,
+ 0x00,
+ 0x12,
+ 0x00
+};
+
+const static unsigned char get_descriptor_config[] = {
+ USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+ USB_REQ_GET_DESCRIPTOR,
+ 0x00,
+ USB_DT_CONFIG,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x00
+};
+
+static unsigned char get_descriptor_string[] = {
+ USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+ USB_REQ_GET_DESCRIPTOR,
+ 0x00,
+ USB_DT_STRING,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0x00
+};
+
+#define SIEx_DEV_DESC_LOC(x) ((x) ? (CY_UDC_DESC_BASE_ADDRESS + 0x200) \
+ : CY_UDC_DESC_BASE_ADDRESS)
+#define SIEx_CONF_DESC_LOC(x) (SIEx_DEV_DESC_LOC(x) + 32)
+
+/* ------------------------------------------------------------------------- */
+/* gadget ops */
+
+static int c67x00_get_frame(struct usb_gadget *_gadget)
+{
+ printk(KERN_DEBUG "c67x00-udc : c67x00_get_frame\n");
+ return -ENODEV;
+}
+
+static int c67x00_wakeup(struct usb_gadget *_gadget)
+{
+ printk(KERN_DEBUG "c67x00-udc : c67x00_wakeup\n");
+ return -ENODEV;
+}
+
+static int c67x00_selfpowered(struct usb_gadget *_gadget,
+ int is_selfpowered)
+{
+ printk(KERN_DEBUG "c67x00-udc : c67x00_selfpowered\n");
+ return -ENODEV;
+}
+
+static int c67x00_vbus_session(struct usb_gadget *_gadget, int is_active)
+{
+ printk(KERN_DEBUG "c67x00-udc : c67x00_vbus_session\n");
+ return -ENODEV;
+}
+
+static int c67x00_pullup(struct usb_gadget *_gadget, int is_on)
+{
+ printk(KERN_DEBUG "c67x00-udc : c67x00_pullup\n");
+ return -ENODEV;
+}
+
+
+static const struct usb_gadget_ops c67x00_udc_ops = {
+ .get_frame = c67x00_get_frame,
+ .wakeup = c67x00_wakeup,
+ .set_selfpowered = c67x00_selfpowered,
+ .vbus_session = c67x00_vbus_session,
+ .pullup = c67x00_pullup
+};
+
+
+
+/*
+ * the sie and gadget_driver get probed/registered from 2 totally independant
+ * places, this datastructure binds them together
+ */
+static struct c67x00_udc controller = {
+ .gadget = {
+ .ops = &c67x00_udc_ops,
+ .name = "c67x00_udc",
+ .speed = USB_SPEED_FULL,
+ .is_dualspeed = 1,
+ .is_a_peripheral = 1,
+ .dev = {
+ .bus_id = "gadget",
+ },
+ },
+};
+
+
+/*----------------------------------------------------------------------------*/
+
+static void c67x00_udc_set_configuration(struct c67x00_sie *sie, u16 config)
+{
+ struct usb_ctrlrequest request;
+ struct c67x00_udc *udc = sie->private_data;
+
+ dev_dbg(sie_dev(sie), "set configuration %d\n", config);
+
+ request.bRequest = USB_REQ_SET_CONFIGURATION;
+ request.bRequestType = 0;
+ request.wValue = cpu_to_le16(config);
+ udc->driver->setup(&udc->gadget, &request);
+}
+
+static int c67x00_udc_parse_descriptor(struct c67x00_udc *udc,
+ struct c67x00_request *req)
+{
+ int retval = 0;
+ u8 *buf = req->req.buf;
+
+ if (req->req.length < 2)
+ return 0;
+
+ switch (buf[1]) {
+ case USB_DT_DEVICE: {
+ struct usb_device_descriptor *desc = req->req.buf;
+
+ /* Look for the highest stringIndex */
+ if (desc->iManufacturer > udc->top_str_id)
+ udc->top_str_id = desc->iManufacturer;
+ if (desc->iProduct > udc->top_str_id)
+ udc->top_str_id = desc->iProduct;
+ if (desc->iSerialNumber > udc->top_str_id)
+ udc->top_str_id = desc->iSerialNumber;
+
+ /* Write descriptor to C67x00 memory */
+ c67x00_ll_write_mem_le16(udc->sie->dev,
+ SIEx_DEV_DESC_LOC(udc->sie->sie_num),
+ req->req.buf, req->req.length);
+
+ /* Write vector address to c67x00 */
+ c67x00_ll_set_device_descriptor_location(
+ udc->sie, SIEx_DEV_DESC_LOC(udc->sie->sie_num));
+
+ retval = 1;
+ break;
+ }
+
+ case USB_DT_CONFIG: {
+ struct usb_config_descriptor *desc = req->req.buf;
+ int offset;
+ u16 length;
+
+ /* store config number to pass to the gadget driver,
+ once the c67x00 is configured */
+ udc->config_nr = desc->bConfigurationValue;
+
+ length = le16_to_cpu(desc->wTotalLength);
+
+ if (desc->iConfiguration > udc->top_str_id)
+ udc->top_str_id = desc->iConfiguration;
+
+ offset = desc->bLength;
+
+ while (offset < length) {
+ if (buf[offset + 1] == USB_DT_INTERFACE) {
+ struct usb_interface_descriptor *if_desc =
+ (struct usb_interface_descriptor *)
+ (buf + offset);
+
+ if (if_desc->iInterface > udc->top_str_id)
+ udc->top_str_id = if_desc->iInterface;
+ }
+
+ offset += buf[offset];
+ }
+
+ if ((length % 8) == 0) {
+ /* BIOS can't handle descriptors with size multiple
+ of xfer size */
+ length += 1;
+ /* desc->wTotalLength = cpu_to_le16(length); */
+ }
+
+ /* BIOS can only handle configuration 1,
+ so make sure the config nr is 1 */
+ desc->bConfigurationValue = 1;
+
+ c67x00_ll_write_mem_le16(udc->sie->dev,
+ SIEx_CONF_DESC_LOC(udc->sie->sie_num),
+ req->req.buf, length);
+
+ /* Write vector address to SW interrupt */
+ c67x00_ll_set_configuration_descriptor_location(
+ udc->sie, SIEx_CONF_DESC_LOC(udc->sie->sie_num));
+
+ /* String descriptors start behind configuration descriptor */
+ udc->string_desc_addr =
+ SIEx_CONF_DESC_LOC(udc->sie->sie_num) + length;
+
+ /* Make sure the address is even */
+ if (udc->string_desc_addr & 0x01)
+ udc->string_desc_addr++;
+
+ /* Write string descriptor vector address */
+ c67x00_ll_set_string_descriptor_location(
+ udc->sie, udc->string_desc_addr);
+
+ retval = 1;
+ break;
+ }
+
+ case USB_DT_STRING:
+ /* Write string descriptor */
+ c67x00_ll_write_mem_le16(udc->sie->dev, udc->string_desc_addr,
+ req->req.buf, req->req.length);
+
+ /* set address to end of this descriptor */
+ udc->string_desc_addr += req->req.length;
+
+ retval = 1;
+ break;
+ }
+
+ return retval;
+}
+
+/*
+ * done - retire a request; caller blocked irqs
+ */
+static void c67x00_udc_done(struct c67x00_udc_ep *ep,
+ struct c67x00_request *req, int status)
+{
+ int stopped = ep->stopped;
+
+ list_del_init(&req->queue);
+
+ if (likely(req->req.status == -EINPROGRESS))
+ req->req.status = status;
+ else
+ status = req->req.status;
+/*
+ if (status && status != -ESHUTDOWN)
+ DBG(DBG_VERBOSE, "complete %s req %p stat %d len %u/%u\n",
+ ep->ep.name, &req->req, status,
+ req->req.actual, req->req.length);
+*/
+
+ /* don't modify queue heads during completion callback */
+ ep->stopped = 1;
+ req->req.complete(&ep->ep, &req->req);
+ ep->stopped = stopped;
+}
+
+/*----------- UDC send/receive functions -------------------------------------*/
+
+static void c67x00_udc_start_io_irq(struct c67x00_udc_ep *ep)
+{
+ struct c67x00_sie *sie = ep->udc->sie;
+ struct c67x00_request *req =
+ list_entry(ep->queue.next, struct c67x00_request, queue);
+
+ if (ep->is_ep_in)
+ c67x00_ll_susb_start_send(sie, ep->ep_num,
+ req->req.buf, req->req.length);
+ else
+ c67x00_ll_susb_start_receive(sie, ep->ep_num, req->req.length);
+}
+
+static void c67x00_udc_io_work(struct work_struct *_udc)
+{
+ int i = 0;
+ struct c67x00_udc *udc =
+ container_of(_udc, struct c67x00_udc, io_work);
+
+ for (i = 0; i < C67X00_MAX_NB_END_POINTS; i++) {
+ struct c67x00_udc_ep *ep = &udc->ep[i];
+ if (ep->start_io) {
+ ep->start_io = 0;
+ c67x00_udc_start_io_irq(ep);
+ }
+ }
+}
+
+static void c67x00_udc_schedule_io_irq(struct c67x00_udc_ep *ep)
+{
+ ep->start_io = 1;
+
+ /* start work queue */
+ schedule_work(&ep->udc->io_work);
+}
+
+static void c67x00_udc_done_irq(struct c67x00_udc_ep *ep, int status)
+{
+ struct c67x00_request *req;
+ struct c67x00_sie *sie = ep->udc->sie;
+ int result;
+
+ result = c67x00_ll_susb_get_transfer_status(sie, ep->ep_num);
+ if (result < 0) {
+ dev_err(sie_dev(sie), "udc_done_irq error (%d)\n", result);
+ return;
+ }
+
+ if (unlikely(list_empty(&ep->queue)))
+ return;
+
+ req = list_entry(ep->queue.next, struct c67x00_request, queue);
+
+ req->req.actual = req->req.length - result;
+
+ if (!ep->is_ep_in && ep->ep_num != 0)
+ c67x00_ll_susb_receive(sie, ep->ep_num,
+ req->req.buf, req->req.actual);
+
+ c67x00_udc_done(ep, req, 0);
+ if (!list_empty(&ep->queue) && !ep->stopped)
+ /* restart io req */
+ c67x00_udc_schedule_io_irq(ep);
+}
+
+/* -------------------------------------------------------------------------- */
+/* endpoints */
+
+static const char *c67x00_ep_name[C67X00_MAX_NB_END_POINTS] = {
+ "ep0", "ep1out-bulk", "ep2in-bulk", "ep3", "ep4", "ep5", "ep6", "ep7"
+};
+
+
+/* -------------------------------------------------------------------------- */
+/* ep opts */
+
+/*
+ * empties entire endpoint queue
+ */
+static void c67x00_nuke_ep(struct c67x00_udc_ep *ep, int status)
+{
+ ep->stopped = 1;
+
+ while (!list_empty(&ep->queue)) {
+ struct c67x00_request *req =
+ list_entry(ep->queue.next, struct c67x00_request,
+ queue);
+ c67x00_udc_done(ep, req, status);
+ }
+}
+
+static int c67x00_ep_enable(struct usb_ep *_ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ struct c67x00_udc_ep *ep;
+ struct c67x00_sie *sie;
+ u16 maxpacket;
+
+ ep = container_of(_ep, struct c67x00_udc_ep, ep);
+ sie = ep->udc->sie;
+
+ maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+
+ c67x00_ll_set_device_ep_status(sie, ep->ep_num, 0x0000);
+
+ if (desc->bEndpointAddress & USB_DIR_IN) {
+ ep->is_ep_in = 1;
+ c67x00_ll_set_ep_ctrl_reg(sie, ep->ep_num,
+ EP_ENABLE | DIR_SEL_IN);
+ c67x00_ll_set_ep_packet_size_reg(sie, ep->ep_num, maxpacket);
+ } else {
+ ep->is_ep_in = 0;
+ c67x00_ll_set_ep_ctrl_reg(sie, ep->ep_num, EP_ENABLE);
+ c67x00_ll_set_ep_packet_size_reg(sie, ep->ep_num, maxpacket);
+ }
+
+ ep->enable = 1;
+ ep->stopped = 0;
+ ep->ep.maxpacket = maxpacket;
+
+ return 0;
+}
+
+static int c67x00_ep_disable(struct usb_ep *_ep)
+{
+ unsigned long flags;
+ struct c67x00_udc_ep *ep;
+
+ ep = container_of(_ep, struct c67x00_udc_ep, ep);
+
+ dev_dbg(sie_dev(ep->udc->sie), "ep_disable %s\n", _ep->name);
+
+ spin_lock_irqsave(&ep->udc->lock, flags);
+
+ ep->enable = 0;
+ ep->stopped = 1;
+
+ c67x00_nuke_ep(ep, -ESHUTDOWN);
+
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+ return 0;
+}
+
+
+struct usb_request *c67x00_ep_alloc_request(struct usb_ep *_ep,
+ gfp_t gfp_flags)
+{
+ struct c67x00_request *req;
+
+ req = kzalloc(sizeof(struct c67x00_request), gfp_flags);
+ if (!req)
+ return NULL;
+
+ INIT_LIST_HEAD(&req->queue);
+ return &req->req;
+}
+
+static void c67x00_ep_free_request(struct usb_ep *_ep,
+ struct usb_request *_req)
+{
+ struct c67x00_request *req = NULL;
+ struct c67x00_udc_ep *ep;
+
+ ep = container_of(_ep, struct c67x00_udc_ep, ep);
+ dev_dbg(sie_dev(ep->udc->sie), "free_request %s\n", _ep->name);
+
+ req = container_of(_req, struct c67x00_request, req);
+
+ if (_req)
+ kfree(req);
+}
+
+static int c67x00_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
+ gfp_t gfp_flags)
+{
+ struct c67x00_udc_ep *ep;
+ struct c67x00_request *req;
+ unsigned long flags;
+ int request = 0;
+ struct c67x00_udc *dev;
+
+ req = container_of(_req, struct c67x00_request, req);
+ if (unlikely
+ (!_req || !_req->complete || !_req->buf
+ || !list_empty(&req->queue))) {
+ printk(KERN_WARNING "bad params\n");
+ return -EINVAL;
+ }
+
+ ep = container_of(_ep, struct c67x00_udc_ep, ep);
+ if (unlikely(!_ep)) {
+ dev_warn(sie_dev(ep->udc->sie), "bad ep\n");
+ return -EINVAL;
+ }
+
+ dev = ep->udc;
+ if (unlikely
+ (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
+ dev_warn(sie_dev(ep->udc->sie), "bogus device state\n");
+ return -ESHUTDOWN;
+ }
+
+ if (ep->ep_num == 0) {
+ /* The gadget driver returns the descriptors through this way */
+ if (!c67x00_udc_parse_descriptor(dev, req)) {
+ req->req.actual = req->req.length;
+ return -EINVAL;
+ } else {
+ req->req.status = 0;
+ req->req.actual = req->req.length;
+ req->req.complete(&ep->ep, &req->req);
+ return 0;
+ }
+
+ }
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+ _req->status = -EINPROGRESS;
+ _req->actual = 0;
+
+ /* Start I/O queue if the list was empty */
+ if (list_empty(&ep->queue) && !ep->stopped)
+ request = 1;
+
+ /* Add the request to the queue of the endpoint */
+ list_add_tail(&req->queue, &ep->queue);
+
+ if (request)
+ c67x00_udc_schedule_io_irq(ep);
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ return 0;
+}
+
+
+static int c67x00_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct c67x00_udc_ep *ep;
+ struct c67x00_request *req;
+ unsigned long flags;
+
+ ep = container_of(_ep, struct c67x00_udc_ep, ep);
+ if (!_ep || ep->ep_num == 0)
+ return -EINVAL;
+
+ dev_dbg(sie_dev(ep->udc->sie), "dequeue %s\n", _ep->name);
+
+ spin_lock_irqsave(&ep->udc->lock, flags);
+
+ /* make sure it's actually queued on this endpoint */
+ list_for_each_entry(req, &ep->queue, queue) {
+ if (&req->req == _req)
+ break;
+ }
+ if (&req->req != _req) {
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+ return -EINVAL;
+ }
+
+ c67x00_udc_done(ep, req, -ECONNRESET);
+
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+ return 0;
+}
+
+
+
+static int c67x00_ep_set_halt(struct usb_ep *_ep, int value)
+{
+ printk(KERN_WARNING "c67x00-udc : ep set_halt %s\n", _ep->name);
+ return -ENODEV;
+}
+
+static void c67x00_ep_fifo_flush(struct usb_ep *_ep)
+{
+ printk(KERN_WARNING "c67x00-udc : ep fifo_flush %s\n", _ep->name);
+}
+
+
+static const struct usb_ep_ops c67x00_ep_ops = {
+ .enable = c67x00_ep_enable,
+ .disable = c67x00_ep_disable,
+
+ .alloc_request = c67x00_ep_alloc_request,
+ .free_request = c67x00_ep_free_request,
+
+ .queue = c67x00_ep_queue,
+ .dequeue = c67x00_ep_dequeue,
+
+ .set_halt = c67x00_ep_set_halt,
+ .fifo_flush = c67x00_ep_fifo_flush,
+};
+
+/* -------------------------------------------------------------------------- */
+
+void c67x00_udc_msg_received(struct c67x00_sie *sie, u16 msg)
+{
+ struct c67x00_udc *udc = sie->private_data;
+ u16 EPx_msg_mask = /*SUSB_EP0_MSG | */ SUSB_EP1_MSG
+ | SUSB_EP2_MSG
+ | SUSB_EP3_MSG
+ | SUSB_EP4_MSG
+ | SUSB_EP5_MSG
+ | SUSB_EP6_MSG
+ | SUSB_EP7_MSG;
+
+ if ((msg & EPx_msg_mask) != 0) {
+ int i, mask = 0x01;
+
+ for (i = 0; i < C67X00_MAX_NB_END_POINTS; i++, mask <<= 1)
+ if (msg & mask)
+ c67x00_udc_done_irq(&udc->ep[i], 0);
+ }
+
+ if (msg & SUSB_RST_MSG) {
+ int i;
+ dev_dbg(sie_dev(sie),
+ "udc_msg_rec (0x%04X) : SUSB_RST_MSG\n", msg);
+
+ for (i = 0; i < C67X00_MAX_NB_END_POINTS; i++) {
+ struct c67x00_udc_ep *ep = &udc->ep[i];
+ if (i != 0 && ep->enable) {
+ ep->stopped = 1;
+ c67x00_nuke_ep(ep, -ESHUTDOWN);
+ }
+ }
+ if (udc->driver && udc->driver->disconnect)
+ udc->driver->disconnect(&udc->gadget);
+ }
+
+ if (msg & SUSB_SOF_MSG) {
+ dev_dbg(sie_dev(sie),
+ "udc_msg_rec (0x%04X) : SUSB_SOF_MSG\n", msg);
+ }
+
+ if (msg & SUSB_CFG_MSG) {
+ dev_dbg(sie_dev(sie),
+ "udc_msg_rec (0x%04X) : SUSB_CFG_MSG\n", msg);
+ /* the c67x00 BIOS only supports 1 configuration,
+ so it must be configuration 1 */
+ c67x00_udc_set_configuration(sie, udc->config_nr);
+ }
+
+ if (msg & SUSB_SUS_MSG) {
+ dev_dbg(sie_dev(sie),
+ "udc_msg_rec (0x%04X) : SUSB_SUS_MSG\n", msg);
+ }
+
+ if (msg & SUSB_ID_MSG) {
+ dev_dbg(sie_dev(sie),
+ "udc_msg_rec (0x%04X) : SUSB_ID_MSG\n", msg);
+ }
+
+ if (msg & SUSB_VBUS_MSG) {
+ dev_dbg(sie_dev(sie),
+ "udc_msg_rec (0x%04X) : SUSB_VBUS_MSG\n", msg);
+ }
+}
+
+
+/*
+ * This function is called from the interrupt handler in c67x00-drv.c
+ */
+static void c67x00_udc_irq(struct c67x00_sie *sie, u16 int_status, u16 msg)
+{
+ u16 device_status;
+
+ if (msg)
+ c67x00_udc_msg_received(sie, msg);
+
+ device_status = c67x00_ll_usb_get_status(sie);
+
+ if (int_status & SOFEOP_FLG(sie->sie_num))
+ c67x00_ll_usb_clear_status(sie, SOF_EOP_IRQ_FLG);
+
+ if (int_status & RESET_FLG(sie->sie_num)) {
+ dev_info(sie_dev(sie), "sie%d : reset IRQ\n",
+ sie->sie_num);
+
+ /* Handle reset here */
+ c67x00_ll_usb_clear_status(sie, RESET_IRQ_FLG);
+ }
+
+ if (int_status & DONE_FLG(sie->sie_num))
+ dev_info(sie_dev(sie), "sie%d : done IRQ -> "
+ "device status 0x%04X\n",
+ sie->sie_num, device_status);
+}
+
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+ struct c67x00_udc *udc = &controller;
+ int i, retval;
+
+ if (!driver
+/* || driver->speed < USB_SPEED_FULL*/
+ || !driver->bind || !driver->setup) {
+
+ printk(KERN_ERR
+ "c67x00 : invalid gadget driver provided\n");
+ return -EINVAL;
+ }
+
+
+ spin_lock(&udc->lock);
+ if (!udc->sie || udc->driver) {
+ spin_unlock(&udc->lock);
+ return -EBUSY;
+ }
+
+ udc->driver = driver;
+ udc->gadget.dev.driver = &driver->driver;
+ udc->config_nr = 1;
+ udc->top_str_id = 0;
+ device_add(&udc->gadget.dev);
+
+ driver->driver.bus = NULL;
+
+ dev_dbg(sie_dev(udc->sie), "Binding %s to SIE%d\n",
+ driver->function, udc->sie->sie_num);
+
+ retval = driver->bind(&udc->gadget);
+ if (retval) {
+ dev_warn(sie_dev(udc->sie), "Driver bind failed\n");
+ goto error;
+ }
+
+ /* retrieve descriptors from gadget and program them in device */
+ udc->driver->setup(&udc->gadget,
+ (struct usb_ctrlrequest *)
+ get_descriptor_device);
+ udc->driver->setup(&udc->gadget,
+ (struct usb_ctrlrequest *)
+ get_descriptor_config);
+
+ for (i = 0; i <= udc->top_str_id; i++) {
+ get_descriptor_string[2] = i;
+ udc->driver->setup(&udc->gadget,
+ (struct usb_ctrlrequest *)
+ get_descriptor_string);
+ }
+
+ spin_unlock(&udc->lock);
+
+ /* enable device */
+ c67x00_ll_susb_init(udc->sie);
+
+ return 0;
+
+error :
+ udc->driver = NULL;
+ udc->gadget.dev.driver = NULL;
+ device_del(&udc->gadget.dev);
+
+ spin_unlock(&udc->lock);
+
+ return retval;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+ struct c67x00_udc *udc = &controller;
+
+ printk(KERN_WARNING "c67x00-udc : usb_gadget_unregister_driver\n");
+
+ spin_lock(&udc->lock);
+ if (udc->driver != driver) {
+ spin_unlock(&udc->lock);
+ return -EINVAL;
+ }
+
+ udc->driver = NULL;
+
+ driver->unbind(&udc->gadget);
+ device_del(&udc->gadget.dev);
+
+ c67x00_ll_susb_disable(udc->sie);
+
+ spin_unlock(&udc->lock);
+ return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+/* -------------------------------------------------------------------------- */
+
+int c67x00_udc_probe(struct c67x00_sie *sie)
+{
+ struct c67x00_udc *udc = &controller;
+ unsigned long flags;
+ int i;
+
+ if (udc->sie) {
+ dev_err(sie_dev(sie),
+ "Only 1 peripheral port supported, check sie_config\n");
+ return -EBUSY;
+ }
+
+ spin_lock_init(&udc->lock);
+ INIT_WORK(&udc->io_work, c67x00_udc_io_work);
+ INIT_LIST_HEAD(&udc->gadget.ep_list);
+
+ udc->gadget.ep0 = &udc->ep[0].ep;
+ INIT_LIST_HEAD(&udc->gadget.ep0->ep_list);
+ for (i = 0; i < C67X00_MAX_NB_END_POINTS; i++) {
+ struct c67x00_udc_ep *ep = &udc->ep[i];
+ if (i != 0) {
+ INIT_LIST_HEAD(&udc->ep[i].ep.ep_list);
+ list_add_tail(&udc->ep[i].ep.ep_list,
+ &udc->gadget.ep_list);
+ }
+ ep->ep.name = c67x00_ep_name[i];
+ ep->ep.ops = &c67x00_ep_ops;
+ ep->enable = 0;
+ ep->start_io = 0;
+ if (i == 0)
+ ep->ep.maxpacket = 8;
+ else
+ /* Size is set when endpoint is enabled */
+ ep->ep.maxpacket = 512;
+ ep->ep_num = i;
+ ep->udc = udc;
+ INIT_LIST_HEAD(&ep->queue);
+ }
+
+ udc->sie = sie;
+ udc->gadget.dev.parent = &sie->dev->pdev->dev;
+ device_initialize(&udc->gadget.dev);
+
+ spin_lock_irqsave(&sie->lock, flags);
+ sie->private_data = udc;
+ sie->irq = c67x00_udc_irq;
+ spin_unlock_irqrestore(&sie->lock, flags);
+
+ return 0;
+}
+
+void c67x00_udc_remove(struct c67x00_sie *sie)
+{
+ struct c67x00_udc *udc = sie->private_data;
+
+ if (!udc) {
+ dev_err(sie_dev(sie), "No udc found!\n");
+ return;
+ }
+
+ /* gadget driver must not be registered */
+ BUG_ON(udc->driver != NULL);
+
+ spin_lock(&udc->lock);
+ sie->private_data = NULL;
+ udc->sie = NULL;
+ spin_unlock(&udc->lock);
+}
Index: linux-2.6/drivers/usb/c67x00/c67x00-udc.h
===================================================================
--- /dev/null
+++ linux-2.6/drivers/usb/c67x00/c67x00-udc.h
@@ -0,0 +1,50 @@
+/*
+ * c67x00-udc.h: Cypress C67X00 USB device controller
+ *
+ * Copyright (C) 2006-2008 Barco N.V.
+ * Derived from the Cypress cy7c67200/300 ezusb linux driver and
+ * based on multiple device controller drivers inside the linux kernel.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef _USB_C67X00_UDC_H
+#define _USB_C67X00_UDC_H
+
+#include <linux/kernel.h>
+
+#include "c67x00.h"
+
+#ifdef CONFIG_USB_GADGET_C67X00
+/* Functions used by drv */
+int c67x00_udc_probe(struct c67x00_sie *sie);
+void c67x00_udc_remove(struct c67x00_sie *sie);
+
+#else
+static inline int c67x00_udc_probe(struct c67x00_sie *sie)
+{
+ printk(KERN_ERR "udc requested but CONFIG_USB_GADGET_C67X00 "
+ "not enabled!\n");
+ return -ENODEV;
+}
+
+static inline void c67x00_udc_remove(struct c67x00_sie *sie)
+{
+}
+
+#endif /* CONFIG_USB_GADGET_C67X00 */
+
+#endif /* _USB_C67X00_UDC_H */
Index: linux-2.6/drivers/usb/c67x00/c67x00-drv.c
===================================================================
--- linux-2.6.orig/drivers/usb/c67x00/c67x00-drv.c
+++ linux-2.6/drivers/usb/c67x00/c67x00-drv.c
@@ -42,6 +42,7 @@
#include "c67x00.h"
#include "c67x00-hcd.h"
+#include "c67x00-udc.h"
static void c67x00_probe_sie(struct c67x00_sie *sie,
struct c67x00_device *dev, int sie_num)
@@ -56,6 +57,11 @@
c67x00_hcd_probe(sie);
break;
+ case C67X00_SIE_PERIPHERAL_A:
+ case C67X00_SIE_PERIPHERAL_B:
+ c67x00_udc_probe(sie);
+ break;
+
case C67X00_SIE_UNUSED:
dev_info(sie_dev(sie),
"Not using SIE %d as requested\n", sie->sie_num);
@@ -76,6 +82,11 @@
c67x00_hcd_remove(sie);
break;
+ case C67X00_SIE_PERIPHERAL_A:
+ case C67X00_SIE_PERIPHERAL_B:
+ c67x00_udc_remove(sie);
+ break;
+
default:
break;
}
Index: linux-2.6/drivers/usb/c67x00/c67x00-ll-hpi.c
===================================================================
--- linux-2.6.orig/drivers/usb/c67x00/c67x00-ll-hpi.c
+++ linux-2.6/drivers/usb/c67x00/c67x00-ll-hpi.c
@@ -393,6 +393,190 @@
}
/* -------------------------------------------------------------------------- */
+void c67x00_ll_susb_init(struct c67x00_sie *sie)
+{
+ struct c67x00_device *dev = sie->dev;
+ struct lcp_int_data data;
+ u16 addr;
+ int rc;
+
+ /* The BIOS SUSB_INIT_INT handler for some reason is hardcoded to only
+ enable peripheral support for port A. Relocate the routine to RAM
+ and patch out that instruction (mov [r10-0xe],[r8]) */
+ addr = hpi_read_word(dev, SUSB_INIT_INT_LOC);
+
+ /* already patched? */
+ if (addr != CY_UDC_BIOS_REPLACE_BASE) {
+ u16 buf[64]; /* should be plenty for the handler */
+ int i;
+
+ c67x00_ll_read_mem_le16(dev, addr, buf, sizeof(buf));
+
+ /* patch it */
+ for (i = 0; i < (ARRAY_SIZE(buf)-1); i++) {
+ if ((buf[i] == cpu_to_le16(0x0432))
+ && (buf[i+1] == cpu_to_le16(0xfff2))) {
+ buf[i] = buf[i+1] = 0; /* nop */
+ break;
+ }
+ }
+
+ if (i >= ARRAY_SIZE(buf))
+ dev_warn(sie_dev(sie), "BIOS code not recognized, "
+ "port B may not be available\n");
+
+ c67x00_ll_write_mem_le16(dev, CY_UDC_BIOS_REPLACE_BASE,
+ buf, sizeof(buf));
+ hpi_write_word(dev, SUSB_INIT_INT_LOC,
+ CY_UDC_BIOS_REPLACE_BASE);
+ }
+
+ hpi_clear_bits(dev, HPI_IRQ_ROUTING_REG,
+ SOFEOP_TO_HPI_EN(sie->sie_num));
+ hpi_set_bits(dev,
+ HPI_IRQ_ROUTING_REG,
+ SOFEOP_TO_CPU_EN(sie->sie_num)
+ | RESUME_TO_HPI_ENABLE(sie->sie_num)
+ | ID_TO_HPI_ENABLE | VBUS_TO_HPI_ENABLE);
+
+ hpi_set_bits(dev,
+ DEVICE_N_IRQ_EN_REG(sie->sie_num),
+ SOF_EOP_TMOUT_IRQ_EN | ID_IRQ_EN | VBUS_IRQ_EN);
+
+ hpi_clear_bits(dev,
+ USB_CTL_REG(sie->sie_num),
+ SOF_EOP_EN(0) | SOF_EOP_EN(1));
+
+ if (sie->mode == C67X00_SIE_PERIPHERAL_A)
+ hpi_write_word(dev, DEVICE_N_PORT_SEL(sie->sie_num), 0x0000);
+ else
+ hpi_write_word(dev, DEVICE_N_PORT_SEL(sie->sie_num), 0x4000);
+
+ data.regs[1] = 0; /* full speed */
+ data.regs[2] = sie->sie_num + 1;
+ rc = c67x00_comm_exec_int(dev, SUSB_INIT_INT, &data);
+
+ if ((hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)) & HOST_MODE))
+ dev_warn(sie_dev(sie),
+ "SIE %d not set to peri mode\n", sie->sie_num);
+
+ BUG_ON(rc); /* No return path for error code; crash spectacularly */
+
+ hpi_set_bits(dev,
+ DEVICE_N_IRQ_EN_REG(sie->sie_num),
+ SOF_EOP_TMOUT_IRQ_EN | ID_IRQ_EN | VBUS_IRQ_EN);
+
+ dev_info(sie_dev(sie),
+ "Peripheral USB device setup on SIE%d\n",
+ sie->sie_num);
+}
+
+void c67x00_ll_susb_disable(struct c67x00_sie *sie)
+{
+ hpi_write_word(sie->dev, DEVICE_N_IRQ_EN_REG(sie->sie_num), 0);
+ hpi_write_word(sie->dev, USB_CTL_REG(sie->sie_num), 0x0000);
+}
+
+u16 c67x00_ll_get_device_ep_status(struct c67x00_sie *sie, int ep)
+{
+ return hpi_read_word(sie->dev,
+ DEVICE_N_ENDPOINT_N_STAT_REG(sie->sie_num, ep));
+}
+
+void c67x00_ll_set_device_ep_status(struct c67x00_sie *sie,
+ int ep, u16 value)
+{
+ hpi_write_word(sie->dev,
+ DEVICE_N_ENDPOINT_N_STAT_REG(sie->sie_num, ep),
+ value);
+}
+
+void c67x00_ll_set_device_descriptor_location(struct c67x00_sie *sie,
+ u16 address)
+{
+ hpi_write_word(sie->dev, SUSBx_DEV_DESC_VEC(sie->sie_num), address);
+}
+
+void c67x00_ll_set_configuration_descriptor_location(struct c67x00_sie *sie,
+ u16 address)
+{
+ hpi_write_word(sie->dev, SUSBx_CONF_DESC_VEC(sie->sie_num), address);
+}
+
+void c67x00_ll_set_string_descriptor_location(struct c67x00_sie *sie,
+ u16 address)
+{
+ hpi_write_word(sie->dev, SUSBx_STRING_DESC_VEC(sie->sie_num), address);
+}
+
+int c67x00_ll_susb_start_send(struct c67x00_sie *sie, int ep,
+ void *data, int len)
+{
+ u16 header[4];
+ struct lcp_int_data regs;
+
+ c67x00_ll_write_mem_le16(sie->dev, CY_UDC_REQ_BUFFER_ADDR(ep),
+ data, len);
+
+ header[0] = 0;
+ header[1] = cpu_to_le16(CY_UDC_REQ_BUFFER_ADDR(ep));
+ header[2] = cpu_to_le16(len);
+ header[3] = 0;
+
+ c67x00_ll_write_mem_le16(sie->dev, CY_UDC_REQ_HEADER_ADDR(ep), header,
+ sizeof(header));
+
+ regs.regs[0] = 0;
+ regs.regs[1] = ep;
+ regs.regs[8] = CY_UDC_REQ_HEADER_ADDR(ep);
+
+ return c67x00_comm_exec_int(sie->dev, SUSBx_SEND_INT(sie->sie_num),
+ ®s);
+}
+
+int c67x00_ll_susb_start_receive(struct c67x00_sie *sie, int ep, int len)
+{
+ u16 header[4];
+ struct lcp_int_data regs;
+
+ header[0] = 0;
+ header[1] = cpu_to_le16(CY_UDC_REQ_BUFFER_ADDR(ep));
+ header[2] = cpu_to_le16(len);
+ header[3] = 0;
+
+ c67x00_ll_write_mem_le16(sie->dev, CY_UDC_REQ_HEADER_ADDR(ep), header,
+ sizeof(header));
+
+ regs.regs[0] = 0;
+ regs.regs[1] = ep;
+ regs.regs[8] = CY_UDC_REQ_HEADER_ADDR(ep);
+
+ return c67x00_comm_exec_int(sie->dev, SUSBx_RECEIVE_INT(sie->sie_num),
+ ®s);
+}
+
+int c67x00_ll_susb_get_transfer_status(struct c67x00_sie *sie, int ep)
+{
+ u16 header[4];
+ u16 result = c67x00_get_comm_reg(sie->dev, 0);
+
+ if (result)
+ return -result;
+
+ c67x00_ll_read_mem_le16(sie->dev, CY_UDC_REQ_HEADER_ADDR(ep),
+ header, sizeof(header));
+ /* nr of bytes not transferred */
+ return le16_to_cpu(header[2]);
+}
+
+void c67x00_ll_susb_receive(struct c67x00_sie *sie, int ep,
+ void *data, int len)
+{
+ c67x00_ll_read_mem_le16(sie->dev, CY_UDC_REQ_BUFFER_ADDR(ep),
+ data, len);
+}
+
+/* -------------------------------------------------------------------------- */
void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status)
{
Index: linux-2.6/drivers/usb/c67x00/c67x00.h
===================================================================
--- linux-2.6.orig/drivers/usb/c67x00/c67x00.h
+++ linux-2.6/drivers/usb/c67x00/c67x00.h
@@ -287,6 +287,24 @@
void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie);
void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port);
+/* Slave specific functions */
+void c67x00_ll_susb_init(struct c67x00_sie *sie);
+void c67x00_ll_susb_disable(struct c67x00_sie *sie);
+u16 c67x00_ll_get_device_ep_status(struct c67x00_sie *sie, int ep);
+void c67x00_ll_set_device_ep_status(struct c67x00_sie *sie, int ep, u16 value);
+void c67x00_ll_set_device_descriptor_location(struct c67x00_sie *sie,
+ u16 address);
+void c67x00_ll_set_configuration_descriptor_location(struct c67x00_sie *sie,
+ u16 address);
+void c67x00_ll_set_string_descriptor_location(struct c67x00_sie *sie,
+ u16 address);
+int c67x00_ll_susb_start_send(struct c67x00_sie *sie, int ep,
+ void *data, int len);
+int c67x00_ll_susb_start_receive(struct c67x00_sie *sie, int ep, int len);
+int c67x00_ll_susb_get_transfer_status(struct c67x00_sie *sie, int ep);
+void c67x00_ll_susb_receive(struct c67x00_sie *sie, int ep,
+ void *data, int len);
+
/* Called by c67x00_irq to handle lcp interrupts */
void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status);
Index: linux-2.6/drivers/usb/c67x00/Makefile
===================================================================
--- linux-2.6.orig/drivers/usb/c67x00/Makefile
+++ linux-2.6/drivers/usb/c67x00/Makefile
@@ -6,6 +6,9 @@
EXTRA_CFLAGS += -DDEBUG
endif
-obj-$(CONFIG_USB_C67X00_HCD) += c67x00.o
+obj-$(CONFIG_USB_C67X00_DRV) += c67x00.o
-c67x00-objs := c67x00-drv.o c67x00-ll-hpi.o c67x00-hcd.o c67x00-sched.o
+c67x00-y += c67x00-drv.o c67x00-ll-hpi.o
+
+c67x00-$(CONFIG_USB_C67X00_HCD) += c67x00-hcd.o c67x00-sched.o
+c67x00-$(CONFIG_USB_GADGET_C67X00) += c67x00-udc.o
Index: linux-2.6/drivers/usb/gadget/Kconfig
===================================================================
--- linux-2.6.orig/drivers/usb/gadget/Kconfig
+++ linux-2.6/drivers/usb/gadget/Kconfig
@@ -324,6 +324,13 @@
depends on USB_GADGET_AT91
default USB_GADGET
+config USB_GADGET_C67X00
+ boolean "Cypress C67X00 Gadget support"
+ depends on USB_C67X00_DRV
+ select USB_GADGET_SELECTED
+ help
+ This enables the gadget functionality of the Cypress C67X00.
+
config USB_GADGET_DUMMY_HCD
boolean "Dummy HCD (DEVELOPMENT)"
depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL
Index: linux-2.6/drivers/usb/gadget/gadget_chips.h
===================================================================
--- linux-2.6.orig/drivers/usb/gadget/gadget_chips.h
+++ linux-2.6/drivers/usb/gadget/gadget_chips.h
@@ -147,6 +147,12 @@
#define gadget_is_m66592(g) 0
#endif
+#ifdef CONFIG_USB_GADGET_C67X00
+#define gadget_is_c67x00(g) !strcmp("c67x00_udc", (g)->name)
+#else
+#define gadget_is_c67x00(g) 0
+#endif
+
// CONFIG_USB_GADGET_SX2
// CONFIG_USB_GADGET_AU1X00
@@ -212,5 +218,7 @@
return 0x20;
else if (gadget_is_m66592(gadget))
return 0x21;
+ else if (gadget_is_c67x00(gadget))
+ return 0x22;
return -ENOENT;
}
Index: linux-2.6/drivers/usb/host/Kconfig
===================================================================
--- linux-2.6.orig/drivers/usb/host/Kconfig
+++ linux-2.6/drivers/usb/host/Kconfig
@@ -261,15 +261,3 @@
To compile this driver as a module, choose M here: the
module will be called r8a66597-hcd.
-config USB_C67X00_HCD
- tristate "Cypress C67x00 HCD support"
- depends on USB
- help
- The Cypress C67x00 (EZ-Host/EZ-OTG) chips are dual-role
- host/peripheral/OTG USB controllers.
-
- Enable this option to support this chip in host controller mode.
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called c67x00.
Index: linux-2.6/drivers/usb/Makefile
===================================================================
--- linux-2.6.orig/drivers/usb/Makefile
+++ linux-2.6/drivers/usb/Makefile
@@ -17,7 +17,7 @@
obj-$(CONFIG_USB_U132_HCD) += host/
obj-$(CONFIG_USB_R8A66597_HCD) += host/
-obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
+obj-$(CONFIG_USB_C67X00_DRV) += c67x00/
obj-$(CONFIG_USB_ACM) += class/
obj-$(CONFIG_USB_PRINTER) += class/
Index: linux-2.6/drivers/usb/Kconfig
===================================================================
--- linux-2.6.orig/drivers/usb/Kconfig
+++ linux-2.6/drivers/usb/Kconfig
@@ -91,6 +91,8 @@
source "drivers/usb/host/Kconfig"
+source "drivers/usb/c67x00/Kconfig"
+
source "drivers/usb/class/Kconfig"
source "drivers/usb/storage/Kconfig"
Index: linux-2.6/drivers/usb/c67x00/Kconfig
===================================================================
--- /dev/null
+++ linux-2.6/drivers/usb/c67x00/Kconfig
@@ -0,0 +1,21 @@
+#
+# Cypress C67x00 USB controller
+#
+config USB_C67X00_DRV
+ tristate "Cypress C67x00 support"
+ # only allowed to be =y if both USB!=m and USB_GADGET!=m
+ depends on (!USB && USB_GADGET) || (!USB_GADGET && USB) || (USB && USB_GADGET)
+ help
+ The Cypress C67x00 (EZ-Host/EZ-OTG) chips are dual-role
+ host/peripheral USB controllers.
+
+ To compile this driver as a module, choose M here: the
+ module will be called c67x00.
+
+config USB_C67X00_HCD
+ bool "Cypress C67X00 HCD support"
+ depends on USB && USB_C67X00_DRV
+ default y
+ help
+ Enable this option to support the Cypress C67x00 in host
+ controller mode.
--
Bye, Peter Korsgaard
^ 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