LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Clock running fast on Mac Mini?
From: Benjamin Herrenschmidt @ 2006-04-25  4:14 UTC (permalink / raw)
  To: Mich Lanners; +Cc: linuxppc-dev
In-Reply-To: <E1FY8kd-0000mH-PO@owl.grunz.lu>

On Mon, 2006-04-24 at 23:37 +0200, Mich Lanners wrote:
> Hello all,
> 
> I have a problem on my Mac Mini with the kernel clock, which is running
> fast.
> 
> In fact, it is gaining 10 ms every 5 seconds, as can be seen here, with
> ntpdate called every 5 seconds:
> 
> owl:~# while true; do ntpdate -u be.pool.ntp.org; sleep 5; done
> 24 Apr 23:14:17 ntpdate[2601]: adjust time server 195.47.215.226 offset 0.151197 sec
> 24 Apr 23:14:22 ntpdate[2607]: adjust time server 195.47.215.226 offset 0.160348 sec
> 24 Apr 23:14:28 ntpdate[2613]: adjust time server 195.47.215.226 offset 0.170311 sec
> [...]
> 24 Apr 23:17:15 ntpdate[2813]: adjust time server 195.47.215.226 offset 0.489635 sec
> 24 Apr 23:17:20 ntpdate[2819]: adjust time server 195.47.215.226 offset 0.499386 sec
> 24 Apr 23:17:25 ntpdate[2825]: step time server 195.47.215.226 offset 0.509342 sec
> 24 Apr 23:17:31 ntpdate[2831]: adjust time server 195.47.215.226 offset 0.013693 sec
> 24 Apr 23:17:36 ntpdate[2837]: adjust time server 195.47.215.226 offset 0.021668 sec
> 
> and so on.
> 
> This is with ntpd stopped, after a fresh boot with /etc/adjtime removed
> to make sure hwclock is not falsly tuning the kernel timekeeping (I did
> this because I once had a 2.6.16 kernel running, where clock problems
> have been reported. I thought that may have falsified ntp's drift file
> and/or hwclock's /etc/adjtime).
> 
> All this is with a 2.6.15 kernel.
> 
> My Alu powerbook with a 2.6.15 kernel does not show this problem.

Could be several things... the clock calibration data from the
device-tree incorrect, or a rouding bug we fixed recently... I'd expect
2.6.16 to be good.

Ben

^ permalink raw reply

* Re: 85xx FDT updates?
From: Kumar Gala @ 2006-04-25  6:08 UTC (permalink / raw)
  To: Dan Malek; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <17017F03-078C-4B7F-A961-EC371F534E27@embeddedalley.com>


On Apr 24, 2006, at 5:31 PM, Dan Malek wrote:

>
> On Apr 24, 2006, at 5:43 PM, Kumar Gala wrote:
>
>> However, I am against removing the arch/ppc support until the u-boot
>> patches are picked up.  I think its bad form to give people a kernel
>> they can't easily boot.
>
> What about systems that can't update u-boot, but want to run
> a newer kernel?

Does this situation exist for any in tree boards that are supported?

- kumar

^ permalink raw reply

* Re: 85xx FDT updates?
From: Eugene Surovegin @ 2006-04-25  7:49 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <34C11E8A-ED04-490F-B601-841DC1F94AD6@kernel.crashing.org>

On Tue, Apr 25, 2006 at 01:08:00AM -0500, Kumar Gala wrote:
> 
> On Apr 24, 2006, at 5:31 PM, Dan Malek wrote:
> 
> >
> > On Apr 24, 2006, at 5:43 PM, Kumar Gala wrote:
> >
> >> However, I am against removing the arch/ppc support until the u-boot
> >> patches are picked up.  I think its bad form to give people a kernel
> >> they can't easily boot.
> >
> > What about systems that can't update u-boot, but want to run
> > a newer kernel?
> 
> Does this situation exist for any in tree boards that are supported?

Kumar, with all due respect, I don't like this attitude. I can have 
eval board where I don't want to upgrade firmware.

Also, this "let's screw everybody who doesn't have their board support 
in tree" is very counter productive. FYI, almost all my contributed 
kernel work was done on custom hardware, not on reference boards.

It seems some people here lost touch with reality - embedded Linux is 
mostly run on custom hardware, not on evaluation boards.

-- 
Eugene

^ permalink raw reply

* [PATCH] ppc32: add 440GX erratum 440_43 workaround
From: Eugene Surovegin @ 2006-04-25  8:22 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-embedded

This patch adds workaround for PPC 440GX erratum 440_43. According to 
this erratum spurious MachineChecks (caused by L1 cache parity) can 
happen during DataTLB miss processing. We disable L1 cache parity 
checking for 440GX rev.C and rev.F

Signed-off-by: Eugene Surovegin <ebs@ebshome.net>

diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
index f841972..554776d 100644
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -331,7 +331,7 @@ static void __init ocotea_init(void)
 void __init platform_init(unsigned long r3, unsigned long r4,
 		unsigned long r5, unsigned long r6, unsigned long r7)
 {
-	ibm44x_platform_init(r3, r4, r5, r6, r7);
+	ibm440gx_platform_init(r3, r4, r5, r6, r7);
 
 	ppc_md.setup_arch = ocotea_setup_arch;
 	ppc_md.show_cpuinfo = ocotea_show_cpuinfo;
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
index a7dd55f..f6cc168 100644
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ b/arch/ppc/syslib/ibm440gx_common.c
@@ -2,7 +2,7 @@
  * PPC440GX system library
  *
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- * Copyright (c) 2003, 2004 Zultys Technologies
+ * Copyright (c) 2003 - 2006 Zultys Technologies
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -282,3 +282,14 @@ int ibm440gx_show_cpuinfo(struct seq_fil
 	return 0;
 }
 
+void __init ibm440gx_platform_init(unsigned long r3, unsigned long r4,
+				   unsigned long r5, unsigned long r6,
+				   unsigned long r7)
+{
+	/* Erratum 440_43 workaround, disable L1 cache parity checking */
+	if (!strcmp(cur_cpu_spec->cpu_name, "440GX Rev. C") ||
+	    !strcmp(cur_cpu_spec->cpu_name, "440GX Rev. F"))
+		mtspr(SPRN_CCR1, mfspr(SPRN_CCR1) | CCR1_DPC);
+
+	ibm44x_platform_init(r3, r4, r5, r6, r7);
+}
diff --git a/arch/ppc/syslib/ibm440gx_common.h b/arch/ppc/syslib/ibm440gx_common.h
index a2ab9fa..a03ec60 100644
--- a/arch/ppc/syslib/ibm440gx_common.h
+++ b/arch/ppc/syslib/ibm440gx_common.h
@@ -29,6 +29,10 @@ #include <syslib/ibm44x_common.h>
 void ibm440gx_get_clocks(struct ibm44x_clocks*, unsigned int sys_clk,
 	unsigned int ser_clk) __init;
 
+/* common 440GX platform init */
+void ibm440gx_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+			    unsigned long r6, unsigned long r7) __init;
+
 /* Enable L2 cache */
 void ibm440gx_l2c_enable(void) __init;
 
diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h
index 00ad9c7..4944c0f 100644
--- a/include/asm-ppc/reg_booke.h
+++ b/include/asm-ppc/reg_booke.h
@@ -237,6 +237,7 @@ #define SPRN_CSRR1	SPRN_SRR3 /* Critical
 #endif
 
 /* Bit definitions for CCR1. */
+#define	CCR1_DPC	0x00000100 /* Disable L1 I-Cache/D-Cache parity checking */
 #define	CCR1_TCS	0x00000080 /* Timer Clock Select */
 
 /* Bit definitions for the MCSR. */

^ permalink raw reply related

* Re: [PATCH 0/7] [RFC] Sizing zones and holes in an architecture independent manner V4
From: Mel Gorman @ 2006-04-25  9:05 UTC (permalink / raw)
  To: KAMEZAWA Hiroyuki
  Cc: davej, tony.luck, linux-mm, ak, bob.picco, linux-kernel,
	linuxppc-dev
In-Reply-To: <20060425104855.42c6ca62.kamezawa.hiroyu@jp.fujitsu.com>

On Tue, 25 Apr 2006, KAMEZAWA Hiroyuki wrote:

> On Mon, 24 Apr 2006 21:20:09 +0100 (IST)
> Mel Gorman <mel@csn.ul.ie> wrote:
>
>> This is V4 of the patchset to size zones and memory holes in an
>> architecture-independent manner.
>>
>
> Could you add some documentation about 'how to use' your generic funcs ?
> I think more archs can use your generic routine if well documented.
>
> All initialization path can be written in following way ?
> ==
> for_all_memory_region()
> 	add_active_range(nid, start, end)
> free_area_init_nodes(max_dma, max_dma32, max_low_pfn, max_pfn);
> ==

Yes, that is accurate. I can write in some documentation.

>
> And following functions are really needed ?

Most of them, yes. Without them, the arch-specific could would need to be 
able to iterate through the list of active regions which would lead to 
more similar-looking code.

> ==

> +extern void remove_all_active_ranges(void);

Used by x86_64 when it finds the SRAT table is bad and needs to rediscover 
active regions in another way. Spontaneous reboots were possible without 
it.

> +extern void get_pfn_range_for_nid(unsigned int nid,
> +			unsigned long *start_pfn, unsigned long *end_pfn);

Currently only used by power when initialising the boot allocator. There 
were no obvious canditates for use elsewhere.

> +extern unsigned long find_min_pfn_with_active_regions(void);

This does not need to be in a header.

> +extern unsigned long find_max_pfn_with_active_regions(void);

Could be dropped, only required by x86_64.

> +extern int early_pfn_to_nid(unsigned long pfn);

Removed two copies of similar functions from power and x86. I thought I 
could replace the IA64 one as well, but the code was unusual enough there 
that I decided not to.

> +extern void free_bootmem_with_active_regions(int nid,
> +						unsigned long max_low_pfn);

Removes similar-looking code from power and x86_64.

> +extern void sparse_memory_present_with_active_regions(int nid);

This is only used by power.

> +extern unsigned long absent_pages_in_range(unsigned long start_pfn,
> +						unsigned long end_pfn);
>

Removes similar looking code from x86_64. For all other architectures, it 
does the job of the existing functions that calculate zholes_size[].

-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

^ permalink raw reply

* Question about porting  linux2.6 on mpc860T
From: bharathi kandimalla @ 2006-04-25  9:29 UTC (permalink / raw)
  To: linuxppc-embedded@ozlabs.org; +Cc: linuxppc-embedded@ozlabs.org

[-- Attachment #1: Type: text/plain, Size: 464 bytes --]

Hi
  I know there exits a lot of changes in the linux2.6
and i want to know what are the changes 
related to architecture? 
  As mpc860T is a slow processor 
Is it considerably slow for mpc860T on linux 2.6  ?
 
I came to know there are some bugs on mpc860T for linux2.6 
Is there any bugs?
 
what version of linux(2.4/2.6) is good for mpc860T ? 
regards  
thank you.

		
---------------------------------
Yahoo! Mail goes everywhere you do.  Get it on your phone.

[-- Attachment #2: Type: text/html, Size: 682 bytes --]

^ permalink raw reply

* [PATCH] fix cpm_uart driver for PQ1...
From: David Jander @ 2006-04-25  9:55 UTC (permalink / raw)
  To: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 473 bytes --]


Hi,

This patch fixes the following three problems:

1. Memory mapping virtual<-->dma is broken in the case that 
CONFIG_CONSISTENT_START > CPM_ADDR.

2. SCC uart sends a break sequence each time it is stopped with the 
CPM_CR_STOP_TX command. That means that each time an application closes the 
serial device, a break is transmitted.

3. Implemented default BRG routing for PQ1 (in the same sense as it is done 
for PQ2).

Signed-off-by: David Jander

Regards,

David.


[-- Attachment #2: cpm_uart_patch.diff --]
[-- Type: text/x-diff, Size: 6578 bytes --]

diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -138,25 +138,33 @@ void smc2_lineif(struct uart_cpm_port *p
 
 void scc1_lineif(struct uart_cpm_port *pinfo)
 {
+	volatile cpm8xx_t *cp = cpmp;
 	/* XXX SCC1: insert port configuration here */
+	cp->cp_sicr = (cp->cp_sicr & ~0x0000003f) | 0x00000000; /* Route BRG1 to SCC1 */
 	pinfo->brg = 1;
 }
 
 void scc2_lineif(struct uart_cpm_port *pinfo)
 {
+	volatile cpm8xx_t *cp = cpmp;
 	/* XXX SCC2: insert port configuration here */
+	cp->cp_sicr = (cp->cp_sicr & ~0x00003f00) | 0x00000900; /* Route BRG2 to SCC2 */
 	pinfo->brg = 2;
 }
 
 void scc3_lineif(struct uart_cpm_port *pinfo)
 {
+	volatile cpm8xx_t *cp = cpmp;
 	/* XXX SCC3: insert port configuration here */
+	cp->cp_sicr = (cp->cp_sicr & ~0x003f0000) | 0x00120000; /* Route BRG3 to SCC3 */
 	pinfo->brg = 3;
 }
 
 void scc4_lineif(struct uart_cpm_port *pinfo)
 {
+	volatile cpm8xx_t *cp = cpmp;
 	/* XXX SCC4: insert port configuration here */
+	cp->cp_sicr = (cp->cp_sicr & ~0x3f000000) | 0x1b000000; /* Route BRG4 to SCC4 */
 	pinfo->brg = 4;
 }
 
@@ -191,11 +199,11 @@ int cpm_uart_allocbuf(struct uart_cpm_po
 		/* was hostalloc but changed cause it blows away the */
 		/* large tlb mapping when pinning the kernel area    */
 		mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
-		dma_addr = 0;
+		dma_addr = (dma_addr_t)mem_addr;
 	} else
 		mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
 					      GFP_KERNEL);
-
+	
 	if (mem_addr == NULL) {
 		cpm_dpfree(dp_offset);
 		printk(KERN_ERR
@@ -206,6 +214,7 @@ int cpm_uart_allocbuf(struct uart_cpm_po
 	pinfo->dp_addr = dp_offset;
 	pinfo->mem_addr = mem_addr;
 	pinfo->dma_addr = dma_addr;
+	pinfo->dma_offset = (dma_addr_t)((unsigned long)dma_addr - (unsigned long)mem_addr);
 
 	pinfo->rx_buf = mem_addr;
 	pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -71,17 +71,19 @@ static void cpm_uart_initbd(struct uart_
 
 /**************************************************************/
 
-static inline unsigned long cpu2cpm_addr(void *addr)
+static inline unsigned long cpu2cpm_addr(void *addr, unsigned long offset)
 {
-	if ((unsigned long)addr >= CPM_ADDR)
-		return (unsigned long)addr;
+	if (((unsigned long)addr >= CPM_ADDR) 
+		|| ((unsigned long)addr >= CONFIG_CONSISTENT_START))
+		return (unsigned long)addr + offset;
 	return virt_to_bus(addr);
 }
 
-static inline void *cpm2cpu_addr(unsigned long addr)
+static inline void *cpm2cpu_addr(unsigned long addr, unsigned long offset)
 {
-	if (addr >= CPM_ADDR)
-		return (void *)addr;
+	if (((unsigned long)(addr - offset) >= CPM_ADDR) 
+		|| ((unsigned long)(addr - offset) >= CONFIG_CONSISTENT_START))
+		return (void *)(addr - offset);
 	return bus_to_virt(addr);
 }
 
@@ -260,7 +262,7 @@ static void cpm_uart_int_rx(struct uart_
 		}
 
 		/* get pointer */
-		cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+		cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo->dma_offset);
 
 		/* loop through the buffer */
 		while (i-- > 0) {
@@ -441,7 +443,8 @@ static void cpm_uart_shutdown(struct uar
 		}
 
 		/* Shut them really down */
-		cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
+		if (IS_SMC(pinfo)) cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
+		else cpm_line_cr_cmd(line, CPM_CR_STOP_TX+1); /* Do graceful stop of SCC uart */
 	}
 }
 
@@ -603,7 +606,7 @@ static int cpm_uart_tx_pump(struct uart_
 		/* Pick next descriptor and fill from buffer */
 		bdp = pinfo->tx_cur;
 
-		p = cpm2cpu_addr(bdp->cbd_bufaddr);
+		p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo->dma_offset);
 
 		*p++ = xmit->buf[xmit->tail];
 		bdp->cbd_datlen = 1;
@@ -630,7 +633,7 @@ static int cpm_uart_tx_pump(struct uart_
 
 	while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) {
 		count = 0;
-		p = cpm2cpu_addr(bdp->cbd_bufaddr);
+		p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo->dma_offset);
 		while (count < pinfo->tx_fifosize) {
 			*p++ = xmit->buf[xmit->tail];
 			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -668,6 +671,7 @@ static void cpm_uart_initbd(struct uart_
 {
 	int i;
 	u8 *mem_addr;
+	unsigned long dma_offset;
 	volatile cbd_t *bdp;
 
 	pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line);
@@ -677,14 +681,15 @@ static void cpm_uart_initbd(struct uart_
 	 * virtual address for us to work with.
 	 */
 	mem_addr = pinfo->mem_addr;
+	dma_offset = pinfo->dma_offset;
 	bdp = pinfo->rx_cur = pinfo->rx_bd_base;
 	for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) {
-		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, dma_offset);
 		bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
 		mem_addr += pinfo->rx_fifosize;
 	}
 
-	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, dma_offset);
 	bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
 
 	/* Set the physical address of the host memory
@@ -694,12 +699,12 @@ static void cpm_uart_initbd(struct uart_
 	mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize);
 	bdp = pinfo->tx_cur = pinfo->tx_bd_base;
 	for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) {
-		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, dma_offset);
 		bdp->cbd_sc = BD_SC_INTRPT;
 		mem_addr += pinfo->tx_fifosize;
 	}
 
-	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, dma_offset);
 	bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
 }
 
@@ -1029,7 +1034,7 @@ static void cpm_uart_console_write(struc
 		 * If the buffer address is in the CPM DPRAM, don't
 		 * convert it.
 		 */
-		cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+		cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo->dma_offset);
 
 		*cp = *s;
 
@@ -1046,7 +1051,7 @@ static void cpm_uart_console_write(struc
 			while ((bdp->cbd_sc & BD_SC_READY) != 0)
 				;
 
-			cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+			cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo->dma_offset);
 
 			*cp = 13;
 			bdp->cbd_datlen = 1;
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -64,6 +64,7 @@ struct uart_cpm_port {
 	uint			 dp_addr;
 	void			*mem_addr;
 	dma_addr_t		 dma_addr;
+	unsigned long	 dma_offset;
 	/* helpers */
 	int			 baud;
 	int			 bits;

^ permalink raw reply

* [RFC 1/2] powerpc: add all the iSeries virtual devices to the device tree
From: Stephen Rothwell @ 2006-04-25 11:54 UTC (permalink / raw)
  To: ppc-dev

We do this by putting them in the flattened device tree at setup time.
This required the flattened device tree blob to be made bigger.

Currently we don't do anything with these.

Also make a function static.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---

 arch/powerpc/platforms/iseries/setup.c |   87 ++++++++++++++++++++++++++++++++
 arch/powerpc/platforms/iseries/vio.c   |    2 -
 2 files changed, 87 insertions(+), 2 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

676ab187518bfb5e48aa4c3cc418456e67a2ed70
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 3c51448..9ce2afc 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -45,6 +45,7 @@ #include <asm/paca.h>
 #include <asm/cache.h>
 #include <asm/sections.h>
 #include <asm/abs_addr.h>
+#include <asm/iseries/hv_types.h>
 #include <asm/iseries/hv_lp_config.h>
 #include <asm/iseries/hv_call_event.h>
 #include <asm/iseries/hv_call_xm.h>
@@ -710,7 +711,7 @@ define_machine(iseries) {
 };
 
 struct blob {
-	unsigned char data[PAGE_SIZE];
+	unsigned char data[PAGE_SIZE * 2];
 	unsigned long next;
 };
 
@@ -911,6 +912,88 @@ void dt_model(struct iseries_flat_dt *dt
 	dt_prop_str(dt, "compatible", "IBM,iSeries");
 }
 
+void dt_vdevices(struct iseries_flat_dt *dt)
+{
+	u32 reg = 0;
+	HvLpIndexMap vlan_map;
+	int i;
+	char buf[32];
+
+	dt_start_node(dt, "vdevice");
+	dt_prop_u32(dt, "#address-cells", 1);
+	dt_prop_u32(dt, "#size-cells", 0);
+
+	snprintf(buf, sizeof(buf), "viocons@%08x", reg);
+	dt_start_node(dt, buf);
+	dt_prop_str(dt, "device_type", "serial");
+	dt_prop_empty(dt, "compatible");
+	dt_prop_u32(dt, "reg", reg);
+	dt_end_node(dt);
+	reg++;
+
+	snprintf(buf, sizeof(buf), "v-scsi@%08x", reg);
+	dt_start_node(dt, buf);
+	dt_prop_str(dt, "device_type", "vscsi");
+	dt_prop_str(dt, "compatible", "IBM,v-scsi");
+	dt_prop_u32(dt, "reg", reg);
+	dt_end_node(dt);
+	reg++;
+
+	vlan_map = HvLpConfig_getVirtualLanIndexMap();
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
+		unsigned char mac_addr[6];
+
+		if ((vlan_map & (0x8000 >> i)) == 0)
+			continue;
+		snprintf(buf, 32, "vlan@%08x", reg + i);
+		dt_start_node(dt, buf);
+		dt_prop_str(dt, "device_type", "vlan");
+		dt_prop_empty(dt, "compatible");
+		dt_prop_u32(dt, "reg", reg + i);
+
+		mac_addr[0] = 0x02;
+		mac_addr[1] = 0x01;
+		mac_addr[2] = 0xff;
+		mac_addr[3] = i;
+		mac_addr[4] = 0xff;
+		mac_addr[5] = HvLpConfig_getLpIndex_outline();
+		dt_prop(dt, "local-mac-address", (char *)mac_addr, 6);
+		dt_prop(dt, "mac-address", (char *)mac_addr, 6);
+
+		dt_end_node(dt);
+	}
+	reg += HVMAXARCHITECTEDVIRTUALLANS;
+
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) {
+		snprintf(buf, 32, "viodasd@%08x", reg + i);
+		dt_start_node(dt, buf);
+		dt_prop_str(dt, "device_type", "viodasd");
+		dt_prop_empty(dt, "compatible");
+		dt_prop_u32(dt, "reg", reg + i);
+		dt_end_node(dt);
+	}
+	reg += HVMAXARCHITECTEDVIRTUALDISKS;
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) {
+		snprintf(buf, 32, "viocd@%08x", reg + i);
+		dt_start_node(dt, buf);
+		dt_prop_str(dt, "device_type", "viocd");
+		dt_prop_empty(dt, "compatible");
+		dt_prop_u32(dt, "reg", reg + i);
+		dt_end_node(dt);
+	}
+	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
+	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) {
+		snprintf(buf, 32, "viotape@%08x", reg + i);
+		dt_start_node(dt, buf);
+		dt_prop_str(dt, "device_type", "viotape");
+		dt_prop_empty(dt, "compatible");
+		dt_prop_u32(dt, "reg", reg + i);
+		dt_end_node(dt);
+	}
+
+	dt_end_node(dt);
+}
+
 void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
 {
 	u64 tmp[2];
@@ -941,6 +1024,8 @@ void build_flat_dt(struct iseries_flat_d
 
 	dt_cpus(dt);
 
+	dt_vdevices(dt);
+
 	dt_end_node(dt);
 
 	dt_push_u32(dt, OF_DT_END);
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index ad36ab0..22045a2 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -71,7 +71,7 @@ static struct vio_dev *__init vio_regist
 	return viodev;
 }
 
-void __init probe_bus_iseries(void)
+static void __init probe_bus_iseries(void)
 {
 	HvLpIndexMap vlan_map;
 	struct vio_dev *viodev;
-- 
1.3.1

^ permalink raw reply related

* [RFC 2/2] powerpc: use the device tree for the iSeries vio bus probe
From: Stephen Rothwell @ 2006-04-25 11:59 UTC (permalink / raw)
  To: ppc-dev
In-Reply-To: <20060425215405.648a16e7.sfr@canb.auug.org.au>

As an added bonus, since every vio_dev now has a device_node
associated with it, hotplug now works.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---

 arch/powerpc/kernel/vio.c              |  149 ++++++++++++++++++++++++++------
 arch/powerpc/platforms/iseries/setup.c |    5 +
 arch/powerpc/platforms/iseries/vio.c   |   79 ++++-------------
 arch/powerpc/platforms/pseries/vio.c   |  134 ++---------------------------
 drivers/block/viodasd.c                |    5 +
 drivers/cdrom/viocd.c                  |    5 +
 drivers/char/viotape.c                 |    4 -
 drivers/net/iseries_veth.c             |    7 +-
 include/asm-powerpc/iseries/vio.h      |    5 +
 include/asm-powerpc/vio.h              |    5 -
 10 files changed, 173 insertions(+), 225 deletions(-)

This has been booted on an iSeries 270 and compiled for pSeries.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

a8083bf970bafd0f7139b4b9bbbf12e3ed32e2f7
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 971020c..784528b 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -23,9 +23,6 @@ #include <asm/dma.h>
 #include <asm/vio.h>
 #include <asm/prom.h>
 
-static const struct vio_device_id *vio_match_device(
-		const struct vio_device_id *, const struct vio_dev *);
-
 struct vio_dev vio_bus_device  = { /* fake "parent" device */
 	.name = vio_bus_device.dev.bus_id,
 	.type = "",
@@ -35,6 +32,27 @@ struct vio_dev vio_bus_device  = { /* fa
 
 static struct vio_bus_ops vio_bus_ops;
 
+/**
+ * vio_match_device: - Tell if a VIO device has a matching
+ *			VIO device id structure.
+ * @ids:	array of VIO device id structures to search in
+ * @dev:	the VIO device structure to match against
+ *
+ * Used by a driver to check whether a VIO device present in the
+ * system is in its list of supported devices. Returns the matching
+ * vio_device_id structure or NULL if there is no match.
+ */
+static const struct vio_device_id *vio_match_device(
+		const struct vio_device_id *ids, const struct vio_dev *dev)
+{
+	while (ids->type[0] != '\0') {
+		if (vio_bus_ops.match(ids, dev))
+			return ids;
+		ids++;
+	}
+	return NULL;
+}
+
 /*
  * Convert from struct device to struct vio_dev and pass to driver.
  * dev->driver has already been set by generic code because vio_bus_match
@@ -107,25 +125,70 @@ void vio_unregister_driver(struct vio_dr
 EXPORT_SYMBOL(vio_unregister_driver);
 
 /**
- * vio_match_device: - Tell if a VIO device has a matching
- *			VIO device id structure.
- * @ids:	array of VIO device id structures to search in
- * @dev:	the VIO device structure to match against
+ * vio_register_device_node: - Register a new vio device.
+ * @of_node:	The OF node for this device.
  *
- * Used by a driver to check whether a VIO device present in the
- * system is in its list of supported devices. Returns the matching
- * vio_device_id structure or NULL if there is no match.
+ * Creates and initializes a vio_dev structure from the data in
+ * of_node (dev.platform_data) and adds it to the list of virtual devices.
+ * Returns a pointer to the created vio_dev or NULL if node has
+ * NULL device_type or compatible fields.
  */
-static const struct vio_device_id *vio_match_device(
-		const struct vio_device_id *ids, const struct vio_dev *dev)
+struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
 {
-	while (ids->type[0] != '\0') {
-		if (vio_bus_ops.match(ids, dev))
-			return ids;
-		ids++;
+	struct vio_dev *viodev;
+	unsigned int *unit_address;
+	unsigned int *irq_p;
+
+	/* we need the 'device_type' property, in order to match with drivers */
+	if (of_node->type == NULL) {
+		printk(KERN_WARNING "%s: node %s missing 'device_type'\n",
+				__FUNCTION__,
+				of_node->name ? of_node->name : "<unknown>");
+		return NULL;
 	}
-	return NULL;
+
+	unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
+	if (unit_address == NULL) {
+		printk(KERN_WARNING "%s: node %s missing 'reg'\n",
+				__FUNCTION__,
+				of_node->name ? of_node->name : "<unknown>");
+		return NULL;
+	}
+
+	/* allocate a vio_dev for this node */
+	viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL);
+	if (viodev == NULL)
+		return NULL;
+
+	viodev->dev.platform_data = of_node_get(of_node);
+
+	viodev->irq = NO_IRQ;
+	irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
+	if (irq_p) {
+		int virq = virt_irq_create_mapping(*irq_p);
+		if (virq == NO_IRQ) {
+			printk(KERN_ERR "Unable to allocate interrupt "
+			       "number for %s\n", of_node->full_name);
+		} else
+			viodev->irq = irq_offset_up(virq);
+	}
+
+	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
+	viodev->name = of_node->name;
+	viodev->type = of_node->type;
+	viodev->unit_address = *unit_address;
+	viodev->iommu_table = vio_bus_ops.build_iommu_table(viodev);
+
+	/* register with generic device framework */
+	if (vio_register_device(viodev) == NULL) {
+		/* XXX free TCE table */
+		kfree(viodev);
+		return NULL;
+	}
+
+	return viodev;
 }
+EXPORT_SYMBOL(vio_register_device_node);
 
 /**
  * vio_bus_init: - Initialize the virtual IO bus
@@ -133,6 +196,7 @@ static const struct vio_device_id *vio_m
 int __init vio_bus_init(struct vio_bus_ops *ops)
 {
 	int err;
+	struct device_node *node_vroot;
 
 	vio_bus_ops = *ops;
 
@@ -153,23 +217,54 @@ int __init vio_bus_init(struct vio_bus_o
 		return err;
 	}
 
+	node_vroot = find_devices("vdevice");
+	if (node_vroot) {
+		struct device_node *of_node;
+
+		/*
+		 * Create struct vio_devices for each virtual device in
+		 * the device tree. Drivers will associate with them later.
+		 */
+		for (of_node = node_vroot->child; of_node != NULL;
+				of_node = of_node->sibling) {
+			printk(KERN_DEBUG "%s: processing %p\n",
+					__FUNCTION__, of_node);
+			vio_register_device_node(of_node);
+		}
+	}
+
 	return 0;
 }
 
 /* vio_dev refcount hit 0 */
 static void __devinit vio_dev_release(struct device *dev)
 {
-	if (vio_bus_ops.release_device)
-		vio_bus_ops.release_device(dev);
+	if (dev->platform_data) {
+		/* XXX free TCE table */
+		of_node_put(dev->platform_data);
+	}
 	kfree(to_vio_dev(dev));
 }
 
-static ssize_t viodev_show_name(struct device *dev,
+static ssize_t name_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
 }
-DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL);
+
+static ssize_t devspec_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct device_node *of_node = dev->platform_data;
+
+	return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
+}
+
+static struct device_attribute vio_dev_attrs[] = {
+	__ATTR_RO(name),
+	__ATTR_RO(devspec),
+	__ATTR_NULL
+};
 
 struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev)
 {
@@ -184,16 +279,12 @@ struct vio_dev * __devinit vio_register_
 				__FUNCTION__, viodev->dev.bus_id);
 		return NULL;
 	}
