* Re: [PATCH 3/3] [POWERPC] dts: kill hardcoded phandles
From: Vitaly Bordug @ 2007-05-08 16:26 UTC (permalink / raw)
To: Loeliger Jon-LOELIGER
Cc: linuxppc-dev, linux-pcmcia, linux-kernel, David Gibson
In-Reply-To: <AF0367BA48C55940A43CCF08DF35553C012AA472@az33exm24.fsl.freescale.net>
On Tue, 8 May 2007 07:29:20 -0700
"Loeliger Jon-LOELIGER" <jdl@freescale.com> wrote:
>
> > > - interrupt-controller@f8200000 {
> > > - linux,phandle = <f8200000>;
> > > + pci_pic:interrupt-controller@f8200000 {
> >
> > I'd like to establish a convention of putting a space after the : and
> > using capitals for labels unless there's a strong reason not to in a
> > particular case. It makes them easier to visually distinguish next to
> > the node name.
>
> Colon-space is easy and I'll buy it.
> I'm not big on uppercase shouting, though.
>
> Perhaps something more like case or goto labels:?
>
> pci_pic:
> interrupt-contoller@f8200000 {
>
> if needed?
>
I used middle solution
Pci_pic: interrupt-contoller@f8200000 {
so first letter of the label should be uppercase.
It makes them easily distinguishable and at the same time, not "shouting" manner.
--
Sincerely,
Vitaly
^ permalink raw reply
* Re: kernel expection generated with 2.6.21-mm1 kernel boot up
From: Linas Vepstas @ 2007-05-08 16:23 UTC (permalink / raw)
To: Srinivasa Ds; +Cc: linuxppc-dev, Balbir Singh, Kamalesh Babulal
In-Reply-To: <4640675C.6090104@in.ibm.com>
On Tue, May 08, 2007 at 05:34:44PM +0530, Srinivasa Ds wrote:
>
> Looks like problem is in SLUB layer, I unmarked SLUB(CONFIG_SLUB)
> option and now system is booting.
Its been repored by others (and I can reproduce it),
its a problem with a bad interaction with SLUB and pg_tables
A patch flew by recetnly that would not use slub for pg_tables,
but I don't know if that's the permanent fix.
--linas
^ permalink raw reply
* Re: [PATCH] [POWERPC] 8xx: PQ SoC IRDA support
From: Vitaly Bordug @ 2007-05-08 16:19 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, Samuel Ortiz, linux-kernel
In-Reply-To: <522959B8-DDF1-4AA1-87AE-336793EDA181@kernel.crashing.org>
On Tue, 8 May 2007 08:33:19 -0500
Kumar Gala <galak@kernel.crashing.org> wrote:
> > + scc@a20 {
> > + device_type = "network";
> > + compatible = "fsl,irda";
>
> is this specific enough? 52xx also has irda and I'm guessing they'd
> require different drivers (haven't looked).
Yap, I'll do "fsl,pq-irda" here...
--
Sincerely,
Vitaly
^ permalink raw reply
* Re: [PATCH] [POWERPC] 8xx: PQ SoC IRDA support
From: Vitaly Bordug @ 2007-05-08 16:18 UTC (permalink / raw)
To: Loeliger Jon-LOELIGER; +Cc: linuxppc-dev, Samuel Ortiz, linux-kernel
In-Reply-To: <AF0367BA48C55940A43CCF08DF35553C012AA475@az33exm24.fsl.freescale.net>
On Tue, 8 May 2007 07:36:48 -0700
"Loeliger Jon-LOELIGER" <jdl@freescale.com> wrote:
> > Adds support of IRDA transceiver residing on PowerQUICC processors and
> > enabling such on mpc885ads reference board. The driver is implemented
> > using of_device concept, hereby implies arch/powerpc support
> > of the target.
> >
> > Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
>
> > diff --git a/arch/powerpc/boot/dts/mpc885ads.dts
> > b/arch/powerpc/boot/dts/mpc885ads.dts
> > index 110bf61..95b280c 100644
> > --- a/arch/powerpc/boot/dts/mpc885ads.dts
> > +++ b/arch/powerpc/boot/dts/mpc885ads.dts
> > @@ -178,6 +178,16 @@
> > interrupt-parent = <930>;
> > phy-handle = <e8002>;
> > };
> > +
> > + scc@a20 {
> > + device_type = "network";
> > + compatible = "fsl,irda";
> > + model = "SCC";
> > + device-id = <2>;
> > + reg = <a20 18 3d00 80>;
> > + interrupts = <1d 3>;
> > + interrupt-parent = <930>;
> > + };
> > };
> > };
> > };
>
>
> Any chance we could get an update to the booting-without-of.txt
> for any of this?
>
Yes of course. my note is that it makes sense once defines would settle down
stuff that looks OK in docs might not look such in driver...
--
Sincerely,
Vitaly
^ permalink raw reply
* Re: [PATCH 05/13] Document the fsl, magic-packet property in gianfar nodes.
From: Scott Wood @ 2007-05-08 15:29 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <3FE06AFA-BEE6-46CF-B12C-29D979AE50D7@kernel.crashing.org>
Kumar Gala wrote:
> On May 7, 2007, at 4:51 PM, Andy Fleming wrote:
>> Yeah, I just read that. You should either make that more explicit in
>> the documentation, or make it generic. It's fine if there are
>> drivers/devices that don't need to be told or tell anyone that they
>> recognize magic packets for them to work. The lack of the property
>> in other controllers won't break anything.
>>
>> But I'm fine if you just document that the bit indicates,
>> specifically, the presence of magic-packet bits in certain registers
>> on the eTSEC.
>
> I'd ask is it really freescale specific? In that I'd assume its
> support for the standard wake-on-lan packet.
It is the standard wake-on-lan packet, but the intent of the property is
not to advertise to the entire system that this device supports it, but
rather to indicate that the MPEN bit and the like are valid for the
driver to use. Making it standard means that someone might use it for
other purposes, such as pm config tools digging around in
/proc/device-tree (sure, they could just use ethtool -- but they might
not), which would mean that all magic-packet-capable devices (gianfar or
not) would need the property.
If we want to do that, fine -- but that change is at a different scope
than the one I made.
-Scott
^ permalink raw reply
* Re: [PATCH 03/13] Document the sleep property.
From: Scott Wood @ 2007-05-08 15:23 UTC (permalink / raw)
To: Olof Johansson; +Cc: linuxppc-dev
In-Reply-To: <20070508021149.GE12613@lixom.net>
Olof Johansson wrote:
> On Mon, May 07, 2007 at 01:29:44PM -0500, Scott Wood wrote:
>>+ The first cell of a sleep node is a phandle to the sleep controller.
>>+ The remaining cells are interpreted by said controller. In the case
>>+ of an fsl,mpc83xx-pmc sleep controller, the second cell represents the
>>+ bits to clear in SCCR to stop the device's clock.
>
> The second part here is completely implementation-dependent. I don't
> really see the need to document that in this global document?
In this document, not necessarily (I like David's suggestion of a wiki).
It should be documented somewhere, though, so one doesn't have to dig
through Linux source code to write code for another OS that supports the
binding.
-Scott
^ permalink raw reply
* RE: [PATCH] [POWERPC] 8xx: PQ SoC IRDA support
From: Loeliger Jon-LOELIGER @ 2007-05-08 14:36 UTC (permalink / raw)
To: Vitaly Bordug, Samuel Ortiz; +Cc: Andrew Morton, linuxppc-dev, linux-kernel
In-Reply-To: <20070508052723.18404.8216.stgit@localhost.localdomain>
> Adds support of IRDA transceiver residing on PowerQUICC processors and
> enabling such on mpc885ads reference board. The driver is implemented=20
> using of_device concept, hereby implies arch/powerpc support=20
> of the target.
>=20
> Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
> diff --git a/arch/powerpc/boot/dts/mpc885ads.dts=20
> b/arch/powerpc/boot/dts/mpc885ads.dts
> index 110bf61..95b280c 100644
> --- a/arch/powerpc/boot/dts/mpc885ads.dts
> +++ b/arch/powerpc/boot/dts/mpc885ads.dts
> @@ -178,6 +178,16 @@
> interrupt-parent =3D <930>;
> phy-handle =3D <e8002>;
> };
> +
> + scc@a20 {
> + device_type =3D "network";
> + compatible =3D "fsl,irda";
> + model =3D "SCC";
> + device-id =3D <2>;
> + reg =3D <a20 18 3d00 80>;
> + interrupts =3D <1d 3>;
> + interrupt-parent =3D <930>;
> + };
> };
> };
> };
Any chance we could get an update to the booting-without-of.txt
for any of this?
Thanks,
jdl
^ permalink raw reply
* RE: [PATCH 3/3] [POWERPC] dts: kill hardcoded phandles
From: Loeliger Jon-LOELIGER @ 2007-05-08 14:29 UTC (permalink / raw)
To: David Gibson, Vitaly Bordug; +Cc: linuxppc-dev, linux-pcmcia, linux-kernel
In-Reply-To: <20070508055431.GA21009@localhost.localdomain>
> > - interrupt-controller@f8200000 {
> > - linux,phandle =3D <f8200000>;
> > + pci_pic:interrupt-controller@f8200000 {
>=20
> I'd like to establish a convention of putting a space after the : and
> using capitals for labels unless there's a strong reason not to in a
> particular case. It makes them easier to visually distinguish next to
> the node name.
Colon-space is easy and I'll buy it.
I'm not big on uppercase shouting, though.
Perhaps something more like case or goto labels:?
pci_pic:
interrupt-contoller@f8200000 {
if needed?
jdl
^ permalink raw reply
* Re: [PATCH 1/3] [POWERPC] 8xx: mpc885ads pcmcia support
From: Kumar Gala @ 2007-05-08 14:04 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: linuxppc-dev, linux-pcmcia, linux-kernel
In-Reply-To: <20070508095038.20018.60060.stgit@localhost.localdomain>
On May 8, 2007, at 4:50 AM, Vitaly Bordug wrote:
>
> Adds support for PowerQuicc on-chip PCMCIA. The driver is
> implemented as
> of_device, so only arch/powerpc stuff is capable to use it, which now
> implies only mpc885ads reference board.
>
> To cope with the code that should be hooked inside driver, but is
> really
> board specific (like set_voltage), global structure mpc8xx_pcmcia_ops
> holds necessary function pointers that are filled in the BSP code.
>
> Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Olof Johansson <olof@lixom.net>
>
> ---
>
> arch/powerpc/boot/dts/mpc885ads.dts | 12 +
> arch/powerpc/platforms/8xx/m8xx_setup.c | 5
> arch/powerpc/platforms/8xx/mpc885ads.h | 8 +
> arch/powerpc/platforms/8xx/mpc885ads_setup.c | 72 +++++
> arch/powerpc/sysdev/fsl_soc.c | 13 +
> arch/powerpc/sysdev/mpc8xx_pic.h | 2
> drivers/pcmcia/Kconfig | 1
> drivers/pcmcia/m8xx_pcmcia.c | 351 +++++++++++
> +--------------
> include/asm-powerpc/mpc8xx.h | 4
> include/linux/fsl_devices.h | 5
> 10 files changed, 287 insertions(+), 186 deletions(-)
>
> diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/
> boot/dts/mpc885ads.dts
> index 110bf61..0786ac1 100644
> --- a/arch/powerpc/boot/dts/mpc885ads.dts
> +++ b/arch/powerpc/boot/dts/mpc885ads.dts
> @@ -112,6 +112,18 @@
> compatible = "CPM";
> };
>
> + pcmcia@0080 {
> + #address-cells = <3>;
> + #interrupt-cells = <1>;
> + #size-cells = <2>;
> + compatible = "fsl,pq-pcmcia";
should this be fsl,pq1-pcmcia or fsl,8xx-pcmcia?
> + device_type = "pcmcia";
> + reg = <80 80>;
> + clock-frequency = <2faf080>;
is the clock-freq fixed?
> + interrupt-parent = <&mpc8xx-pic>;
> + interrupts = <d 1>;
> + };
> +
> cpm@ff000000 {
> linux,phandle = <ff000000>;
> #address-cells = <1>;
> diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/
> platforms/8xx/m8xx_setup.c
> index 0901dba..f169355 100644
> --- a/arch/powerpc/platforms/8xx/m8xx_setup.c
> +++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
> @@ -32,6 +32,7 @@
> #include <linux/root_dev.h>
> #include <linux/time.h>
> #include <linux/rtc.h>
> +#include <linux/fsl_devices.h>
>
> #include <asm/mmu.h>
> #include <asm/reg.h>
> @@ -49,6 +50,10 @@
>
> #include "sysdev/mpc8xx_pic.h"
>
> +#ifdef CONFIG_PCMCIA_M8XX
> +struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
> +#endif
> +
> void m8xx_calibrate_decr(void);
> extern void m8xx_wdt_handler_install(bd_t *bp);
> extern int cpm_pic_init(void);
> diff --git a/arch/powerpc/platforms/8xx/mpc885ads.h b/arch/powerpc/
> platforms/8xx/mpc885ads.h
> index 7c31aec..932b59a 100644
> --- a/arch/powerpc/platforms/8xx/mpc885ads.h
> +++ b/arch/powerpc/platforms/8xx/mpc885ads.h
> @@ -91,5 +91,13 @@
> #define SICR_ENET_MASK ((uint)0x00ff0000)
> #define SICR_ENET_CLKRT ((uint)0x002c0000)
>
> +/*
> + * Some internal interrupt registers use an 8-bit mask for the
> interrupt
> + * level instead of a number.
> + */
> +static inline uint mk_int_int_mask(uint mask) {
> + return (1 << (7 - (mask/2)));
> +}
would this be better off in sysdev/mpc8xx_pic.h?
> +
> #endif /* __ASM_MPC885ADS_H__ */
> #endif /* __KERNEL__ */
> diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/
> powerpc/platforms/8xx/mpc885ads_setup.c
> index a57b577..80e7214 100644
> --- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
> +++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
> @@ -22,6 +22,7 @@
>
> #include <linux/fs_enet_pd.h>
> #include <linux/fs_uart_pd.h>
> +#include <linux/fsl_devices.h>
> #include <linux/mii.h>
>
> #include <asm/delay.h>
> @@ -51,6 +52,70 @@ static void init_smc1_uart_ioports(struct
> fs_uart_platform_info* fpi);
> static void init_smc2_uart_ioports(struct fs_uart_platform_info*
> fpi);
> static void init_scc3_ioports(struct fs_platform_info* ptr);
>
> +#ifdef CONFIG_PCMCIA_M8XX
> +static void pcmcia_hw_setup(int slot, int enable)
> +{
> + unsigned *bcsr_io;
> +
> + bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
> + if (enable)
> + clrbits32(bcsr_io, BCSR1_PCCEN);
> + else
> + setbits32(bcsr_io, BCSR1_PCCEN);
> +
> + iounmap(bcsr_io);
> +}
> +
> +static int pcmcia_set_voltage(int slot, int vcc, int vpp)
> +{
> + u32 reg = 0;
> + unsigned *bcsr_io;
> +
> + bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
> +
> + switch(vcc) {
> + case 0:
> + break;
> + case 33:
> + reg |= BCSR1_PCCVCC0;
> + break;
> + case 50:
> + reg |= BCSR1_PCCVCC1;
> + break;
> + default:
> + return 1;
> + }
> +
> + switch(vpp) {
> + case 0:
> + break;
> + case 33:
> + case 50:
> + if(vcc == vpp)
> + reg |= BCSR1_PCCVPP1;
> + else
> + return 1;
> + break;
> + case 120:
> + if ((vcc == 33) || (vcc == 50))
> + reg |= BCSR1_PCCVPP0;
> + else
> + return 1;
> + default:
> + return 1;
> + }
> +
seems like formatting is of (but that could just me my email reader)
> + /* first, turn off all power */
> + clrbits32(bcsr_io, 0x00610000);
> +
> + /* enable new powersettings */
> + setbits32(bcsr_io, reg);
> +
> + iounmap(bcsr_io);
> + return 0;
> +}
> +#endif
> +
> void __init mpc885ads_board_setup(void)
> {
> cpm8xx_t *cp;
> @@ -115,6 +180,12 @@ void __init mpc885ads_board_setup(void)
> immr_unmap(io_port);
>
> #endif
> +
> +#ifdef CONFIG_PCMCIA_M8XX
> + /*Set up board specific hook-ups*/
> + m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup;
> + m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage;
> +#endif
> }
>
>
> @@ -322,6 +393,7 @@ void init_smc_ioports(struct
> fs_uart_platform_info *data)
> }
> }
>
> +
extra whitespace?
> int platform_device_skip(const char *model, int id)
> {
> #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
> diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/
> fsl_soc.c
> index 8a123c7..880e45f 100644
> --- a/arch/powerpc/sysdev/fsl_soc.c
> +++ b/arch/powerpc/sysdev/fsl_soc.c
> @@ -1028,6 +1028,19 @@ err:
>
> arch_initcall(fs_enet_of_init);
>
> +static int __init fsl_pcmcia_of_init(void)
> +{
> + struct device_node *np = NULL;
> + /*
> + * Register all the devices which type is "pcmcia"
> + */
> + while ((np = of_find_compatible_node(np,
> + "pcmcia", "fsl,pq-pcmcia")) != NULL)
> + of_platform_device_create(np, "m8xx-pcmcia", NULL);
> + return 0;
> +}
> +
> +arch_initcall(fsl_pcmcia_of_init);
>
> static const char *smc_regs = "regs";
> static const char *smc_pram = "pram";
> diff --git a/arch/powerpc/sysdev/mpc8xx_pic.h b/arch/powerpc/sysdev/
> mpc8xx_pic.h
> index afa2ee6..b4a1d33 100644
> --- a/arch/powerpc/sysdev/mpc8xx_pic.h
> +++ b/arch/powerpc/sysdev/mpc8xx_pic.h
> @@ -4,8 +4,6 @@
> #include <linux/irq.h>
> #include <linux/interrupt.h>
>
> -extern struct hw_interrupt_type mpc8xx_pic;
> -
> int mpc8xx_pic_init(void);
> unsigned int mpc8xx_get_irq(void);
>
> diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
> index 35f8864..c3fd55d 100644
> --- a/drivers/pcmcia/Kconfig
> +++ b/drivers/pcmcia/Kconfig
> @@ -183,6 +183,7 @@ config PCMCIA_M8XX
> tristate "MPC8xx PCMCIA support"
> depends on PCMCIA && PPC && 8xx
> select PCCARD_IODYN
> + select PCCARD_NONSTATIC
> help
> Say Y here to include support for PowerPC 8xx series PCMCIA
> controller.
> diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/
> m8xx_pcmcia.c
> index 9721ed7..40f6e20 100644
> --- a/drivers/pcmcia/m8xx_pcmcia.c
> +++ b/drivers/pcmcia/m8xx_pcmcia.c
> @@ -10,7 +10,7 @@
> * Further fixes, v2.6 kernel port
> * <marcelo.tosatti@cyclades.com>
> *
> - * Some fixes, additions (C) 2005 Montavista Software, Inc.
> + * Some fixes, additions (C) 2005-2007 Montavista Software, Inc.
> * <vbordug@ru.mvista.com>
> *
> * "The ExCA standard specifies that socket controllers should
> provide
> @@ -40,10 +40,6 @@
> #include <linux/fcntl.h>
> #include <linux/string.h>
>
> -#include <asm/io.h>
> -#include <asm/bitops.h>
> -#include <asm/system.h>
> -
> #include <linux/kernel.h>
> #include <linux/errno.h>
> #include <linux/slab.h>
> @@ -51,11 +47,18 @@
> #include <linux/ioport.h>
> #include <linux/delay.h>
> #include <linux/interrupt.h>
> -#include <linux/platform_device.h>
> +#include <linux/fsl_devices.h>
>
> +#include <asm/io.h>
> +#include <asm/bitops.h>
> +#include <asm/system.h>
> +#include <asm/time.h>
> #include <asm/mpc8xx.h>
> #include <asm/8xx_immap.h>
> #include <asm/irq.h>
> +#include <asm/fs_pd.h>
> +#include <asm/of_device.h>
> +#include <asm/of_platform.h>
>
> #include <pcmcia/version.h>
> #include <pcmcia/cs_types.h>
> @@ -146,27 +149,17 @@ MODULE_LICENSE("Dual MPL/GPL");
> #define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory
> window 0 */
> #define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64
> MByte */
> #define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io
> window 0 */
> -
> -#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt
> Level */
> -
> /*
> ----------------------------------------------------------------------
> --- */
>
> -/* 2.4.x and newer has this always in HZ */
> -#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
> -
> -static int pcmcia_schlvl = PCMCIA_SCHLVL;
> +static int pcmcia_schlvl;
>
> static DEFINE_SPINLOCK(events_lock);
>
> -
> #define PCMCIA_SOCKET_KEY_5V 1
> #define PCMCIA_SOCKET_KEY_LV 2
>
> /* look up table for pgcrx registers */
> -static u32 *m8xx_pgcrx[2] = {
> - &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
> - &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
> -};
> +static u32 *m8xx_pgcrx[2];
>
> /*
> * This structure is used to address each window in the PCMCIA
> controller.
> @@ -228,11 +221,16 @@ struct event_table {
> u32 eventbit;
> };
>
> +static const char driver_name[] = "m8xx-pcmcia";
> +
> struct socket_info {
> void (*handler)(void *info, u32 events);
> void *info;
>
> u32 slot;
> + pcmconf8xx_t *pcmcia;
> + u32 bus_freq;
> + int hwirq;
>
> socket_state_t state;
> struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
> @@ -408,78 +406,21 @@ static void hardware_disable(int slot)
> #if defined(CONFIG_MPC885ADS)
>
> #define PCMCIA_BOARD_MSG "MPC885ADS"
> +#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
>
> -static int voltage_set(int slot, int vcc, int vpp)
> +static inline void hardware_enable(int slot)
> {
> - u32 reg = 0;
> - unsigned *bcsr_io;
> -
> - bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
> -
> - switch(vcc) {
> - case 0:
> - break;
> - case 33:
> - reg |= BCSR1_PCCVCC0;
> - break;
> - case 50:
> - reg |= BCSR1_PCCVCC1;
> - break;
> - default:
> - goto out_unmap;
> - }
> -
> - switch(vpp) {
> - case 0:
> - break;
> - case 33:
> - case 50:
> - if(vcc == vpp)
> - reg |= BCSR1_PCCVPP1;
> - else
> - goto out_unmap;
> - break;
> - case 120:
> - if ((vcc == 33) || (vcc == 50))
> - reg |= BCSR1_PCCVPP0;
> - else
> - goto out_unmap;
> - default:
> - goto out_unmap;
> - }
> -
> - /* first, turn off all power */
> - out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK |
> BCSR1_PCCVPP_MASK));
> -
> - /* enable new powersettings */
> - out_be32(bcsr_io, in_be32(bcsr_io) | reg);
> -
> - iounmap(bcsr_io);
> - return 0;
> -
> -out_unmap:
> - iounmap(bcsr_io);
> - return 1;
> + m8xx_pcmcia_ops.hw_ctrl(slot, 1);
> }
>
> -#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
> -
> -static void hardware_enable(int slot)
> +static inline void hardware_disable(int slot)
> {
> - unsigned *bcsr_io;
> -
> - bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
> - out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN);
> - iounmap(bcsr_io);
> + m8xx_pcmcia_ops.hw_ctrl(slot, 0);
> }
>
> -static void hardware_disable(int slot)
> +static inline int voltage_set(int slot, int vcc, int vpp)
> {
> - unsigned *bcsr_io;
> -
> - bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
> - out_be32(bcsr_io, in_be32(bcsr_io) | BCSR1_PCCEN);
> - iounmap(bcsr_io);
> + return m8xx_pcmcia_ops.voltage_set(slot, vcc, vpp);
> }
>
> #endif
> @@ -604,48 +545,6 @@ static int voltage_set(int slot, int vcc, int
> vpp)
>
> #endif /* CONFIG_PRxK */
>
> -static void m8xx_shutdown(void)
> -{
> - u32 m, i;
> - struct pcmcia_win *w;
> -
> - for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
> - w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
> -
> - out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr,
> M8XX_PCMCIA_MASK(i));
> - out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, in_be32(&
> ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & ~M8XX_PCMCIA_MASK(i));
> -
> - /* turn off interrupt and disable CxOE */
> - out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
> -
> - /* turn off memory windows */
> - for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
> - out_be32(&w->or, 0); /* set to not valid */
> - w++;
> - }
> -
> - /* turn off voltage */
> - voltage_set(i, 0, 0);
> -
> - /* disable external hardware */
> - hardware_disable(i);
> - }
> -
> - free_irq(pcmcia_schlvl, NULL);
> -}
> -
> -static struct device_driver m8xx_driver = {
> - .name = "m8xx-pcmcia",
> - .bus = &platform_bus_type,
> - .suspend = pcmcia_socket_dev_suspend,
> - .resume = pcmcia_socket_dev_resume,
> -};
> -
> -static struct platform_device m8xx_device = {
> - .name = "m8xx-pcmcia",
> - .id = 0,
> -};
> -
> static u32 pending_events[PCMCIA_SOCKETS_NO];
> static DEFINE_SPINLOCK(pending_event_lock);
>
> @@ -654,13 +553,14 @@ static irqreturn_t m8xx_interrupt(int irq,
> void *dev)
> struct socket_info *s;
> struct event_table *e;
> unsigned int i, events, pscr, pipr, per;
> + pcmconf8xx_t *pcmcia = socket[0].pcmcia;
>
> dprintk("Interrupt!\n");
> /* get interrupt sources */
>
> - pscr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr);
> - pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
> - per = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per);
> + pscr = in_be32(&pcmcia->pcmc_pscr);
> + pipr = in_be32(&pcmcia->pcmc_pipr);
> + per = in_be32(&pcmcia->pcmc_per);
>
> for(i = 0; i < PCMCIA_SOCKETS_NO; i++) {
> s = &socket[i];
> @@ -724,7 +624,7 @@ static irqreturn_t m8xx_interrupt(int irq, void
> *dev)
> per &= ~M8XX_PCMCIA_RDY_L(0);
> per &= ~M8XX_PCMCIA_RDY_L(1);
>
> - out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, per);
> + out_be32(&pcmcia->pcmc_per, per);
>
> if (events)
> pcmcia_parse_events(&socket[i].socket, events);
> @@ -732,7 +632,7 @@ static irqreturn_t m8xx_interrupt(int irq, void
> *dev)
> }
>
> /* clear the interrupt sources */
> - out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, pscr);
> + out_be32(&pcmcia->pcmc_pscr, pscr);
>
> dprintk("Interrupt done.\n");
>
> @@ -753,7 +653,7 @@ static u32 m8xx_get_graycode(u32 size)
> return k;
> }
>
> -static u32 m8xx_get_speed(u32 ns, u32 is_io)
> +static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
> {
> u32 reg, clocks, psst, psl, psht;
>
> @@ -781,7 +681,7 @@ static u32 m8xx_get_speed(u32 ns, u32 is_io)
>
> #define ADJ 180 /* 80 % longer accesstime - to be sure */
>
> - clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
> + clocks = ((bus_freq / 1000) * ns) / 1000;
> clocks = (clocks * ADJ) / (100*1000);
> if(clocks >= PCMCIA_BMT_LIMIT) {
> printk( "Max access time limit reached\n");
> @@ -806,8 +706,9 @@ static int m8xx_get_status(struct pcmcia_socket
> *sock, unsigned int *value)
> int lsock = container_of(sock, struct socket_info, socket)->slot;
> struct socket_info *s = &socket[lsock];
> unsigned int pipr, reg;
> + pcmconf8xx_t *pcmcia = s->pcmcia;
>
> - pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
> + pipr = in_be32(&pcmcia->pcmc_pipr);
>
> *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
> | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
> @@ -918,6 +819,7 @@ static int m8xx_set_socket(struct pcmcia_socket
> *sock, socket_state_t *state)
> struct event_table *e;
> unsigned int reg;
> unsigned long flags;
> + pcmconf8xx_t *pcmcia = socket[0].pcmcia;
>
> dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
> "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
> @@ -927,6 +829,7 @@ static int m8xx_set_socket(struct pcmcia_socket
> *sock, socket_state_t *state)
> if(voltage_set(lsock, state->Vcc, state->Vpp))
> return -EINVAL;
>
> +
> /* Take care of reset... */
> if(state->flags & SS_RESET)
> out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) |
> M8XX_PGCRX_CXRESET); /* active high */
> @@ -982,7 +885,8 @@ static int m8xx_set_socket(struct pcmcia_socket
> *sock, socket_state_t *state)
> * If io_irq is non-zero we should enable irq.
> */
> if(state->io_irq) {
> - out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) |
> mk_int_int_mask(state->io_irq) << 24);
> + out_be32(M8XX_PGCRX(lsock),
> + in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(s->hwirq) << 24);
> /*
> * Strange thing here:
> * The manual does not tell us which interrupt
> @@ -1027,7 +931,7 @@ static int m8xx_set_socket(struct
> pcmcia_socket *sock, socket_state_t *state)
> * Writing ones will clear the bits.
> */
>
> - out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, reg);
> + out_be32(&pcmcia->pcmc_pscr, reg);
>
> /*
> * Write the mask.
> @@ -1036,15 +940,8 @@ static int m8xx_set_socket(struct
> pcmcia_socket *sock, socket_state_t *state)
> * Ones will enable the interrupt.
> */
>
> - /*
> - reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
> - & M8XX_PCMCIA_MASK(lsock);
> - */
> -
> - reg |= in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
> - (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
> -
> - out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, reg);
> + reg |= in_be32(&pcmcia->pcmc_per) & (M8XX_PCMCIA_MASK(0) |
> M8XX_PCMCIA_MASK(1));
> + out_be32(&pcmcia->pcmc_per, reg);
>
> spin_unlock_irqrestore(&events_lock, flags);
>
> @@ -1062,6 +959,8 @@ static int m8xx_set_io_map(struct
> pcmcia_socket *sock, struct pccard_io_map *io)
> struct socket_info *s = &socket[lsock];
> struct pcmcia_win *w;
> unsigned int reg, winnr;
> + pcmconf8xx_t *pcmcia = s->pcmcia;
> +
>
> #define M8XX_SIZE (io->stop - io->start + 1)
> #define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
> @@ -1086,7 +985,7 @@ static int m8xx_set_io_map(struct
> pcmcia_socket *sock, struct pccard_io_map *io)
>
> /* setup registers */
>
> - w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
> + w = (void *) &pcmcia->pcmc_pbr0;
> w += winnr;
>
> out_be32(&w->or, 0); /* turn off window first */
> @@ -1095,12 +994,13 @@ static int m8xx_set_io_map(struct
> pcmcia_socket *sock, struct pccard_io_map *io)
> reg <<= 27;
> reg |= M8XX_PCMCIA_POR_IO |(lsock << 2);
>
> - reg |= m8xx_get_speed(io->speed, 1);
> + reg |= m8xx_get_speed(io->speed, 1, s->bus_freq);
>
> if(io->flags & MAP_WRPROT)
> reg |= M8XX_PCMCIA_POR_WRPROT;
>
> - if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
> + /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
> + if(io->flags & MAP_16BIT)
> reg |= M8XX_PCMCIA_POR_16BIT;
>
> if(io->flags & MAP_ACTIVE)
> @@ -1117,7 +1017,7 @@ static int m8xx_set_io_map(struct
> pcmcia_socket *sock, struct pccard_io_map *io)
>
> /* setup registers */
>
> - w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
> + w = (void *) &pcmcia->pcmc_pbr0;
> w += winnr;
>
> out_be32(&w->or, 0); /* turn off window */
> @@ -1144,6 +1044,7 @@ static int m8xx_set_mem_map(struct
> pcmcia_socket *sock, struct pccard_mem_map *m
> struct pcmcia_win *w;
> struct pccard_mem_map *old;
> unsigned int reg, winnr;
> + pcmconf8xx_t *pcmcia = s->pcmcia;
>
> dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, "
> "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
> @@ -1166,12 +1067,12 @@ static int m8xx_set_mem_map(struct
> pcmcia_socket *sock, struct pccard_mem_map *m
>
> /* Setup the window in the pcmcia controller */
>
> - w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
> + w = (void *) &pcmcia->pcmc_pbr0;
> w += winnr;
>
> reg |= lsock << 2;
>
> - reg |= m8xx_get_speed(mem->speed, 0);
> + reg |= m8xx_get_speed(mem->speed, 0, s->bus_freq);
>
> if(mem->flags & MAP_ATTRIB)
> reg |= M8XX_PCMCIA_POR_ATTRMEM;
> @@ -1236,60 +1137,69 @@ static int m8xx_sock_init(struct
> pcmcia_socket *sock)
>
> }
>
> -static int m8xx_suspend(struct pcmcia_socket *sock)
> +static int m8xx_sock_suspend(struct pcmcia_socket *sock)
> {
> return m8xx_set_socket(sock, &dead_socket);
> }
>
> static struct pccard_operations m8xx_services = {
> .init = m8xx_sock_init,
> - .suspend = m8xx_suspend,
> + .suspend = m8xx_sock_suspend,
> .get_status = m8xx_get_status,
> .set_socket = m8xx_set_socket,
> .set_io_map = m8xx_set_io_map,
> .set_mem_map = m8xx_set_mem_map,
> };
>
> -static int __init m8xx_init(void)
> +static int __init m8xx_probe(struct of_device *ofdev, const struct
> of_device_id *match)
> {
> struct pcmcia_win *w;
> - unsigned int i,m;
> + unsigned int i, m, hwirq;
> + pcmconf8xx_t *pcmcia;
> + int status;
> + struct device_node *np = ofdev->node;
>
> pcmcia_info("%s\n", version);
>
> - if (driver_register(&m8xx_driver))
> - return -1;
> + pcmcia = of_iomap(np, 0);
> + if(pcmcia == NULL)
> + return -EINVAL;
> +
> + pcmcia_schlvl = irq_of_parse_and_map(np, 0);
> + hwirq = irq_map[pcmcia_schlvl].hwirq;
> + if (pcmcia_schlvl < 0)
> + return -EINVAL;
> +
> + m8xx_pgcrx[0] = &pcmcia->pcmc_pgcra;
> + m8xx_pgcrx[1] = &pcmcia->pcmc_pgcrb;
> +
>
> pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
> - " with IRQ %u.\n", pcmcia_schlvl);
> + " with IRQ %u (%d). \n", pcmcia_schlvl, hwirq);
>
> /* Configure Status change interrupt */
>
> - if(request_irq(pcmcia_schlvl, m8xx_interrupt, 0,
> - "m8xx_pcmcia", NULL)) {
> + if(request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
> + driver_name, socket)) {
> pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
> pcmcia_schlvl);
> return -1;
> }
>
> - w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
> -
> - out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr,
> - M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
> + w = (void *) &pcmcia->pcmc_pbr0;
>
> - out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per,
> - in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
> - ~(M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1)));
> + out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK
> (1));
> + clrbits32(&pcmcia->pcmc_per, M8XX_PCMCIA_MASK(0) |
> M8XX_PCMCIA_MASK(1));
>
> -/* connect interrupt and disable CxOE */
> + /* connect interrupt and disable CxOE */
>
> - out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask
> (pcmcia_schlvl) << 16));
> - out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask
> (pcmcia_schlvl) << 16));
> + out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq)
> << 16));
> + out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq)
> << 16));
>
> -/* intialize the fixed memory windows */
> + /* intialize the fixed memory windows */
>
> for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
> - for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
> + for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
> out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
> (PCMCIA_MEM_WIN_SIZE
> * (m + i * PCMCIA_MEM_WIN_NO)));
> @@ -1300,16 +1210,14 @@ static int __init m8xx_init(void)
> }
> }
>
> -/* turn off voltage */
> + /* turn off voltage */
> voltage_set(0, 0, 0);
> voltage_set(1, 0, 0);
>
> -/* Enable external hardware */
> + /* Enable external hardware */
> hardware_enable(0);
> hardware_enable(1);
>
> - platform_device_register(&m8xx_device);
> -
> for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) {
> socket[i].slot = i;
> socket[i].socket.owner = THIS_MODULE;
> @@ -1317,30 +1225,105 @@ static int __init m8xx_init(void)
> socket[i].socket.irq_mask = 0x000;
> socket[i].socket.map_size = 0x1000;
> socket[i].socket.io_offset = 0;
> - socket[i].socket.pci_irq = i ? 7 : 9;
> + socket[i].socket.pci_irq = pcmcia_schlvl;
> socket[i].socket.ops = &m8xx_services;
> - socket[i].socket.resource_ops = &pccard_iodyn_ops;
> + socket[i].socket.resource_ops = &pccard_nonstatic_ops;
> socket[i].socket.cb_dev = NULL;
> - socket[i].socket.dev.parent = &m8xx_device.dev;
> + socket[i].socket.dev.parent = &ofdev->dev;
> + socket[i].pcmcia = pcmcia;
> + socket[i].bus_freq = ppc_proc_freq;
> + socket[i].hwirq = hwirq;
> +
> +
> }
>
> - for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
> - pcmcia_register_socket(&socket[i].socket);
> + for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
> + status = pcmcia_register_socket(&socket[i].socket);
> + if (status < 0)
> + pcmcia_error("Socket register failed\n");
> + }
>
> return 0;
> }
>
> -static void __exit m8xx_exit(void)
> +static int m8xx_remove(struct of_device* ofdev)
> {
> - int i;
> + u32 m, i;
> + struct pcmcia_win *w;
> + pcmconf8xx_t *pcmcia = socket[0].pcmcia;
> +
> + for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
> + w = (void *) &pcmcia->pcmc_pbr0;
> +
> + out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(i));
> + out_be32(&pcmcia->pcmc_per,
> + in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
>
> + /* turn off interrupt and disable CxOE */
> + out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
> +
> + /* turn off memory windows */
> + for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
> + out_be32(&w->or, 0); /* set to not valid */
> + w++;
> + }
> +
> + /* turn off voltage */
> + voltage_set(i, 0, 0);
> +
> + /* disable external hardware */
> + hardware_disable(i);
> + }
> for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
> pcmcia_unregister_socket(&socket[i].socket);
>
> - m8xx_shutdown();
> + free_irq(pcmcia_schlvl, NULL);
>
> - platform_device_unregister(&m8xx_device);
> - driver_unregister(&m8xx_driver);
> + return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int m8xx_suspend(struct platform_device *pdev, pm_message_t
> state)
> +{
> + return pcmcia_socket_dev_suspend(&pdev->dev, state);
> +}
> +
> +static int m8xx_resume(struct platform_device *pdev)
> +{
> + return pcmcia_socket_dev_resume(&pdev->dev);
> +}
> +#else
> +#define m8xx_suspend NULL
> +#define m8xx_resume NULL
> +#endif
> +
> +static struct of_device_id m8xx_pcmcia_match[] = {
> + {
> + .type = "pcmcia",
> + .compatible = "fsl,pq-pcmcia",
> + },
> + {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
> +
> +static struct of_platform_driver m8xx_pcmcia_driver = {
> + .name = (char *) driver_name,
> + .match_table = m8xx_pcmcia_match,
> + .probe = m8xx_probe,
> + .remove = m8xx_remove,
> + .suspend = m8xx_suspend,
> + .resume = m8xx_resume,
> +};
> +
> +static int __init m8xx_init(void)
> +{
> + return of_register_platform_driver(&m8xx_pcmcia_driver);
> +}
> +
> +static void __exit m8xx_exit(void)
> +{
> + of_unregister_platform_driver(&m8xx_pcmcia_driver);
> }
>
> module_init(m8xx_init);
> diff --git a/include/asm-powerpc/mpc8xx.h b/include/asm-powerpc/
> mpc8xx.h
> index 5803711..c1a6efc 100644
> --- a/include/asm-powerpc/mpc8xx.h
> +++ b/include/asm-powerpc/mpc8xx.h
> @@ -23,6 +23,10 @@
> #include <platforms/8xx/mpc885ads.h>
> #endif
>
> +#ifdef CONFIG_PCMCIA_M8XX
> +extern struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
> +#endif
> +
> #endif /* CONFIG_8xx */
> #endif /* __CONFIG_8xx_DEFS */
> #endif /* __KERNEL__ */
> diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
> index 73710d6..12e631f 100644
> --- a/include/linux/fsl_devices.h
> +++ b/include/linux/fsl_devices.h
> @@ -120,5 +120,10 @@ struct fsl_spi_platform_data {
> u32 sysclk;
> };
>
> +struct mpc8xx_pcmcia_ops {
> + void(*hw_ctrl)(int slot, int enable);
> + int(*voltage_set)(int slot, int vcc, int vpp);
> +};
> +
> #endif /* _FSL_DEVICE_H_ */
> #endif /* __KERNEL__ */
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* RE: [PATCH v4 0/7] Add support for 750CL Holly board
From: Zang Roy-r61911 @ 2007-05-08 13:49 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev, paulus
In-Reply-To: <20070508104640.GM23995@crusty.rchland.ibm.com>
>=20
> On Tue, May 08, 2007 at 11:45:05AM +0800, Zang Roy-r61911 wrote:
> > >=20
> > > Hi All,
> > >=20
> > > This is round 4 of the patches to support the 750CL Holly=20
> board, and
> > > hopefully the last. They also fix one of the PCI issues=20
> I was seeing.
> > Sorry, Maybe I missed your previous comment.
> > What is the PCI issue? Associated with your board or tsi108/9 ?
>=20
> Mostly it was the fact that PIBS (the low level boot=20
> firmware) setup the PCI
> bridge in an odd fashion. The other small issue was that the=20
> TSI PCI bridge
> was not being designated as the primary. Both of these were=20
> found working
> with a developer from Tundra.
That is great.=20
I will test your patch on 7448hpc2 board tomorrow and give the feedback.
Roy
^ permalink raw reply
* Re: [PATCH] [POWERPC] 8xx: PQ SoC IRDA support
From: Kumar Gala @ 2007-05-08 13:33 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: Andrew Morton, linuxppc-dev, Samuel Ortiz, linux-kernel
In-Reply-To: <20070508013044.6407.20509.stgit@localhost.localdomain>
On May 7, 2007, at 8:30 PM, Vitaly Bordug wrote:
>
> Adds support of IRDA transceiver residing on PowerQUICC processors and
> enabling such on mpc885ads reference board. The driver is implemented
> using of_device concept, hereby implies arch/powerpc support of the
> target.
>
> Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
>
> Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
> ---
>
> arch/powerpc/Kconfig | 1
> arch/powerpc/boot/dts/mpc885ads.dts | 10
> arch/powerpc/platforms/8xx/mpc885ads_setup.c | 39 +
> arch/powerpc/sysdev/fsl_soc.c | 58 ++
> drivers/net/irda/Kconfig | 4
> drivers/net/irda/Makefile | 1
> drivers/net/irda/m8xx-sir.c | 715 +++++++++++++++
> +++++++++++
> include/asm-ppc/commproc.h | 67 ++
> 8 files changed, 895 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a8e08f4..c283907 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -605,6 +605,7 @@ endmenu
> config ISA_DMA_API
> bool
> default y
> + depends on !PPC_8xx
>
> menu "Bus options"
>
> diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/
> boot/dts/mpc885ads.dts
> index 110bf61..95b280c 100644
> --- a/arch/powerpc/boot/dts/mpc885ads.dts
> +++ b/arch/powerpc/boot/dts/mpc885ads.dts
> @@ -178,6 +178,16 @@
> interrupt-parent = <930>;
> phy-handle = <e8002>;
> };
> +
> + scc@a20 {
> + device_type = "network";
> + compatible = "fsl,irda";
is this specific enough? 52xx also has irda and I'm guessing they'd
require different drivers (haven't looked).
> + model = "SCC";
> + device-id = <2>;
> + reg = <a20 18 3d00 80>;
> + interrupts = <1d 3>;
> + interrupt-parent = <930>;
> + };
> };
> };
> };
[snip]
^ permalink raw reply
* Re: [PATCH] powerpc: add dts entries to 85xx for EDAC
From: Kumar Gala @ 2007-05-08 13:16 UTC (permalink / raw)
To: Dave Jiang; +Cc: linuxppc-dev, paulus
In-Reply-To: <20070507232634.GA11166@blade.az.mvista.com>
On May 7, 2007, at 6:26 PM, Dave Jiang wrote:
> Adding memory-controller and l2-cache-controller entries to be used
> by EDAC as
> of_devices.
we should distinguish the memory controllers on 8540/8560 (DDR1) from
the one on 8548 (DDR1 & DDR2).
- k
>
> Signed-off-by: Dave Jiang <djiang@mvista.com>
>
> ---
>
> arch/powerpc/boot/dts/mpc8540ads.dts | 16 ++++++++++++++++
> arch/powerpc/boot/dts/mpc8548cds.dts | 16 ++++++++++++++++
> arch/powerpc/boot/dts/mpc8560ads.dts | 18 +++++++++++++++++-
> 3 files changed, 49 insertions(+), 1 deletions(-)
>
> diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/
> boot/dts/mpc8540ads.dts
> index f261d64..f411bc1 100644
> --- a/arch/powerpc/boot/dts/mpc8540ads.dts
> +++ b/arch/powerpc/boot/dts/mpc8540ads.dts
> @@ -48,6 +48,22 @@
> reg = <e0000000 00100000>; // CCSRBAR 1M
> bus-frequency = <0>;
>
> + memory-controller@2000 {
> + compatible = "fsl,85xx-memory-controller";
> + reg = <2000 1000>;
> + interrupt-parent = <&mpic>;
> + interrupts = <2 2>;
> + };
> +
> + l2-cache-controller@20000 {
> + compatible = "fsl,85xx-memory-controller";
> + reg = <20000 1000>;
> + cache-line-size = <20>; // 32 bytes
> + cache-size = <40000>; // L2, 256K
> + interrupt-parent = <&mpic>;
> + interrupts = <0 2>;
> + };
> +
> i2c@3000 {
> device_type = "i2c";
> compatible = "fsl-i2c";
> diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/
> boot/dts/mpc8548cds.dts
> index b2b2200..9de5c3a 100644
> --- a/arch/powerpc/boot/dts/mpc8548cds.dts
> +++ b/arch/powerpc/boot/dts/mpc8548cds.dts
> @@ -48,6 +48,22 @@
> reg = <e0000000 00100000>; // CCSRBAR 1M
> bus-frequency = <0>;
>
> + memory-controller@2000 {
> + compatible = "fsl,85xx-memory-controller";
> + reg = <2000 1000>;
> + interrupt-parent = <&mpic>;
> + interrupts = <2 2>;
> + };
> +
> + l2-cache-controller@20000 {
> + compatible = "fsl,85xx-l2-cache-controller";
> + reg = <20000 1000>;
> + cache-line-size = <20>; // 32 bytes
> + cache-size = <40000>; // L2, 256K
> + interrupt-parent = <&mpic>;
> + interrupts = <0 2>;
> + };
> +
> i2c@3000 {
> device_type = "i2c";
> compatible = "fsl-i2c";
> diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/
> boot/dts/mpc8560ads.dts
> index 1f2afe9..6e59364 100644
> --- a/arch/powerpc/boot/dts/mpc8560ads.dts
> +++ b/arch/powerpc/boot/dts/mpc8560ads.dts
> @@ -48,6 +48,22 @@
> reg = <e0000000 00000200>;
> bus-frequency = <13ab6680>;
>
> + memory-controller@2000 {
> + compatible = "fsl,85xx-memory-controller";
> + reg = <2000 1000>;
> + interrupt-parent = <&mpic>;
> + interrupts = <2 2>;
> + };
> +
> + l2-cache-controller@20000 {
> + compatible = "fsl,85xx-l2-cache-controller";
> + reg = <20000 1000>;
> + cache-line-size = <20>; // 32 bytes
> + cache-size = <40000>; // L2, 256K
> + interrupt-parent = <&mpic>;
> + interrupts = <0 2>;
> + };
> +
> mdio@24520 {
> device_type = "mdio";
> compatible = "gianfar";
> @@ -110,7 +126,7 @@
> #address-cells = <3>;
> compatible = "85xx";
> device_type = "pci";
> - reg = <8000 400>;
> + reg = <8000 1000>;
> clock-frequency = <3f940aa>;
> interrupt-map-mask = <f800 0 0 7>;
> interrupt-map = <
^ permalink raw reply
* Re: [PATCH] ehea: Receive SKB Aggregation
From: Stephen Rothwell @ 2007-05-08 12:44 UTC (permalink / raw)
To: Thomas Klein
Cc: Thomas Klein, Jeff Garzik, Jan-Bernd Themann, netdev,
linux-kernel, Stefan Roscher, linux-ppc, Christoph Raisch,
Marcus Eder
In-Reply-To: <200705081405.33742.osstklei@de.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 407 bytes --]
On Tue, 8 May 2007 14:05:33 +0200 Thomas Klein <osstklei@de.ibm.com> wrote:
>
> +struct ehea_lro {
> + struct sk_buff *parent;
> + struct sk_buff *last_skb;
> + struct iphdr *iph;
> + struct tcphdr *tcph;
^^^^^^^^
Spaces instead of tabs.
Also in at least one other place in this patch.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: initramfs on PowerPC
From: Richard Danter @ 2007-05-08 12:41 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <463B833E.6070401@dlasys.net>
Hi David,
I did as you suggested, made a very small initramfs, and it worked!
All it contained was a simple "hello world" file plus a /dev/console node.
I then tried to increase the size of this small fs by adding a file (dd
if=/dev/urandom of=bigfatfile bs=1M count=1) but this then gives a CRC error
when I try to boot.
I have also tried increasing the default ramdisk size to 16MB but that makes
no difference.
Are there any limitrations to the size of the initramfs or on the contents of
this fs?
Any other suggestions?
Thanks!
Rich
On Friday 04 May 2007 20:02, David H. Lynch Jr. wrote:
> I tried numerous approaches, I never got anything to work except pointing
> CONFIG_INITRAMFS_SOURCE at a directory with my intramfs tree in it.
> I am sure other ways work, but I never managed to figure out what I was
> doing
> wrong. Regardless that has worked well for me.
>
> When I build I end up with a single file - zImage,.elf that has both my
> kernel
> and the initramfs tree in it. While there are a number of distro's that
> seem to
> use initramfs as a separate file - much like initrd, my loader has no
> provisions for a 2nd file, and the kernel build process wraps everything
> together
> which works fine for me.
>
> I have never seen your "junk in compressed archive" error, and I have
> been doing this
> for almost 2 years. But I have frequently had decompression errors.
> These typically
> have been the result of errors in the PPC zlib libraries. I beleive
> somewhere between
> 2.6.16 and 2.6.18 these libraries got updated, and the PPC version of
> the new ones
> had problems. Anyway, after 2.6.18 the new ones are good - though somehow
> once in a while the broken ones seem to creep into my development tree,
> but updating it usually fixes things.
>
> There also may be a total size issue. I am hazy on the details, but I
> beleive if the
> size of size of the kernel goes over 3mb that there are CONFIG values that
> may need to be changed. I am not sure whether that is compressed size
> decompressed size, kernel size, or combined kernel + initramfs size.
>
> Regardless, one suguestion would be to try with a very minimal initramfs
> tree
> and add things until it blows up.
>
> Richard Danter wrote:
> > Hi all,
> >
> > I am having a problem booting a kernel with an initramfs. The kernel
> > version is 2.6.14. The target is a ppc 82xx board.
> >
> > I have tried both generating the cpio.gz file myself (find . | copi -o -H
> > newc | gzip > ../initramfs_data.cpio.gz) and pointing initramfs source to
> > a root FS directory (using xconfig) and then re-building my kernel.
> >
> > Usually the error is "junk in compressed archive" though I also see an
> > occasional error about padding.
> >
> > I am using U-Boot to load the kernel image (uImage).
> >
> > My host is SuSE 10.0 (x86), though I guess that shouldn't make any
> > difference (endianism?).
> >
> > Any thoughts on what I may be doing wrong?
> >
> > Thanks
> > Rich
> > _______________________________________________
> > Linuxppc-embedded mailing list
> > Linuxppc-embedded@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-embedded
^ permalink raw reply
* Re: [PATCH] ehea: Receive SKB Aggregation
From: Christoph Hellwig @ 2007-05-08 12:15 UTC (permalink / raw)
To: Thomas Klein
Cc: Thomas Klein, Jeff Garzik, Jan-Bernd Themann, netdev,
linux-kernel, Christoph Raisch, Stefan Roscher, linux-ppc,
Marcus Eder
In-Reply-To: <200705081405.33742.osstklei@de.ibm.com>
On Tue, May 08, 2007 at 02:05:33PM +0200, Thomas Klein wrote:
> This patch enables the receive side processing to aggregate TCP packets within
> the HEA device driver. It analyses the packets already received after a
> interrupt arrived and forwards these as a chains of SKBs for the same TCP
> connection with modified header field. We have seen a lower CPU load and
> improved throughput for small numbers of parallel TCP connections.
>
> We added a disabled module parameter to prevent disruption of normal driver
> operation.
> We currently consider this as "experimental" until further review and tests
> have been passed.
>
> Are there any concerns about including this in the mainline driver?
So we grow yet another LRO copy in drivers? I think someone needs to
bite the bullet and make it generic.
^ permalink raw reply
* [PATCH] ehea: Receive SKB Aggregation
From: Thomas Klein @ 2007-05-08 12:05 UTC (permalink / raw)
To: Jeff Garzik
Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
Christoph Raisch, Stefan Roscher, linux-ppc, Marcus Eder
This patch enables the receive side processing to aggregate TCP packets within
the HEA device driver. It analyses the packets already received after a
interrupt arrived and forwards these as a chains of SKBs for the same TCP
connection with modified header field. We have seen a lower CPU load and
improved throughput for small numbers of parallel TCP connections.
We added a disabled module parameter to prevent disruption of normal driver
operation.
We currently consider this as "experimental" until further review and tests
have been passed.
Are there any concerns about including this in the mainline driver?
Signed-off-by: Thomas Klein <tklein@de.ibm.com>
---
diff -Nurp -X dontdiff linux-2.6.22pre/drivers/net/ehea/ehea.h patched_kernel/drivers/net/ehea/ehea.h
--- linux-2.6.22pre/drivers/net/ehea/ehea.h 2007-05-07 15:55:43.000000000 +0200
+++ patched_kernel/drivers/net/ehea/ehea.h 2007-05-07 16:00:34.000000000 +0200
@@ -39,7 +39,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0058"
+#define DRV_VERSION "EHEA_0060"
#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -49,6 +49,7 @@
#define EHEA_MAX_ENTRIES_RQ3 16383
#define EHEA_MAX_ENTRIES_SQ 32767
#define EHEA_MIN_ENTRIES_QP 127
+#define EHEA_LRO_MAX_PKTS 60
#define EHEA_SMALL_QUEUES
#define EHEA_NUM_TX_QP 1
@@ -78,6 +79,9 @@
#define EHEA_RQ2_PKT_SIZE 1522
#define EHEA_L_PKT_SIZE 256 /* low latency */
+#define MAX_LRO_DESCRIPTORS 8
+#define LRO_DESC_MASK 0xFFFFFFFF
+
/* Send completion signaling */
/* Protection Domain Identifier */
@@ -334,6 +338,29 @@ struct ehea_q_skb_arr {
};
/*
+ * Large Receive Offload (LRO) descriptor for a tcp seesion
+ */
+struct ehea_lro {
+ struct sk_buff *parent;
+ struct sk_buff *last_skb;
+ struct iphdr *iph;
+ struct tcphdr *tcph;
+
+ u32 tcp_rcv_tsecr;
+ u32 tcp_rcv_tsval;
+ u32 tcp_ack;
+ u32 tcp_next_seq;
+ u32 skb_tot_frags_len;
+ u16 ip_tot_len;
+ u16 tcp_saw_tstamp; /* timestamps enabled */
+ u16 tcp_window;
+ u16 vlan_tag;
+ int skb_sg_cnt; /* counts aggregated skbs */
+ int vlan_packet;
+ int active;
+};
+
+/*
* Port resources
*/
struct ehea_port_res {
@@ -362,6 +389,9 @@ struct ehea_port_res {
u64 tx_packets;
u64 rx_packets;
u32 poll_counter;
+ struct ehea_lro lro[MAX_LRO_DESCRIPTORS];
+ u64 lro_desc;
+ struct port_stats p_state;
};
@@ -411,6 +441,7 @@ struct ehea_port {
u32 msg_enable;
u32 sig_comp_iv;
u32 state;
+ u32 lro_max_aggr;
u8 full_duplex;
u8 autoneg;
u8 num_def_qps;
diff -Nurp -X dontdiff linux-2.6.22pre/drivers/net/ehea/ehea_main.c patched_kernel/drivers/net/ehea/ehea_main.c
--- linux-2.6.22pre/drivers/net/ehea/ehea_main.c 2007-05-07 15:59:16.000000000 +0200
+++ patched_kernel/drivers/net/ehea/ehea_main.c 2007-05-07 16:00:34.000000000 +0200
@@ -34,6 +34,7 @@
#include <linux/list.h>
#include <linux/if_ether.h>
#include <net/ip.h>
+#include <net/tcp.h>
#include "ehea.h"
#include "ehea_qmr.h"
@@ -52,6 +53,8 @@ static int rq2_entries = EHEA_DEF_ENTRIE
static int rq3_entries = EHEA_DEF_ENTRIES_RQ3;
static int sq_entries = EHEA_DEF_ENTRIES_SQ;
static int use_mcs = 0;
+static int use_lro = 0;
+static int lro_max_pkts = EHEA_LRO_MAX_PKTS;
static int num_tx_qps = EHEA_NUM_TX_QP;
module_param(msg_level, int, 0);
@@ -60,6 +63,8 @@ module_param(rq2_entries, int, 0);
module_param(rq3_entries, int, 0);
module_param(sq_entries, int, 0);
module_param(use_mcs, int, 0);
+module_param(use_lro, int, 0);
+module_param(lro_max_pkts, int, 0);
module_param(num_tx_qps, int, 0);
MODULE_PARM_DESC(num_tx_qps, "Number of TX-QPS");
@@ -77,6 +82,9 @@ MODULE_PARM_DESC(sq_entries, " Number of
"[2^x - 1], x = [6..14]. Default = "
__MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")");
MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
+MODULE_PARM_DESC(lro_max_pkts, "LRO: Max packets to be aggregated. Default = "
+ __MODULE_STRING(EHEA_LRO_MAX_PKTS));
+MODULE_PARM_DESC(use_lro, "1: enable, 0: disable Large Reveive Offload ");
static int port_name_cnt = 0;
@@ -380,6 +388,282 @@ static int ehea_treat_poll_error(struct
return 0;
}
+static int try_get_ip_tcp_hdr(struct ehea_cqe *cqe, struct sk_buff *skb,
+ struct iphdr **iph, struct tcphdr **tcph)
+{
+ int ip_len;
+
+ /* non tcp/udp packets */
+ if (!cqe->header_length)
+ return -1;
+
+ /* non tcp packet */
+ *iph = (struct iphdr *)(skb->data);
+ if ((*iph)->protocol != IPPROTO_TCP)
+ return -1;
+
+ ip_len = (u8)((*iph)->ihl);
+ ip_len <<= 2;
+ *tcph = (struct tcphdr *)(((u64)*iph) + ip_len);
+
+ return 0;
+}
+
+#define TCP_PAYLOAD_LENGTH(iph, tcph) \
+(ntohs(iph->tot_len) - (iph->ihl << 2) - (tcph->doff << 2))
+
+#define IPH_LEN_WO_OPTIONS 5
+#define TCPH_LEN_WO_OPTIONS 5
+#define TCPH_LEN_W_TIMESTAMP 8
+
+static int lro_tcp_check(struct iphdr *iph, struct tcphdr *tcph,
+ int tcp_data_len, struct ehea_lro *lro)
+{
+ if (tcp_data_len == 0)
+ return -1;
+
+ if (iph->ihl != IPH_LEN_WO_OPTIONS)
+ return -1;
+
+ if (tcph->cwr || tcph->ece || tcph->urg || !tcph->ack || tcph->psh
+ || tcph->rst || tcph->syn || tcph->fin)
+ return -1;
+
+ if (INET_ECN_is_ce(ipv4_get_dsfield(iph)))
+ return -1;
+
+ if (tcph->doff != TCPH_LEN_WO_OPTIONS
+ && tcph->doff != TCPH_LEN_W_TIMESTAMP)
+ return -1;
+
+ /* check tcp options (only timestamp allowed) */
+ if (tcph->doff == TCPH_LEN_W_TIMESTAMP) {
+ u32 *topt = (u32 *)(tcph + 1);
+
+ if (*topt != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
+ | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))
+ return -1;
+
+ /* timestamp should be in right order */
+ topt++;
+ if (lro && (ntohl(lro->tcp_rcv_tsval) > ntohl(*topt)))
+ return -1;
+
+ /* timestamp reply should not be zero */
+ topt++;
+ if (*topt == 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static void update_tcp_ip_header(struct ehea_lro *lro)
+{
+ struct iphdr *iph = lro->iph;
+ struct tcphdr *tcph = lro->tcph;
+ u32 *p;
+
+ tcph->ack_seq = lro->tcp_ack;
+ tcph->window = lro->tcp_window;
+
+ if (lro->tcp_saw_tstamp) {
+ p = (u32 *)(tcph + 1);
+ *(p+2) = lro->tcp_rcv_tsecr;
+ }
+
+ iph->tot_len = htons(lro->ip_tot_len);
+ iph->check = 0;
+ iph->check = ip_fast_csum((u8 *)lro->iph, iph->ihl);
+}
+
+static void init_lro_desc(struct ehea_lro *lro, struct ehea_cqe *cqe,
+ struct sk_buff *skb, struct iphdr *iph,
+ struct tcphdr *tcph, u32 tcp_data_len)
+{
+ u32 *ptr;
+
+ lro->parent = skb;
+ lro->iph = iph;
+ lro->tcph = tcph;
+ lro->tcp_next_seq = ntohl(tcph->seq) + tcp_data_len;
+ lro->tcp_ack = ntohl(tcph->ack_seq);
+
+ lro->skb_sg_cnt = 1;
+ lro->ip_tot_len = ntohs(iph->tot_len);
+
+ if (tcph->doff == 8) {
+ ptr = (u32 *)(tcph+1);
+ lro->tcp_saw_tstamp = 1;
+ lro->tcp_rcv_tsval = *(ptr+1);
+ lro->tcp_rcv_tsecr = *(ptr+2);
+ }
+
+ if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) {
+ lro->vlan_packet = 1;
+ lro->vlan_tag = cqe->vlan_tag;
+ }
+
+ lro->active = 1;
+}
+
+static inline void clear_lro_desc(struct ehea_lro *lro)
+{
+ memset(lro, 0, sizeof(struct ehea_lro));
+}
+
+static void lro_add_packet(struct ehea_lro *lro, struct sk_buff *skb,
+ struct tcphdr *tcph, u32 tcp_len)
+{
+ struct sk_buff *parent = lro->parent;
+ u32 *topt;
+
+ lro->skb_sg_cnt++;
+
+ lro->ip_tot_len += tcp_len;
+ lro->tcp_next_seq += tcp_len;
+ lro->tcp_window = lro->tcph->window;
+ lro->tcp_ack = lro->tcph->ack_seq;
+
+ if (lro->tcp_saw_tstamp) {
+ topt = (u32 *) (tcph + 1);
+ lro->tcp_rcv_tsval = *(topt + 1);
+ lro->tcp_rcv_tsecr = *(topt + 2);
+ }
+
+ parent->len += tcp_len;
+ parent->data_len += tcp_len;
+
+ skb_pull(skb, (skb->len - tcp_len));
+ parent->truesize += skb->truesize;
+
+ if (lro->last_skb)
+ lro->last_skb->next = skb;
+ else
+ skb_shinfo(parent)->frag_list = skb;
+
+ lro->last_skb = skb;
+
+ return;
+}
+
+static int check_tcp_conn(struct ehea_lro *lro, struct iphdr *iph,
+ struct tcphdr *tcph)
+{
+ // fixme: compare source and destination at the same time? u64 compare?
+ if ((lro->iph->saddr != iph->saddr) || (lro->iph->daddr != iph->daddr) ||
+ (lro->tcph->source != tcph->source) || (lro->tcph->dest != tcph->dest))
+ return -1;
+ return 0;
+}
+
+static void flush_lro(struct ehea_port_res *pr, struct ehea_lro *lro)
+{
+ update_tcp_ip_header(lro);
+
+ if (lro->vlan_packet)
+ vlan_hwaccel_receive_skb(lro->parent, pr->port->vgrp,
+ lro->vlan_tag);
+ else
+ netif_receive_skb(lro->parent);
+
+ clear_lro_desc(lro);
+}
+
+static void flush_all_lro(struct ehea_port_res *pr)
+{
+ int i;
+ struct ehea_lro *lro;
+
+ for (i = 0; i < MAX_LRO_DESCRIPTORS; i++) {
+ lro = &pr->lro[i];
+ if (lro->active)
+ flush_lro(pr, lro);
+ }
+}
+
+static struct ehea_lro *ehea_get_lro(struct ehea_port_res *pr,
+ struct iphdr *iph, struct tcphdr *tcph)
+{
+ struct ehea_lro *lro = NULL;
+ struct ehea_lro *tmp;
+ int i;
+
+ for (i = 0; i < MAX_LRO_DESCRIPTORS; i++) {
+ tmp = &pr->lro[i];
+ if (tmp->active)
+ if (!check_tcp_conn(tmp, iph, tcph)) {
+ lro = tmp;
+ goto out;
+ }
+ }
+
+ for (i = 0; i < MAX_LRO_DESCRIPTORS; i++) {
+ if(!pr->lro[i].active) {
+ lro = &pr->lro[i];
+ goto out;
+ }
+ }
+
+out:
+ return lro;
+}
+
+static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe,
+ struct sk_buff *skb)
+{
+ struct iphdr *iph;
+ struct tcphdr *tcph;
+ struct ehea_lro *lro;
+ int tcp_data_len;
+ int skip_orig_skb = 0;
+
+ if (use_lro) {
+ if (try_get_ip_tcp_hdr(cqe, skb, &iph, &tcph))
+ goto out;
+
+ lro = ehea_get_lro(pr, iph, tcph);
+ if (!lro)
+ goto out;
+
+ tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
+
+ if (!lro->active) {
+ if (lro_tcp_check(iph, tcph, tcp_data_len, NULL))
+ goto out;
+
+ init_lro_desc(lro, cqe, skb, iph, tcph, tcp_data_len);
+ return;
+ }
+
+ if (lro->tcp_next_seq != ntohl(tcph->seq)) {
+ flush_lro(pr, lro);
+ goto out;
+ }
+
+ if (lro_tcp_check(iph, tcph, tcp_data_len, lro)) {
+ flush_lro(pr, lro);
+ goto out;
+ }
+
+ lro_add_packet(lro, skb, tcph, tcp_data_len);
+
+ if (lro->skb_sg_cnt > pr->port->lro_max_aggr)
+ flush_lro(pr, lro);
+
+ skip_orig_skb = 1;
+ }
+
+out:
+ if (skip_orig_skb)
+ return;
+
+ if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT)
+ vlan_hwaccel_receive_skb(skb, pr->port->vgrp, cqe->vlan_tag);
+ else
+ netif_receive_skb(skb);
+}
+
static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
struct ehea_port_res *pr,
int *budget)
@@ -426,9 +710,10 @@ static struct ehea_cqe *ehea_proc_rwqes(
if (!skb)
break;
}
- skb_copy_to_linear_data(skb, ((char*)cqe) + 64,
- cqe->num_bytes_transfered - 4);
- ehea_fill_skb(dev, skb, cqe);
+ skb_reserve(skb, NET_IP_ALIGN);
+ memcpy(skb->data, ((char*)cqe) + 64,
+ cqe->num_bytes_transfered - 4);
+ ehea_fill_skb(port->netdev, skb, cqe);
} else if (rq == 2) { /* RQ2 */
skb = get_skb_by_index(skb_arr_rq2,
skb_arr_rq2_len, cqe);
@@ -451,11 +736,7 @@ static struct ehea_cqe *ehea_proc_rwqes(
processed_rq3++;
}
- if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT)
- vlan_hwaccel_receive_skb(skb, port->vgrp,
- cqe->vlan_tag);
- else
- netif_receive_skb(skb);
+ ehea_proc_skb(pr, cqe, skb);
} else {
pr->p_stats.poll_receive_errors++;
port_reset = ehea_treat_poll_error(pr, rq, cqe,
@@ -467,6 +748,8 @@ static struct ehea_cqe *ehea_proc_rwqes(
cqe = ehea_poll_rq1(qp, &wqe_index);
}
+ flush_all_lro(pr);
+
pr->rx_packets += processed;
*budget -= processed;
@@ -1267,8 +1550,8 @@ static int ehea_clean_portres(struct ehe
static inline void write_ip_start_end(struct ehea_swqe *swqe,
const struct sk_buff *skb)
{
- swqe->ip_start = skb_network_offset(skb);
- swqe->ip_end = (u8)(swqe->ip_start + ip_hdrlen(skb) - 1);
+ swqe->ip_start = (u8)(((u64)ip_hdr(skb)) - ((u64)skb->data));
+ swqe->ip_end = (u8)(swqe->ip_start + ip_hdr(skb)->ihl * 4 - 1);
}
static inline void write_tcp_offset_end(struct ehea_swqe *swqe,
@@ -1305,13 +1588,13 @@ static void write_swqe2_TSO(struct sk_bu
/* copy only eth/ip/tcp headers to immediate data and
* the rest of skb->data to sg1entry
*/
- headersize = ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
+ headersize = ETH_HLEN + (ip_hdr(skb)->ihl * 4) + tcp_hdrlen(skb);
skb_data_size = skb->len - skb->data_len;
if (skb_data_size >= headersize) {
/* copy immediate data */
- skb_copy_from_linear_data(skb, imm_data, headersize);
+ memcpy(imm_data, skb->data, headersize);
swqe->immediate_data_length = headersize;
if (skb_data_size > headersize) {
@@ -1342,7 +1625,7 @@ static void write_swqe2_nonTSO(struct sk
*/
if (skb_data_size >= SWQE2_MAX_IMM) {
/* copy immediate data */
- skb_copy_from_linear_data(skb, imm_data, SWQE2_MAX_IMM);
+ memcpy(imm_data, skb->data, SWQE2_MAX_IMM);
swqe->immediate_data_length = SWQE2_MAX_IMM;
@@ -1355,7 +1638,7 @@ static void write_swqe2_nonTSO(struct sk
swqe->descriptors++;
}
} else {
- skb_copy_from_linear_data(skb, imm_data, skb_data_size);
+ memcpy(imm_data, skb->data, skb_data_size);
swqe->immediate_data_length = skb_data_size;
}
}
@@ -1683,9 +1966,15 @@ out:
static int ehea_change_mtu(struct net_device *dev, int new_mtu)
{
+ struct ehea_port *port = netdev_priv(dev);
+
if ((new_mtu < 68) || (new_mtu > EHEA_MAX_PACKET_SIZE))
return -EINVAL;
dev->mtu = new_mtu;
+
+ if (use_lro)
+ port->lro_max_aggr = (0xFFFF / new_mtu);
+
return 0;
}
@@ -1693,7 +1982,6 @@ static void ehea_xmit2(struct sk_buff *s
struct ehea_swqe *swqe, u32 lkey)
{
if (skb->protocol == htons(ETH_P_IP)) {
- const struct iphdr *iph = ip_hdr(skb);
/* IPv4 */
swqe->tx_control |= EHEA_SWQE_CRC
| EHEA_SWQE_IP_CHECKSUM
@@ -1703,15 +1991,15 @@ static void ehea_xmit2(struct sk_buff *s
write_ip_start_end(swqe, skb);
- if (iph->protocol == IPPROTO_UDP) {
- if ((iph->frag_off & IP_MF) ||
- (iph->frag_off & IP_OFFSET))
+ if (ip_hdr(skb)->protocol == IPPROTO_UDP) {
+ if ((ip_hdr(skb)->frag_off & IP_MF) ||
+ (ip_hdr(skb)->frag_off & IP_OFFSET))
/* IP fragment, so don't change cs */
swqe->tx_control &= ~EHEA_SWQE_TCP_CHECKSUM;
else
write_udp_offset_end(swqe, skb);
- } else if (iph->protocol == IPPROTO_TCP) {
+ } else if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
write_tcp_offset_end(swqe, skb);
}
@@ -1737,11 +2025,10 @@ static void ehea_xmit3(struct sk_buff *s
int i;
if (skb->protocol == htons(ETH_P_IP)) {
- const struct iphdr *iph = ip_hdr(skb);
/* IPv4 */
write_ip_start_end(swqe, skb);
- if (iph->protocol == IPPROTO_TCP) {
+ if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
swqe->tx_control |= EHEA_SWQE_CRC
| EHEA_SWQE_IP_CHECKSUM
| EHEA_SWQE_TCP_CHECKSUM
@@ -1749,9 +2036,9 @@ static void ehea_xmit3(struct sk_buff *s
write_tcp_offset_end(swqe, skb);
- } else if (iph->protocol == IPPROTO_UDP) {
- if ((iph->frag_off & IP_MF) ||
- (iph->frag_off & IP_OFFSET))
+ } else if (ip_hdr(skb)->protocol == IPPROTO_UDP) {
+ if ((ip_hdr(skb)->frag_off & IP_MF) ||
+ (ip_hdr(skb)->frag_off & IP_OFFSET))
/* IP fragment, so don't change cs */
swqe->tx_control |= EHEA_SWQE_CRC
| EHEA_SWQE_IMM_DATA_PRESENT;
@@ -1777,11 +2064,10 @@ static void ehea_xmit3(struct sk_buff *s
/* copy (immediate) data */
if (nfrags == 0) {
/* data is in a single piece */
- skb_copy_from_linear_data(skb, imm_data, skb->len);
+ memcpy(imm_data, skb->data, skb->len);
} else {
/* first copy data from the skb->data buffer ... */
- skb_copy_from_linear_data(skb, imm_data,
- skb->len - skb->data_len);
+ memcpy(imm_data, skb->data, skb->len - skb->data_len);
imm_data += skb->len - skb->data_len;
/* ... then copy data from the fragments */
@@ -2492,6 +2778,7 @@ struct ehea_port *ehea_setup_single_port
struct ehea_port *port;
struct device *port_dev;
int jumbo;
+ int lro_pkts;
/* allocate memory for the port structures */
dev = alloc_etherdev(sizeof(struct ehea_port));
@@ -2566,6 +2853,12 @@ struct ehea_port *ehea_setup_single_port
goto out_unreg_port;
}
+ lro_pkts = (0xFFFF / dev->mtu);
+ if (lro_pkts < lro_max_pkts)
+ port->lro_max_aggr = lro_pkts;
+ else
+ port->lro_max_aggr = lro_max_pkts;
+
ret = ehea_get_jumboframe_status(port, &jumbo);
if (ret)
ehea_error("failed determining jumbo frame status for %s",
^ permalink raw reply
* Re: kernel expection generated with 2.6.21-mm1 kernel boot up
From: Srinivasa Ds @ 2007-05-08 12:04 UTC (permalink / raw)
To: Kamalesh Babulal; +Cc: linuxppc-dev, Balbir Singh
In-Reply-To: <463F1CA9.40501@linux.vnet.ibm.com>
Kamalesh Babulal wrote:
>
>
> Michael Ellerman wrote:
>> On Mon, 2007-05-07 at 16:30 +0530, Kamalesh Babulal wrote:
>>
>>> Hi,
>>>
>>> I tried compiling and booting up with 2.6.21-mm1 kernel
>>> on the following machine
>>>
>>> Architecture : PPC64
>>> CPU Type : POWER5 (gr)
>>> Machine Type : CHRP IBM,9117-570
>>> Base OS : Fedora Core 5
>>>
>>>
>>
>>
Looks like problem is in SLUB layer, I unmarked SLUB(CONFIG_SLUB)
option and now system is booting.
Thanks
Srinivasa DS
^ permalink raw reply
* Re: [PATCH v4 0/7] Add support for 750CL Holly board
From: Josh Boyer @ 2007-05-08 10:46 UTC (permalink / raw)
To: Zang Roy-r61911; +Cc: linuxppc-dev, paulus
In-Reply-To: <7EA18FDD2DC2154AA3BD6D2F22A62A0E753A11@zch01exm23.fsl.freescale.net>
On Tue, May 08, 2007 at 11:45:05AM +0800, Zang Roy-r61911 wrote:
> >
> > Hi All,
> >
> > This is round 4 of the patches to support the 750CL Holly board, and
> > hopefully the last. They also fix one of the PCI issues I was seeing.
> Sorry, Maybe I missed your previous comment.
> What is the PCI issue? Associated with your board or tsi108/9 ?
Mostly it was the fact that PIBS (the low level boot firmware) setup the PCI
bridge in an odd fashion. The other small issue was that the TSI PCI bridge
was not being designated as the primary. Both of these were found working
with a developer from Tundra.
josh
^ permalink raw reply
* Re: zImage.elf loads but does not start
From: Mirek23 @ 2007-05-08 9:46 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <463B5422.6030105@ru.mvista.com>
Thank you Andrei for your hint. I have hard-coded the mac address in the
arch/ppc/boot/simple/embed_config.c. Maybe it is not the most elegant
solution but it works.
Right now I was able to mount the root file system via nfs but it seems to
be still somthing missing:
[ 0.000000] Kernel command line: console=ttyUL0,9600 root=/dev/nfs rw
nfsroot
=129.129.130.106:/opt/eldk41/ppc_4xx,tcp macaddr=00:50:c2:46:d8:01
ip=129.129.10
7.50:129.129.130.106:129.129.107.1:255.255.255.0:ml403-mirek:eth0:off
panic=1
[ 0.000000] Xilinx INTC #0 at 0x41200000 mapped to 0xFDFFF000
[ 0.000000] PID hash table entries: 256 (order: 8, 1024 bytes)
[ 0.000424] Console: colour dummy device 80x25
[ 0.001483] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.003209] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.034369] Memory: 62720k available (1572k kernel code, 508k data, 96k
init,
0k highmem)
[ 0.121167] Mount-cache hash table entries: 512
[ 0.129517] NET: Registered protocol family 16
[ 0.166530] NET: Registered protocol family 2
[ 0.204693] IP route cache hash table entries: 1024 (order: 0, 4096
bytes)
[ 0.205867] TCP established hash table entries: 2048 (order: 2, 16384
bytes)
[ 0.206574] TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.207009] TCP: Hash tables configured (established 2048 bind 2048)
.
.
.
[ 2.670863] XTemac: using FIFO direct interrupt driven mode.
[ 2.739134] eth%d: XTemac: PHY detected at address 3.
[ 2.802585] eth0: Xilinx TEMAC #0 at 0x81200000 mapped to 0xC5040000,
irq=1
[ 2.886290] eth0: XTemac id 1.0f, block id 5, type 8
[ 2.947439] mice: PS/2 mouse device common for all mice
[ 3.010300] TCP cubic registered
[ 3.049323] NET: Registered protocol family 1
[ 3.101718] NET: Registered protocol family 17
[ 3.661970] eth0: XTemac: Options: 0xb8f2
[ 7.693861] eth0: XTemac: We renegotiated the speed to: 100
[ 7.760541] eth0: XTemac: speed set to 100Mb/s
[ 8.830367] IP-Config: Complete:
[ 8.867105] device=eth0, addr=129.129.107.50, mask=255.255.255.0,
gw=129.129.107.1,
[ 8.964390] host=ml403-mirek, domain=, nis-domain=(none),
[ 9.034414] bootserver=129.129.130.106, rootserver=129.129.130.106,
rootpath=
[ 9.130834] Looking up port of RPC 100003/2 on 129.129.130.106
[ 9.207363] Looking up port of RPC 100005/1 on 129.129.130.106
[ 9.303794] VFS: Mounted root (nfs filesystem).
[ 9.359316] Freeing unused kernel memory: 96k init
[ 9.422162] Warning: unable to open an initial console.
To satisfy last problem "unable to open an initial console" I have created
an entry in the /opt/eldk41/ppc_4xx/dev directory:
mknod ttyUL0 c 204 187
ln -s ttyUL0 console
I have rebooted the kernel once again and this time kernel has reached the
point as listed below.:
[ 8.964390] host=ml403-mirek, domain=, nis-domain=(none),
[ 9.034414] bootserver=129.129.130.106, rootserver=129.129.130.106,
rootpath=
[ 9.130834] Looking up port of RPC 100003/2 on 129.129.130.106
[ 9.207363] Looking up port of RPC 100005/1 on 129.129.130.106
[ 9.303794] VFS: Mounted root (nfs filesystem).
[ 9.359316] Freeing unused kernel memory: 96k init
I do not know if the console was taken into account or not (the warning has
disapeared but I am not able to ping
to my board nor telnet to it).
Any idea what could be wrong?
I use the root file system from eldk4.1:
/opt/eldk41/ppc_4xx/etc/inittab:
-------------------------------------------------------------------------------------------------------
id:3:initdefault:
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
# Run gettys in standard runlevels
3:2345:respawn:/sbin/mingetty --noclear console
-----------------------------------------------------------------------------------------------------------------------------------------
The contents of the /opt/eldk41/ppc_4xx/etc/rc3.d/ is as following:
K15appWeb K80random S12syslog
_S30mouse-emulation
K70mouse-emulation K90network _S20random S56xinetd
K75netfs S10network S25netfs S99local
--
View this message in context: http://www.nabble.com/zImage.elf-loads-but-not-starts-tf3607582.html#a10372619
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* [PATCH 3/3] [POWERPC] dts: kill hardcoded phandles
From: Vitaly Bordug @ 2007-05-08 9:50 UTC (permalink / raw)
To: linux-pcmcia; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20070508095001.20018.85403.stgit@localhost.localdomain>
Removed explicit linux,phandle usage. Using references and labels now in
PQ and PQ2 boards currently supported in arch/powerpc.
Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
---
arch/powerpc/boot/dts/mpc8272ads.dts | 42 +++++++++++---------------------
arch/powerpc/boot/dts/mpc866ads.dts | 31 ++++++++---------------
arch/powerpc/boot/dts/mpc885ads.dts | 45 +++++++++++++---------------------
3 files changed, 43 insertions(+), 75 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 423eedc..1934b80 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -14,12 +14,10 @@
compatible = "MPC8260ADS";
#address-cells = <1>;
#size-cells = <1>;
- linux,phandle = <100>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
- linux,phandle = <200>;
PowerPC,8272@0 {
device_type = "cpu";
@@ -32,12 +30,10 @@
bus-frequency = <0>;
clock-frequency = <0>;
32-bit;
- linux,phandle = <201>;
};
};
- interrupt-controller@f8200000 {
- linux,phandle = <f8200000>;
+ pci_pic: interrupt-controller@f8200000 {
#address-cells = <0>;
#interrupt-cells = <2>;
interrupt-controller;
@@ -47,15 +43,13 @@
};
memory {
device_type = "memory";
- linux,phandle = <300>;
reg = <00000000 4000000 f4500000 00000020>;
};
chosen {
name = "chosen";
linux,platform = <0>;
- interrupt-controller = <10c00>;
- linux,phandle = <400>;
+ interrupt-controller = <&Cpm_pic>;
};
soc8272@f0000000 {
@@ -70,20 +64,17 @@
device_type = "mdio";
compatible = "fs_enet";
reg = <0 0>;
- linux,phandle = <24520>;
#address-cells = <1>;
#size-cells = <0>;
- ethernet-phy@0 {
- linux,phandle = <2452000>;
- interrupt-parent = <10c00>;
+ phy0:ethernet-phy@0 {
+ interrupt-parent = <&Cpm_pic>;
interrupts = <17 4>;
reg = <0>;
bitbang = [ 12 12 13 02 02 01 ];
device_type = "ethernet-phy";
};
- ethernet-phy@1 {
- linux,phandle = <2452001>;
- interrupt-parent = <10c00>;
+ phy1:ethernet-phy@1 {
+ interrupt-parent = <&Cpm_pic>;
interrupts = <17 4>;
bitbang = [ 12 12 13 02 02 01 ];
reg = <3>;
@@ -101,8 +92,8 @@
reg = <11300 20 8400 100 11380 30>;
mac-address = [ 00 11 2F 99 43 54 ];
interrupts = <20 2>;
- interrupt-parent = <10c00>;
- phy-handle = <2452000>;
+ interrupt-parent = <&Cpm_pic>;
+ phy-handle = <&Phy0>;
rx-clock = <13>;
tx-clock = <12>;
};
@@ -115,14 +106,13 @@
reg = <11320 20 8500 100 113b0 30>;
mac-address = [ 00 11 2F 99 44 54 ];
interrupts = <21 2>;
- interrupt-parent = <10c00>;
- phy-handle = <2452001>;
+ interrupt-parent = <&Cpm_pic>;
+ phy-handle = <&Phy1>;
rx-clock = <17>;
tx-clock = <18>;
};
cpm@f0000000 {
- linux,phandle = <f0000000>;
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
@@ -142,7 +132,7 @@
reg = <11a00 20 8000 100>;
current-speed = <1c200>;
interrupts = <28 2>;
- interrupt-parent = <10c00>;
+ interrupt-parent = <&Cpm_pic>;
clock-setup = <0 00ffffff>;
rx-clock = <1>;
tx-clock = <1>;
@@ -156,15 +146,14 @@
reg = <11a60 20 8300 100>;
current-speed = <1c200>;
interrupts = <2b 2>;
- interrupt-parent = <10c00>;
+ interrupt-parent = <&Cpm_pic>;
clock-setup = <1b ffffff00>;
rx-clock = <4>;
tx-clock = <4>;
};
};
- interrupt-controller@10c00 {
- linux,phandle = <10c00>;
+ cpm_pic:interrupt-controller@10c00 {
#address-cells = <0>;
#interrupt-cells = <2>;
interrupt-controller;
@@ -174,7 +163,6 @@
compatible = "CPM2";
};
pci@0500 {
- linux,phandle = <0500>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
@@ -202,7 +190,7 @@
c000 0 0 2 f8200000 43 8
c000 0 0 3 f8200000 40 8
c000 0 0 4 f8200000 41 8>;
- interrupt-parent = <10c00>;
+ interrupt-parent = <&Cpm_pic>;
interrupts = <14 8>;
bus-range = <0 0>;
ranges = <02000000 0 80000000 80000000 0 40000000
@@ -216,7 +204,7 @@
compatible = "talitos";
reg = <30000 10000>;
interrupts = <b 2>;
- interrupt-parent = <10c00>;
+ interrupt-parent = <&Cpm_pic>;
num-channels = <4>;
channel-fifo-len = <18>;
exec-units-mask = <0000007e>;
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index c0d06fd..e5e7726 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -15,12 +15,10 @@
compatible = "mpc8xx";
#address-cells = <1>;
#size-cells = <1>;
- linux,phandle = <100>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
- linux,phandle = <200>;
PowerPC,866@0 {
device_type = "cpu";
@@ -34,14 +32,12 @@
clock-frequency = <0>;
32-bit;
interrupts = <f 2>; // decrementer interrupt
- interrupt-parent = <ff000000>;
- linux,phandle = <201>;
+ interrupt-parent = <&Mpc8xx_pic>;
};
};
memory {
device_type = "memory";
- linux,phandle = <300>;
reg = <00000000 800000>;
};
@@ -57,11 +53,9 @@
device_type = "mdio";
compatible = "fs_enet";
reg = <e80 8>;
- linux,phandle = <e80>;
#address-cells = <1>;
#size-cells = <0>;
- ethernet-phy@f {
- linux,phandle = <e800f>;
+ phy: ethernet-phy@f {
reg = <f>;
device_type = "ethernet-phy";
};
@@ -75,12 +69,11 @@
reg = <e00 188>;
mac-address = [ 00 00 0C 00 01 FD ];
interrupts = <3 1>;
- interrupt-parent = <ff000000>;
- phy-handle = <e800f>;
+ interrupt-parent = <&Mpc8xx_pic>;
+ phy-handle = <&Phy>;
};
- pic@ff000000 {
- linux,phandle = <ff000000>;
+ mpc8xx_pic: pic@ff000000 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
@@ -91,7 +84,6 @@
};
cpm@ff000000 {
- linux,phandle = <ff000000>;
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
@@ -102,15 +94,14 @@
command-proc = <9c0>;
brg-frequency = <0>;
interrupts = <0 2>; // cpm error interrupt
- interrupt-parent = <930>;
+ interrupt-parent = <&Cpm_pic>;
- pic@930 {
- linux,phandle = <930>;
+ cpm_pic: pic@930 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
interrupts = <5 2 0 2>;
- interrupt-parent = <ff000000>;
+ interrupt-parent = <&Mpc8xx_pic>;
reg = <930 20>;
built-in;
device_type = "cpm-pic";
@@ -128,7 +119,7 @@
tx-clock = <1>;
current-speed = <0>;
interrupts = <4 3>;
- interrupt-parent = <930>;
+ interrupt-parent = <&Cpm_pic>;
};
smc@a90 {
@@ -142,7 +133,7 @@
tx-clock = <2>;
current-speed = <0>;
interrupts = <3 3>;
- interrupt-parent = <930>;
+ interrupt-parent = <&Cpm_pic>;
};
scc@a00 {
@@ -153,7 +144,7 @@
reg = <a00 18 3c00 80>;
mac-address = [ 00 00 0C 00 03 FD ];
interrupts = <1e 3>;
- interrupt-parent = <930>;
+ interrupt-parent = <&Cpm_pic>;
};
};
};
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 0786ac1..2b2fec8 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -15,12 +15,10 @@
compatible = "mpc8xx";
#address-cells = <1>;
#size-cells = <1>;
- linux,phandle = <100>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
- linux,phandle = <200>;
PowerPC,885@0 {
device_type = "cpu";
@@ -34,14 +32,12 @@
clock-frequency = <0>;
32-bit;
interrupts = <f 2>; // decrementer interrupt
- interrupt-parent = <ff000000>;
- linux,phandle = <201>;
+ interrupt-parent = <&Mpc8xx_pic>;
};
};
memory {
device_type = "memory";
- linux,phandle = <300>;
reg = <00000000 800000>;
};
@@ -57,21 +53,17 @@
device_type = "mdio";
compatible = "fs_enet";
reg = <e80 8>;
- linux,phandle = <e80>;
#address-cells = <1>;
#size-cells = <0>;
- ethernet-phy@0 {
- linux,phandle = <e8000>;
+ Phy0: ethernet-phy@0 {
reg = <0>;
device_type = "ethernet-phy";
};
- ethernet-phy@1 {
- linux,phandle = <e8001>;
+ Phy1: ethernet-phy@1 {
reg = <1>;
device_type = "ethernet-phy";
};
- ethernet-phy@2 {
- linux,phandle = <e8002>;
+ Phy2: ethernet-phy@2 {
reg = <2>;
device_type = "ethernet-phy";
};
@@ -85,8 +77,8 @@
reg = <e00 188>;
mac-address = [ 00 00 0C 00 01 FD ];
interrupts = <3 1>;
- interrupt-parent = <ff000000>;
- phy-handle = <e8000>;
+ interrupt-parent = <&Mpc8xx_pic>;
+ phy-handle = <&Phy1>;
};
fec@1e00 {
@@ -97,12 +89,11 @@
reg = <1e00 188>;
mac-address = [ 00 00 0C 00 02 FD ];
interrupts = <7 1>;
- interrupt-parent = <ff000000>;
- phy-handle = <e8001>;
+ interrupt-parent = <&Mpc8xx_pic>;
+ phy-handle = <&Phy2>;
};
- pic@ff000000 {
- linux,phandle = <ff000000>;
+ Mpc8xx_pic: pic@ff000000 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
@@ -120,12 +111,11 @@
device_type = "pcmcia";
reg = <80 80>;
clock-frequency = <2faf080>;
- interrupt-parent = <&mpc8xx-pic>;
+ interrupt-parent = <&Mpc8xx_pic>;
interrupts = <d 1>;
};
cpm@ff000000 {
- linux,phandle = <ff000000>;
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
@@ -136,15 +126,14 @@
command-proc = <9c0>;
brg-frequency = <0>;
interrupts = <0 2>; // cpm error interrupt
- interrupt-parent = <930>;
+ interrupt-parent = <&Cpm_pic>;
- pic@930 {
- linux,phandle = <930>;
+ Cpm_pic: pic@930 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
interrupts = <5 2 0 2>;
- interrupt-parent = <ff000000>;
+ interrupt-parent = <&Mpc8xx_pic>;
reg = <930 20>;
built-in;
device_type = "cpm-pic";
@@ -162,7 +151,7 @@
tx-clock = <1>;
current-speed = <0>;
interrupts = <4 3>;
- interrupt-parent = <930>;
+ interrupt-parent = <&Cpm_pic>;
};
smc@a90 {
@@ -176,7 +165,7 @@
tx-clock = <2>;
current-speed = <0>;
interrupts = <3 3>;
- interrupt-parent = <930>;
+ interrupt-parent = <&Cpm_pic>;
};
scc@a40 {
@@ -187,8 +176,8 @@
reg = <a40 18 3e00 80>;
mac-address = [ 00 00 0C 00 03 FD ];
interrupts = <1c 3>;
- interrupt-parent = <930>;
- phy-handle = <e8002>;
+ interrupt-parent = <&Cpm_pic>;
+ phy-handle = <&Phy2>;
};
};
};
^ permalink raw reply related
* [PATCH 1/3] [POWERPC] 8xx: mpc885ads pcmcia support
From: Vitaly Bordug @ 2007-05-08 9:50 UTC (permalink / raw)
To: linux-pcmcia; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20070508095001.20018.85403.stgit@localhost.localdomain>
Adds support for PowerQuicc on-chip PCMCIA. The driver is implemented as
of_device, so only arch/powerpc stuff is capable to use it, which now
implies only mpc885ads reference board.
To cope with the code that should be hooked inside driver, but is really
board specific (like set_voltage), global structure mpc8xx_pcmcia_ops
holds necessary function pointers that are filled in the BSP code.
Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Olof Johansson <olof@lixom.net>
---
arch/powerpc/boot/dts/mpc885ads.dts | 12 +
arch/powerpc/platforms/8xx/m8xx_setup.c | 5
arch/powerpc/platforms/8xx/mpc885ads.h | 8 +
arch/powerpc/platforms/8xx/mpc885ads_setup.c | 72 +++++
arch/powerpc/sysdev/fsl_soc.c | 13 +
arch/powerpc/sysdev/mpc8xx_pic.h | 2
drivers/pcmcia/Kconfig | 1
drivers/pcmcia/m8xx_pcmcia.c | 351 ++++++++++++--------------
include/asm-powerpc/mpc8xx.h | 4
include/linux/fsl_devices.h | 5
10 files changed, 287 insertions(+), 186 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 110bf61..0786ac1 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -112,6 +112,18 @@
compatible = "CPM";
};
+ pcmcia@0080 {
+ #address-cells = <3>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ compatible = "fsl,pq-pcmcia";
+ device_type = "pcmcia";
+ reg = <80 80>;
+ clock-frequency = <2faf080>;
+ interrupt-parent = <&mpc8xx-pic>;
+ interrupts = <d 1>;
+ };
+
cpm@ff000000 {
linux,phandle = <ff000000>;
#address-cells = <1>;
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 0901dba..f169355 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -32,6 +32,7 @@
#include <linux/root_dev.h>
#include <linux/time.h>
#include <linux/rtc.h>
+#include <linux/fsl_devices.h>
#include <asm/mmu.h>
#include <asm/reg.h>
@@ -49,6 +50,10 @@
#include "sysdev/mpc8xx_pic.h"
+#ifdef CONFIG_PCMCIA_M8XX
+struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
+#endif
+
void m8xx_calibrate_decr(void);
extern void m8xx_wdt_handler_install(bd_t *bp);
extern int cpm_pic_init(void);
diff --git a/arch/powerpc/platforms/8xx/mpc885ads.h b/arch/powerpc/platforms/8xx/mpc885ads.h
index 7c31aec..932b59a 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads.h
+++ b/arch/powerpc/platforms/8xx/mpc885ads.h
@@ -91,5 +91,13 @@
#define SICR_ENET_MASK ((uint)0x00ff0000)
#define SICR_ENET_CLKRT ((uint)0x002c0000)
+/*
+ * Some internal interrupt registers use an 8-bit mask for the interrupt
+ * level instead of a number.
+ */
+static inline uint mk_int_int_mask(uint mask) {
+ return (1 << (7 - (mask/2)));
+}
+
#endif /* __ASM_MPC885ADS_H__ */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index a57b577..80e7214 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -22,6 +22,7 @@
#include <linux/fs_enet_pd.h>
#include <linux/fs_uart_pd.h>
+#include <linux/fsl_devices.h>
#include <linux/mii.h>
#include <asm/delay.h>
@@ -51,6 +52,70 @@ static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi);
static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
static void init_scc3_ioports(struct fs_platform_info* ptr);
+#ifdef CONFIG_PCMCIA_M8XX
+static void pcmcia_hw_setup(int slot, int enable)
+{
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+ if (enable)
+ clrbits32(bcsr_io, BCSR1_PCCEN);
+ else
+ setbits32(bcsr_io, BCSR1_PCCEN);
+
+ iounmap(bcsr_io);
+}
+
+static int pcmcia_set_voltage(int slot, int vcc, int vpp)
+{
+ u32 reg = 0;
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ switch(vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= BCSR1_PCCVCC0;
+ break;
+ case 50:
+ reg |= BCSR1_PCCVCC1;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= BCSR1_PCCVPP1;
+ else
+ return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= BCSR1_PCCVPP0;
+ else
+ return 1;
+ default:
+ return 1;
+ }
+
+ /* first, turn off all power */
+ clrbits32(bcsr_io, 0x00610000);
+
+ /* enable new powersettings */
+ setbits32(bcsr_io, reg);
+
+ iounmap(bcsr_io);
+ return 0;
+}
+#endif
+
void __init mpc885ads_board_setup(void)
{
cpm8xx_t *cp;
@@ -115,6 +180,12 @@ void __init mpc885ads_board_setup(void)
immr_unmap(io_port);
#endif
+
+#ifdef CONFIG_PCMCIA_M8XX
+ /*Set up board specific hook-ups*/
+ m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup;
+ m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage;
+#endif
}
@@ -322,6 +393,7 @@ void init_smc_ioports(struct fs_uart_platform_info *data)
}
}
+
int platform_device_skip(const char *model, int id)
{
#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 8a123c7..880e45f 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1028,6 +1028,19 @@ err:
arch_initcall(fs_enet_of_init);
+static int __init fsl_pcmcia_of_init(void)
+{
+ struct device_node *np = NULL;
+ /*
+ * Register all the devices which type is "pcmcia"
+ */
+ while ((np = of_find_compatible_node(np,
+ "pcmcia", "fsl,pq-pcmcia")) != NULL)
+ of_platform_device_create(np, "m8xx-pcmcia", NULL);
+ return 0;
+}
+
+arch_initcall(fsl_pcmcia_of_init);
static const char *smc_regs = "regs";
static const char *smc_pram = "pram";
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.h b/arch/powerpc/sysdev/mpc8xx_pic.h
index afa2ee6..b4a1d33 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.h
+++ b/arch/powerpc/sysdev/mpc8xx_pic.h
@@ -4,8 +4,6 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
-extern struct hw_interrupt_type mpc8xx_pic;
-
int mpc8xx_pic_init(void);
unsigned int mpc8xx_get_irq(void);
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 35f8864..c3fd55d 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -183,6 +183,7 @@ config PCMCIA_M8XX
tristate "MPC8xx PCMCIA support"
depends on PCMCIA && PPC && 8xx
select PCCARD_IODYN
+ select PCCARD_NONSTATIC
help
Say Y here to include support for PowerPC 8xx series PCMCIA
controller.
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 9721ed7..40f6e20 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -10,7 +10,7 @@
* Further fixes, v2.6 kernel port
* <marcelo.tosatti@cyclades.com>
*
- * Some fixes, additions (C) 2005 Montavista Software, Inc.
+ * Some fixes, additions (C) 2005-2007 Montavista Software, Inc.
* <vbordug@ru.mvista.com>
*
* "The ExCA standard specifies that socket controllers should provide
@@ -40,10 +40,6 @@
#include <linux/fcntl.h>
#include <linux/string.h>
-#include <asm/io.h>
-#include <asm/bitops.h>
-#include <asm/system.h>
-
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
@@ -51,11 +47,18 @@
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/system.h>
+#include <asm/time.h>
#include <asm/mpc8xx.h>
#include <asm/8xx_immap.h>
#include <asm/irq.h>
+#include <asm/fs_pd.h>
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
@@ -146,27 +149,17 @@ MODULE_LICENSE("Dual MPL/GPL");
#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
-
-#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level */
-
/* ------------------------------------------------------------------------- */
-/* 2.4.x and newer has this always in HZ */
-#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
-
-static int pcmcia_schlvl = PCMCIA_SCHLVL;
+static int pcmcia_schlvl;
static DEFINE_SPINLOCK(events_lock);
-
#define PCMCIA_SOCKET_KEY_5V 1
#define PCMCIA_SOCKET_KEY_LV 2
/* look up table for pgcrx registers */
-static u32 *m8xx_pgcrx[2] = {
- &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
- &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
-};
+static u32 *m8xx_pgcrx[2];
/*
* This structure is used to address each window in the PCMCIA controller.
@@ -228,11 +221,16 @@ struct event_table {
u32 eventbit;
};
+static const char driver_name[] = "m8xx-pcmcia";
+
struct socket_info {
void (*handler)(void *info, u32 events);
void *info;
u32 slot;
+ pcmconf8xx_t *pcmcia;
+ u32 bus_freq;
+ int hwirq;
socket_state_t state;
struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
@@ -408,78 +406,21 @@ static void hardware_disable(int slot)
#if defined(CONFIG_MPC885ADS)
#define PCMCIA_BOARD_MSG "MPC885ADS"
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
-static int voltage_set(int slot, int vcc, int vpp)
+static inline void hardware_enable(int slot)
{
- u32 reg = 0;
- unsigned *bcsr_io;
-
- bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
-
- switch(vcc) {
- case 0:
- break;
- case 33:
- reg |= BCSR1_PCCVCC0;
- break;
- case 50:
- reg |= BCSR1_PCCVCC1;
- break;
- default:
- goto out_unmap;
- }
-
- switch(vpp) {
- case 0:
- break;
- case 33:
- case 50:
- if(vcc == vpp)
- reg |= BCSR1_PCCVPP1;
- else
- goto out_unmap;
- break;
- case 120:
- if ((vcc == 33) || (vcc == 50))
- reg |= BCSR1_PCCVPP0;
- else
- goto out_unmap;
- default:
- goto out_unmap;
- }
-
- /* first, turn off all power */
- out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
-
- /* enable new powersettings */
- out_be32(bcsr_io, in_be32(bcsr_io) | reg);
-
- iounmap(bcsr_io);
- return 0;
-
-out_unmap:
- iounmap(bcsr_io);
- return 1;
+ m8xx_pcmcia_ops.hw_ctrl(slot, 1);
}
-#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
-
-static void hardware_enable(int slot)
+static inline void hardware_disable(int slot)
{
- unsigned *bcsr_io;
-
- bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
- out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN);
- iounmap(bcsr_io);
+ m8xx_pcmcia_ops.hw_ctrl(slot, 0);
}
-static void hardware_disable(int slot)
+static inline int voltage_set(int slot, int vcc, int vpp)
{
- unsigned *bcsr_io;
-
- bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
- out_be32(bcsr_io, in_be32(bcsr_io) | BCSR1_PCCEN);
- iounmap(bcsr_io);
+ return m8xx_pcmcia_ops.voltage_set(slot, vcc, vpp);
}
#endif
@@ -604,48 +545,6 @@ static int voltage_set(int slot, int vcc, int vpp)
#endif /* CONFIG_PRxK */
-static void m8xx_shutdown(void)
-{
- u32 m, i;
- struct pcmcia_win *w;
-
- for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
- w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
-
- out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, M8XX_PCMCIA_MASK(i));
- out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) & ~M8XX_PCMCIA_MASK(i));
-
- /* turn off interrupt and disable CxOE */
- out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
-
- /* turn off memory windows */
- for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
- out_be32(&w->or, 0); /* set to not valid */
- w++;
- }
-
- /* turn off voltage */
- voltage_set(i, 0, 0);
-
- /* disable external hardware */
- hardware_disable(i);
- }
-
- free_irq(pcmcia_schlvl, NULL);
-}
-
-static struct device_driver m8xx_driver = {
- .name = "m8xx-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
-};
-
-static struct platform_device m8xx_device = {
- .name = "m8xx-pcmcia",
- .id = 0,
-};
-
static u32 pending_events[PCMCIA_SOCKETS_NO];
static DEFINE_SPINLOCK(pending_event_lock);
@@ -654,13 +553,14 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
struct socket_info *s;
struct event_table *e;
unsigned int i, events, pscr, pipr, per;
+ pcmconf8xx_t *pcmcia = socket[0].pcmcia;
dprintk("Interrupt!\n");
/* get interrupt sources */
- pscr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr);
- pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
- per = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per);
+ pscr = in_be32(&pcmcia->pcmc_pscr);
+ pipr = in_be32(&pcmcia->pcmc_pipr);
+ per = in_be32(&pcmcia->pcmc_per);
for(i = 0; i < PCMCIA_SOCKETS_NO; i++) {
s = &socket[i];
@@ -724,7 +624,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
per &= ~M8XX_PCMCIA_RDY_L(0);
per &= ~M8XX_PCMCIA_RDY_L(1);
- out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, per);
+ out_be32(&pcmcia->pcmc_per, per);
if (events)
pcmcia_parse_events(&socket[i].socket, events);
@@ -732,7 +632,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
}
/* clear the interrupt sources */
- out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, pscr);
+ out_be32(&pcmcia->pcmc_pscr, pscr);
dprintk("Interrupt done.\n");
@@ -753,7 +653,7 @@ static u32 m8xx_get_graycode(u32 size)
return k;
}
-static u32 m8xx_get_speed(u32 ns, u32 is_io)
+static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
{
u32 reg, clocks, psst, psl, psht;
@@ -781,7 +681,7 @@ static u32 m8xx_get_speed(u32 ns, u32 is_io)
#define ADJ 180 /* 80 % longer accesstime - to be sure */
- clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
+ clocks = ((bus_freq / 1000) * ns) / 1000;
clocks = (clocks * ADJ) / (100*1000);
if(clocks >= PCMCIA_BMT_LIMIT) {
printk( "Max access time limit reached\n");
@@ -806,8 +706,9 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
int lsock = container_of(sock, struct socket_info, socket)->slot;
struct socket_info *s = &socket[lsock];
unsigned int pipr, reg;
+ pcmconf8xx_t *pcmcia = s->pcmcia;
- pipr = in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr);
+ pipr = in_be32(&pcmcia->pcmc_pipr);
*value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
| M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
@@ -918,6 +819,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
struct event_table *e;
unsigned int reg;
unsigned long flags;
+ pcmconf8xx_t *pcmcia = socket[0].pcmcia;
dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
"io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
@@ -927,6 +829,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
if(voltage_set(lsock, state->Vcc, state->Vpp))
return -EINVAL;
+
/* Take care of reset... */
if(state->flags & SS_RESET)
out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
@@ -982,7 +885,8 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
* If io_irq is non-zero we should enable irq.
*/
if(state->io_irq) {
- out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(state->io_irq) << 24);
+ out_be32(M8XX_PGCRX(lsock),
+ in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(s->hwirq) << 24);
/*
* Strange thing here:
* The manual does not tell us which interrupt
@@ -1027,7 +931,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
* Writing ones will clear the bits.
*/
- out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr, reg);
+ out_be32(&pcmcia->pcmc_pscr, reg);
/*
* Write the mask.
@@ -1036,15 +940,8 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
* Ones will enable the interrupt.
*/
- /*
- reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per
- & M8XX_PCMCIA_MASK(lsock);
- */
-
- reg |= in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
- (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
-
- out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per, reg);
+ reg |= in_be32(&pcmcia->pcmc_per) & (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
+ out_be32(&pcmcia->pcmc_per, reg);
spin_unlock_irqrestore(&events_lock, flags);
@@ -1062,6 +959,8 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
struct socket_info *s = &socket[lsock];
struct pcmcia_win *w;
unsigned int reg, winnr;
+ pcmconf8xx_t *pcmcia = s->pcmcia;
+
#define M8XX_SIZE (io->stop - io->start + 1)
#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
@@ -1086,7 +985,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
/* setup registers */
- w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+ w = (void *) &pcmcia->pcmc_pbr0;
w += winnr;
out_be32(&w->or, 0); /* turn off window first */
@@ -1095,12 +994,13 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
reg <<= 27;
reg |= M8XX_PCMCIA_POR_IO |(lsock << 2);
- reg |= m8xx_get_speed(io->speed, 1);
+ reg |= m8xx_get_speed(io->speed, 1, s->bus_freq);
if(io->flags & MAP_WRPROT)
reg |= M8XX_PCMCIA_POR_WRPROT;
- if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
+ /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
+ if(io->flags & MAP_16BIT)
reg |= M8XX_PCMCIA_POR_16BIT;
if(io->flags & MAP_ACTIVE)
@@ -1117,7 +1017,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
/* setup registers */
- w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+ w = (void *) &pcmcia->pcmc_pbr0;
w += winnr;
out_be32(&w->or, 0); /* turn off window */
@@ -1144,6 +1044,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
struct pcmcia_win *w;
struct pccard_mem_map *old;
unsigned int reg, winnr;
+ pcmconf8xx_t *pcmcia = s->pcmcia;
dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, "
"%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
@@ -1166,12 +1067,12 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
/* Setup the window in the pcmcia controller */
- w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+ w = (void *) &pcmcia->pcmc_pbr0;
w += winnr;
reg |= lsock << 2;
- reg |= m8xx_get_speed(mem->speed, 0);
+ reg |= m8xx_get_speed(mem->speed, 0, s->bus_freq);
if(mem->flags & MAP_ATTRIB)
reg |= M8XX_PCMCIA_POR_ATTRMEM;
@@ -1236,60 +1137,69 @@ static int m8xx_sock_init(struct pcmcia_socket *sock)
}
-static int m8xx_suspend(struct pcmcia_socket *sock)
+static int m8xx_sock_suspend(struct pcmcia_socket *sock)
{
return m8xx_set_socket(sock, &dead_socket);
}
static struct pccard_operations m8xx_services = {
.init = m8xx_sock_init,
- .suspend = m8xx_suspend,
+ .suspend = m8xx_sock_suspend,
.get_status = m8xx_get_status,
.set_socket = m8xx_set_socket,
.set_io_map = m8xx_set_io_map,
.set_mem_map = m8xx_set_mem_map,
};
-static int __init m8xx_init(void)
+static int __init m8xx_probe(struct of_device *ofdev, const struct of_device_id *match)
{
struct pcmcia_win *w;
- unsigned int i,m;
+ unsigned int i, m, hwirq;
+ pcmconf8xx_t *pcmcia;
+ int status;
+ struct device_node *np = ofdev->node;
pcmcia_info("%s\n", version);
- if (driver_register(&m8xx_driver))
- return -1;
+ pcmcia = of_iomap(np, 0);
+ if(pcmcia == NULL)
+ return -EINVAL;
+
+ pcmcia_schlvl = irq_of_parse_and_map(np, 0);
+ hwirq = irq_map[pcmcia_schlvl].hwirq;
+ if (pcmcia_schlvl < 0)
+ return -EINVAL;
+
+ m8xx_pgcrx[0] = &pcmcia->pcmc_pgcra;
+ m8xx_pgcrx[1] = &pcmcia->pcmc_pgcrb;
+
pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
- " with IRQ %u.\n", pcmcia_schlvl);
+ " with IRQ %u (%d). \n", pcmcia_schlvl, hwirq);
/* Configure Status change interrupt */
- if(request_irq(pcmcia_schlvl, m8xx_interrupt, 0,
- "m8xx_pcmcia", NULL)) {
+ if(request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
+ driver_name, socket)) {
pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
pcmcia_schlvl);
return -1;
}
- w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
-
- out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr,
- M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
+ w = (void *) &pcmcia->pcmc_pbr0;
- out_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per,
- in_be32(&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per) &
- ~(M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1)));
+ out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
+ clrbits32(&pcmcia->pcmc_per, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
-/* connect interrupt and disable CxOE */
+ /* connect interrupt and disable CxOE */
- out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16));
- out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(pcmcia_schlvl) << 16));
+ out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
+ out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
-/* intialize the fixed memory windows */
+ /* intialize the fixed memory windows */
for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
- for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+ for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
(PCMCIA_MEM_WIN_SIZE
* (m + i * PCMCIA_MEM_WIN_NO)));
@@ -1300,16 +1210,14 @@ static int __init m8xx_init(void)
}
}
-/* turn off voltage */
+ /* turn off voltage */
voltage_set(0, 0, 0);
voltage_set(1, 0, 0);
-/* Enable external hardware */
+ /* Enable external hardware */
hardware_enable(0);
hardware_enable(1);
- platform_device_register(&m8xx_device);
-
for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) {
socket[i].slot = i;
socket[i].socket.owner = THIS_MODULE;
@@ -1317,30 +1225,105 @@ static int __init m8xx_init(void)
socket[i].socket.irq_mask = 0x000;
socket[i].socket.map_size = 0x1000;
socket[i].socket.io_offset = 0;
- socket[i].socket.pci_irq = i ? 7 : 9;
+ socket[i].socket.pci_irq = pcmcia_schlvl;
socket[i].socket.ops = &m8xx_services;
- socket[i].socket.resource_ops = &pccard_iodyn_ops;
+ socket[i].socket.resource_ops = &pccard_nonstatic_ops;
socket[i].socket.cb_dev = NULL;
- socket[i].socket.dev.parent = &m8xx_device.dev;
+ socket[i].socket.dev.parent = &ofdev->dev;
+ socket[i].pcmcia = pcmcia;
+ socket[i].bus_freq = ppc_proc_freq;
+ socket[i].hwirq = hwirq;
+
+
}
- for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
- pcmcia_register_socket(&socket[i].socket);
+ for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
+ status = pcmcia_register_socket(&socket[i].socket);
+ if (status < 0)
+ pcmcia_error("Socket register failed\n");
+ }
return 0;
}
-static void __exit m8xx_exit(void)
+static int m8xx_remove(struct of_device* ofdev)
{
- int i;
+ u32 m, i;
+ struct pcmcia_win *w;
+ pcmconf8xx_t *pcmcia = socket[0].pcmcia;
+
+ for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
+ w = (void *) &pcmcia->pcmc_pbr0;
+
+ out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(i));
+ out_be32(&pcmcia->pcmc_per,
+ in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
+ /* turn off interrupt and disable CxOE */
+ out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
+
+ /* turn off memory windows */
+ for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+ out_be32(&w->or, 0); /* set to not valid */
+ w++;
+ }
+
+ /* turn off voltage */
+ voltage_set(i, 0, 0);
+
+ /* disable external hardware */
+ hardware_disable(i);
+ }
for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
pcmcia_unregister_socket(&socket[i].socket);
- m8xx_shutdown();
+ free_irq(pcmcia_schlvl, NULL);
- platform_device_unregister(&m8xx_device);
- driver_unregister(&m8xx_driver);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&pdev->dev, state);
+}
+
+static int m8xx_resume(struct platform_device *pdev)
+{
+ return pcmcia_socket_dev_resume(&pdev->dev);
+}
+#else
+#define m8xx_suspend NULL
+#define m8xx_resume NULL
+#endif
+
+static struct of_device_id m8xx_pcmcia_match[] = {
+ {
+ .type = "pcmcia",
+ .compatible = "fsl,pq-pcmcia",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
+
+static struct of_platform_driver m8xx_pcmcia_driver = {
+ .name = (char *) driver_name,
+ .match_table = m8xx_pcmcia_match,
+ .probe = m8xx_probe,
+ .remove = m8xx_remove,
+ .suspend = m8xx_suspend,
+ .resume = m8xx_resume,
+};
+
+static int __init m8xx_init(void)
+{
+ return of_register_platform_driver(&m8xx_pcmcia_driver);
+}
+
+static void __exit m8xx_exit(void)
+{
+ of_unregister_platform_driver(&m8xx_pcmcia_driver);
}
module_init(m8xx_init);
diff --git a/include/asm-powerpc/mpc8xx.h b/include/asm-powerpc/mpc8xx.h
index 5803711..c1a6efc 100644
--- a/include/asm-powerpc/mpc8xx.h
+++ b/include/asm-powerpc/mpc8xx.h
@@ -23,6 +23,10 @@
#include <platforms/8xx/mpc885ads.h>
#endif
+#ifdef CONFIG_PCMCIA_M8XX
+extern struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
+#endif
+
#endif /* CONFIG_8xx */
#endif /* __CONFIG_8xx_DEFS */
#endif /* __KERNEL__ */
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 73710d6..12e631f 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -120,5 +120,10 @@ struct fsl_spi_platform_data {
u32 sysclk;
};
+struct mpc8xx_pcmcia_ops {
+ void(*hw_ctrl)(int slot, int enable);
+ int(*voltage_set)(int slot, int vcc, int vpp);
+};
+
#endif /* _FSL_DEVICE_H_ */
#endif /* __KERNEL__ */
^ permalink raw reply related
* [PATCH 2/3] [POWERPC] 8xx: fix whitespace and indentation
From: Vitaly Bordug @ 2007-05-08 9:50 UTC (permalink / raw)
To: linux-pcmcia; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20070508095001.20018.85403.stgit@localhost.localdomain>
Rolling forward PCMCIA driver, it was discovered that the indentation
in existing one is very odd. This patch is just result of Lindent run ontop
of culprit files.
Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
---
drivers/pcmcia/m8xx_pcmcia.c | 548 +++++++++++++++++++++---------------------
1 files changed, 278 insertions(+), 270 deletions(-)
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 40f6e20..79e14ab 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -113,7 +113,7 @@ MODULE_LICENSE("Dual MPL/GPL");
#define CONFIG_PCMCIA_SLOT_B
#endif
-#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
+#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
@@ -146,9 +146,9 @@ MODULE_LICENSE("Dual MPL/GPL");
/* ------------------------------------------------------------------------- */
-#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
-#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
-#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
+#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
+#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
+#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
/* ------------------------------------------------------------------------- */
static int pcmcia_schlvl;
@@ -169,8 +169,8 @@ static u32 *m8xx_pgcrx[2];
*/
struct pcmcia_win {
- u32 br;
- u32 or;
+ u32 br;
+ u32 or;
};
/*
@@ -214,7 +214,7 @@ struct pcmcia_win {
/* we keep one lookup table per socket to check flags */
-#define PCMCIA_EVENTS_MAX 5 /* 4 max at a time + termination */
+#define PCMCIA_EVENTS_MAX 5 /* 4 max at a time + termination */
struct event_table {
u32 regbit;
@@ -224,8 +224,8 @@ struct event_table {
static const char driver_name[] = "m8xx-pcmcia";
struct socket_info {
- void (*handler)(void *info, u32 events);
- void *info;
+ void (*handler) (void *info, u32 events);
+ void *info;
u32 slot;
pcmconf8xx_t *pcmcia;
@@ -234,7 +234,7 @@ struct socket_info {
socket_state_t state;
struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
- struct pccard_io_map io_win[PCMCIA_IO_WIN_NO];
+ struct pccard_io_map io_win[PCMCIA_IO_WIN_NO];
struct event_table events[PCMCIA_EVENTS_MAX];
struct pcmcia_socket socket;
};
@@ -248,8 +248,7 @@ static struct socket_info socket[PCMCIA_SOCKETS_NO];
#define M8XX_SIZES_NO 32
-static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] =
-{
+static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] = {
0x00000001, 0x00000002, 0x00000008, 0x00000004,
0x00000080, 0x00000040, 0x00000010, 0x00000020,
0x00008000, 0x00004000, 0x00001000, 0x00002000,
@@ -265,7 +264,7 @@ static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] =
static irqreturn_t m8xx_interrupt(int irq, void *dev);
-#define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */
+#define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */
/* ------------------------------------------------------------------------- */
/* board specific stuff: */
@@ -289,8 +288,9 @@ static int voltage_set(int slot, int vcc, int vpp)
{
u32 reg = 0;
- switch(vcc) {
- case 0: break;
+ switch (vcc) {
+ case 0:
+ break;
case 33:
reg |= BCSR1_PCVCTL4;
break;
@@ -301,11 +301,12 @@ static int voltage_set(int slot, int vcc, int vpp)
return 1;
}
- switch(vpp) {
- case 0: break;
+ switch (vpp) {
+ case 0:
+ break;
case 33:
case 50:
- if(vcc == vpp)
+ if (vcc == vpp)
reg |= BCSR1_PCVCTL6;
else
return 1;
@@ -316,25 +317,29 @@ static int voltage_set(int slot, int vcc, int vpp)
return 1;
}
- if(!((vcc == 50) || (vcc == 0)))
+ if (!((vcc == 50) || (vcc == 0)))
return 1;
/* first, turn off all power */
- out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) & ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7));
+ out_be32(((u32 *) RPX_CSR_ADDR),
+ in_be32(((u32 *) RPX_CSR_ADDR)) & ~(BCSR1_PCVCTL4 |
+ BCSR1_PCVCTL5 |
+ BCSR1_PCVCTL6 |
+ BCSR1_PCVCTL7));
/* enable new powersettings */
- out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) | reg);
+ out_be32(((u32 *) RPX_CSR_ADDR), in_be32(((u32 *) RPX_CSR_ADDR)) | reg);
return 0;
}
#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
-#define hardware_enable(_slot_) /* No hardware to enable */
-#define hardware_disable(_slot_) /* No hardware to disable */
+#define hardware_enable(_slot_) /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
-#endif /* CONFIG_RPXCLASSIC */
+#endif /* CONFIG_RPXCLASSIC */
/* FADS Boards from Motorola */
@@ -346,43 +351,45 @@ static int voltage_set(int slot, int vcc, int vpp)
{
u32 reg = 0;
- switch(vcc) {
- case 0:
- break;
- case 33:
- reg |= BCSR1_PCCVCC0;
- break;
- case 50:
- reg |= BCSR1_PCCVCC1;
- break;
- default:
- return 1;
+ switch (vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= BCSR1_PCCVCC0;
+ break;
+ case 50:
+ reg |= BCSR1_PCCVCC1;
+ break;
+ default:
+ return 1;
}
- switch(vpp) {
- case 0:
- break;
- case 33:
- case 50:
- if(vcc == vpp)
- reg |= BCSR1_PCCVPP1;
- else
- return 1;
- break;
- case 120:
- if ((vcc == 33) || (vcc == 50))
- reg |= BCSR1_PCCVPP0;
- else
- return 1;
- default:
+ switch (vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if (vcc == vpp)
+ reg |= BCSR1_PCCVPP1;
+ else
return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= BCSR1_PCCVPP0;
+ else
+ return 1;
+ default:
+ return 1;
}
/* first, turn off all power */
- out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
+ out_be32((u32 *) BCSR1,
+ in_be32((u32 *) BCSR1) & ~(BCSR1_PCCVCC_MASK |
+ BCSR1_PCCVPP_MASK));
/* enable new powersettings */
- out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | reg);
+ out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | reg);
return 0;
}
@@ -391,12 +398,12 @@ static int voltage_set(int slot, int vcc, int vpp)
static void hardware_enable(int slot)
{
- out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~BCSR1_PCCEN);
+ out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) & ~BCSR1_PCCEN);
}
static void hardware_disable(int slot)
{
- out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | BCSR1_PCCEN);
+ out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | BCSR1_PCCEN);
}
#endif
@@ -410,7 +417,7 @@ static void hardware_disable(int slot)
static inline void hardware_enable(int slot)
{
- m8xx_pcmcia_ops.hw_ctrl(slot, 1);
+ m8xx_pcmcia_ops.hw_ctrl(slot, 1);
}
static inline void hardware_disable(int slot)
@@ -436,52 +443,53 @@ static int voltage_set(int slot, int vcc, int vpp)
{
u8 reg = 0;
- switch(vcc) {
- case 0:
- break;
- case 33:
- reg |= CSR2_VCC_33;
- break;
- case 50:
- reg |= CSR2_VCC_50;
- break;
- default:
- return 1;
+ switch (vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= CSR2_VCC_33;
+ break;
+ case 50:
+ reg |= CSR2_VCC_50;
+ break;
+ default:
+ return 1;
}
- switch(vpp) {
- case 0:
- break;
- case 33:
- case 50:
- if(vcc == vpp)
- reg |= CSR2_VPP_VCC;
- else
- return 1;
- break;
- case 120:
- if ((vcc == 33) || (vcc == 50))
- reg |= CSR2_VPP_12;
- else
- return 1;
- default:
+ switch (vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if (vcc == vpp)
+ reg |= CSR2_VPP_VCC;
+ else
+ return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= CSR2_VPP_12;
+ else
return 1;
+ default:
+ return 1;
}
/* first, turn off all power */
- out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
+ out_8((u8 *) MBX_CSR2_ADDR,
+ in_8((u8 *) MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
/* enable new powersettings */
- out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) | reg);
+ out_8((u8 *) MBX_CSR2_ADDR, in_8((u8 *) MBX_CSR2_ADDR) | reg);
return 0;
}
#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
-#define hardware_enable(_slot_) /* No hardware to enable */
-#define hardware_disable(_slot_) /* No hardware to disable */
+#define hardware_enable(_slot_) /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
-#endif /* CONFIG_MBX */
+#endif /* CONFIG_MBX */
#if defined(CONFIG_PRxK)
#include <asm/cpld.h>
@@ -495,43 +503,46 @@ static int voltage_set(int slot, int vcc, int vpp)
u8 regread;
cpld_regs *ccpld = get_cpld();
- switch(vcc) {
- case 0:
- break;
- case 33:
- reg |= PCMCIA_VCC_33;
- break;
- case 50:
- reg |= PCMCIA_VCC_50;
- break;
- default:
- return 1;
+ switch (vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= PCMCIA_VCC_33;
+ break;
+ case 50:
+ reg |= PCMCIA_VCC_50;
+ break;
+ default:
+ return 1;
}
- switch(vpp) {
- case 0:
- break;
- case 33:
- case 50:
- if(vcc == vpp)
- reg |= PCMCIA_VPP_VCC;
- else
- return 1;
- break;
- case 120:
- if ((vcc == 33) || (vcc == 50))
- reg |= PCMCIA_VPP_12;
- else
- return 1;
- default:
+ switch (vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if (vcc == vpp)
+ reg |= PCMCIA_VPP_VCC;
+ else
return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= PCMCIA_VPP_12;
+ else
+ return 1;
+ default:
+ return 1;
}
reg = reg >> (slot << 2);
regread = in_8(&ccpld->fpga_pc_ctl);
- if (reg != (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) {
+ if (reg !=
+ (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) {
/* enable new powersettings */
- regread = regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2));
+ regread =
+ regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >>
+ (slot << 2));
out_8(&ccpld->fpga_pc_ctl, reg | regread);
msleep(100);
}
@@ -540,10 +551,10 @@ static int voltage_set(int slot, int vcc, int vpp)
}
#define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV
-#define hardware_enable(_slot_) /* No hardware to enable */
-#define hardware_disable(_slot_) /* No hardware to disable */
+#define hardware_enable(_slot_) /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
-#endif /* CONFIG_PRxK */
+#endif /* CONFIG_PRxK */
static u32 pending_events[PCMCIA_SOCKETS_NO];
static DEFINE_SPINLOCK(pending_event_lock);
@@ -553,7 +564,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
struct socket_info *s;
struct event_table *e;
unsigned int i, events, pscr, pipr, per;
- pcmconf8xx_t *pcmcia = socket[0].pcmcia;
+ pcmconf8xx_t *pcmcia = socket[0].pcmcia;
dprintk("Interrupt!\n");
/* get interrupt sources */
@@ -562,16 +573,16 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
pipr = in_be32(&pcmcia->pcmc_pipr);
per = in_be32(&pcmcia->pcmc_per);
- for(i = 0; i < PCMCIA_SOCKETS_NO; i++) {
+ for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
s = &socket[i];
e = &s->events[0];
events = 0;
- while(e->regbit) {
- if(pscr & e->regbit)
+ while (e->regbit) {
+ if (pscr & e->regbit)
events |= e->eventbit;
- e++;
+ e++;
}
/*
@@ -579,13 +590,11 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
* not too nice done,
* we depend on that CD2 is the bit to the left of CD1...
*/
- if(events & SS_DETECT)
- if(((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^
- (pipr & M8XX_PCMCIA_CD1(i)))
- {
+ if (events & SS_DETECT)
+ if (((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^
+ (pipr & M8XX_PCMCIA_CD1(i))) {
events &= ~SS_DETECT;
}
-
#ifdef PCMCIA_GLITCHY_CD
/*
* I've experienced CD problems with my ADS board.
@@ -593,24 +602,23 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
* real change of Card detection.
*/
- if((events & SS_DETECT) &&
- ((pipr &
- (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) &&
- (s->state.Vcc | s->state.Vpp)) {
+ if ((events & SS_DETECT) &&
+ ((pipr &
+ (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) &&
+ (s->state.Vcc | s->state.Vpp)) {
events &= ~SS_DETECT;
/*printk( "CD glitch workaround - CD = 0x%08x!\n",
- (pipr & (M8XX_PCMCIA_CD2(i)
- | M8XX_PCMCIA_CD1(i))));*/
+ (pipr & (M8XX_PCMCIA_CD2(i)
+ | M8XX_PCMCIA_CD1(i)))); */
}
#endif
/* call the handler */
dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, "
- "pipr = 0x%08x\n",
- i, events, pscr, pipr);
+ "pipr = 0x%08x\n", i, events, pscr, pipr);
- if(events) {
+ if (events) {
spin_lock(&pending_event_lock);
pending_events[i] |= events;
spin_unlock(&pending_event_lock);
@@ -643,11 +651,11 @@ static u32 m8xx_get_graycode(u32 size)
{
u32 k;
- for(k = 0; k < M8XX_SIZES_NO; k++)
- if(m8xx_size_to_gray[k] == size)
+ for (k = 0; k < M8XX_SIZES_NO; k++)
+ if (m8xx_size_to_gray[k] == size)
break;
- if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
+ if ((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
k = -1;
return k;
@@ -657,7 +665,7 @@ static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
{
u32 reg, clocks, psst, psl, psht;
- if(!ns) {
+ if (!ns) {
/*
* We get called with IO maps setup to 0ns
@@ -665,10 +673,10 @@ static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
* They should be 255ns.
*/
- if(is_io)
+ if (is_io)
ns = 255;
else
- ns = 100; /* fast memory if 0 */
+ ns = 100; /* fast memory if 0 */
}
/*
@@ -679,23 +687,23 @@ static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
/* how we want to adjust the timing - in percent */
-#define ADJ 180 /* 80 % longer accesstime - to be sure */
+#define ADJ 180 /* 80 % longer accesstime - to be sure */
clocks = ((bus_freq / 1000) * ns) / 1000;
- clocks = (clocks * ADJ) / (100*1000);
- if(clocks >= PCMCIA_BMT_LIMIT) {
- printk( "Max access time limit reached\n");
- clocks = PCMCIA_BMT_LIMIT-1;
+ clocks = (clocks * ADJ) / (100 * 1000);
+ if (clocks >= PCMCIA_BMT_LIMIT) {
+ printk("Max access time limit reached\n");
+ clocks = PCMCIA_BMT_LIMIT - 1;
}
- psst = clocks / 7; /* setup time */
- psht = clocks / 7; /* hold time */
- psl = (clocks * 5) / 7; /* strobe length */
+ psst = clocks / 7; /* setup time */
+ psht = clocks / 7; /* hold time */
+ psl = (clocks * 5) / 7; /* strobe length */
psst += clocks - (psst + psht + psl);
- reg = psst << 12;
- reg |= psl << 7;
+ reg = psst << 12;
+ reg |= psl << 7;
reg |= psht << 16;
return reg;
@@ -710,8 +718,8 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
pipr = in_be32(&pcmcia->pcmc_pipr);
- *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
- | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
+ *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
+ | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
*value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0;
if (s->state.flags & SS_IOCARD)
@@ -795,16 +803,16 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
/* read out VS1 and VS2 */
reg = (pipr & M8XX_PCMCIA_VS_MASK(lsock))
- >> M8XX_PCMCIA_VS_SHIFT(lsock);
+ >> M8XX_PCMCIA_VS_SHIFT(lsock);
- if(socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) {
- switch(reg) {
+ if (socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) {
+ switch (reg) {
case 1:
*value |= SS_3VCARD;
- break; /* GND, NC - 3.3V only */
+ break; /* GND, NC - 3.3V only */
case 2:
*value |= SS_XVCARD;
- break; /* NC. GND - x.xV only */
+ break; /* NC. GND - x.xV only */
};
}
@@ -812,7 +820,7 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
return 0;
}
-static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
+static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t * state)
{
int lsock = container_of(sock, struct socket_info, socket)->slot;
struct socket_info *s = &socket[lsock];
@@ -821,20 +829,20 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
unsigned long flags;
pcmconf8xx_t *pcmcia = socket[0].pcmcia;
- dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
- "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
- state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+ dprintk("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+ "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
+ state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
/* First, set voltage - bail out if invalid */
- if(voltage_set(lsock, state->Vcc, state->Vpp))
+ if (voltage_set(lsock, state->Vcc, state->Vpp))
return -EINVAL;
-
/* Take care of reset... */
- if(state->flags & SS_RESET)
- out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
+ if (state->flags & SS_RESET)
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
else
- out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET);
+ out_be32(M8XX_PGCRX(lsock),
+ in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET);
/* ... and output enable. */
@@ -846,10 +854,11 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
no pullups are present -> the cards act wierd.
So right now the buffers are enabled if the power is on. */
- if(state->Vcc || state->Vpp)
- out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE); /* active low */
+ if (state->Vcc || state->Vpp)
+ out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE); /* active low */
else
- out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE);
+ out_be32(M8XX_PGCRX(lsock),
+ in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE);
/*
* We'd better turn off interrupts before
@@ -866,17 +875,17 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
e = &s->events[0];
reg = 0;
- if(state->csc_mask & SS_DETECT) {
+ if (state->csc_mask & SS_DETECT) {
e->eventbit = SS_DETECT;
reg |= e->regbit = (M8XX_PCMCIA_CD2(lsock)
| M8XX_PCMCIA_CD1(lsock));
e++;
}
- if(state->flags & SS_IOCARD) {
+ if (state->flags & SS_IOCARD) {
/*
* I/O card
*/
- if(state->csc_mask & SS_STSCHG) {
+ if (state->csc_mask & SS_STSCHG) {
e->eventbit = SS_STSCHG;
reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
e++;
@@ -884,9 +893,10 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
/*
* If io_irq is non-zero we should enable irq.
*/
- if(state->io_irq) {
+ if (state->io_irq) {
out_be32(M8XX_PGCRX(lsock),
- in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(s->hwirq) << 24);
+ in_be32(M8XX_PGCRX(lsock)) |
+ mk_int_int_mask(s->hwirq) << 24);
/*
* Strange thing here:
* The manual does not tell us which interrupt
@@ -897,33 +907,32 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
* have to be cleared in PSCR in the interrupt handler.
*/
reg |= M8XX_PCMCIA_RDY_L(lsock);
- }
- else
- out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff);
- }
- else {
+ } else
+ out_be32(M8XX_PGCRX(lsock),
+ in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff);
+ } else {
/*
* Memory card
*/
- if(state->csc_mask & SS_BATDEAD) {
+ if (state->csc_mask & SS_BATDEAD) {
e->eventbit = SS_BATDEAD;
reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
e++;
}
- if(state->csc_mask & SS_BATWARN) {
+ if (state->csc_mask & SS_BATWARN) {
e->eventbit = SS_BATWARN;
reg |= e->regbit = M8XX_PCMCIA_BVD2(lsock);
e++;
}
/* What should I trigger on - low/high,raise,fall? */
- if(state->csc_mask & SS_READY) {
+ if (state->csc_mask & SS_READY) {
e->eventbit = SS_READY;
- reg |= e->regbit = 0; //??
+ reg |= e->regbit = 0; //??
e++;
}
}
- e->regbit = 0; /* terminate list */
+ e->regbit = 0; /* terminate list */
/*
* Clear the status changed .
@@ -940,7 +949,9 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
* Ones will enable the interrupt.
*/
- reg |= in_be32(&pcmcia->pcmc_per) & (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
+ reg |=
+ in_be32(&pcmcia->
+ pcmc_per) & (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
out_be32(&pcmcia->pcmc_per, reg);
spin_unlock_irqrestore(&events_lock, flags);
@@ -961,67 +972,66 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
unsigned int reg, winnr;
pcmconf8xx_t *pcmcia = s->pcmcia;
-
#define M8XX_SIZE (io->stop - io->start + 1)
#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
- dprintk( "SetIOMap(%d, %d, %#2.2x, %d ns, "
- "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
- io->speed, io->start, io->stop);
+ dprintk("SetIOMap(%d, %d, %#2.2x, %d ns, "
+ "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
+ io->speed, io->start, io->stop);
if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
|| (io->stop > 0xffff) || (io->stop < io->start))
return -EINVAL;
- if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
+ if ((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
return -EINVAL;
- if(io->flags & MAP_ACTIVE) {
+ if (io->flags & MAP_ACTIVE) {
- dprintk( "io->flags & MAP_ACTIVE\n");
+ dprintk("io->flags & MAP_ACTIVE\n");
winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
- + (lsock * PCMCIA_IO_WIN_NO) + io->map;
+ + (lsock * PCMCIA_IO_WIN_NO) + io->map;
/* setup registers */
- w = (void *) &pcmcia->pcmc_pbr0;
+ w = (void *)&pcmcia->pcmc_pbr0;
w += winnr;
- out_be32(&w->or, 0); /* turn off window first */
+ out_be32(&w->or, 0); /* turn off window first */
out_be32(&w->br, M8XX_BASE);
reg <<= 27;
- reg |= M8XX_PCMCIA_POR_IO |(lsock << 2);
+ reg |= M8XX_PCMCIA_POR_IO | (lsock << 2);
reg |= m8xx_get_speed(io->speed, 1, s->bus_freq);
- if(io->flags & MAP_WRPROT)
+ if (io->flags & MAP_WRPROT)
reg |= M8XX_PCMCIA_POR_WRPROT;
- /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
- if(io->flags & MAP_16BIT)
+ /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ)) */
+ if (io->flags & MAP_16BIT)
reg |= M8XX_PCMCIA_POR_16BIT;
- if(io->flags & MAP_ACTIVE)
+ if (io->flags & MAP_ACTIVE)
reg |= M8XX_PCMCIA_POR_VALID;
out_be32(&w->or, reg);
dprintk("Socket %u: Mapped io window %u at %#8.8x, "
- "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+ "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
} else {
/* shutdown IO window */
winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
- + (lsock * PCMCIA_IO_WIN_NO) + io->map;
+ + (lsock * PCMCIA_IO_WIN_NO) + io->map;
/* setup registers */
- w = (void *) &pcmcia->pcmc_pbr0;
+ w = (void *)&pcmcia->pcmc_pbr0;
w += winnr;
- out_be32(&w->or, 0); /* turn off window */
- out_be32(&w->br, 0); /* turn off base address */
+ out_be32(&w->or, 0); /* turn off window */
+ out_be32(&w->br, 0); /* turn off base address */
dprintk("Socket %u: Unmapped io window %u at %#8.8x, "
"OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
@@ -1029,15 +1039,14 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
/* copy the struct and modify the copy */
s->io_win[io->map] = *io;
- s->io_win[io->map].flags &= (MAP_WRPROT
- | MAP_16BIT
- | MAP_ACTIVE);
+ s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
dprintk("SetIOMap exit\n");
return 0;
}
-static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
+static int m8xx_set_mem_map(struct pcmcia_socket *sock,
+ struct pccard_mem_map *mem)
{
int lsock = container_of(sock, struct socket_info, socket)->slot;
struct socket_info *s = &socket[lsock];
@@ -1046,19 +1055,19 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
unsigned int reg, winnr;
pcmconf8xx_t *pcmcia = s->pcmcia;
- dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, "
- "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
- mem->speed, mem->static_start, mem->card_start);
+ dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
+ "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+ mem->speed, mem->static_start, mem->card_start);
if ((mem->map >= PCMCIA_MEM_WIN_NO)
-// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
+// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
|| (mem->card_start >= 0x04000000)
- || (mem->static_start & 0xfff) /* 4KByte resolution */
- || (mem->card_start & 0xfff))
+ || (mem->static_start & 0xfff) /* 4KByte resolution */
+ ||(mem->card_start & 0xfff))
return -EINVAL;
- if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
- printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
+ if ((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
+ printk("Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
return -EINVAL;
}
reg <<= 27;
@@ -1067,50 +1076,47 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
/* Setup the window in the pcmcia controller */
- w = (void *) &pcmcia->pcmc_pbr0;
+ w = (void *)&pcmcia->pcmc_pbr0;
w += winnr;
reg |= lsock << 2;
reg |= m8xx_get_speed(mem->speed, 0, s->bus_freq);
- if(mem->flags & MAP_ATTRIB)
- reg |= M8XX_PCMCIA_POR_ATTRMEM;
+ if (mem->flags & MAP_ATTRIB)
+ reg |= M8XX_PCMCIA_POR_ATTRMEM;
- if(mem->flags & MAP_WRPROT)
+ if (mem->flags & MAP_WRPROT)
reg |= M8XX_PCMCIA_POR_WRPROT;
- if(mem->flags & MAP_16BIT)
+ if (mem->flags & MAP_16BIT)
reg |= M8XX_PCMCIA_POR_16BIT;
- if(mem->flags & MAP_ACTIVE)
+ if (mem->flags & MAP_ACTIVE)
reg |= M8XX_PCMCIA_POR_VALID;
out_be32(&w->or, reg);
dprintk("Socket %u: Mapped memory window %u at %#8.8x, "
- "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
+ "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
- if(mem->flags & MAP_ACTIVE) {
+ if (mem->flags & MAP_ACTIVE) {
/* get the new base address */
mem->static_start = PCMCIA_MEM_WIN_BASE +
- (PCMCIA_MEM_WIN_SIZE * winnr)
- + mem->card_start;
+ (PCMCIA_MEM_WIN_SIZE * winnr)
+ + mem->card_start;
}
dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
- "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
- mem->speed, mem->static_start, mem->card_start);
+ "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+ mem->speed, mem->static_start, mem->card_start);
/* copy the struct and modify the copy */
old = &s->mem_win[mem->map];
*old = *mem;
- old->flags &= (MAP_ATTRIB
- | MAP_WRPROT
- | MAP_16BIT
- | MAP_ACTIVE);
+ old->flags &= (MAP_ATTRIB | MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
return 0;
}
@@ -1121,7 +1127,7 @@ static int m8xx_sock_init(struct pcmcia_socket *sock)
pccard_io_map io = { 0, 0, 0, 0, 1 };
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
- dprintk( "sock_init(%d)\n", s);
+ dprintk("sock_init(%d)\n", s);
m8xx_set_socket(sock, &dead_socket);
for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
@@ -1143,7 +1149,7 @@ static int m8xx_sock_suspend(struct pcmcia_socket *sock)
}
static struct pccard_operations m8xx_services = {
- .init = m8xx_sock_init,
+ .init = m8xx_sock_init,
.suspend = m8xx_sock_suspend,
.get_status = m8xx_get_status,
.set_socket = m8xx_set_socket,
@@ -1151,7 +1157,8 @@ static struct pccard_operations m8xx_services = {
.set_mem_map = m8xx_set_mem_map,
};
-static int __init m8xx_probe(struct of_device *ofdev, const struct of_device_id *match)
+static int __init m8xx_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
{
struct pcmcia_win *w;
unsigned int i, m, hwirq;
@@ -1162,49 +1169,50 @@ static int __init m8xx_probe(struct of_device *ofdev, const struct of_device_id
pcmcia_info("%s\n", version);
pcmcia = of_iomap(np, 0);
- if(pcmcia == NULL)
+ if (pcmcia == NULL)
return -EINVAL;
pcmcia_schlvl = irq_of_parse_and_map(np, 0);
- hwirq = irq_map[pcmcia_schlvl].hwirq;
+ hwirq = irq_map[pcmcia_schlvl].hwirq;
if (pcmcia_schlvl < 0)
return -EINVAL;
m8xx_pgcrx[0] = &pcmcia->pcmc_pgcra;
m8xx_pgcrx[1] = &pcmcia->pcmc_pgcrb;
-
pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
" with IRQ %u (%d). \n", pcmcia_schlvl, hwirq);
/* Configure Status change interrupt */
- if(request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
- driver_name, socket)) {
+ if (request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
+ driver_name, socket)) {
pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
pcmcia_schlvl);
return -1;
}
- w = (void *) &pcmcia->pcmc_pbr0;
+ w = (void *)&pcmcia->pcmc_pbr0;
- out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
+ out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
clrbits32(&pcmcia->pcmc_per, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
/* connect interrupt and disable CxOE */
- out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
- out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
+ out_be32(M8XX_PGCRX(0),
+ M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
+ out_be32(M8XX_PGCRX(1),
+ M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
/* intialize the fixed memory windows */
- for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
+ for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
- (PCMCIA_MEM_WIN_SIZE
- * (m + i * PCMCIA_MEM_WIN_NO)));
+ (PCMCIA_MEM_WIN_SIZE
+ * (m + i * PCMCIA_MEM_WIN_NO)));
- out_be32(&w->or, 0); /* set to not valid */
+ out_be32(&w->or, 0); /* set to not valid */
w++;
}
@@ -1218,10 +1226,11 @@ static int __init m8xx_probe(struct of_device *ofdev, const struct of_device_id
hardware_enable(0);
hardware_enable(1);
- for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) {
+ for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
socket[i].slot = i;
socket[i].socket.owner = THIS_MODULE;
- socket[i].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP;
+ socket[i].socket.features =
+ SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP;
socket[i].socket.irq_mask = 0x000;
socket[i].socket.map_size = 0x1000;
socket[i].socket.io_offset = 0;
@@ -1234,7 +1243,6 @@ static int __init m8xx_probe(struct of_device *ofdev, const struct of_device_id
socket[i].bus_freq = ppc_proc_freq;
socket[i].hwirq = hwirq;
-
}
for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
@@ -1246,25 +1254,25 @@ static int __init m8xx_probe(struct of_device *ofdev, const struct of_device_id
return 0;
}
-static int m8xx_remove(struct of_device* ofdev)
+static int m8xx_remove(struct of_device *ofdev)
{
u32 m, i;
struct pcmcia_win *w;
pcmconf8xx_t *pcmcia = socket[0].pcmcia;
for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
- w = (void *) &pcmcia->pcmc_pbr0;
+ w = (void *)&pcmcia->pcmc_pbr0;
out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(i));
out_be32(&pcmcia->pcmc_per,
- in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
+ in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
/* turn off interrupt and disable CxOE */
out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
/* turn off memory windows */
for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
- out_be32(&w->or, 0); /* set to not valid */
+ out_be32(&w->or, 0); /* set to not valid */
w++;
}
@@ -1299,21 +1307,21 @@ static int m8xx_resume(struct platform_device *pdev)
static struct of_device_id m8xx_pcmcia_match[] = {
{
- .type = "pcmcia",
- .compatible = "fsl,pq-pcmcia",
- },
+ .type = "pcmcia",
+ .compatible = "fsl,pq-pcmcia",
+ },
{},
};
MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
static struct of_platform_driver m8xx_pcmcia_driver = {
- .name = (char *) driver_name,
- .match_table = m8xx_pcmcia_match,
- .probe = m8xx_probe,
- .remove = m8xx_remove,
- .suspend = m8xx_suspend,
- .resume = m8xx_resume,
+ .name = (char *)driver_name,
+ .match_table = m8xx_pcmcia_match,
+ .probe = m8xx_probe,
+ .remove = m8xx_remove,
+ .suspend = m8xx_suspend,
+ .resume = m8xx_resume,
};
static int __init m8xx_init(void)
^ permalink raw reply related
* [PATCH 0/3] 8xx PCMCIA stuff && cleanup: take 3
From: Vitaly Bordug @ 2007-05-08 9:50 UTC (permalink / raw)
To: linux-pcmcia; +Cc: linuxppc-dev, linux-kernel
Sorry for such amount of noise, have to resubmit to catch up
with Olof's notes, and to kill empty ranges property in dts since
it is not appropriate before driver could handle it.
Thanks all for attention.
--
Sincerely, Vitaly
^ permalink raw reply
* [PATCH] powerpc: mark pages that don't exist as nosave
From: Johannes Berg @ 2007-05-08 9:25 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev list
On some powerpc architectures (notably 64-bit powermac) there is a memory
hole, for example on powermacs between 2G and 4G. Since we use the flat
memory model regardless, these pages must be marked as nosave (for suspend
to disk.)
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Tested on powerbook and G5 powermac, this patch is required for suspend
to disk on G5 as well due to the memory hole.
---
arch/powerpc/mm/mem.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
--- powerpc.orig/arch/powerpc/mm/mem.c 2007-05-08 11:18:12.279080051 +0200
+++ powerpc/arch/powerpc/mm/mem.c 2007-05-08 11:22:02.559080051 +0200
@@ -31,6 +31,7 @@
#include <linux/highmem.h>
#include <linux/initrd.h>
#include <linux/pagemap.h>
+#include <linux/suspend.h>
#include <asm/pgalloc.h>
#include <asm/prom.h>
@@ -276,6 +277,28 @@ void __init do_init_bootmem(void)
init_bootmem_done = 1;
}
+/* mark pages that don't exist as nosave */
+static int __init mark_nonram_nosave(void)
+{
+ unsigned long lmb_next_region_start_pfn,
+ lmb_region_max_pfn;
+ int i;
+
+ for (i = 0; i < lmb.memory.cnt - 1; i++) {
+ lmb_region_max_pfn =
+ (lmb.memory.region[i].base >> PAGE_SHIFT) +
+ (lmb.memory.region[i].size >> PAGE_SHIFT);
+ lmb_next_region_start_pfn =
+ lmb.memory.region[i+1].base >> PAGE_SHIFT;
+
+ if (lmb_region_max_pfn < lmb_next_region_start_pfn)
+ register_nosave_region(lmb_region_max_pfn,
+ lmb_next_region_start_pfn);
+ }
+
+ return 0;
+}
+
/*
* paging_init() sets up the page tables - in fact we've already done this.
*/
@@ -307,6 +330,8 @@ void __init paging_init(void)
max_zone_pfns[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
#endif
free_area_init_nodes(max_zone_pfns);
+
+ mark_nonram_nosave();
}
#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
^ permalink raw reply
* [PATCH] swsusp: introduce register_nosave_region_late
From: Johannes Berg @ 2007-05-08 9:23 UTC (permalink / raw)
To: Paul Mackerras; +Cc: Rafael J. Wysocki, linuxppc-dev list
This patch introduces a new register_nosave_region_late function that
can be called from initcalls when register_nosave_region can no longer
be used because it uses bootmem.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
---
Paul, I see you merged the suspend to disk for G5 patches, but this one
is required for it to build. Rafael said that we should merge it with
the user, since our code is the only user right now I take it that means
it should go through the powerpc tree.
include/linux/suspend.h | 11 ++++++++++-
kernel/power/snapshot.c | 12 +++++++++---
2 files changed, 19 insertions(+), 4 deletions(-)
--- linux-2.6-git.orig/include/linux/suspend.h 2007-05-03 15:20:29.081123904 +0200
+++ linux-2.6-git/include/linux/suspend.h 2007-05-03 15:23:03.819123904 +0200
@@ -52,7 +52,15 @@ struct hibernation_ops {
#if defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND)
/* kernel/power/snapshot.c */
-extern void __init register_nosave_region(unsigned long, unsigned long);
+extern void __register_nosave_region(unsigned long b, unsigned long e, int km);
+static inline void register_nosave_region(unsigned long b, unsigned long e)
+{
+ __register_nosave_region(b, e, 0);
+}
+static inline void register_nosave_region_late(unsigned long b, unsigned long e)
+{
+ __register_nosave_region(b, e, 1);
+}
extern int swsusp_page_is_forbidden(struct page *);
extern void swsusp_set_page_free(struct page *);
extern void swsusp_unset_page_free(struct page *);
@@ -70,6 +78,7 @@ void hibernation_set_ops(struct hibernat
extern int hibernate(void);
#else
static inline void register_nosave_region(unsigned long b, unsigned long e) {}
+static inline void register_nosave_region_late(unsigned long b, unsigned long e) {}
static inline int swsusp_page_is_forbidden(struct page *p) { return 0; }
static inline void swsusp_set_page_free(struct page *p) {}
static inline void swsusp_unset_page_free(struct page *p) {}
--- linux-2.6-git.orig/kernel/power/snapshot.c 2007-05-03 15:20:01.842123904 +0200
+++ linux-2.6-git/kernel/power/snapshot.c 2007-05-03 15:22:19.138123904 +0200
@@ -608,7 +608,8 @@ static LIST_HEAD(nosave_regions);
*/
void __init
-register_nosave_region(unsigned long start_pfn, unsigned long end_pfn)
+__register_nosave_region(unsigned long start_pfn, unsigned long end_pfn,
+ int use_kmalloc)
{
struct nosave_region *region;
@@ -624,8 +625,13 @@ register_nosave_region(unsigned long sta
goto Report;
}
}
- /* This allocation cannot fail */
- region = alloc_bootmem_low(sizeof(struct nosave_region));
+ if (use_kmalloc) {
+ /* during init, this shouldn't fail */
+ region = kmalloc(sizeof(struct nosave_region), GFP_KERNEL);
+ BUG_ON(!region);
+ } else
+ /* This allocation cannot fail */
+ region = alloc_bootmem_low(sizeof(struct nosave_region));
region->start_pfn = start_pfn;
region->end_pfn = end_pfn;
list_add_tail(®ion->list, &nosave_regions);
^ 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