-	device_create_file(&viodev->dev, &dev_attr_name);
 
 	return viodev;
 }
 
 void __devinit vio_unregister_device(struct vio_dev *viodev)
 {
-	if (vio_bus_ops.unregister_device)
-		vio_bus_ops.unregister_device(viodev);
-	device_remove_file(&viodev->dev, &dev_attr_name);
 	device_unregister(&viodev->dev);
 }
 EXPORT_SYMBOL(vio_unregister_device);
@@ -267,22 +358,23 @@ static int vio_hotplug(struct device *de
 			char *buffer, int buffer_size)
 {
 	const struct vio_dev *vio_dev = to_vio_dev(dev);
+	struct device_node *dn = dev->platform_data;
 	char *cp;
 	int length;
 
 	if (!num_envp)
 		return -ENOMEM;
 
-	if (!vio_dev->dev.platform_data)
+	if (!dn)
 		return -ENODEV;
-	cp = (char *)get_property(vio_dev->dev.platform_data, "compatible", &length);
+	cp = (char *)get_property(dn, "compatible", &length);
 	if (!cp)
 		return -ENODEV;
 
 	envp[0] = buffer;
 	length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
 				vio_dev->type, cp);
-	if (buffer_size - length <= 0)
+	if ((buffer_size - length) <= 0)
 		return -ENOMEM;
 	envp[1] = NULL;
 	return 0;
@@ -290,6 +382,7 @@ static int vio_hotplug(struct device *de
 
 struct bus_type vio_bus_type = {
 	.name = "vio",
+	.dev_attrs = vio_dev_attrs,
 	.uevent = vio_hotplug,
 	.match = vio_bus_match,
 	.probe = vio_bus_probe,
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 9ce2afc..af5609a 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -54,6 +54,7 @@ #include <asm/iseries/mf.h>
 #include <asm/iseries/it_exp_vpd_panel.h>
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/lpar_map.h>
+#include <asm/iseries/vio.h>
 #include <asm/udbg.h>
 #include <asm/irq.h>
 
@@ -939,6 +940,7 @@ void dt_vdevices(struct iseries_flat_dt 
 	dt_end_node(dt);
 	reg++;
 
+	vio_first_vlan_unit = reg;
 	vlan_map = HvLpConfig_getVirtualLanIndexMap();
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
 		unsigned char mac_addr[6];
@@ -964,6 +966,7 @@ void dt_vdevices(struct iseries_flat_dt 
 	}
 	reg += HVMAXARCHITECTEDVIRTUALLANS;
 
+	vio_first_viodasd_unit = reg;
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) {
 		snprintf(buf, 32, "viodasd@%08x", reg + i);
 		dt_start_node(dt, buf);
@@ -973,6 +976,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		dt_end_node(dt);
 	}
 	reg += HVMAXARCHITECTEDVIRTUALDISKS;
+	vio_first_viocd_unit = reg;
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) {
 		snprintf(buf, 32, "viocd@%08x", reg + i);
 		dt_start_node(dt, buf);
@@ -982,6 +986,7 @@ void dt_vdevices(struct iseries_flat_dt 
 		dt_end_node(dt);
 	}
 	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
+	vio_first_viotape_unit = reg;
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) {
 		snprintf(buf, 32, "viotape@%08x", reg + i);
 		dt_start_node(dt, buf);
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 22045a2..5cd197b 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -24,6 +24,15 @@ #include <asm/iseries/hv_call_xm.h>
 
 #include "iommu.h"
 
+int vio_first_vlan_unit;
+EXPORT_SYMBOL(vio_first_vlan_unit);
+int vio_first_viodasd_unit;
+EXPORT_SYMBOL(vio_first_viodasd_unit);
+int vio_first_viocd_unit;
+EXPORT_SYMBOL(vio_first_viocd_unit);
+int vio_first_viotape_unit;
+EXPORT_SYMBOL(vio_first_viotape_unit);
+
 struct device *iSeries_vio_dev = &vio_bus_device.dev;
 EXPORT_SYMBOL(iSeries_vio_dev);
 
@@ -43,58 +52,11 @@ static void __init iommu_vio_init(void)
 		printk("Virtual Bus VIO TCE table failed.\n");
 }
 
-/**
- * vio_register_device_iseries: - Register a new iSeries vio device.
- * @voidev:	The device to register.
- */
-static struct vio_dev *__init vio_register_device_iseries(char *type,
-		uint32_t unit_num)
-{
-	struct vio_dev *viodev;
-
-	/* allocate a vio_dev for this device */
-	viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
-	if (!viodev)
-		return NULL;
-	memset(viodev, 0, sizeof(struct vio_dev));
-
-	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num);
-
-	viodev->name = viodev->dev.bus_id;
-	viodev->type = type;
-	viodev->unit_address = unit_num;
-	viodev->iommu_table = &vio_iommu_table;
-	if (vio_register_device(viodev) == NULL) {
-		kfree(viodev);
-		return NULL;
-	}
-	return viodev;
-}
-
-static void __init probe_bus_iseries(void)
+static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
 {
-	HvLpIndexMap vlan_map;
-	struct vio_dev *viodev;
-	int i;
-
-	/* there is only one of each of these */
-	vio_register_device_iseries("viocons", 0);
-	vio_register_device_iseries("vscsi", 0);
-
-	vlan_map = HvLpConfig_getVirtualLanIndexMap();
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
-		if ((vlan_map & (0x8000 >> i)) == 0)
-			continue;
-		viodev = vio_register_device_iseries("vlan", i);
-		/* veth is special and has it own iommu_table */
-		viodev->iommu_table = &veth_iommu_table;
-	}
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
-		vio_register_device_iseries("viodasd", i);
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
-		vio_register_device_iseries("viocd", i);
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
-		vio_register_device_iseries("viotape", i);
+	if (strcmp(dev->type, "vlan") == 0)
+		return &veth_iommu_table;
+	return &vio_iommu_table;
 }
 
 /**
@@ -109,6 +71,7 @@ static int vio_match_device_iseries(cons
 
 static struct vio_bus_ops vio_bus_ops_iseries = {
 	.match = vio_match_device_iseries,
+	.build_iommu_table = vio_build_iommu_table,
 };
 
 /**
@@ -116,16 +79,10 @@ static struct vio_bus_ops vio_bus_ops_is
  */
 static int __init vio_bus_init_iseries(void)
 {
-	int err;
-
-	err = vio_bus_init(&vio_bus_ops_iseries);
-	if (err == 0) {
-		iommu_vio_init();
-		vio_bus_device.iommu_table = &vio_iommu_table;
-		iSeries_vio_dev = &vio_bus_device.dev;
-		probe_bus_iseries();
-	}
-	return err;
+	iommu_vio_init();
+	vio_bus_device.iommu_table = &vio_iommu_table;
+	iSeries_vio_dev = &vio_bus_device.dev;
+	return vio_bus_init(&vio_bus_ops_iseries);
 }
 
 __initcall(vio_bus_init_iseries);
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index 8e53e04..8f9e3a6 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -26,26 +26,6 @@ #include <asm/tce.h>
 
 extern struct subsystem devices_subsys; /* needed for vio_find_name() */
 
-static void probe_bus_pseries(void)
-{
-	struct device_node *node_vroot, *of_node;
-
-	node_vroot = find_devices("vdevice");
-	if ((node_vroot == NULL) || (node_vroot->child == NULL))
-		/* this machine doesn't do virtual IO, and that's ok */
-		return;
-
-	/*
-	 * Create struct vio_devices for each virtual device in the device tree.
-	 * Drivers will associate with them later.
-	 */
-	for (of_node = node_vroot->child; of_node != NULL;
-			of_node = of_node->sibling) {
-		printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node);
-		vio_register_device_node(of_node);
-	}
-}
-
 /**
  * vio_match_device_pseries: - Tell if a pSeries VIO device matches a
  *	vio_device_id
@@ -57,47 +37,6 @@ static int vio_match_device_pseries(cons
 			device_is_compatible(dev->dev.platform_data, id->compat);
 }
 
-static void vio_release_device_pseries(struct device *dev)
-{
-	/* XXX free TCE table */
-	of_node_put(dev->platform_data);
-}
-
-static ssize_t viodev_show_devspec(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct device_node *of_node = dev->platform_data;
-
-	return sprintf(buf, "%s\n", of_node->full_name);
-}
-DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
-
-static void vio_unregister_device_pseries(struct vio_dev *viodev)
-{
-	device_remove_file(&viodev->dev, &dev_attr_devspec);
-}
-
-static struct vio_bus_ops vio_bus_ops_pseries = {
-	.match = vio_match_device_pseries,
-	.unregister_device = vio_unregister_device_pseries,
-	.release_device = vio_release_device_pseries,
-};
-
-/**
- * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
- */
-static int __init vio_bus_init_pseries(void)
-{
-	int err;
-
-	err = vio_bus_init(&vio_bus_ops_pseries);
-	if (err == 0)
-		probe_bus_pseries();
-	return err;
-}
-
-__initcall(vio_bus_init_pseries);
-
 /**
  * vio_build_iommu_table: - gets the dma information from OF and
  *	builds the TCE tree.
@@ -136,73 +75,20 @@ static struct iommu_table *vio_build_iom
 	return iommu_init_table(newTceTable);
 }
 
+static struct vio_bus_ops vio_bus_ops_pseries = {
+	.match = vio_match_device_pseries,
+	.build_iommu_table = vio_build_iommu_table,
+};
+
 /**
- * vio_register_device_node: - Register a new vio device.
- * @of_node:	The OF node for this device.
- *
- * Creates and initializes a vio_dev structure from the data in
- * of_node (dev.platform_data) and adds it to the list of virtual devices.
- * Returns a pointer to the created vio_dev or NULL if node has
- * NULL device_type or compatible fields.
+ * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
  */
-struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
+static int __init vio_bus_init_pseries(void)
 {
-	struct vio_dev *viodev;
-	unsigned int *unit_address;
-	unsigned int *irq_p;
-
-	/* we need the 'device_type' property, in order to match with drivers */
-	if ((NULL == of_node->type)) {
-		printk(KERN_WARNING
-			"%s: node %s missing 'device_type'\n", __FUNCTION__,
-			of_node->name ? of_node->name : "<unknown>");
-		return NULL;
-	}
-
-	unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
-	if (!unit_address) {
-		printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__,
-			of_node->name ? of_node->name : "<unknown>");
-		return NULL;
-	}
-
-	/* allocate a vio_dev for this node */
-	viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
-	if (!viodev) {
-		return NULL;
-	}
-	memset(viodev, 0, sizeof(struct vio_dev));
-
-	viodev->dev.platform_data = of_node_get(of_node);
-
-	viodev->irq = NO_IRQ;
-	irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
-	if (irq_p) {
-		int virq = virt_irq_create_mapping(*irq_p);
-		if (virq == NO_IRQ) {
-			printk(KERN_ERR "Unable to allocate interrupt "
-			       "number for %s\n", of_node->full_name);
-		} else
-			viodev->irq = irq_offset_up(virq);
-	}
-
-	snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
-	viodev->name = of_node->name;
-	viodev->type = of_node->type;
-	viodev->unit_address = *unit_address;
-	viodev->iommu_table = vio_build_iommu_table(viodev);
-
-	/* register with generic device framework */
-	if (vio_register_device(viodev) == NULL) {
-		/* XXX free TCE table */
-		kfree(viodev);
-		return NULL;
-	}
-	device_create_file(&viodev->dev, &dev_attr_devspec);
-
-	return viodev;
+	return vio_bus_init(&vio_bus_ops_pseries);
 }
-EXPORT_SYMBOL(vio_register_device_node);
+
+__initcall(vio_bus_init_pseries);
 
 /**
  * vio_get_attribute: - get attribute for virtual device
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index f63e07b..1dbcc35 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -718,7 +718,8 @@ static DRIVER_ATTR(probe, S_IWUSR, NULL,
 
 static int viodasd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 {
-	struct viodasd_device *d = &viodasd_devices[vdev->unit_address];
+	struct viodasd_device *d =
+		&viodasd_devices[vdev->unit_address - vio_first_viodasd_unit];
 
 	d->dev = &vdev->dev;
 	probe_disk(d);
@@ -731,7 +732,7 @@ static int viodasd_remove(struct vio_dev
 {
 	struct viodasd_device *d;
 
-	d = &viodasd_devices[vdev->unit_address];
+	d = &viodasd_devices[vdev->unit_address - vio_first_viodasd_unit];
 	if (d->disk) {
 		del_gendisk(d->disk);
 		blk_cleanup_queue(d->disk->queue);
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index c0f817b..8547b35 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -649,7 +649,7 @@ static int viocd_probe(struct vio_dev *v
 	struct cdrom_info *ci;
 	struct request_queue *q;
 
-	deviceno = vdev->unit_address;
+	deviceno = vdev->unit_address - vio_first_viocd_unit;
 	if (deviceno >= viocd_numdev)
 		return -ENODEV;
 
@@ -714,7 +714,8 @@ out:
 
 static int viocd_remove(struct vio_dev *vdev)
 {
-	struct disk_info *d = &viocd_diskinfo[vdev->unit_address];
+	struct disk_info *d =
+		&viocd_diskinfo[vdev->unit_address - vio_first_viocd_unit];
 
 	if (unregister_cdrom(&d->viocd_info) != 0)
 		printk(VIOCD_KERN_WARNING
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 60aabdb..e2c69f1 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -944,7 +944,7 @@ static void vioHandleTapeEvent(struct Hv
 static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 {
 	char tapename[32];
-	int i = vdev->unit_address;
+	int i = vdev->unit_address - vio_first_viotape_unit;
 	int j;
 
 	if (i >= viotape_numdev)
@@ -974,7 +974,7 @@ static int viotape_probe(struct vio_dev 
 
 static int viotape_remove(struct vio_dev *vdev)
 {
-	int i = vdev->unit_address;
+	int i = vdev->unit_address - vio_first_viotape_unit;
 
 	devfs_remove("iseries/nvt%d", i);
 	devfs_remove("iseries/vt%d", i);
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index f0f04be..1b98915 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -77,6 +77,7 @@ #include <asm/uaccess.h>
 #include <asm/iseries/hv_lp_config.h>
 #include <asm/iseries/hv_types.h>
 #include <asm/iseries/hv_lp_event.h>
+#include <asm/iseries/vio.h>
 #include <asm/iommu.h>
 #include <asm/vio.h>
 
@@ -1577,7 +1578,7 @@ static int veth_remove(struct vio_dev *v
 	struct veth_port *port;
 	int i;
 
-	dev = veth_dev[vdev->unit_address];
+	dev = veth_dev[vdev->unit_address - vio_first_vlan_unit];
 
 	if (! dev)
 		return 0;
@@ -1593,7 +1594,7 @@ static int veth_remove(struct vio_dev *v
 		}
 	}
 
-	veth_dev[vdev->unit_address] = NULL;
+	veth_dev[vdev->unit_address - vio_first_vlan_unit] = NULL;
 	kobject_del(&port->kobject);
 	kobject_put(&port->kobject);
 	unregister_netdev(dev);
@@ -1604,7 +1605,7 @@ static int veth_remove(struct vio_dev *v
 
 static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 {
-	int i = vdev->unit_address;
+	int i = vdev->unit_address - vio_first_vlan_unit;
 	struct net_device *dev;
 	struct veth_port *port;
 
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 72a97d3..fe073e6 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -126,4 +126,9 @@ struct device;
 
 extern struct device *iSeries_vio_dev;
 
+extern int vio_first_vlan_unit;
+extern int vio_first_viodasd_unit;
+extern int vio_first_viocd_unit;
+extern int vio_first_viotape_unit;
+
 #endif /* _ASM_POWERPC_ISERIES_VIO_H */
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 0544ece..dea55c7 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -66,8 +66,7 @@ struct vio_driver {
 
 struct vio_bus_ops {
 	int (*match)(const struct vio_device_id *id, const struct vio_dev *dev);
-	void (*unregister_device)(struct vio_dev *);
-	void (*release_device)(struct device *);
+	struct iommu_table *(*build_iommu_table)(struct vio_dev *dev);
 };
 
 extern struct dma_mapping_ops vio_dma_ops;
@@ -82,11 +81,11 @@ extern void __devinit vio_unregister_dev
 
 extern int vio_bus_init(struct vio_bus_ops *);
 
-#ifdef CONFIG_PPC_PSERIES
 struct device_node;
 
 extern struct vio_dev * __devinit vio_register_device_node(
 		struct device_node *node_vdev);
+#ifdef CONFIG_PPC_PSERIES
 extern struct vio_dev *vio_find_node(struct device_node *vnode);
 extern const void *vio_get_attribute(struct vio_dev *vdev, void *which,
 		int *length);
-- 
1.3.1

^ permalink raw reply related

* Re: [RFC 1/2] powerpc: add all the iSeries virtual devices to the device tree
From: Michael Ellerman @ 2006-04-25 13:17 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev
In-Reply-To: <20060425215405.648a16e7.sfr@canb.auug.org.au>

[-- Attachment #1: Type: text/plain, Size: 3048 bytes --]

On Tue, 2006-04-25 at 21:54 +1000, Stephen Rothwell wrote:
> We do this by putting them in the flattened device tree at setup time.
> This required the flattened device tree blob to be made bigger.

Fully sick! As the kids say .. I hear.

We should probably think about allocating the blob at run time, just by
sticking it at klimit. I think I decided that was a good idea, I just
never got around to coding it up.

> 676ab187518bfb5e48aa4c3cc418456e67a2ed70
> diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
> index 3c51448..9ce2afc 100644
> --- a/arch/powerpc/platforms/iseries/setup.c
> +++ b/arch/powerpc/platforms/iseries/setup.c
> @@ -45,6 +45,7 @@ #include <asm/paca.h>
>  #include <asm/cache.h>
>  #include <asm/sections.h>
>  #include <asm/abs_addr.h>
> +#include <asm/iseries/hv_types.h>
>  #include <asm/iseries/hv_lp_config.h>
>  #include <asm/iseries/hv_call_event.h>
>  #include <asm/iseries/hv_call_xm.h>
> @@ -710,7 +711,7 @@ define_machine(iseries) {
>  };
>  
>  struct blob {
> -	unsigned char data[PAGE_SIZE];
> +	unsigned char data[PAGE_SIZE * 2];
>  	unsigned long next;
>  };
>  
> @@ -911,6 +912,88 @@ void dt_model(struct iseries_flat_dt *dt
>  	dt_prop_str(dt, "compatible", "IBM,iSeries");
>  }
>  
> +void dt_vdevices(struct iseries_flat_dt *dt)
> +{
> +	u32 reg = 0;
> +	HvLpIndexMap vlan_map;
> +	int i;
> +	char buf[32];
> +
> +	dt_start_node(dt, "vdevice");
> +	dt_prop_u32(dt, "#address-cells", 1);
> +	dt_prop_u32(dt, "#size-cells", 0);
> +
> +	snprintf(buf, sizeof(buf), "viocons@%08x", reg);
> +	dt_start_node(dt, buf);
> +	dt_prop_str(dt, "device_type", "serial");
> +	dt_prop_empty(dt, "compatible");
> +	dt_prop_u32(dt, "reg", reg);
> +	dt_end_node(dt);
> +	reg++;
> +
> +	snprintf(buf, sizeof(buf), "v-scsi@%08x", reg);
> +	dt_start_node(dt, buf);
> +	dt_prop_str(dt, "device_type", "vscsi");
> +	dt_prop_str(dt, "compatible", "IBM,v-scsi");
> +	dt_prop_u32(dt, "reg", reg);
> +	dt_end_node(dt);
> +	reg++;
> +
> +	vlan_map = HvLpConfig_getVirtualLanIndexMap();
> +	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
> +		unsigned char mac_addr[6];

ETH_ALEN instead of 6 ?

> +
> +		if ((vlan_map & (0x8000 >> i)) == 0)
> +			continue;
> +		snprintf(buf, 32, "vlan@%08x", reg + i);
> +		dt_start_node(dt, buf);
> +		dt_prop_str(dt, "device_type", "vlan");
> +		dt_prop_empty(dt, "compatible");
> +		dt_prop_u32(dt, "reg", reg + i);
> +
> +		mac_addr[0] = 0x02;
> +		mac_addr[1] = 0x01;
> +		mac_addr[2] = 0xff;
> +		mac_addr[3] = i;
> +		mac_addr[4] = 0xff;
> +		mac_addr[5] = HvLpConfig_getLpIndex_outline();
> +		dt_prop(dt, "local-mac-address", (char *)mac_addr, 6);
> +		dt_prop(dt, "mac-address", (char *)mac_addr, 6);

Ditto, ditto.

cheers

-- 
Michael Ellerman
IBM OzLabs

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply

* Re: [RFC 2/2] powerpc: use the device tree for the iSeries vio bus probe
From: Michael Ellerman @ 2006-04-25 13:22 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev
In-Reply-To: <20060425215950.36c01f2b.sfr@canb.auug.org.au>

[-- Attachment #1: Type: text/plain, Size: 2909 bytes --]

On Tue, 2006-04-25 at 21:59 +1000, Stephen Rothwell wrote:
> As an added bonus, since every vio_dev now has a device_node
> associated with it, hotplug now works.
> 
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>

> diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
> index 9ce2afc..af5609a 100644
> --- a/arch/powerpc/platforms/iseries/setup.c
> +++ b/arch/powerpc/platforms/iseries/setup.c
> @@ -54,6 +54,7 @@ #include <asm/iseries/mf.h>
>  #include <asm/iseries/it_exp_vpd_panel.h>
>  #include <asm/iseries/hv_lp_event.h>
>  #include <asm/iseries/lpar_map.h>
> +#include <asm/iseries/vio.h>
>  #include <asm/udbg.h>
>  #include <asm/irq.h>
>  
> @@ -939,6 +940,7 @@ void dt_vdevices(struct iseries_flat_dt 
>  	dt_end_node(dt);
>  	reg++;
>  
> +	vio_first_vlan_unit = reg;
>  	vlan_map = HvLpConfig_getVirtualLanIndexMap();
>  	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
>  		unsigned char mac_addr[6];
> @@ -964,6 +966,7 @@ void dt_vdevices(struct iseries_flat_dt 
>  	}
>  	reg += HVMAXARCHITECTEDVIRTUALLANS;
>  
> +	vio_first_viodasd_unit = reg;
>  	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) {
>  		snprintf(buf, 32, "viodasd@%08x", reg + i);
>  		dt_start_node(dt, buf);
> @@ -973,6 +976,7 @@ void dt_vdevices(struct iseries_flat_dt 
>  		dt_end_node(dt);
>  	}
>  	reg += HVMAXARCHITECTEDVIRTUALDISKS;
> +	vio_first_viocd_unit = reg;
>  	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) {
>  		snprintf(buf, 32, "viocd@%08x", reg + i);
>  		dt_start_node(dt, buf);
> @@ -982,6 +986,7 @@ void dt_vdevices(struct iseries_flat_dt 
>  		dt_end_node(dt);
>  	}
>  	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
> +	vio_first_viotape_unit = reg;
>  	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) {
>  		snprintf(buf, 32, "viotape@%08x", reg + i);
>  		dt_start_node(dt, buf);
> diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
> index 22045a2..5cd197b 100644
> --- a/arch/powerpc/platforms/iseries/vio.c
> +++ b/arch/powerpc/platforms/iseries/vio.c
> @@ -24,6 +24,15 @@ #include <asm/iseries/hv_call_xm.h>
>  
>  #include "iommu.h"
>  
> +int vio_first_vlan_unit;
> +EXPORT_SYMBOL(vio_first_vlan_unit);
> +int vio_first_viodasd_unit;
> +EXPORT_SYMBOL(vio_first_viodasd_unit);
> +int vio_first_viocd_unit;
> +EXPORT_SYMBOL(vio_first_viocd_unit);
> +int vio_first_viotape_unit;
> +EXPORT_SYMBOL(vio_first_viotape_unit);

Why do we need these guys? If we have to have them then I'd rather they
were in the device tree, rather than have the "bootloader" passing info
to the kernel via globals.

cheers

-- 
Michael Ellerman
IBM OzLabs

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply

* maple_defconfig - CONFIG_ALTIVEC is not set
From: Stephen Winiecki @ 2006-04-25 13:29 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 124 bytes --]





Is there a reason why ALTIVEC is not enabled in maple_defconfig?  Can it be
enabled in future versions?

Thanks,

Steve

[-- Attachment #2: Type: text/html, Size: 175 bytes --]

^ permalink raw reply

* Kernel panic on mpc852.
From: Gautam Borad @ 2006-04-25 13:57 UTC (permalink / raw)
  To: linuxppc-embedded

Hi,
I'm trying to port linux-2.4.21 to mpc852t custom board.
The bootloader (u-boot) works fine and the kernel boots.
The kernel is _VERY_ unstable, in that it gives sig 11
( Oops: kernel access of bad area, sig: 11 ) at random
intervals.
I've created this short test program :

    int *testmem;
    g = atoi(argv[1]);
    if(( testmem =(int*)malloc(1024*g)) == NULL ) {
        printf("mem test failed at iteration : %d",i);
        exit(0);
    }
    bzero(testmem,1024*g);
    printf("mem test at 0x%08x \t i = %d\n",testmem,i);

We have 32MB RAM.The above code never returns cleanly,
it always gives panic with sig 11.
I've added a printk to arch/ppc/mm/fault.c kernel for debugging purpose

    if (!(vma->vm_flags & VM_GROWSDOWN)){
        printk("\nerror : vm_start = 0x%08x  Address = 0x%08x\n 
",vma->vm_start,address);
        goto bad_area;
    }

Sample output:

[root]$ ./b0memtest 64

mem test at 0x10010c60   i = 0
mem test at 0x10020c68   i = 1
....
mem test at 0x10140cf8   i = 19
mem test at 0x10150d00   i = 20
mem test at 0x10160d08   i = 21

<comment> The following is my printk from arch/ppc/mm/fault.c </comment>

vm_start = 0x10000000 vm_end = 0x10001000 Address = 0x00000024  <===== 
Why is it trying to access 0x00000024

 Oops: kernel access of bad area, sig: 11
 NIP: C000B80C XER: 00000000 LR: C000B7F4 SP: C1D59F00 REGS: c1d59e50 
TRAP: 0300    Not tainted
 MSR: 00009032 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11
 DAR: 00000024, DSISR: 0000000B
 TASK = c1d58000[32] 'b0memtest' Last syscall: 4
 last math 00000000 last altivec 00000000
 GPR00: 00000005 C1D59F00 C1D58000 00009032 C1F22C3C C1D59EA0 C0138258 
00000000
 GPR08: C1D58000 00000006 C0136050 00000000 44004082 00000000 00000000 
00000000
 GPR16: 00000000 00000000 00000000 00000000 C0160000 C0140000 C0130000 
C0140000
 GPR24: C00025C0 10000A00 7FFFFB40 00000020 C1D58000 C0144940 00000000 
C1D59F00
 Call backtrace:
 10000A00 C000286C 3003B55E 30068BF8 3006954C 300690F8 3006CA50
 30068024 10000788 300593A4 00000000

[root]$ ./b0memtest 128

mem test at 0x10010c60   i = 0
mem test at 0x10030c68   i = 1
....
mem test at 0x10190cc0   i = 12
mem test at 0x101b0cc8   i = 13

<comment> Again the same address </comment>

vm_start = 0x10000000 vm_end = 0x10001000 Address = 0x00000024   <=====

 Oops: kernel access of bad area, sig: 11
 NIP: C000B80C XER: 00000000 LR: C000B7F4 SP: C1DE1F00 REGS: c1de1e50 
TRAP: 0300    Not tainted
 MSR: 00009032 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11
 DAR: 00000024, DSISR: 0000000B
 TASK = c1de0000[24] 'b0memtest' Last syscall: 45
 last math 00000000 last altivec 00000000
 GPR00: 00000005 C1DE1F00 C1DE0000 00009032 00001032 000000E4 C0138258 
00000000
 GPR08: C1DE0000 00000006 C0136050 00000000 04000084 00000000 00000000 
00000000
 GPR16: 00000000 00000000 00000000 00000000 C0160000 C0140000 C0130000 
C0140000
 GPR24: C0003F78 10000A00 00000002 100004D8 C1DE0000 C0144940 00000000 
C1DE1F00
 Call backtrace:
 C000402C C000286C 30074024 10000728 300593A4 00000000

Thanks in advance.

^ permalink raw reply

* Re: 85xx FDT updates?
From: Kumar Gala @ 2006-04-25 14:05 UTC (permalink / raw)
  To: Eugene Surovegin; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20060425074902.GA20228@gate.ebshome.net>


On Apr 25, 2006, at 2:49 AM, Eugene Surovegin wrote:

> On Tue, Apr 25, 2006 at 01:08:00AM -0500, Kumar Gala wrote:
>>
>> On Apr 24, 2006, at 5:31 PM, Dan Malek wrote:
>>
>>>
>>> On Apr 24, 2006, at 5:43 PM, Kumar Gala wrote:
>>>
>>>> However, I am against removing the arch/ppc support until the u- 
>>>> boot
>>>> patches are picked up.  I think its bad form to give people a  
>>>> kernel
>>>> they can't easily boot.
>>>
>>> What about systems that can't update u-boot, but want to run
>>> a newer kernel?
>>
>> Does this situation exist for any in tree boards that are supported?
>
> Kumar, with all due respect, I don't like this attitude. I can have
> eval board where I don't want to upgrade firmware.
>
> Also, this "let's screw everybody who doesn't have their board support
> in tree" is very counter productive. FYI, almost all my contributed
> kernel work was done on custom hardware, not on reference boards.
>
> It seems some people here lost touch with reality - embedded Linux is
> mostly run on custom hardware, not on evaluation boards.

Well, first all I said was that we shouldn't remove arch/ppc support  
until the u-boot patches are in.  I made no statement about when  
after that we should remove arch/ppc support.

Second, this seems normal like normal kernel development to me.  I  
think its reasonable to pick some time frame after which we will  
remove the support and to let everyone know what that is.  I see this  
as no different than having a driver outside of the kernel tree and  
having it break when APIs change.

- kumar

^ permalink raw reply

* Re: Rebuilding FS MDS 8349 BSP & JFFS2 integration
From: Kumar Gala @ 2006-04-25 14:18 UTC (permalink / raw)
  To: Krawczuk, Victor; +Cc: linuxppc-embedded
In-Reply-To: <64A27FD84D948C48ABF3250BF78446FD01B7DF5D@OTTSVW100.gdcan.com>


On Apr 24, 2006, at 4:30 PM, Krawczuk, Victor wrote:

> Hi,
>
> I am a newbie to Linux but not to embedded PPC. I was hoping =20
> someone could point me to the direction here. I apologize in =20
> advance if this is kindergarten stuff.
>
> I downloaded the MDS-8349 Linux BSP from FreeScale. I was able to =20
> burn the default prebuilt images "uboot" and "jffs2.img" to my =20
> MDS-8349 (PB) board and have uboot tftp the prebuilt "uImage" to my =20=

> PB. I used "tftpboot 200000 uImage" to download and "bootm" to =20
> boot.  As per included instructions, I had "setenv bootargs root=3D/=20=

> dev/mtdblock1 rootfstype=3Djffs2 rw console=3DttyS0,115200" in uboot, =20=

> followed by a "saveenv". The prebuilt Linux (uImage) came up, no =20
> problem.
>
> As I need to include USB Host support to the PPC kernel, I used the =20=

> ltib tool to reconfigure and rebuild Linux, as well as a matching =20
> jffs2 (I would think). Ltib produced vmlinux.gz.uboot and =20
> rootfs.jffs2 for me.  For some reason, rootfs.jffs2 was =20
> significantly smaller than the prebuilt "jffs2.img" (2483184 bytes =20
> vs. 4325376 bytes). I'm not sure why. I then did the following:
Questions regarding the Freescale BSP are best directed at Freescale =20
as they have a custom kernel they are providing with their BSPs.
> bootargs is still set to "root=3D/dev/mtdblock1 rootfstype=3Djffs2 rw =20=

> console=3DttyS0,115200"  in uboot:
>
> Using the same (prebuilt) uboot as before:
>
> - tftpboot 400000 rootfs.jffs2 (rebuilt jffs2)
> - erase fe020000 fe5fffff
> - cp.b 400000 fe020000 25e3f0
>
> - tftpboot 200000 vmlinux.gz.uboot (rebuilt Linux containing USB =20
> Host stuff)
> - bootm
>
> Linux could not boot!  I got the following root FS error:
>
> [stuff deleted=85]
> io scheduler deadline registered
> io scheduler cfq registered
> RAMDISK driver initialized: 16 RAM disks of 32768K size 1024 blocksize
> loop: loaded (max 8 devices)
> eth0: Gianfar Ethernet Controller Version 1.1, 00:04:9f:00:2d:b7
> eth0: Running with NAPI disabled
> eth0: 64/64 RX/TX BD ring size
> eth1: Gianfar Ethernet Controller Version 1.1, 00:04:9f:00:2d:b8
> eth1: Running with NAPI disabled
> eth1: 64/64 RX/TX BD ring size
> i2c /dev entries driver
> NET: Registered protocol family 2
> IP: routing cache hash table of 2048 buckets, 16Kbytes
> TCP established hash table entries: 16384 (order: 5, 131072 bytes)
> TCP bind hash table entries: 16384 (order: 4, 65536 bytes)
> TCP: Hash tables configured (established 16384 bind 16384)
> NET: Registered protocol family 1
> NET: Registered protocol family 17
> Root-NFS: No NFS server available, giving up.
> VFS: Unable to mount root fs via NFS, trying floppy.
> VFS: Cannot open root device "mtdblock1" or unknown-block(2,0)
> Please append a correct "root=3D" boot option
> Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-=20=

> block(2,0)
>  <0>Rebooting in 180 seconds..
>
> Would anybody happen to know what is going wrong?  How am I =20
> supposed to know the correct "root=3D" boot option for a rebuilt =20
> jffs2 using LTIB, if that is my problem?
Where there any messages related to MTD or flash in the boot log?  If =20=

not that would seem to be the first place to look.

- kumar=

^ permalink raw reply

* USB working on MPC875/885 ?
From: Josef Angermeier @ 2006-04-25 15:03 UTC (permalink / raw)
  To: linuxppc-embedded


Hello,

anyone who got a USB working on the MPC885 or MPC875 processor ? With 
linux 2.4 ? Using the patch from brad parker ?

It would help me alot to know, if this has been successfully done 
before! Thanks in advance!

Best regards,
Josef

^ permalink raw reply

* Re: Re: PPC exception 0x320
From: jeanwelly @ 2006-04-25 15:03 UTC (permalink / raw)
  To: Becky Bruce; +Cc: linuxppc-embedded@ozlabs.org
In-Reply-To: <9866A56E-AF4C-477D-A035-E6D6A78A75D3@freescale.com>


SGkgQmVja3kgQnJ1Y2UsDQpJJ20gdXNpbmcgUFBDIDc1MC4uLiBKdXN0IGFzIHlvdSBzYWlkLCAw
eDMwMCBpcyBmb3IgRFNJLCBhbmQgSSBndWVzcyB0aGV5IGFyZSBhIHNldCBvZiBleGNlcHRpb25z
LCBub3QganVzdCBvbmUuIEFuZCAweDMyMCBpcyBvbmUgb2YgdGhlbS4NCkkgZ290IGEgYm9hcmQg
Y3Jhc2gsIGFuZCBQUEMgYWxhcm1lZCBleGNlcHRpb24gMHgzMjAuIENvdWxkIHlvdSBzaG93IG1l
IHRoZSBtZWNoYW5pc20gb2YgaGFuZGxpbmcgb2YgYSBzcGVjaWFsIGV4Y2VwdGlvbiBub3Qgb25l
IHNldC4NCgkNCg0KPT09PT09PSAyMDA2LTA0LTI1IDAyOjUzOjM1IMT61NrAtNDF1tDQtLXAo7o9
PT09PT09DQoNCj5Db3VsZCB5b3UgdHJ5IHRvIGJlIG1vcmUgc3BlY2lmaWM/ICBXaGF0IHByb2Nl
c3NvciBkbyB5b3UgaGF2ZSwgd2hhdCAgDQo+bGludXggdmVyc2lvbiBhcmUgeW91IHJ1bm5pbmcs
IGFuZCB3aGF0IGRvIHlvdSBtZWFuIGV4YWN0bHkgd2hlbiB5b3UgIA0KPnNheSB5b3UgImVuY291
bnRlcmVkIFBQQyBleGNlcHRpb24gMHgzMjAiPyAgQXMgZmFyIGFzIEkga25vdywgdGhlICANCj5w
b3dlcnBjIGFyY2hpdGVjdHVyZSBkb2VzIG5vdCBkZWZpbmUgYW4gZXhjZXB0aW9uIDB4MzIwLiAg
MHgzMDAgaXMgIA0KPnVzdWFsbHkgRFNJIG9uIGNsYXNzaWMgcG93ZXJwYyBwYXJ0cy4gIEJvb2tF
IHBhcnRzIGhhbmRsZSB0aGluZ3MgIA0KPmRpZmZlcmVudGx5Lg0KPg0KPlRoYW5rcywNCj4tQmVj
a3kNCj4NCj5PbiBBcHIgMjQsIDIwMDYsIGF0IDg6NTEgQU0sIGplYW53ZWxseSB3cm90ZToNCj4N
Cj4+IEhpLA0KPj4gSSBlbmNvdW50ZXJlZCBQUEMgZXhjZXB0aW9uIDB4MzIwLCBidXQgZG9uJ3Qg
a25vdyB3aGF0IGl0IGZvci4gQW55ICANCj4+IG9uZSBjb3VsZCBoZWxwIG1lIG9uIHRoaXM/DQo+
PiBUaGFua3MhDQo+PiAgCQkJCQ0KPj4NCj4+IKGhoaGhoaGhoaGhoaGhoaFqZWFud2VsbHkNCj4+
IKGhoaGhoaGhoaGhoaGhoaFqZWFud2VsbHlAMTI2LmNvbQ0KPj4goaGhoaGhoaGhoaGhoaGhoaGh
oaEyMDA2LTA0LTI0DQo+PiBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fXw0KPj4gTGludXhwcGMtZW1iZWRkZWQgbWFpbGluZyBsaXN0DQo+PiBMaW51eHBwYy1l
bWJlZGRlZEBvemxhYnMub3JnDQo+PiBodHRwczovL296bGFicy5vcmcvbWFpbG1hbi9saXN0aW5m
by9saW51eHBwYy1lbWJlZGRlZA0KPg0KPg0KPi4NCg0KPSA9ID0gPSA9ID0gPSA9ID0gPSA9ID0g
PSA9ID0gPSA9ID0gPSA9DQoJCQkNCg0KoaGhoaGhoaGhoaGhoaGhodbCDQrA8aOhDQogDQoJCQkJ
IA0KoaGhoaGhoaGhoaGhoaGhoWplYW53ZWxseQ0KoaGhoaGhoaGhoaGhoaGhoWplYW53ZWxseUAx
MjYuY29tDQqhoaGhoaGhoaGhoaGhoaGhoaGhoTIwMDYtMDQtMjUNCg0K

^ permalink raw reply

* Re: PPC exception 0x320
From: Becky Bruce @ 2006-04-25 15:44 UTC (permalink / raw)
  To: jeanwelly; +Cc: linuxppc-embedded@ozlabs.org
In-Reply-To: <200604252303190264825@126.com>

Is there some error message you can show me?

-B

On Apr 25, 2006, at 10:03 AM, jeanwelly wrote:

> Hi Becky Bruce,
> I'm using PPC 750... Just as you said, 0x300 is for DSI, and I =20
> guess they are a set of exceptions, not just one. And 0x320 is one =20
> of them.
> I got a board crash, and PPC alarmed exception 0x320. Could you =20
> show me the mechanism of handling of a special exception not one set.
> =09
>
> =3D=3D=3D=3D=3D=3D=3D 2006-04-25 02:53:35 =
=E6=82=A8=E5=9C=A8=E6=9D=A5=E4=BF=A1=E4=B8=AD=E5=86=99=E9=81=93=EF=BC=9A=3D=
=3D=3D=3D=3D=3D=3D
>
>> Could you try to be more specific?  What processor do you have, what
>> linux version are you running, and what do you mean exactly when you
>> say you "encountered PPC exception 0x320"?  As far as I know, the
>> powerpc architecture does not define an exception 0x320.  0x300 is
>> usually DSI on classic powerpc parts.  BookE parts handle things
>> differently.
>>
>> Thanks,
>> -Becky
>>
>> On Apr 24, 2006, at 8:51 AM, jeanwelly wrote:
>>
>>> Hi,
>>> I encountered PPC exception 0x320, but don't know what it for. Any
>>> one could help me on this?
>>> Thanks!
>>>  			=09
>>>
>>> =E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=
jeanwelly
>>> =E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=
jeanwelly@126.com
>>> =E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=
=E3=80=80=E3=80=802006-04-24
>>> _______________________________________________
>>> Linuxppc-embedded mailing list
>>> Linuxppc-embedded@ozlabs.org
>>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>
>>
>> .
>
> =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =
=3D =3D
> 		=09
>
> =E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=
=E8=87=B4
> =E7=A4=BC=EF=BC=81
>
> 			=09
> =E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=
jeanwelly
> =E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=
jeanwelly@126.com
> =E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=E3=80=80=
=E3=80=80=E3=80=802006-04-25
>

^ permalink raw reply

* Re: 85xx FDT updates?
From: Eugene Surovegin @ 2006-04-25 16:12 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <A64C3686-0123-4750-BA7B-630E8BF2E4D8@kernel.crashing.org>

On Tue, Apr 25, 2006 at 09:05:54AM -0500, Kumar Gala wrote:
> 
> Second, this seems normal like normal kernel development to me.  I  
> think its reasonable to pick some time frame after which we will  
> remove the support and to let everyone know what that is.  I see this  
> as no different than having a driver outside of the kernel tree and  
> having it break when APIs change.

I don't agree. This is not the same as changing _internal_ kernel API 
for a simple reason that _firmware_ was never part of the kernel and 
will never be. You seem to have an idea that's that's OK to _remove_ 
existing functionality from the kernel for no reason except your 
convenience. I think this is unacceptable. If kernel was able to boot 
on some hardware (including reference one) in the past it should be 
able to do this now even if this will require some boot shim.

-- 
Eugene

^ permalink raw reply

* Re: 85xx FDT updates?
From: Kumar Gala @ 2006-04-25 16:25 UTC (permalink / raw)
  To: Eugene Surovegin; +Cc: linuxppc-dev@ozlabs.org list, Paul Mackerras
In-Reply-To: <20060425161200.GC20228@gate.ebshome.net>


On Apr 25, 2006, at 11:12 AM, Eugene Surovegin wrote:

> On Tue, Apr 25, 2006 at 09:05:54AM -0500, Kumar Gala wrote:
>>
>> Second, this seems normal like normal kernel development to me.  I
>> think its reasonable to pick some time frame after which we will
>> remove the support and to let everyone know what that is.  I see this
>> as no different than having a driver outside of the kernel tree and
>> having it break when APIs change.
>
> I don't agree. This is not the same as changing _internal_ kernel API
> for a simple reason that _firmware_ was never part of the kernel and
> will never be. You seem to have an idea that's that's OK to _remove_
> existing functionality from the kernel for no reason except your
> convenience. I think this is unacceptable. If kernel was able to boot
> on some hardware (including reference one) in the past it should be
> able to do this now even if this will require some boot shim.

If we are talking about a reference board than I think this is an  
absurd requirement.  If you are willing to update your kernel on such  
a board why would you not be willing to update the firmware as well.

To my knowledge all the in tree boards that are supported for 85xx  
all boot via u-boot.  So if u-boot is available for the given board  
that is capable of booting an arch/powerpc kernel why would we need  
to continue supporting the board in arch/ppc.

- kumar 

^ permalink raw reply

* [PATCH 1/4] ppc32: odd fixes and improvements in ppc_sys
From: Vitaly Bordug @ 2006-04-25 16:26 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-embedded


This consists of offsets fix in ..._devices.c, and update of
ppc_sys_fixup_mem_resource() function to prevent subsequent fixups

Sigbed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
---

 arch/ppc/syslib/mpc8xx_devices.c |   25 +++++++++++++++++++------
 arch/ppc/syslib/ppc_sys.c        |    4 +++-
 arch/ppc/syslib/pq2_sys.c        |    8 ++++----
 include/asm-ppc/ppc_sys.h        |    2 ++
 4 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
index bd41ed8..6f53638 100644
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -170,12 +170,18 @@ struct platform_device ppc_sys_platform_
 	[MPC8xx_CPM_SMC1] = {
 		.name = "fsl-cpm-smc",
 		.id	= 1,
-		.num_resources	= 2,
+		.num_resources	= 3,
 		.resource = (struct resource[]) {
 			{
 				.name	= "regs",
-				.start	= 0xa82,
-				.end	= 0xa91,
+				.start	= 0xa80,
+				.end	= 0xa8f,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.name	= "pram",
+				.start	= 0x3e80,
+				.end	= 0x3ebf,
 				.flags	= IORESOURCE_MEM,
 			},
 			{
@@ -189,15 +195,22 @@ struct platform_device ppc_sys_platform_
 	[MPC8xx_CPM_SMC2] = {
 		.name = "fsl-cpm-smc",
 		.id	= 2,
-		.num_resources	= 2,
+		.num_resources	= 3,
 		.resource = (struct resource[]) {
 			{
 				.name	= "regs",
-				.start	= 0xa92,
-				.end	= 0xaa1,
+				.start	= 0xa90,
+				.end	= 0xa9f,
 				.flags	= IORESOURCE_MEM,
 			},
 			{
+ 				.name	= "pram",
+ 				.start	= 0x3f80,
+ 				.end	= 0x3fbf,
+ 				.flags	= IORESOURCE_MEM,
+
+			},
+			{
 				.name	= "interrupt",
 				.start	= MPC8xx_INT_SMC2,
 				.end	= MPC8xx_INT_SMC2,
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 7662c4e..2d48018 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -109,9 +109,11 @@ ppc_sys_fixup_mem_resource(struct platfo
 	int i;
 	for (i = 0; i < pdev->num_resources; i++) {
 		struct resource *r = &pdev->resource[i];
-		if ((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) {
+		if (((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) && 
+			((r->flags & PPC_SYS_IORESOURCE_FIXUPPED) != PPC_SYS_IORESOURCE_FIXUPPED)) {
 			r->start += paddr;
 			r->end += paddr;
+			r->flags |= PPC_SYS_IORESOURCE_FIXUPPED;
 		}
 	}
 }
diff --git a/arch/ppc/syslib/pq2_sys.c b/arch/ppc/syslib/pq2_sys.c
index 75e64f1..433b0fa 100644
--- a/arch/ppc/syslib/pq2_sys.c
+++ b/arch/ppc/syslib/pq2_sys.c
@@ -113,13 +113,13 @@ struct ppc_sys_spec ppc_sys_specs[] = {
 		.ppc_sys_name	= "8248",
 		.mask		= 0x0000ff00,
 		.value		= 0x00000c00,
-		.num_devices	= 11,
+		.num_devices	= 12,
 		.device_list = (enum ppc_sys_devices[])
 		{
 			MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
-			MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SMC1,
-			MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C,
-			MPC82xx_CPM_USB, MPC82xx_SEC1,
+			MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4,
+			MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
+			MPC82xx_CPM_I2C, MPC82xx_CPM_USB, MPC82xx_SEC1,
 		},
 	},
 	{
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 4b94f70..40f197a 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -39,6 +39,8 @@
 #error "need definition of ppc_sys_devices"
 #endif
 
+#define PPC_SYS_IORESOURCE_FIXUPPED	0x00000001	
+
 struct ppc_sys_spec {
 	/* PPC sys is matched via (ID & mask) == value, id could be
 	 * PVR, SVR, IMMR, * etc. */

^ permalink raw reply related

* [PATCH 4/4] ppc32 CPM_UART: Fixed odd address translations
From: Vitaly Bordug @ 2006-04-25 16:26 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-embedded
In-Reply-To: <20060425162633.23551.85273.stgit@vitb.ru.mvista.com>


Current address translation methods can produce wrong results, because
virt_to_bus and vice versa may not produce correct offsets on dma-allocated
memory. The right way is, while tracking both phys and virt address of the
window that has been allocated for boffer descriptors, and use those
numbers to compute the offset and make translation properly.

Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
---

 drivers/serial/cpm_uart/cpm_uart.h      |   33 +++++++++++++++++++++++++++++++
 drivers/serial/cpm_uart/cpm_uart_core.c |   31 ++++++++---------------------
 drivers/serial/cpm_uart/cpm_uart_cpm1.c |    7 ++++---
 drivers/serial/cpm_uart/cpm_uart_cpm2.c |    5 ++++-
 4 files changed, 50 insertions(+), 26 deletions(-)

diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 17f2c7a..9db402c 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -66,6 +66,7 @@ struct uart_cpm_port {
 	uint			 dp_addr;
 	void			*mem_addr;
 	dma_addr_t		 dma_addr;
+	u32			mem_size;
 	/* helpers */
 	int			 baud;
 	int			 bits;
@@ -92,4 +93,36 @@ void scc2_lineif(struct uart_cpm_port *p
 void scc3_lineif(struct uart_cpm_port *pinfo);
 void scc4_lineif(struct uart_cpm_port *pinfo);
 
+/* 
+   virtual to phys transtalion
+*/
+static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo)
+{
+	int offset;
+	u32 val = (u32)addr;
+	/* sane check */
+	if ((val >= (u32)pinfo->mem_addr) && 
+			(val<((u32)pinfo->mem_addr + pinfo->mem_size))) {
+		offset = val - (u32)pinfo->mem_addr;
+		return pinfo->dma_addr+offset;
+	}
+	printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
+	return 0;
+}
+
+static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo)
+{	
+	int offset;
+	u32 val = addr;
+	/* sane check */
+	if ((val >= pinfo->dma_addr) && 
+			(val<(pinfo->dma_addr + pinfo->mem_size))) {
+		offset = val - (u32)pinfo->dma_addr;
+		return (void*)(pinfo->mem_addr+offset);
+	}
+	printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
+	return 0;
+}
+
+
 #endif /* CPM_UART_H */
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 8f33815..3549073 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -72,19 +72,6 @@ static void cpm_uart_initbd(struct uart_
 
 /**************************************************************/
 
-static inline unsigned long cpu2cpm_addr(void *addr)
-{
-	if ((unsigned long)addr >= CPM_ADDR)
-		return (unsigned long)addr;
-	return virt_to_bus(addr);
-}
-
-static inline void *cpm2cpu_addr(unsigned long addr)
-{
-	if (addr >= CPM_ADDR)
-		return (void *)addr;
-	return bus_to_virt(addr);
-}
 
 /* Place-holder for board-specific stuff */
 struct platform_device* __attribute__ ((weak)) __init
@@ -290,7 +277,7 @@ static void cpm_uart_int_rx(struct uart_
 		}
 
 		/* get pointer */
-		cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+		cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
 
 		/* loop through the buffer */
 		while (i-- > 0) {
@@ -633,7 +620,7 @@ static int cpm_uart_tx_pump(struct uart_
 		/* Pick next descriptor and fill from buffer */
 		bdp = pinfo->tx_cur;
 
-		p = cpm2cpu_addr(bdp->cbd_bufaddr);
+		p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
 
 		*p++ = port->x_char;
 		bdp->cbd_datlen = 1;
@@ -660,7 +647,7 @@ static int cpm_uart_tx_pump(struct uart_
 
 	while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) {
 		count = 0;
-		p = cpm2cpu_addr(bdp->cbd_bufaddr);
+		p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
 		while (count < pinfo->tx_fifosize) {
 			*p++ = xmit->buf[xmit->tail];
 			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -709,12 +696,12 @@ static void cpm_uart_initbd(struct uart_
 	mem_addr = pinfo->mem_addr;
 	bdp = pinfo->rx_cur = pinfo->rx_bd_base;
 	for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) {
-		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
 		bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
 		mem_addr += pinfo->rx_fifosize;
 	}
 
-	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
 	bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
 
 	/* Set the physical address of the host memory
@@ -724,12 +711,12 @@ static void cpm_uart_initbd(struct uart_
 	mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize);
 	bdp = pinfo->tx_cur = pinfo->tx_bd_base;
 	for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) {
-		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
 		bdp->cbd_sc = BD_SC_INTRPT;
 		mem_addr += pinfo->tx_fifosize;
 	}
 
-	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
 	bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
 }
 
@@ -1099,7 +1086,7 @@ static void cpm_uart_console_write(struc
 		 * If the buffer address is in the CPM DPRAM, don't
 		 * convert it.
 		 */
-		cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+		cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
 
 		*cp = *s;
 
@@ -1116,7 +1103,7 @@ static void cpm_uart_console_write(struc
 			while ((bdp->cbd_sc & BD_SC_READY) != 0)
 				;
 
-			cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+			cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
 
 			*cp = 13;
 			bdp->cbd_datlen = 1;
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 31223aa..a5a3062 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -144,7 +144,7 @@ int cpm_uart_allocbuf(struct uart_cpm_po
 		/* was hostalloc but changed cause it blows away the */
 		/* large tlb mapping when pinning the kernel area    */
 		mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
-		dma_addr = 0;
+		dma_addr = (u32)mem_addr;
 	} else
 		mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
 					      GFP_KERNEL);
@@ -157,8 +157,9 @@ int cpm_uart_allocbuf(struct uart_cpm_po
 	}
 
 	pinfo->dp_addr = dp_offset;
-	pinfo->mem_addr = mem_addr;
-	pinfo->dma_addr = dma_addr;
+	pinfo->mem_addr = mem_addr;             /*  virtual address*/
+	pinfo->dma_addr = dma_addr;             /*  physical address*/
+	pinfo->mem_size = memsz;
 
 	pinfo->rx_buf = mem_addr;
 	pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index c9c3b1d..7c6b07a 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -209,8 +209,10 @@ int cpm_uart_allocbuf(struct uart_cpm_po
 
 	memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
 	    L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
-	if (is_con)
+	if (is_con) {
 		mem_addr = alloc_bootmem(memsz);
+		dma_addr = mem_addr;
+	}
 	else
 		mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
 					      GFP_KERNEL);
@@ -225,6 +227,7 @@ int cpm_uart_allocbuf(struct uart_cpm_po
 	pinfo->dp_addr = dp_offset;
 	pinfo->mem_addr = mem_addr;
 	pinfo->dma_addr = dma_addr;
+	pinfo->mem_size = memsz;
 
 	pinfo->rx_buf = mem_addr;
 	pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos

^ permalink raw reply related

* [PATCH 3/4] PPC32: Update board-specific code of the CPM UART users
From: Vitaly Bordug @ 2006-04-25 16:26 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-embedded
In-Reply-To: <20060425162633.23551.85273.stgit@vitb.ru.mvista.com>


This has the relevant updates/additions to the BSP code so that proper
platform_info struct well be passed to the CPM UART drivers. The changes
covered mpc866ads, mpc885ads and mpc8272ads.

Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
---

 arch/ppc/platforms/mpc8272ads_setup.c |  114 +++++++++++++++++++++++++++
 arch/ppc/platforms/mpc866ads_setup.c  |  140 +++++++++++++++++++++++++++++++++
 arch/ppc/platforms/mpc885ads_setup.c  |  131 +++++++++++++++++++++++++++++++
 arch/ppc/platforms/pq2ads.c           |   31 +++++++
 4 files changed, 415 insertions(+), 1 deletions(-)

diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c
index bc9b94f..d5c8a3a 100644
--- a/arch/ppc/platforms/mpc8272ads_setup.c
+++ b/arch/ppc/platforms/mpc8272ads_setup.c
@@ -26,11 +26,35 @@
 #include <asm/irq.h>
 #include <asm/ppc_sys.h>
 #include <asm/ppcboot.h>
+#include <linux/fs_uart_pd.h>
 
 #include "pq2ads_pd.h"
 
 static void init_fcc1_ioports(void);
 static void init_fcc2_ioports(void);
+static void init_scc1_uart_ioports(void);
+static void init_scc4_uart_ioports(void);
+
+static struct fs_uart_platform_info mpc8272_uart_pdata[] = {
+	[fsid_scc1_uart] = {
+		.init_ioports 	= init_scc1_uart_ioports,
+		.fs_no		= fsid_scc1_uart,
+		.brg		= 1,
+		.tx_num_fifo	= 4,
+		.tx_buf_size	= 32,
+		.rx_num_fifo	= 4,
+		.rx_buf_size	= 32,
+	},
+	[fsid_scc4_uart] = {
+		.init_ioports 	= init_scc4_uart_ioports,
+		.fs_no		= fsid_scc4_uart,
+		.brg		= 4,
+		.tx_num_fifo	= 4,
+		.tx_buf_size	= 32,
+		.rx_num_fifo	= 4,
+		.rx_buf_size	= 32,
+	},
+};
 
 static struct fs_mii_bus_info mii_bus_info = {
 	.method                 = fsmii_bitbang,
@@ -201,6 +225,55 @@ static void __init mpc8272ads_fixup_enet
 	}
 }
 
+static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
+					      int idx)
+{
+	bd_t *bd = (bd_t *) __res;
+	struct fs_uart_platform_info *pinfo;
+	int num = ARRAY_SIZE(mpc8272_uart_pdata);
+	int id = fs_uart_id_scc2fsid(idx);
+	
+	/* no need to alter anything if console */
+	if ((id <= num) && (!pdev->dev.platform_data)) {
+		pinfo = &mpc8272_uart_pdata[id];
+		pinfo->uart_clk = bd->bi_intfreq;
+		pdev->dev.platform_data = pinfo; 
+	}
+}
+
+static void init_scc1_uart_ioports(void)
+{
+	cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
+
+        /* SCC1 is only on port D */
+	setbits32(&immap->im_ioport.iop_ppard,0x00000003);
+	clrbits32(&immap->im_ioport.iop_psord,0x00000001);
+	setbits32(&immap->im_ioport.iop_psord,0x00000002);
+	clrbits32(&immap->im_ioport.iop_pdird,0x00000001);
+	setbits32(&immap->im_ioport.iop_pdird,0x00000002);
+
+        /* Wire BRG1 to SCC1 */
+	clrbits32(&immap->im_cpmux.cmx_scr,0x00ffffff);
+
+	iounmap(immap);
+}
+
+static void init_scc4_uart_ioports(void)
+{
+	cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
+
+	setbits32(&immap->im_ioport.iop_ppard,0x00000600);
+	clrbits32(&immap->im_ioport.iop_psord,0x00000600);
+	clrbits32(&immap->im_ioport.iop_pdird,0x00000200);
+	setbits32(&immap->im_ioport.iop_pdird,0x00000400);
+
+        /* Wire BRG4 to SCC4 */
+	clrbits32(&immap->im_cpmux.cmx_scr,0x000000ff);
+	setbits32(&immap->im_cpmux.cmx_scr,0x0000001b);
+
+	iounmap(immap);
+}
+
 static int mpc8272ads_platform_notify(struct device *dev)
 {
 	static const struct platform_notify_dev_map dev_map[] = {
@@ -209,6 +282,10 @@ static int mpc8272ads_platform_notify(st
 			.rtn = mpc8272ads_fixup_enet_pdata
 		},
 		{
+			.bus_id = "fsl-cpm-scc:uart",
+			.rtn = mpc
+		},
+		{
 			.bus_id = NULL
 		}
 	};
@@ -230,7 +307,44 @@ int __init mpc8272ads_init(void)
 	ppc_sys_device_enable(MPC82xx_CPM_FCC1);
 	ppc_sys_device_enable(MPC82xx_CPM_FCC2);
 
+	/* to be ready for console, let's attach pdata here */
+#ifdef CONFIG_SERIAL_CPM_SCC1
+	ppc_sys_device_setfunc(MPC82xx_CPM_SCC1, PPC_SYS_FUNC_UART);
+	ppc_sys_device_enable(MPC82xx_CPM_SCC1);
+
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC4
+	ppc_sys_device_setfunc(MPC82xx_CPM_SCC4, PPC_SYS_FUNC_UART);
+	ppc_sys_device_enable(MPC82xx_CPM_SCC4);
+#endif
+
+
 	return 0;
 }
 
+/* 
+   To prevent confusion, console selection is gross:
+   by 0 assumed SCC1 and by 1 assumed SCC4
+ */
+struct platform_device* early_uart_get_pdev(int index)
+{
+	bd_t *bd = (bd_t *) __res;
+	struct fs_uart_platform_info *pinfo;
+
+	struct platform_device* pdev = NULL;
+	if(index) { /*assume SCC4 here*/
+		pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC4];
+		pinfo = &mpc8272<F12>_uart_pdata[1];
+	} else { /*over SCC1*/
+		pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC1];
+		pinfo = &mpc8272_uart_pdata[0];
+	}
+	
+	pinfo->uart_clk = bd->bi_intfreq;
+	pdev->dev.platform_data = pinfo;
+	ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
+	return NULL;
+}
+
 arch_initcall(mpc8272ads_init);
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c
index ac8fcc6..7edefa5 100644
--- a/arch/ppc/platforms/mpc866ads_setup.c
+++ b/arch/ppc/platforms/mpc866ads_setup.c
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 
 #include <linux/fs_enet_pd.h>
+#include <linux/fs_uart_pd.h>
 #include <linux/mii.h>
 
 #include <asm/delay.h>
@@ -37,6 +38,11 @@
 
 extern unsigned char __res[];
 
+static void setup_fec1_ioports(void);
+static void setup_scc1_ioports(void);
+static void setup_smc1_ioports(void);
+static void setup_smc2_ioports(void);
+
 static struct fs_mii_bus_info fec_mii_bus_info = {
 	.method = fsmii_fec,
 	.id = 0,
@@ -79,6 +85,28 @@ static struct fs_platform_info mpc8xx_sc
 	.phy_irq = -1,
 
 	.bus_info = &scc_mii_bus_info,
+
+};
+
+static struct fs_uart_platform_info mpc866_uart_pdata[] = {
+	[fsid_smc1_uart] = {
+		.brg		= 1,
+ 		.fs_no 		= fsid_smc1_uart,
+ 		.init_ioports	= setup_smc1_ioports,
+		.tx_num_fifo	= 4,
+		.tx_buf_size	= 32,
+		.rx_num_fifo	= 4,
+		.rx_buf_size	= 32,
+ 	},
+ 	[fsid_smc2_uart] = {
+ 		.brg		= 2,
+ 		.fs_no 		= fsid_smc2_uart,
+ 		.init_ioports	= setup_smc2_ioports,
+		.tx_num_fifo	= 4,
+		.tx_buf_size	= 32,
+		.rx_num_fifo	= 4,
+		.rx_buf_size	= 32,
+ 	},
 };
 
 void __init board_init(void)
@@ -92,9 +120,12 @@ void __init board_init(void)
 		printk(KERN_CRIT "Could not remap BCSR1\n");
 		return;
 	}
+
 #ifdef CONFIG_SERIAL_CPM_SMC1
 	cp->cp_simode &= ~(0xe0000000 >> 17);	/* brg1 */
 	clrbits32(bcsr_io,(0x80000000 >> 7));
+	cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
+	cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
 #else
 	setbits32(bcsr_io,(0x80000000 >> 7));
 
@@ -108,6 +139,8 @@ void __init board_init(void)
 	cp->cp_simode &= ~(0xe0000000 >> 1);
 	cp->cp_simode |= (0x20000000 >> 1);	/* brg2 */
 	clrbits32(bcsr_io,(0x80000000 >> 13));
+	cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
+	cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
 #else
 	clrbits32(bcsr_io,(0x80000000 >> 13));
 	cp->cp_pbpar &= ~(0x00000c00);
@@ -232,6 +265,74 @@ static void mpc866ads_fixup_scc_enet_pda
 	mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
 }
 
+static void setup_smc1_ioports(void)
+{
+	immap_t *immap = (immap_t *) IMAP_ADDR;
+	unsigned *bcsr_io;
+	unsigned int iobits = 0x000000c0;
+
+	bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+	if (bcsr_io == NULL) {
+		printk(KERN_CRIT "Could not remap BCSR1\n");
+		return;
+	}
+
+	clrbits32(bcsr_io,BCSR1_RS232EN_1);
+	iounmap(bcsr_io);
+
+	setbits32(&immap->im_cpm.cp_pbpar, iobits);
+	clrbits32(&immap->im_cpm.cp_pbdir, iobits);
+	clrbits16(&immap->im_cpm.cp_pbodr, iobits);
+
+}
+
+static void setup_smc2_ioports(void)
+{
+	immap_t *immap = (immap_t *) IMAP_ADDR;
+	unsigned *bcsr_io;
+	unsigned int iobits = 0x00000c00;
+
+	bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+	if (bcsr_io == NULL) {
+		printk(KERN_CRIT "Could not remap BCSR1\n");
+		return;
+	} 
+
+	clrbits32(bcsr_io,BCSR1_RS232EN_2);
+
+	iounmap(bcsr_io);
+	
+#ifndef CONFIG_SERIAL_CPM_ALT_SMC2
+	setbits32(&immap->im_cpm.cp_pbpar, iobits);
+	clrbits32(&immap->im_cpm.cp_pbdir, iobits);
+	clrbits16(&immap->im_cpm.cp_pbodr, iobits);
+#else
+	setbits16(&immap->im_ioport.iop_papar, iobits);
+	clrbits16(&immap->im_ioport.iop_padir, iobits);
+	clrbits16(&immap->im_ioport.iop_paodr, iobits);
+#endif
+
+}
+
+static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev,
+                                              int idx)
+{
+	bd_t *bd = (bd_t *) __res;
+	struct fs_uart_platform_info *pinfo;
+	int num = ARRAY_SIZE(mpc866_uart_pdata);
+
+	int id = fs_uart_id_smc2fsid(idx);
+	
+	/* no need to alter anything if console */
+	if ((id <= num) && (!pdev->dev.platform_data)) {
+		pinfo = &mpc866_uart_pdata[id];
+		pinfo->uart_clk = bd->bi_intfreq;
+		pdev->dev.platform_data = pinfo; 
+	}
+}
+
 static int mpc866ads_platform_notify(struct device *dev)
 {
 	static const struct platform_notify_dev_map dev_map[] = {
@@ -244,6 +345,10 @@ static int mpc866ads_platform_notify(str
 			.rtn = mpc866ads_fixup_scc_enet_pdata,
 		},
 		{
+			.bus_id = "fsl-cpm-smc:uart",
+			.rtn = mpc866ads_fixup_uart_pdata
+		},
+		{
 			.bus_id = NULL
 		}
 	};
@@ -267,7 +372,42 @@ int __init mpc866ads_init(void)
 #endif
 	ppc_sys_device_enable(MPC8xx_CPM_FEC1);
 
+/* Since either of the uarts could be used as console, they need to ready */
+#ifdef CONFIG_SERIAL_CPM_SMC1
+	ppc_sys_device_enable(MPC8xx_CPM_SMC1);
+	ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SMCer
+	ppc_sys_device_enable(MPC8xx_CPM_SMC2);
+	ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
+#endif
+
 	return 0;
 }
 
+/* 
+   To prevent confusion, console selection is gross:
+   by 0 assumed SMC1 and by 1 assumed SMC2
+ */
+struct platform_device* early_uart_get_pdev(int index)
+{
+	bd_t *bd = (bd_t *) __res;
+	struct fs_uart_platform_info *pinfo;
+
+	struct platform_device* pdev = NULL;
+	if(index) { /*assume SMC2 here*/
+		pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
+		pinfo = &mpc866_uart_pdata[1];
+	} else { /*over SMC1*/
+		pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
+		pinfo = &mpc866_uart_pdata[0];
+	}
+	
+	pinfo->uart_clk = bd->bi_intfreq;
+	pdev->dev.platform_data = pinfo;
+	ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
+	return NULL;
+}
+
 arch_initcall(mpc866ads_init);
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c
index 50a99e5..fc37aea 100644
--- a/arch/ppc/platforms/mpc885ads_setup.c
+++ b/arch/ppc/platforms/mpc885ads_setup.c
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 
 #include <linux/fs_enet_pd.h>
+#include <linux/fs_uart_pd.h>
 #include <linux/mii.h>
 
 #include <asm/delay.h>
@@ -35,9 +36,32 @@
 #include <asm/ppc_sys.h>
 
 extern unsigned char __res[];
+static void setup_smc1_ioports(void);
+static void setup_smc2_ioports(void);
 
 static void __init mpc885ads_scc_phy_init(char);
 
+static struct fs_uart_platform_info mpc885_uart_pdata[] = {
+	[fsid_smc1_uart] = {
+		.brg		= 1,
+ 		.fs_no 		= fsid_smc1_uart,
+ 		.init_ioports	= setup_smc1_ioports,
+		.tx_num_fifo	= 4,
+		.tx_buf_size	= 32,
+		.rx_num_fifo	= 4,
+		.rx_buf_size	= 32,
+ 	},
+ 	[fsid_smc2_uart] = {
+ 		.brg		= 2,
+ 		.fs_no 		= fsid_smc2_uart,
+ 		.init_ioports	= setup_smc2_ioports,
+		.tx_num_fifo	= 4,
+		.tx_buf_size	= 32,
+		.rx_num_fifo	= 4,
+		.rx_buf_size	= 32,
+ 	},
+};
+
 static struct fs_mii_bus_info fec_mii_bus_info = {
 	.method = fsmii_fec,
 	.id = 0,
@@ -116,6 +140,8 @@ void __init board_init(void)
 #ifdef CONFIG_SERIAL_CPM_SMC1
 	cp->cp_simode &= ~(0xe0000000 >> 17);	/* brg1 */
 	clrbits32(bcsr_io, BCSR1_RS232EN_1);
+        cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
+        cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
 #else
 	setbits32(bcsr_io,BCSR1_RS232EN_1);
 	cp->cp_smc[0].smc_smcmr = 0;
@@ -126,6 +152,8 @@ void __init board_init(void)
 	cp->cp_simode &= ~(0xe0000000 >> 1);
 	cp->cp_simode |= (0x20000000 >> 1);	/* brg2 */
 	clrbits32(bcsr_io,BCSR1_RS232EN_2);
+        cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
+        cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
 #else
 	setbits32(bcsr_io,BCSR1_RS232EN_2);
 	cp->cp_smc[1].smc_smcmr = 0;
@@ -343,6 +371,70 @@ static void mpc885ads_scc_phy_init(char 
 	out_be32(&fecp->fec_mii_speed, 0);
 }
 
+static void setup_smc1_ioports(void)
+{
+        immap_t *immap = (immap_t *) IMAP_ADDR;
+        unsigned *bcsr_io;
+        unsigned int iobits = 0x000000c0;
+
+        bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+        if (bcsr_io == NULL) {
+                printk(KERN_CRIT "Could not remap BCSR1\n");
+                return;
+        }
+        clrbits32(bcsr_io,BCSR1_RS232EN_1);
+        iounmap(bcsr_io);
+
+        setbits32(&immap->im_cpm.cp_pbpar, iobits);
+        clrbits32(&immap->im_cpm.cp_pbdir, iobits);
+        clrbits16(&immap->im_cpm.cp_pbodr, iobits);
+}
+
+static void setup_smc2_ioports(void)
+{
+        immap_t *immap = (immap_t *) IMAP_ADDR;
+        unsigned *bcsr_io;
+        unsigned int iobits = 0x00000c00;
+
+        bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+        if (bcsr_io == NULL) {
+                printk(KERN_CRIT "Could not remap BCSR1\n");
+                return;
+        }
+        clrbits32(bcsr_io,BCSR1_RS232EN_2);
+        iounmap(bcsr_io);
+
+#ifndef CONFIG_SERIAL_CPM_ALT_SMC2
+        setbits32(&immap->im_cpm.cp_pbpar, iobits);
+        clrbits32(&immap->im_cpm.cp_pbdir, iobits);
+        clrbits16(&immap->im_cpm.cp_pbodr, iobits);
+#else
+        setbits16(&immap->im_ioport.iop_papar, iobits);
+        clrbits16(&immap->im_ioport.iop_padir, iobits);
+        clrbits16(&immap->im_ioport.iop_paodr, iobits);
+#endif
+}
+
+static void __init mpc885ads_fixup_uart_pdata(struct platform_device *pdev,
+                                              int idx)
+{
+	bd_t *bd = (bd_t *) __res;
+	struct fs_uart_platform_info *pinfo;
+	int num = ARRAY_SIZE(mpc885_uart_pdata);
+
+	int id = fs_uart_id_smc2fsid(idx);
+	
+	/* no need to alter anything if console */
+	if ((id <= num) && (!pdev->dev.platform_data)) {
+		pinfo = &mpc885_uart_pdata[id];
+		pinfo->uart_clk = bd->bi_intfreq;
+		pdev->dev.platform_data = pinfo; 
+	}
+}
+
+
 static int mpc885ads_platform_notify(struct device *dev)
 {
 
@@ -356,12 +448,17 @@ static int mpc885ads_platform_notify(str
 			.rtn = mpc885ads_fixup_scc_enet_pdata,
 		},
 		{
+			.bus_id = "fsl-cpm-smc:uart",
+			.rtn = mpc885ads_fixup_uart_pdata
+		},
+		{
 			.bus_id = NULL
 		}
 	};
 
 	platform_notify_map(dev_map,dev);
 
+	return 0;	
 }
 
 int __init mpc885ads_init(void)
@@ -383,7 +480,41 @@ int __init mpc885ads_init(void)
 	ppc_sys_device_enable(MPC8xx_CPM_FEC2);
 #endif
 
+#ifdef CONFIG_SERIAL_CPM_SMC1
+	ppc_sys_device_enable(MPC8xx_CPM_SMC1);
+	ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SMC2
+	ppc_sys_device_enable(MPC8xx_CPM_SMC2);
+	ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
+#endif
 	return 0;
 }
 
 arch_initcall(mpc885ads_init);
+
+/* 
+   To prevent confusion, console selection is gross:
+   by 0 assumed SMC1 and by 1 assumed SMC2
+ */
+struct platform_device* early_uart_get_pdev(int index)
+{
+	bd_t *bd = (bd_t *) __res;
+	struct fs_uart_platform_info *pinfo;
+
+	struct platform_device* pdev = NULL;
+	if(index) { /*assume SMC2 here*/
+		pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
+		pinfo = &mpc885_uart_pdata[1];
+	} else { /*over SMC1*/
+		pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
+		pinfo = &mpc885_uart_pdata[0];
+	}
+	
+	pinfo->uart_clk = bd->bi_intfreq;
+	pdev->dev.platform_data = pinfo;
+	ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
+	return NULL;
+}
+
diff --git a/arch/ppc/platforms/pq2ads.c b/arch/ppc/platforms/pq2ads.c
index 3365fd7..7fc2e02 100644
--- a/arch/ppc/platforms/pq2ads.c
+++ b/arch/ppc/platforms/pq2ads.c
@@ -14,11 +14,40 @@
 
 #include <linux/init.h>
 
+#include <asm/io.h>
 #include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+#include <asm/immap_cpm2.h>
 
 void __init
 m82xx_board_setup(void)
 {
+	cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
+	u32 *bcsr = ioremap(BCSR_ADDR+4, sizeof(u32));
+
 	/* Enable the 2nd UART port */
-	*(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_RS232_EN2;
+	clrbits32(bcsr, BCSR1_RS232_EN2);
+
+#ifdef CONFIG_SERIAL_CPM_SCC1
+	clrbits32((u32*)&immap->im_scc[0].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+	clrbits32((u32*)&immap->im_scc[0].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC2
+	clrbits32((u32*)&immap->im_scc[1].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+	clrbits32((u32*)&immap->im_scc[1].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC3
+	clrbits32((u32*)&immap->im_scc[2].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+	clrbits32((u32*)&immap->im_scc[2].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC4
+	clrbits32((u32*)&immap->im_scc[3].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+	clrbits32((u32*)&immap->im_scc[3].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+	iounmap(bcsr);
+	iounmap(immap);
 }

^ permalink raw reply related

* [PATCH 2/4] CPM_UART: Convert to use platform devices
From: Vitaly Bordug @ 2006-04-25 16:26 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-embedded
In-Reply-To: <20060425162633.23551.85273.stgit@vitb.ru.mvista.com>


This is intended to make the driver code more generic and flexible,
to get rid of board-specific layouts within driver, and generic rehaul,
yet keeping compatibility with the existing stuff utilizing it, being
compatible with legacy behavior (but with complaints that legacy mode
used).

Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
---

 drivers/serial/cpm_uart/cpm_uart.h      |   16 +-
 drivers/serial/cpm_uart/cpm_uart_core.c |  259 +++++++++++++++++++++++++------
 drivers/serial/cpm_uart/cpm_uart_cpm1.c |   47 ------
 drivers/serial/cpm_uart/cpm_uart_cpm2.c |    9 -
 4 files changed, 220 insertions(+), 111 deletions(-)

diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 73c8a08..17f2c7a 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -10,6 +10,8 @@
 #define CPM_UART_H
 
 #include <linux/config.h>
+#include <linux/platform_device.h>
+#include <linux/fs_uart_pd.h>
 
 #if defined(CONFIG_CPM2)
 #include "cpm_uart_cpm2.h"
@@ -26,14 +28,14 @@
 #define FLAG_SMC	0x00000002
 #define FLAG_CONSOLE	0x00000001
 
-#define UART_SMC1	0
-#define UART_SMC2	1
-#define UART_SCC1	2
-#define UART_SCC2	3
-#define UART_SCC3	4
-#define UART_SCC4	5
+#define UART_SMC1	fsid_smc1_uart
+#define UART_SMC2	fsid_smc2_uart
+#define UART_SCC1	fsid_scc1_uart
+#define UART_SCC2	fsid_scc2_uart
+#define UART_SCC3	fsid_scc3_uart
+#define UART_SCC4	fsid_scc4_uart
 
-#define UART_NR	6
+#define UART_NR		fs_uart_nr
 
 #define RX_NUM_FIFO	4
 #define RX_BUF_SIZE	32
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index b7bf4c6..8f33815 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -41,6 +41,7 @@
 #include <linux/device.h>
 #include <linux/bootmem.h>
 #include <linux/dma-mapping.h>
+#include <linux/fs_uart_pd.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -60,7 +61,7 @@
 /* Track which ports are configured as uarts */
 int cpm_uart_port_map[UART_NR];
 /* How many ports did we config as uarts */
-int cpm_uart_nr;
+int cpm_uart_nr = 0;
 
 /**************************************************************/
 
@@ -85,6 +86,37 @@ static inline void *cpm2cpu_addr(unsigne
 	return bus_to_virt(addr);
 }
 
+/* Place-holder for board-specific stuff */
+struct platform_device* __attribute__ ((weak)) __init
+early_uart_get_pdev(int index)
+{
+	return NULL;
+}
+
+
+void cpm_uart_count(void)
+{
+	cpm_uart_nr = 0;
+#ifdef CONFIG_SERIAL_CPM_SMC1
+	cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SMC2
+	cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SCC1
+	cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SCC2
+	cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SCC3
+	cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SCC4
+	cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
+#endif
+}
+
 /*
  * Check, if transmit buffers are processed
 */
@@ -829,14 +861,6 @@ static int cpm_uart_request_port(struct 
 	if (pinfo->flags & FLAG_CONSOLE)
 		return 0;
 
-	/*
-	 * Setup any port IO, connect any baud rate generators,
-	 * etc.  This is expected to be handled by board
-	 * dependant code
-	 */
-	if (pinfo->set_lineif)
-		pinfo->set_lineif(pinfo);
-
 	if (IS_SMC(pinfo)) {
 		pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
 		pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
@@ -988,6 +1012,54 @@ struct uart_cpm_port cpm_uart_ports[UART
 	},
 };
 
+int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
+{
+	struct resource *r;
+	struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
+	int idx = pdata->fs_no;	/* It is UART_SMCx or UART_SCCx index */
+	struct uart_cpm_port *pinfo;
+	int line;
+	u32 mem, pram;
+
+	for (line=0; line<UART_NR && cpm_uart_port_map[line]!=pdata->fs_no; line++);
+
+	pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
+
+	pinfo->brg = pdata->brg;
+
+	if (!is_con) {
+		pinfo->port.line = line;
+		pinfo->port.flags = UPF_BOOT_AUTOCONF;
+	}
+
+	if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
+		return -EINVAL;
+	mem = r->start;
+
+	if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
+		return -EINVAL;
+	pram = r->start;
+
+	if(idx > fsid_smc2_uart) {
+		pinfo->sccp = (scc_t *)mem;
+		pinfo->sccup = (scc_uart_t *)pram; 
+	} else {
+		pinfo->smcp = (smc_t *)mem;
+		pinfo->smcup = (smc_uart_t *)pram; 
+	}
+	pinfo->tx_nrfifos = pdata->tx_num_fifo;
+	pinfo->tx_fifosize = pdata->tx_buf_size;
+
+	pinfo->rx_nrfifos = pdata->rx_num_fifo;
+	pinfo->rx_fifosize = pdata->rx_buf_size;
+
+	pinfo->port.uartclk = pdata->uart_clk;
+	pinfo->port.mapbase = (unsigned long)mem;
+	pinfo->port.irq = platform_get_irq(pdev, 0);
+	
+	return 0;
+}
+
 #ifdef CONFIG_SERIAL_CPM_CONSOLE
 /*
  *	Print a string to the serial port trying not to disturb
@@ -1067,9 +1139,7 @@ static void cpm_uart_console_write(struc
 	pinfo->tx_cur = (volatile cbd_t *) bdp;
 }
 
-/*
- * Setup console. Be careful is called early !
- */
+
 static int __init cpm_uart_console_setup(struct console *co, char *options)
 {
 	struct uart_port *port;
@@ -1080,9 +1150,27 @@ static int __init cpm_uart_console_setup
 	int flow = 'n';
 	int ret;
 
+	struct fs_uart_platform_info *pdata;
+	struct platform_device* pdev = early_uart_get_pdev(co->index);
+	
 	port =
 	    (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
 	pinfo = (struct uart_cpm_port *)port;
+	if (!pdev) {
+		pr_info("cpm_uart: console: compat mode\n");
+		/* compatibility - will be cleaned up */
+		cpm_uart_init_portdesc();
+
+		if (pinfo->set_lineif)
+			pinfo->set_lineif(pinfo);
+	} else {
+		pdata = pdev->dev.platform_data;
+		if (pdata)
+			if (pdata->init_ioports)
+    	                	pdata->init_ioports();
+
+		cpm_uart_drv_get_platform_data(pdev, 1);
+	}
 
 	pinfo->flags |= FLAG_CONSOLE;
 
@@ -1097,14 +1185,6 @@ static int __init cpm_uart_console_setup
 			baud = 9600;
 	}
 
-	/*
-	 * Setup any port IO, connect any baud rate generators,
-	 * etc.  This is expected to be handled by board
-	 * dependant code
-	 */
-	if (pinfo->set_lineif)
-		pinfo->set_lineif(pinfo);
-
 	if (IS_SMC(pinfo)) {
 		pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
 		pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
@@ -1143,11 +1223,8 @@ static struct console cpm_scc_uart_conso
 
 int __init cpm_uart_console_init(void)
 {
-	int ret = cpm_uart_init_portdesc();
-
-	if (!ret)
-		register_console(&cpm_scc_uart_console);
-	return ret;
+	register_console(&cpm_scc_uart_console);
+	return 0;
 }
 
 console_initcall(cpm_uart_console_init);
@@ -1165,44 +1242,130 @@ static struct uart_driver cpm_reg = {
 	.minor		= SERIAL_CPM_MINOR,
 	.cons		= CPM_UART_CONSOLE,
 };
-
-static int __init cpm_uart_init(void)
+static int cpm_uart_drv_probe(struct device *dev)
 {
-	int ret, i;
+	struct platform_device  *pdev = to_platform_device(dev);
+	struct fs_uart_platform_info *pdata;
+	int ret = -ENODEV;
 
-	printk(KERN_INFO "Serial: CPM driver $Revision: 0.01 $\n");
-
-#ifndef CONFIG_SERIAL_CPM_CONSOLE
-	ret = cpm_uart_init_portdesc();
-	if (ret)
+	if(!pdev) {
+		printk(KERN_ERR"CPM UART: platform data missing!\n");
 		return ret;
-#endif
+	}
 
-	cpm_reg.nr = cpm_uart_nr;
-	ret = uart_register_driver(&cpm_reg);
+	pdata = pdev->dev.platform_data;
+	pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n",
+			cpm_uart_port_map[pdata->fs_no]);
 
-	if (ret)
+	if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
 		return ret;
 
-	for (i = 0; i < cpm_uart_nr; i++) {
-		int con = cpm_uart_port_map[i];
-		cpm_uart_ports[con].port.line = i;
-		cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
-		uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
-	}
+	if (pdata->init_ioports)
+                pdata->init_ioports();
+ 
+	ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
 
-	return ret;
+        return ret;
 }
 
-static void __exit cpm_uart_exit(void)
+static int cpm_uart_drv_remove(struct device *dev)
 {
+	struct platform_device  *pdev = to_platform_device(dev);
+	struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
+
+	pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n", 
+			cpm_uart_port_map[pdata->fs_no]);
+
+        uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
+        return 0;
+}
+
+static struct device_driver cpm_smc_uart_driver = {
+        .name   = "fsl-cpm-smc:uart",
+        .bus    = &platform_bus_type,
+        .probe  = cpm_uart_drv_probe,
+        .remove = cpm_uart_drv_remove,
+};
+
+static struct device_driver cpm_scc_uart_driver = {
+        .name   = "fsl-cpm-scc:uart",
+        .bus    = &platform_bus_type,
+        .probe  = cpm_uart_drv_probe,
+        .remove = cpm_uart_drv_remove,
+};
+
+/* 
+   This is supposed to match uart devices on platform bus,
+   */
+static int match_is_uart (struct device* dev, void* data)
+{
+	struct platform_device* pdev = container_of(dev, struct platform_device, dev);
+	int ret = 0;
+	/* this was setfunc as uart */
+	if(strstr(pdev->name,":uart")) {
+		ret = 1;
+	}
+	return ret;
+}
+
+
+static int cpm_uart_init(void) {
+
+	int ret;
 	int i;
+	struct device *dev; 
+	printk(KERN_INFO "Serial: CPM driver $Revision: 0.02 $\n");
+
+	/* lookup the bus for uart devices */
+	dev = bus_find_device(&platform_bus_type, NULL, 0, match_is_uart);
+
+	/* There are devices on the bus - all should be OK  */
+	if (dev) {
+		cpm_uart_count();
+		cpm_reg.nr = cpm_uart_nr;
+
+		if (!(ret = uart_register_driver(&cpm_reg))) {
+			if ((ret = driver_register(&cpm_smc_uart_driver))) {
+				uart_unregister_driver(&cpm_reg);
+				return ret;
+			}
+			if ((ret = driver_register(&cpm_scc_uart_driver))) {
+				driver_unregister(&cpm_scc_uart_driver);
+				uart_unregister_driver(&cpm_reg);
+			}
+		}
+	} else {
+	/* No capable platform devices found - falling back to legacy mode */
+		pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n");
+		pr_info(
+		"cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n");
+#ifndef CONFIG_SERIAL_CPM_CONSOLE
+		ret = cpm_uart_init_portdesc();
+		if (ret)
+			return ret;
+#endif
+
+		cpm_reg.nr = cpm_uart_nr;
+		ret = uart_register_driver(&cpm_reg);
+
+		if (ret)
+			return ret;
+
+		for (i = 0; i < cpm_uart_nr; i++) {
+			int con = cpm_uart_port_map[i];
+			cpm_uart_ports[con].port.line = i;
+			cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
+			uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
+		}
 
-	for (i = 0; i < cpm_uart_nr; i++) {
-		int con = cpm_uart_port_map[i];
-		uart_remove_one_port(&cpm_reg, &cpm_uart_ports[con].port);
 	}
+	return ret;
+}
 
+static void __exit cpm_uart_exit(void)
+{
+	driver_unregister(&cpm_scc_uart_driver);
+	driver_unregister(&cpm_smc_uart_driver);
 	uart_unregister_driver(&cpm_reg);
 }
 
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index d789ee5..31223aa 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -81,58 +81,11 @@ void cpm_line_cr_cmd(int line, int cmd)
 
 void smc1_lineif(struct uart_cpm_port *pinfo)
 {
-	volatile cpm8xx_t *cp = cpmp;
-
-	(void)cp;	/* fix warning */
-#if defined (CONFIG_MPC885ADS)
-	/* Enable SMC1 transceivers */
-	{
-		cp->cp_pepar |= 0x000000c0;
-		cp->cp_pedir &= ~0x000000c0;
-		cp->cp_peso &= ~0x00000040;
-		cp->cp_peso |= 0x00000080;
-	}
-#elif defined (CONFIG_MPC86XADS)
-	unsigned int iobits = 0x000000c0;
-
-	if (!pinfo->is_portb) {
-		cp->cp_pbpar |= iobits;
-		cp->cp_pbdir &= ~iobits;
-		cp->cp_pbodr &= ~iobits;
-	} else {
-		((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
-		((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
-		((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
-	}
-#endif
 	pinfo->brg = 1;
 }
 
 void smc2_lineif(struct uart_cpm_port *pinfo)
 {
-	volatile cpm8xx_t *cp = cpmp;
-
-	(void)cp;	/* fix warning */
-#if defined (CONFIG_MPC885ADS)
-	cp->cp_pepar |= 0x00000c00;
-	cp->cp_pedir &= ~0x00000c00;
-	cp->cp_peso &= ~0x00000400;
-	cp->cp_peso |= 0x00000800;
-#elif defined (CONFIG_MPC86XADS)
-	unsigned int iobits = 0x00000c00;
-
-	if (!pinfo->is_portb) {
-		cp->cp_pbpar |= iobits;
-		cp->cp_pbdir &= ~iobits;
-		cp->cp_pbodr &= ~iobits;
-	} else {
-		((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
-		((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
-		((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
-	}
-
-#endif
-
 	pinfo->brg = 2;
 }
 
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index fd9e53e..c9c3b1d 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -142,14 +142,6 @@ void scc2_lineif(struct uart_cpm_port *p
 	 * be supported in a sane fashion.
 	 */
 #ifndef CONFIG_STX_GP3
-#ifdef CONFIG_MPC8560_ADS
-	volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
-	io->iop_ppard |= 0x00000018;
-	io->iop_psord &= ~0x00000008;	/* Rx */
-	io->iop_psord &= ~0x00000010;	/* Tx */
-	io->iop_pdird &= ~0x00000008;	/* Rx */
-	io->iop_pdird |= 0x00000010;	/* Tx */
-#else
 	volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
 	io->iop_pparb |= 0x008b0000;
 	io->iop_pdirb |= 0x00880000;
@@ -157,7 +149,6 @@ void scc2_lineif(struct uart_cpm_port *p
 	io->iop_pdirb &= ~0x00030000;
 	io->iop_psorb &= ~0x00030000;
 #endif
-#endif
 	cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
 	cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
 	pinfo->brg = 2;

^ permalink raw reply related

* Re: 85xx FDT updates?
From: Eugene Surovegin @ 2006-04-25 16:31 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev@ozlabs.org list, Paul Mackerras
In-Reply-To: <6F7CAB43-B4C0-47DA-BC7D-3FD04A552131@kernel.crashing.org>

On Tue, Apr 25, 2006 at 11:25:59AM -0500, Kumar Gala wrote:
> If we are talking about a reference board than I think this is an  
> absurd requirement.  If you are willing to update your kernel on such  
> a board why would you not be willing to update the firmware as well.

1) I don't have JTAG
2) I don't trust new U-Boot version
3) I want to be able to boot old kernels

What you are proposing is more like saying - we changed kernel 
user-space API, old applications aren't supported anymore, get the new 
libc and rebuild them all. For some reason we don't intentionally do 
this, I wonder why.

-- 
Eugene

^ permalink raw reply


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