* [PATCH 4/9] 8xx: Work around CPU15 erratum.
From: Scott Wood @ 2007-08-28 20:17 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
The CPU15 erratum on MPC8xx chips can cause incorrect code execution
under certain circumstances, where there is a conditional or indirect
branch in the last word of a page, with a target in the last cache line
of the next page. This patch implements one of the suggested
workarounds, by forcing a TLB miss whenever execution crosses a page
boundary. This is done by invalidating the pages before and after the
one being loaded into the TLB in the ITLB miss handler.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/kernel/head_8xx.S | 6 ++++++
arch/powerpc/platforms/8xx/Kconfig | 16 ++++++++++++++++
2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index e40e122..dd223df 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -301,6 +301,12 @@ InstructionTLBMiss:
stw r10, 0(r0)
stw r11, 4(r0)
mfspr r10, SPRN_SRR0 /* Get effective address of fault */
+#ifdef CONFIG_8xx_CPU15
+ addi r11, r10, 0x1000
+ tlbie r11
+ addi r11, r10, -0x1000
+ tlbie r11
+#endif
DO_8xx_CPU6(0x3780, r3)
mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */
mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
index 39bb8c5..b8dd515 100644
--- a/arch/powerpc/platforms/8xx/Kconfig
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -99,6 +99,22 @@ config 8xx_CPU6
If in doubt, say N here.
+config 8xx_CPU15
+ bool "CPU15 Silicon Errata"
+ default y
+ help
+ This enables a workaround for erratum CPU15 on MPC8xx chips.
+ This bug can cause incorrect code execution under certain
+ circumstances. This workaround adds some overhead (a TLB miss
+ every time execution crosses a page boundary), and you may wish
+ to disable it if you have worked around the bug in the compiler
+ (by not placing conditional branches or branches to LR or CTR
+ in the last word of a page, with a target of the last cache
+ line in the next page), or if you have used some other
+ workaround.
+
+ If in doubt, say Y here.
+
choice
prompt "Microcode patch selection"
default NO_UCODE_PATCH
--
1.5.0.3
^ permalink raw reply related
* [PATCH 2/9] 8xx: Infrastructure code cleanup.
From: Scott Wood @ 2007-08-28 20:17 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
1. Keep a global mpc8xx_immr mapping, rather than constantly
creating temporary mappings.
2. Look for new fsl,cpm1 and fsl,cpm1-pic names.
3. Always reset the CPM when not using the udbg console;
this is required in case the firmware initialized a device
that is incompatible with one that the kernel is about to
use.
4. Remove some superfluous casts and header includes.
5. Change a usage of IMAP_ADDR to get_immrbase().
6. Use phys_addr_t, not uint, for dpram_pbase.
7. Various sparse-related fixes, such as __iomem annotations.
8. Remove mpc8xx_show_cpuinfo, which doesn't provide anything
useful beyond the generic cpuinfo handler.
9. Move prototypes for 8xx support functions from board files
to sysdev/commproc.h.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/platforms/8xx/m8xx_setup.c | 90 ++++++--------------------
arch/powerpc/platforms/8xx/mpc86xads.h | 3 -
arch/powerpc/platforms/8xx/mpc86xads_setup.c | 10 +---
arch/powerpc/platforms/8xx/mpc885ads.h | 3 -
arch/powerpc/platforms/8xx/mpc885ads_setup.c | 11 +---
arch/powerpc/sysdev/commproc.c | 71 +++++++++++---------
arch/powerpc/sysdev/commproc.h | 12 ++++
arch/powerpc/sysdev/mpc8xx_pic.c | 16 ++--
include/asm-powerpc/commproc.h | 5 +-
include/asm-powerpc/fs_pd.h | 19 +----
10 files changed, 90 insertions(+), 150 deletions(-)
create mode 100644 arch/powerpc/sysdev/commproc.h
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index b2b98dd..d35eda8 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -10,57 +10,33 @@
* bootup setup stuff..
*/
-#include <linux/errno.h>
-#include <linux/sched.h>
#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/tty.h>
-#include <linux/major.h>
#include <linux/interrupt.h>
-#include <linux/reboot.h>
#include <linux/init.h>
-#include <linux/initrd.h>
-#include <linux/ioport.h>
-#include <linux/bootmem.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
#include <linux/time.h>
#include <linux/rtc.h>
-#include <linux/fsl_devices.h>
-#include <asm/mmu.h>
-#include <asm/reg.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/mpc8xx.h>
#include <asm/8xx_immap.h>
-#include <asm/machdep.h>
-#include <asm/time.h>
#include <asm/prom.h>
#include <asm/fs_pd.h>
#include <mm/mmu_decl.h>
-#include "sysdev/mpc8xx_pic.h"
+#include <sysdev/mpc8xx_pic.h>
+#include <sysdev/commproc.h>
#ifdef CONFIG_PCMCIA_M8XX
struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
#endif
void m8xx_calibrate_decr(void);
-#ifdef CONFIG_8xx_WDT
-extern void m8xx_wdt_handler_install(bd_t *bp);
-#endif
extern int cpm_pic_init(void);
extern int cpm_get_irq(void);
/* A place holder for time base interrupts, if they are ever enabled. */
-irqreturn_t timebase_interrupt(int irq, void * dev)
+static irqreturn_t timebase_interrupt(int irq, void *dev)
{
printk ("timebase_interrupt()\n");
@@ -77,7 +53,7 @@ static struct irqaction tbint_irqaction = {
void __init __attribute__ ((weak))
init_internal_rtc(void)
{
- sit8xx_t *sys_tmr = (sit8xx_t *) immr_map(im_sit);
+ sit8xx_t __iomem *sys_tmr = immr_map(im_sit);
/* Disable the RTC one second and alarm interrupts. */
clrbits16(&sys_tmr->sit_rtcsc, (RTCSC_SIE | RTCSC_ALE));
@@ -116,13 +92,13 @@ static int __init get_freq(char *name, unsigned long *val)
void __init mpc8xx_calibrate_decr(void)
{
struct device_node *cpu;
- cark8xx_t *clk_r1;
- car8xx_t *clk_r2;
- sitk8xx_t *sys_tmr1;
- sit8xx_t *sys_tmr2;
+ cark8xx_t __iomem *clk_r1;
+ car8xx_t __iomem *clk_r2;
+ sitk8xx_t __iomem *sys_tmr1;
+ sit8xx_t __iomem *sys_tmr2;
int irq, virq;
- clk_r1 = (cark8xx_t *) immr_map(im_clkrstk);
+ clk_r1 = immr_map(im_clkrstk);
/* Unlock the SCCR. */
out_be32(&clk_r1->cark_sccrk, ~KAPWR_KEY);
@@ -130,7 +106,7 @@ void __init mpc8xx_calibrate_decr(void)
immr_unmap(clk_r1);
/* Force all 8xx processors to use divide by 16 processor clock. */
- clk_r2 = (car8xx_t *) immr_map(im_clkrst);
+ clk_r2 = immr_map(im_clkrst);
setbits32(&clk_r2->car_sccr, 0x02000000);
immr_unmap(clk_r2);
@@ -164,7 +140,7 @@ void __init mpc8xx_calibrate_decr(void)
* we guarantee the registers are locked, then we unlock them
* for our use.
*/
- sys_tmr1 = (sitk8xx_t *) immr_map(im_sitk);
+ sys_tmr1 = immr_map(im_sitk);
out_be32(&sys_tmr1->sitk_tbscrk, ~KAPWR_KEY);
out_be32(&sys_tmr1->sitk_rtcsck, ~KAPWR_KEY);
out_be32(&sys_tmr1->sitk_tbk, ~KAPWR_KEY);
@@ -184,20 +160,13 @@ void __init mpc8xx_calibrate_decr(void)
virq= irq_of_parse_and_map(cpu, 0);
irq = irq_map[virq].hwirq;
- sys_tmr2 = (sit8xx_t *) immr_map(im_sit);
+ sys_tmr2 = immr_map(im_sit);
out_be16(&sys_tmr2->sit_tbscr, ((1 << (7 - (irq/2))) << 8) |
(TBSCR_TBF | TBSCR_TBE));
immr_unmap(sys_tmr2);
if (setup_irq(virq, &tbint_irqaction))
panic("Could not allocate timer IRQ!");
-
-#ifdef CONFIG_8xx_WDT
- /* Install watchdog timer handler early because it might be
- * already enabled by the bootloader
- */
- m8xx_wdt_handler_install(binfo);
-#endif
}
/* The RTC on the MPC8xx is an internal register.
@@ -207,12 +176,12 @@ void __init mpc8xx_calibrate_decr(void)
int mpc8xx_set_rtc_time(struct rtc_time *tm)
{
- sitk8xx_t *sys_tmr1;
- sit8xx_t *sys_tmr2;
+ sitk8xx_t __iomem *sys_tmr1;
+ sit8xx_t __iomem *sys_tmr2;
int time;
- sys_tmr1 = (sitk8xx_t *) immr_map(im_sitk);
- sys_tmr2 = (sit8xx_t *) immr_map(im_sit);
+ sys_tmr1 = immr_map(im_sitk);
+ sys_tmr2 = immr_map(im_sit);
time = mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
@@ -228,7 +197,7 @@ int mpc8xx_set_rtc_time(struct rtc_time *tm)
void mpc8xx_get_rtc_time(struct rtc_time *tm)
{
unsigned long data;
- sit8xx_t *sys_tmr = (sit8xx_t *) immr_map(im_sit);
+ sit8xx_t __iomem *sys_tmr = immr_map(im_sit);
/* Get time from the RTC. */
data = in_be32(&sys_tmr->sit_rtc);
@@ -241,8 +210,7 @@ void mpc8xx_get_rtc_time(struct rtc_time *tm)
void mpc8xx_restart(char *cmd)
{
- __volatile__ unsigned char dummy;
- car8xx_t * clk_r = (car8xx_t *) immr_map(im_clkrst);
+ car8xx_t __iomem *clk_r = immr_map(im_clkrst);
local_irq_disable();
@@ -252,26 +220,8 @@ void mpc8xx_restart(char *cmd)
*/
mtmsr(mfmsr() & ~0x1000);
- dummy = in_8(&clk_r->res[0]);
- printk("Restart failed\n");
- while(1);
-}
-
-void mpc8xx_show_cpuinfo(struct seq_file *m)
-{
- struct device_node *root;
- uint memsize = total_memory;
- const char *model = "";
-
- seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
-
- root = of_find_node_by_path("/");
- if (root)
- model = of_get_property(root, "model", NULL);
- seq_printf(m, "Machine\t\t: %s\n", model);
- of_node_put(root);
-
- seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+ in_8(&clk_r->res[0]);
+ panic("Restart failed\n");
}
static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
diff --git a/arch/powerpc/platforms/8xx/mpc86xads.h b/arch/powerpc/platforms/8xx/mpc86xads.h
index dd10cd2..cffa194 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads.h
+++ b/arch/powerpc/platforms/8xx/mpc86xads.h
@@ -29,9 +29,6 @@
#define CFG_PHYDEV_ADDR ((uint)0xff0a0000)
#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300))
-#define IMAP_ADDR (get_immrbase())
-#define IMAP_SIZE ((uint)(64 * 1024))
-
#define MPC8xx_CPM_OFFSET (0x9c0)
#define CPM_MAP_ADDR (get_immrbase() + MPC8xx_CPM_OFFSET)
#define CPM_IRQ_OFFSET 16 // for compability with cpm_uart driver
diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index 8f64f48..4901283 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -37,14 +37,7 @@
#include <asm/fs_pd.h>
#include <asm/prom.h>
-extern void cpm_reset(void);
-extern void mpc8xx_show_cpuinfo(struct seq_file*);
-extern void mpc8xx_restart(char *cmd);
-extern void mpc8xx_calibrate_decr(void);
-extern int mpc8xx_set_rtc_time(struct rtc_time *tm);
-extern void mpc8xx_get_rtc_time(struct rtc_time *tm);
-extern void m8xx_pic_init(void);
-extern unsigned int mpc8xx_get_irq(void);
+#include <sysdev/commproc.h>
static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi);
static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
@@ -277,7 +270,6 @@ define_machine(mpc86x_ads) {
.probe = mpc86xads_probe,
.setup_arch = mpc86xads_setup_arch,
.init_IRQ = m8xx_pic_init,
- .show_cpuinfo = mpc8xx_show_cpuinfo,
.get_irq = mpc8xx_get_irq,
.restart = mpc8xx_restart,
.calibrate_decr = mpc8xx_calibrate_decr,
diff --git a/arch/powerpc/platforms/8xx/mpc885ads.h b/arch/powerpc/platforms/8xx/mpc885ads.h
index 14db124..a21e528 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads.h
+++ b/arch/powerpc/platforms/8xx/mpc885ads.h
@@ -29,9 +29,6 @@
#define CFG_PHYDEV_ADDR ((uint)0xff0a0000)
#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300))
-#define IMAP_ADDR (get_immrbase())
-#define IMAP_SIZE ((uint)(64 * 1024))
-
#define MPC8xx_CPM_OFFSET (0x9c0)
#define CPM_MAP_ADDR (get_immrbase() + MPC8xx_CPM_OFFSET)
#define CPM_IRQ_OFFSET 16 // for compability with cpm_uart driver
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index d3da385..bb54268 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -38,15 +38,6 @@
#include <asm/fs_pd.h>
#include <asm/prom.h>
-extern void cpm_reset(void);
-extern void mpc8xx_show_cpuinfo(struct seq_file *);
-extern void mpc8xx_restart(char *cmd);
-extern void mpc8xx_calibrate_decr(void);
-extern int mpc8xx_set_rtc_time(struct rtc_time *tm);
-extern void mpc8xx_get_rtc_time(struct rtc_time *tm);
-extern void m8xx_pic_init(void);
-extern unsigned int mpc8xx_get_irq(void);
-
static void init_smc1_uart_ioports(struct fs_uart_platform_info *fpi);
static void init_smc2_uart_ioports(struct fs_uart_platform_info *fpi);
static void init_scc3_ioports(struct fs_platform_info *ptr);
@@ -428,7 +419,7 @@ define_machine(mpc885_ads)
{
.name = "MPC885 ADS",.probe = mpc885ads_probe,.setup_arch =
mpc885ads_setup_arch,.init_IRQ =
- m8xx_pic_init,.show_cpuinfo = mpc8xx_show_cpuinfo,.get_irq =
+ m8xx_pic_init,.get_irq =
mpc8xx_get_irq,.restart = mpc8xx_restart,.calibrate_decr =
mpc8xx_calibrate_decr,.set_rtc_time =
mpc8xx_set_rtc_time,.get_rtc_time = mpc8xx_get_rtc_time,};
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index e8e79f8..af26659 100644
--- a/arch/powerpc/sysdev/commproc.c
+++ b/arch/powerpc/sysdev/commproc.c
@@ -47,8 +47,9 @@
static void m8xx_cpm_dpinit(void);
static uint host_buffer; /* One page of host buffer */
static uint host_end; /* end + 1 */
-cpm8xx_t *cpmp; /* Pointer to comm processor space */
-cpic8xx_t *cpic_reg;
+cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */
+immap_t __iomem *mpc8xx_immr;
+static cpic8xx_t __iomem *cpic_reg;
static struct device_node *cpm_pic_node;
static struct irq_host *cpm_pic_host;
@@ -140,16 +141,19 @@ unsigned int cpm_pic_init(void)
pr_debug("cpm_pic_init\n");
- np = of_find_compatible_node(NULL, "cpm-pic", "CPM");
+ np = of_find_compatible_node(NULL, NULL, "fsl,cpm1-pic");
+ if (np == NULL)
+ np = of_find_compatible_node(NULL, "cpm-pic", "CPM");
if (np == NULL) {
printk(KERN_ERR "CPM PIC init: can not find cpm-pic node\n");
return sirq;
}
+
ret = of_address_to_resource(np, 0, &res);
if (ret)
goto end;
- cpic_reg = (void *)ioremap(res.start, res.end - res.start + 1);
+ cpic_reg = ioremap(res.start, res.end - res.start + 1);
if (cpic_reg == NULL)
goto end;
@@ -173,14 +177,16 @@ unsigned int cpm_pic_init(void)
sirq = NO_IRQ;
goto end;
}
- of_node_put(np);
/* Install our own error handler. */
- np = of_find_node_by_type(NULL, "cpm");
+ np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
+ if (np == NULL)
+ np = of_find_node_by_type(NULL, "cpm");
if (np == NULL) {
printk(KERN_ERR "CPM PIC init: can not find cpm node\n");
goto end;
}
+
eirq = irq_of_parse_and_map(np, 0);
if (eirq == NO_IRQ)
goto end;
@@ -197,21 +203,28 @@ end:
void cpm_reset(void)
{
- cpm8xx_t *commproc;
- sysconf8xx_t *siu_conf;
+ sysconf8xx_t __iomem *siu_conf;
- commproc = (cpm8xx_t *)ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
+ mpc8xx_immr = ioremap(get_immrbase(), 0x4000);
+ if (!mpc8xx_immr) {
+ printk(KERN_CRIT "Could not map IMMR\n");
+ return;
+ }
-#ifdef CONFIG_UCODE_PATCH
+ cpmp = &mpc8xx_immr->im_cpm;
+
+#ifndef CONFIG_PPC_EARLY_DEBUG_CPM
/* Perform a reset.
*/
- out_be16(&commproc->cp_cpcr, CPM_CR_RST | CPM_CR_FLG);
+ out_be16(&cpmp->cp_cpcr, CPM_CR_RST | CPM_CR_FLG);
/* Wait for it.
*/
- while (in_be16(&commproc->cp_cpcr) & CPM_CR_FLG);
+ while (in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG);
+#endif
- cpm_load_patch(commproc);
+#ifdef CONFIG_UCODE_PATCH
+ cpm_load_patch(cpmp);
#endif
/* Set SDMA Bus Request priority 5.
@@ -220,16 +233,12 @@ void cpm_reset(void)
* manual recommends it.
* Bit 25, FAM can also be set to use FEC aggressive mode (860T).
*/
- siu_conf = (sysconf8xx_t*)immr_map(im_siu_conf);
+ siu_conf = immr_map(im_siu_conf);
out_be32(&siu_conf->sc_sdcr, 1);
immr_unmap(siu_conf);
/* Reclaim the DP memory for our use. */
m8xx_cpm_dpinit();
-
- /* Tell everyone where the comm processor resides.
- */
- cpmp = commproc;
}
/* We used to do this earlier, but have to postpone as long as possible
@@ -279,20 +288,20 @@ m8xx_cpm_hostalloc(uint size)
void
cpm_setbrg(uint brg, uint rate)
{
- volatile uint *bp;
+ u32 __iomem *bp;
/* This is good enough to get SMCs running.....
*/
- bp = (uint *)&cpmp->cp_brgc1;
+ bp = &cpmp->cp_brgc1;
bp += brg;
/* The BRG has a 12-bit counter. For really slow baud rates (or
* really fast processors), we may have to further divide by 16.
*/
if (((BRG_UART_CLK / rate) - 1) < 4096)
- *bp = (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN;
+ out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN);
else
- *bp = (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) |
- CPM_BRG_EN | CPM_BRG_DIV16;
+ out_be32(bp, (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) |
+ CPM_BRG_EN | CPM_BRG_DIV16);
}
/*
@@ -307,15 +316,15 @@ static rh_block_t cpm_boot_dpmem_rh_block[16];
static rh_info_t cpm_dpmem_info;
#define CPM_DPMEM_ALIGNMENT 8
-static u8 *dpram_vbase;
-static uint dpram_pbase;
+static u8 __iomem *dpram_vbase;
+static phys_addr_t dpram_pbase;
-void m8xx_cpm_dpinit(void)
+static void m8xx_cpm_dpinit(void)
{
spin_lock_init(&cpm_dpmem_lock);
- dpram_vbase = immr_map_size(im_cpm.cp_dpmem, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE);
- dpram_pbase = (uint)&((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem;
+ dpram_vbase = cpmp->cp_dpmem;
+ dpram_pbase = get_immrbase() + offsetof(immap_t, im_cpm.cp_dpmem);
/* Initialize the info header */
rh_init(&cpm_dpmem_info, CPM_DPMEM_ALIGNMENT,
@@ -387,12 +396,12 @@ EXPORT_SYMBOL(cpm_dpdump);
void *cpm_dpram_addr(unsigned long offset)
{
- return (void *)(dpram_vbase + offset);
+ return (void __force *)(dpram_vbase + offset);
}
EXPORT_SYMBOL(cpm_dpram_addr);
-uint cpm_dpram_phys(u8* addr)
+uint cpm_dpram_phys(u8 *addr)
{
- return (dpram_pbase + (uint)(addr - dpram_vbase));
+ return (dpram_pbase + (uint)(addr - (u8 __force *)dpram_vbase));
}
EXPORT_SYMBOL(cpm_dpram_addr);
diff --git a/arch/powerpc/sysdev/commproc.h b/arch/powerpc/sysdev/commproc.h
new file mode 100644
index 0000000..9155ba4
--- /dev/null
+++ b/arch/powerpc/sysdev/commproc.h
@@ -0,0 +1,12 @@
+#ifndef _POWERPC_SYSDEV_COMMPROC_H
+#define _POWERPC_SYSDEV_COMMPROC_H
+
+extern void cpm_reset(void);
+extern void mpc8xx_restart(char *cmd);
+extern void mpc8xx_calibrate_decr(void);
+extern int mpc8xx_set_rtc_time(struct rtc_time *tm);
+extern void mpc8xx_get_rtc_time(struct rtc_time *tm);
+extern void m8xx_pic_init(void);
+extern unsigned int mpc8xx_get_irq(void);
+
+#endif
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 2fc2bcd..e50d3ae 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -23,7 +23,7 @@ static struct device_node *mpc8xx_pic_node;
static struct irq_host *mpc8xx_pic_host;
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
-static sysconf8xx_t *siu_reg;
+static sysconf8xx_t __iomem *siu_reg;
int cpm_get_irq(struct pt_regs *regs);
@@ -166,24 +166,24 @@ static struct irq_host_ops mpc8xx_pic_host_ops = {
int mpc8xx_pic_init(void)
{
struct resource res;
- struct device_node *np = NULL;
+ struct device_node *np;
int ret;
- np = of_find_node_by_type(np, "mpc8xx-pic");
-
+ np = of_find_compatible_node(NULL, NULL, "fsl,pq1-pic");
+ if (np == NULL)
+ np = of_find_node_by_type(NULL, "mpc8xx-pic");
if (np == NULL) {
- printk(KERN_ERR "Could not find open-pic node\n");
+ printk(KERN_ERR "Could not find fsl,pq1-pic node\n");
return -ENOMEM;
}
- mpc8xx_pic_node = of_node_get(np);
+ mpc8xx_pic_node = np;
ret = of_address_to_resource(np, 0, &res);
- of_node_put(np);
if (ret)
return ret;
- siu_reg = (void *)ioremap(res.start, res.end - res.start + 1);
+ siu_reg = ioremap(res.start, res.end - res.start + 1);
if (siu_reg == NULL)
return -EINVAL;
diff --git a/include/asm-powerpc/commproc.h b/include/asm-powerpc/commproc.h
index 3972487..ccb32cd 100644
--- a/include/asm-powerpc/commproc.h
+++ b/include/asm-powerpc/commproc.h
@@ -66,7 +66,7 @@
/* Export the base address of the communication processor registers
* and dual port ram.
*/
-extern cpm8xx_t *cpmp; /* Pointer to comm processor */
+extern cpm8xx_t __iomem *cpmp; /* Pointer to comm processor */
extern unsigned long cpm_dpalloc(uint size, uint align);
extern int cpm_dpfree(unsigned long offset);
extern unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align);
@@ -689,4 +689,7 @@ typedef struct risc_timer_pram {
extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
extern void cpm_free_handler(int vec);
+#define IMAP_ADDR (get_immrbase())
+#define IMAP_SIZE ((uint)(64 * 1024))
+
#endif /* __CPM_8XX__ */
diff --git a/include/asm-powerpc/fs_pd.h b/include/asm-powerpc/fs_pd.h
index c624915..733e8cb 100644
--- a/include/asm-powerpc/fs_pd.h
+++ b/include/asm-powerpc/fs_pd.h
@@ -45,22 +45,11 @@
#include <asm/8xx_immap.h>
#include <asm/mpc8xx.h>
-#define immr_map(member) \
-({ \
- u32 offset = offsetof(immap_t, member); \
- void *addr = ioremap (IMAP_ADDR + offset, \
- sizeof( ((immap_t*)0)->member)); \
- addr; \
-})
-
-#define immr_map_size(member, size) \
-({ \
- u32 offset = offsetof(immap_t, member); \
- void *addr = ioremap (IMAP_ADDR + offset, size); \
- addr; \
-})
+extern immap_t __iomem *mpc8xx_immr;
-#define immr_unmap(addr) iounmap(addr)
+#define immr_map(member) (&mpc8xx_immr->member)
+#define immr_map_size(member, size) (&mpc8xx_immr->member)
+#define immr_unmap(addr) iounmap(addr)
#endif
static inline int uart_baudrate(void)
--
1.5.0.3
^ permalink raw reply related
* [PATCH 3/9] 8xx: Add pin and clock setting functions.
From: Scott Wood @ 2007-08-28 20:17 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
These let board code set up pins and clocks without having to
put magic numbers directly into the registers.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/sysdev/commproc.c | 201 ++++++++++++++++++++++++++++++++++++++++
include/asm-powerpc/commproc.h | 41 ++++++++
2 files changed, 242 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index af26659..a21a292 100644
--- a/arch/powerpc/sysdev/commproc.c
+++ b/arch/powerpc/sysdev/commproc.c
@@ -405,3 +405,204 @@ uint cpm_dpram_phys(u8 *addr)
return (dpram_pbase + (uint)(addr - (u8 __force *)dpram_vbase));
}
EXPORT_SYMBOL(cpm_dpram_addr);
+
+struct cpm_ioport16 {
+ __be16 dir, par, sor, dat, intr;
+ __be16 res[3];
+};
+
+struct cpm_ioport32 {
+ __be32 dir, par, sor;
+};
+
+static void cpm1_set_pin32(int port, int pin, int flags)
+{
+ struct cpm_ioport32 __iomem *iop;
+ pin = 1 << (31 - pin);
+
+ if (port == 1)
+ iop = (struct cpm_ioport32 __iomem *)
+ &mpc8xx_immr->im_cpm.cp_pbdir;
+ else
+ iop = (struct cpm_ioport32 __iomem *)
+ &mpc8xx_immr->im_cpm.cp_pedir;
+
+ if (flags & CPM_PIN_OUTPUT)
+ setbits32(&iop->dir, pin);
+ else
+ clrbits32(&iop->dir, pin);
+
+ if (!(flags & CPM_PIN_GPIO))
+ setbits32(&iop->par, pin);
+ else
+ clrbits32(&iop->par, pin);
+
+ if (port == 4) {
+ if (flags & CPM_PIN_SECONDARY)
+ setbits32(&iop->sor, pin);
+ else
+ clrbits32(&iop->sor, pin);
+
+ if (flags & CPM_PIN_OPENDRAIN)
+ setbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
+ else
+ clrbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
+ }
+}
+
+static void cpm1_set_pin16(int port, int pin, int flags)
+{
+ struct cpm_ioport16 __iomem *iop =
+ (struct cpm_ioport16 __iomem *)&mpc8xx_immr->im_ioport;
+
+ pin = 1 << (15 - pin);
+
+ if (port != 0)
+ iop += port - 1;
+
+ if (flags & CPM_PIN_OUTPUT)
+ setbits16(&iop->dir, pin);
+ else
+ clrbits16(&iop->dir, pin);
+
+ if (!(flags & CPM_PIN_GPIO))
+ setbits16(&iop->par, pin);
+ else
+ clrbits16(&iop->par, pin);
+
+ if (port == 2) {
+ if (flags & CPM_PIN_SECONDARY)
+ setbits16(&iop->sor, pin);
+ else
+ clrbits16(&iop->sor, pin);
+ }
+}
+
+void cpm1_set_pin(int port, int pin, int flags)
+{
+ if (port == 1 || port == 4)
+ cpm1_set_pin32(port, pin, flags);
+ else
+ cpm1_set_pin16(port, pin, flags);
+}
+
+int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
+{
+ int shift;
+ int i, bits = 0;
+ u32 __iomem *reg;
+ u32 mask = 7;
+
+ u8 clk_map[][3] = {
+ {CPM_CLK_SCC1, CPM_BRG1, 0},
+ {CPM_CLK_SCC1, CPM_BRG2, 1},
+ {CPM_CLK_SCC1, CPM_BRG3, 2},
+ {CPM_CLK_SCC1, CPM_BRG4, 3},
+ {CPM_CLK_SCC1, CPM_CLK1, 4},
+ {CPM_CLK_SCC1, CPM_CLK2, 5},
+ {CPM_CLK_SCC1, CPM_CLK3, 6},
+ {CPM_CLK_SCC1, CPM_CLK4, 7},
+
+ {CPM_CLK_SCC2, CPM_BRG1, 0},
+ {CPM_CLK_SCC2, CPM_BRG2, 1},
+ {CPM_CLK_SCC2, CPM_BRG3, 2},
+ {CPM_CLK_SCC2, CPM_BRG4, 3},
+ {CPM_CLK_SCC2, CPM_CLK1, 4},
+ {CPM_CLK_SCC2, CPM_CLK2, 5},
+ {CPM_CLK_SCC2, CPM_CLK3, 6},
+ {CPM_CLK_SCC2, CPM_CLK4, 7},
+
+ {CPM_CLK_SCC3, CPM_BRG1, 0},
+ {CPM_CLK_SCC3, CPM_BRG2, 1},
+ {CPM_CLK_SCC3, CPM_BRG3, 2},
+ {CPM_CLK_SCC3, CPM_BRG4, 3},
+ {CPM_CLK_SCC3, CPM_CLK5, 4},
+ {CPM_CLK_SCC3, CPM_CLK6, 5},
+ {CPM_CLK_SCC3, CPM_CLK7, 6},
+ {CPM_CLK_SCC3, CPM_CLK8, 7},
+
+ {CPM_CLK_SCC4, CPM_BRG1, 0},
+ {CPM_CLK_SCC4, CPM_BRG2, 1},
+ {CPM_CLK_SCC4, CPM_BRG3, 2},
+ {CPM_CLK_SCC4, CPM_BRG4, 3},
+ {CPM_CLK_SCC4, CPM_CLK5, 4},
+ {CPM_CLK_SCC4, CPM_CLK6, 5},
+ {CPM_CLK_SCC4, CPM_CLK7, 6},
+ {CPM_CLK_SCC4, CPM_CLK8, 7},
+
+ {CPM_CLK_SMC1, CPM_BRG1, 0},
+ {CPM_CLK_SMC1, CPM_BRG2, 1},
+ {CPM_CLK_SMC1, CPM_BRG3, 2},
+ {CPM_CLK_SMC1, CPM_BRG4, 3},
+ {CPM_CLK_SMC1, CPM_CLK1, 4},
+ {CPM_CLK_SMC1, CPM_CLK2, 5},
+ {CPM_CLK_SMC1, CPM_CLK3, 6},
+ {CPM_CLK_SMC1, CPM_CLK4, 7},
+
+ {CPM_CLK_SMC2, CPM_BRG1, 0},
+ {CPM_CLK_SMC2, CPM_BRG2, 1},
+ {CPM_CLK_SMC2, CPM_BRG3, 2},
+ {CPM_CLK_SMC2, CPM_BRG4, 3},
+ {CPM_CLK_SMC2, CPM_CLK5, 4},
+ {CPM_CLK_SMC2, CPM_CLK6, 5},
+ {CPM_CLK_SMC2, CPM_CLK7, 6},
+ {CPM_CLK_SMC2, CPM_CLK8, 7},
+ };
+
+ switch (target) {
+ case CPM_CLK_SCC1:
+ reg = &mpc8xx_immr->im_cpm.cp_sicr;
+ shift = 0;
+ break;
+
+ case CPM_CLK_SCC2:
+ reg = &mpc8xx_immr->im_cpm.cp_sicr;
+ shift = 8;
+ break;
+
+ case CPM_CLK_SCC3:
+ reg = &mpc8xx_immr->im_cpm.cp_sicr;
+ shift = 16;
+ break;
+
+ case CPM_CLK_SCC4:
+ reg = &mpc8xx_immr->im_cpm.cp_sicr;
+ shift = 24;
+ break;
+
+ case CPM_CLK_SMC1:
+ reg = &mpc8xx_immr->im_cpm.cp_simode;
+ shift = 12;
+ break;
+
+ case CPM_CLK_SMC2:
+ reg = &mpc8xx_immr->im_cpm.cp_simode;
+ shift = 28;
+ break;
+
+ default:
+ printk(KERN_ERR "cpm1_clock_setup: invalid clock target\n");
+ return -EINVAL;
+ }
+
+ if (reg == &mpc8xx_immr->im_cpm.cp_sicr && mode == CPM_CLK_RX)
+ shift += 3;
+
+ for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
+ if (clk_map[i][0] == target && clk_map[i][1] == clock) {
+ bits = clk_map[i][2];
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(clk_map)) {
+ printk(KERN_ERR "cpm1_clock_setup: invalid clock combination\n");
+ return -EINVAL;
+ }
+
+ bits <<= shift;
+ mask <<= shift;
+ out_be32(reg, (in_be32(reg) & ~mask) | bits);
+
+ return 0;
+}
diff --git a/include/asm-powerpc/commproc.h b/include/asm-powerpc/commproc.h
index ccb32cd..a95a434 100644
--- a/include/asm-powerpc/commproc.h
+++ b/include/asm-powerpc/commproc.h
@@ -692,4 +692,45 @@ extern void cpm_free_handler(int vec);
#define IMAP_ADDR (get_immrbase())
#define IMAP_SIZE ((uint)(64 * 1024))
+#define CPM_PIN_INPUT 0
+#define CPM_PIN_OUTPUT 1
+#define CPM_PIN_PRIMARY 0
+#define CPM_PIN_SECONDARY 2
+#define CPM_PIN_GPIO 4
+#define CPM_PIN_OPENDRAIN 8
+
+void cpm1_set_pin(int port, int pin, int flags);
+
+enum cpm_clk_dir {
+ CPM_CLK_RX,
+ CPM_CLK_TX,
+ CPM_CLK_RTX
+};
+
+enum cpm_clk_target {
+ CPM_CLK_SCC1,
+ CPM_CLK_SCC2,
+ CPM_CLK_SCC3,
+ CPM_CLK_SCC4,
+ CPM_CLK_SMC1,
+ CPM_CLK_SMC2,
+};
+
+enum cpm_clk {
+ CPM_BRG1, /* Baud Rate Generator 1 */
+ CPM_BRG2, /* Baud Rate Generator 2 */
+ CPM_BRG3, /* Baud Rate Generator 3 */
+ CPM_BRG4, /* Baud Rate Generator 4 */
+ CPM_CLK1, /* Clock 1 */
+ CPM_CLK2, /* Clock 2 */
+ CPM_CLK3, /* Clock 3 */
+ CPM_CLK4, /* Clock 4 */
+ CPM_CLK5, /* Clock 5 */
+ CPM_CLK6, /* Clock 6 */
+ CPM_CLK7, /* Clock 7 */
+ CPM_CLK8, /* Clock 8 */
+};
+
+int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode);
+
#endif /* __CPM_8XX__ */
--
1.5.0.3
^ permalink raw reply related
* [PATCH 1/9] 8xx: Fix CONFIG_PIN_TLB.
From: Scott Wood @ 2007-08-28 20:17 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
1. Only map 512K of the IMMR, rather than 8M, to avoid conflicting with
the default ioremap region.
2. The wrong register was being loaded into SPRN_MD_RPN.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/kernel/head_8xx.S | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 901be47..e40e122 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -695,7 +695,7 @@ initial_mmu:
mtspr SPRN_MI_AP, r8
mtspr SPRN_MD_AP, r8
- /* Map another 8 MByte at the IMMR to get the processor
+ /* Map another 512 KByte at the IMMR to get the processor
* internal registers (among other things).
*/
#ifdef CONFIG_PIN_TLB
@@ -703,12 +703,12 @@ initial_mmu:
mtspr SPRN_MD_CTR, r10
#endif
mfspr r9, 638 /* Get current IMMR */
- andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */
+ andis. r9, r9, 0xfff8 /* Get 512K boundary */
mr r8, r9 /* Create vaddr for TLB */
ori r8, r8, MD_EVALID /* Mark it valid */
mtspr SPRN_MD_EPN, r8
- li r8, MD_PS8MEG /* Set 8M byte page */
+ li r8, MD_PS512K /* Set 512K byte page */
ori r8, r8, MD_SVALID /* Make it valid */
mtspr SPRN_MD_TWC, r8
mr r8, r9 /* Create paddr for TLB */
@@ -730,13 +730,13 @@ initial_mmu:
mtspr SPRN_MD_TWC, r9
li r11, MI_BOOTINIT /* Create RPN for address 0 */
addis r11, r11, 0x0080 /* Add 8M */
- mtspr SPRN_MD_RPN, r8
+ mtspr SPRN_MD_RPN, r11
addis r8, r8, 0x0080 /* Add 8M */
mtspr SPRN_MD_EPN, r8
mtspr SPRN_MD_TWC, r9
addis r11, r11, 0x0080 /* Add 8M */
- mtspr SPRN_MD_RPN, r8
+ mtspr SPRN_MD_RPN, r11
#endif
/* Since the cache is enabled according to the information we
--
1.5.0.3
^ permalink raw reply related
* [PATCH 3/4] cpm_uart: sparse fixes
From: Scott Wood @ 2007-08-28 20:16 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
Mostly a bunch of direct access to in/out conversions, plus a few
cast removals, __iomem annotations, and miscellaneous cleanup.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/serial/cpm_uart/cpm_uart.h | 42 +++--
drivers/serial/cpm_uart/cpm_uart_core.c | 299 ++++++++++++++++---------------
drivers/serial/cpm_uart/cpm_uart_cpm1.c | 2 +-
drivers/serial/cpm_uart/cpm_uart_cpm1.h | 14 +-
drivers/serial/cpm_uart/cpm_uart_cpm2.c | 4 +-
drivers/serial/cpm_uart/cpm_uart_cpm2.h | 14 +-
6 files changed, 192 insertions(+), 183 deletions(-)
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 4e1987a..32b9737 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -56,21 +56,21 @@ struct uart_cpm_port {
u16 rx_fifosize;
u16 tx_nrfifos;
u16 tx_fifosize;
- smc_t *smcp;
- smc_uart_t *smcup;
- scc_t *sccp;
- scc_uart_t *sccup;
- volatile cbd_t *rx_bd_base;
- volatile cbd_t *rx_cur;
- volatile cbd_t *tx_bd_base;
- volatile cbd_t *tx_cur;
+ smc_t __iomem *smcp;
+ smc_uart_t __iomem *smcup;
+ scc_t __iomem *sccp;
+ scc_uart_t __iomem *sccup;
+ cbd_t __iomem *rx_bd_base;
+ cbd_t __iomem *rx_cur;
+ cbd_t __iomem *tx_bd_base;
+ cbd_t __iomem *tx_cur;
unsigned char *tx_buf;
unsigned char *rx_buf;
u32 flags;
void (*set_lineif)(struct uart_cpm_port *);
u8 brg;
uint dp_addr;
- void *mem_addr;
+ void *mem_addr;
dma_addr_t dma_addr;
u32 mem_size;
/* helpers */
@@ -106,34 +106,36 @@ 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)
+static inline unsigned long cpu2cpm_addr(void *addr,
+ struct uart_cpm_port *pinfo)
{
int offset;
u32 val = (u32)addr;
+ u32 mem = (u32)pinfo->mem_addr;
/* sane check */
- if (likely((val >= (u32)pinfo->mem_addr)) &&
- (val<((u32)pinfo->mem_addr + pinfo->mem_size))) {
- offset = val - (u32)pinfo->mem_addr;
- return pinfo->dma_addr+offset;
+ if (likely(val >= mem && val < mem + pinfo->mem_size)) {
+ offset = val - mem;
+ return pinfo->dma_addr + offset;
}
/* something nasty happened */
BUG();
return 0;
}
-static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo)
+static inline void *cpm2cpu_addr(unsigned long addr,
+ struct uart_cpm_port *pinfo)
{
int offset;
u32 val = addr;
+ u32 dma = (u32)pinfo->dma_addr;
/* sane check */
- if (likely((val >= pinfo->dma_addr) &&
- (val<(pinfo->dma_addr + pinfo->mem_size)))) {
- offset = val - (u32)pinfo->dma_addr;
- return (void*)(pinfo->mem_addr+offset);
+ if (likely(val >= dma && val < dma + pinfo->mem_size)) {
+ offset = val - dma;
+ return pinfo->mem_addr + offset;
}
/* something nasty happened */
BUG();
- return 0;
+ return NULL;
}
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 78171d0..c43706e 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -131,14 +131,14 @@ static int cpm_uart_id2nr(int id)
static unsigned int cpm_uart_tx_empty(struct uart_port *port)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- volatile cbd_t *bdp = pinfo->tx_bd_base;
+ cbd_t __iomem *bdp = pinfo->tx_bd_base;
int ret = 0;
while (1) {
- if (bdp->cbd_sc & BD_SC_READY)
+ if (in_be16(&bdp->cbd_sc) & BD_SC_READY)
break;
- if (bdp->cbd_sc & BD_SC_WRAP) {
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) {
ret = TIOCSER_TEMT;
break;
}
@@ -167,15 +167,15 @@ static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
static void cpm_uart_stop_tx(struct uart_port *port)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- volatile smc_t *smcp = pinfo->smcp;
- volatile scc_t *sccp = pinfo->sccp;
+ smc_t __iomem *smcp = pinfo->smcp;
+ scc_t __iomem *sccp = pinfo->sccp;
pr_debug("CPM uart[%d]:stop tx\n", port->line);
if (IS_SMC(pinfo))
- smcp->smc_smcm &= ~SMCM_TX;
+ clrbits8(&smcp->smc_smcm, SMCM_TX);
else
- sccp->scc_sccm &= ~UART_SCCM_TX;
+ clrbits16(&sccp->scc_sccm, UART_SCCM_TX);
}
/*
@@ -184,24 +184,24 @@ static void cpm_uart_stop_tx(struct uart_port *port)
static void cpm_uart_start_tx(struct uart_port *port)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- volatile smc_t *smcp = pinfo->smcp;
- volatile scc_t *sccp = pinfo->sccp;
+ smc_t __iomem *smcp = pinfo->smcp;
+ scc_t __iomem *sccp = pinfo->sccp;
pr_debug("CPM uart[%d]:start tx\n", port->line);
if (IS_SMC(pinfo)) {
- if (smcp->smc_smcm & SMCM_TX)
+ if (in_8(&smcp->smc_smcm) & SMCM_TX)
return;
} else {
- if (sccp->scc_sccm & UART_SCCM_TX)
+ if (in_be16(&sccp->scc_sccm) & UART_SCCM_TX)
return;
}
if (cpm_uart_tx_pump(port) != 0) {
if (IS_SMC(pinfo)) {
- smcp->smc_smcm |= SMCM_TX;
+ setbits8(&smcp->smc_smcm, SMCM_TX);
} else {
- sccp->scc_sccm |= UART_SCCM_TX;
+ setbits16(&sccp->scc_sccm, UART_SCCM_TX);
}
}
}
@@ -212,15 +212,15 @@ static void cpm_uart_start_tx(struct uart_port *port)
static void cpm_uart_stop_rx(struct uart_port *port)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- volatile smc_t *smcp = pinfo->smcp;
- volatile scc_t *sccp = pinfo->sccp;
+ smc_t __iomem *smcp = pinfo->smcp;
+ scc_t __iomem *sccp = pinfo->sccp;
pr_debug("CPM uart[%d]:stop rx\n", port->line);
if (IS_SMC(pinfo))
- smcp->smc_smcm &= ~SMCM_RX;
+ clrbits8(&smcp->smc_smcm, SMCM_RX);
else
- sccp->scc_sccm &= ~UART_SCCM_RX;
+ clrbits16(&sccp->scc_sccm, UART_SCCM_RX);
}
/*
@@ -263,10 +263,11 @@ static void cpm_uart_int_tx(struct uart_port *port)
static void cpm_uart_int_rx(struct uart_port *port)
{
int i;
- unsigned char ch, *cp;
+ unsigned char ch;
+ u8 *cp;
struct tty_struct *tty = port->info->tty;
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- volatile cbd_t *bdp;
+ cbd_t __iomem *bdp;
u16 status;
unsigned int flg;
@@ -278,13 +279,13 @@ static void cpm_uart_int_rx(struct uart_port *port)
bdp = pinfo->rx_cur;
for (;;) {
/* get status */
- status = bdp->cbd_sc;
+ status = in_be16(&bdp->cbd_sc);
/* If this one is empty, return happy */
if (status & BD_SC_EMPTY)
break;
/* get number of characters, and check spce in flip-buffer */
- i = bdp->cbd_datlen;
+ i = in_be16(&bdp->cbd_datlen);
/* If we have not enough room in tty flip buffer, then we try
* later, which will be the next rx-interrupt or a timeout
@@ -295,7 +296,7 @@ static void cpm_uart_int_rx(struct uart_port *port)
}
/* get pointer */
- cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
+ cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
/* loop through the buffer */
while (i-- > 0) {
@@ -315,10 +316,11 @@ static void cpm_uart_int_rx(struct uart_port *port)
} /* End while (i--) */
/* This BD is ready to be used again. Clear status. get next */
- bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
- bdp->cbd_sc |= BD_SC_EMPTY;
+ clrbits16(&bdp->cbd_sc, BD_SC_BR | BD_SC_FR | BD_SC_PR |
+ BD_SC_OV | BD_SC_ID);
+ setbits16(&bdp->cbd_sc, BD_SC_EMPTY);
- if (bdp->cbd_sc & BD_SC_WRAP)
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
bdp = pinfo->rx_bd_base;
else
bdp++;
@@ -326,7 +328,7 @@ static void cpm_uart_int_rx(struct uart_port *port)
} /* End for (;;) */
/* Write back buffer pointer */
- pinfo->rx_cur = (volatile cbd_t *) bdp;
+ pinfo->rx_cur = bdp;
/* activate BH processing */
tty_flip_buffer_push(tty);
@@ -380,14 +382,14 @@ static irqreturn_t cpm_uart_int(int irq, void *data)
u8 events;
struct uart_port *port = (struct uart_port *)data;
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- volatile smc_t *smcp = pinfo->smcp;
- volatile scc_t *sccp = pinfo->sccp;
+ smc_t __iomem *smcp = pinfo->smcp;
+ scc_t __iomem *sccp = pinfo->sccp;
pr_debug("CPM uart[%d]:IRQ\n", port->line);
if (IS_SMC(pinfo)) {
- events = smcp->smc_smce;
- smcp->smc_smce = events;
+ events = in_8(&smcp->smc_smce);
+ out_8(&smcp->smc_smce, events);
if (events & SMCM_BRKE)
uart_handle_break(port);
if (events & SMCM_RX)
@@ -395,8 +397,8 @@ static irqreturn_t cpm_uart_int(int irq, void *data)
if (events & SMCM_TX)
cpm_uart_int_tx(port);
} else {
- events = sccp->scc_scce;
- sccp->scc_scce = events;
+ events = in_be16(&sccp->scc_scce);
+ out_be16(&sccp->scc_scce, events);
if (events & UART_SCCM_BRKE)
uart_handle_break(port);
if (events & UART_SCCM_RX)
@@ -421,11 +423,11 @@ static int cpm_uart_startup(struct uart_port *port)
/* Startup rx-int */
if (IS_SMC(pinfo)) {
- pinfo->smcp->smc_smcm |= SMCM_RX;
- pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
+ setbits8(&pinfo->smcp->smc_smcm, SMCM_RX);
+ setbits16(&pinfo->smcp->smc_smcmr, (SMCMR_REN | SMCMR_TEN));
} else {
- pinfo->sccp->scc_sccm |= UART_SCCM_RX;
- pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+ setbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
+ setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT));
}
if (!(pinfo->flags & FLAG_CONSOLE))
@@ -464,13 +466,13 @@ static void cpm_uart_shutdown(struct uart_port *port)
/* Stop uarts */
if (IS_SMC(pinfo)) {
- volatile smc_t *smcp = pinfo->smcp;
- smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
- smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
+ smc_t __iomem *smcp = pinfo->smcp;
+ clrbits16(&smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
+ clrbits8(&smcp->smc_smcm, SMCM_RX | SMCM_TX);
} else {
- volatile scc_t *sccp = pinfo->sccp;
- sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
+ scc_t __iomem *sccp = pinfo->sccp;
+ clrbits32(&sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+ clrbits16(&sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
}
/* Shut them really down and reinit buffer descriptors */
@@ -492,8 +494,8 @@ static void cpm_uart_set_termios(struct uart_port *port,
u16 cval, scval, prev_mode;
int bits, sbits;
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- volatile smc_t *smcp = pinfo->smcp;
- volatile scc_t *sccp = pinfo->sccp;
+ smc_t __iomem *smcp = pinfo->smcp;
+ scc_t __iomem *sccp = pinfo->sccp;
pr_debug("CPM uart[%d]:set_termios\n", port->line);
@@ -588,11 +590,11 @@ static void cpm_uart_set_termios(struct uart_port *port,
* enables, because we want to put them back if they were
* present.
*/
- prev_mode = smcp->smc_smcmr;
- smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART;
- smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN));
+ prev_mode = in_be16(&smcp->smc_smcmr);
+ out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART);
+ setbits16(&smcp->smc_smcmr, (prev_mode & (SMCMR_REN | SMCMR_TEN)));
} else {
- sccp->scc_psmr = (sbits << 12) | scval;
+ out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
}
cpm_set_brg(pinfo->brg - 1, baud);
@@ -630,8 +632,8 @@ static int cpm_uart_verify_port(struct uart_port *port,
*/
static int cpm_uart_tx_pump(struct uart_port *port)
{
- volatile cbd_t *bdp;
- unsigned char *p;
+ cbd_t __iomem *bdp;
+ u8 *p;
int count;
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
struct circ_buf *xmit = &port->info->xmit;
@@ -641,13 +643,14 @@ static int cpm_uart_tx_pump(struct uart_port *port)
/* Pick next descriptor and fill from buffer */
bdp = pinfo->tx_cur;
- p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
+ p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
*p++ = port->x_char;
- bdp->cbd_datlen = 1;
- bdp->cbd_sc |= BD_SC_READY;
+
+ out_be16(&bdp->cbd_datlen, 1);
+ setbits16(&bdp->cbd_sc, BD_SC_READY);
/* Get next BD. */
- if (bdp->cbd_sc & BD_SC_WRAP)
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
bdp = pinfo->tx_bd_base;
else
bdp++;
@@ -666,9 +669,10 @@ static int cpm_uart_tx_pump(struct uart_port *port)
/* Pick next descriptor and fill from buffer */
bdp = pinfo->tx_cur;
- while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) {
+ while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) &&
+ xmit->tail != xmit->head) {
count = 0;
- p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
+ p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
while (count < pinfo->tx_fifosize) {
*p++ = xmit->buf[xmit->tail];
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -677,11 +681,10 @@ static int cpm_uart_tx_pump(struct uart_port *port)
if (xmit->head == xmit->tail)
break;
}
- bdp->cbd_datlen = count;
- bdp->cbd_sc |= BD_SC_READY;
- eieio();
+ out_be16(&bdp->cbd_datlen, count);
+ setbits16(&bdp->cbd_sc, BD_SC_READY);
/* Get next BD. */
- if (bdp->cbd_sc & BD_SC_WRAP)
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
bdp = pinfo->tx_bd_base;
else
bdp++;
@@ -706,7 +709,7 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
{
int i;
u8 *mem_addr;
- volatile cbd_t *bdp;
+ cbd_t __iomem *bdp;
pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line);
@@ -717,13 +720,13 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
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, pinfo);
- bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
+ out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo));
+ out_be16(&bdp->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT);
mem_addr += pinfo->rx_fifosize;
}
- bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
- bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
+ out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo));
+ out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT);
/* Set the physical address of the host memory
* buffers in the buffer descriptors, and the
@@ -732,19 +735,19 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
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, pinfo);
- bdp->cbd_sc = BD_SC_INTRPT;
+ out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo));
+ out_be16(&bdp->cbd_sc, BD_SC_INTRPT);
mem_addr += pinfo->tx_fifosize;
}
- bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
- bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
+ out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo));
+ out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_INTRPT);
}
static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
{
- volatile scc_t *scp;
- volatile scc_uart_t *sup;
+ scc_t __iomem *scp;
+ scc_uart_t __iomem *sup;
pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line);
@@ -752,8 +755,10 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
sup = pinfo->sccup;
/* Store address */
- pinfo->sccup->scc_genscc.scc_rbase = (unsigned char *)pinfo->rx_bd_base - DPRAM_BASE;
- pinfo->sccup->scc_genscc.scc_tbase = (unsigned char *)pinfo->tx_bd_base - DPRAM_BASE;
+ out_be16(&pinfo->sccup->scc_genscc.scc_rbase,
+ (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE);
+ out_be16(&pinfo->sccup->scc_genscc.scc_tbase,
+ (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);
/* Set up the uart parameters in the
* parameter ram.
@@ -761,25 +766,25 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
cpm_set_scc_fcr(sup);
- sup->scc_genscc.scc_mrblr = pinfo->rx_fifosize;
- sup->scc_maxidl = pinfo->rx_fifosize;
- sup->scc_brkcr = 1;
- sup->scc_parec = 0;
- sup->scc_frmec = 0;
- sup->scc_nosec = 0;
- sup->scc_brkec = 0;
- sup->scc_uaddr1 = 0;
- sup->scc_uaddr2 = 0;
- sup->scc_toseq = 0;
- sup->scc_char1 = 0x8000;
- sup->scc_char2 = 0x8000;
- sup->scc_char3 = 0x8000;
- sup->scc_char4 = 0x8000;
- sup->scc_char5 = 0x8000;
- sup->scc_char6 = 0x8000;
- sup->scc_char7 = 0x8000;
- sup->scc_char8 = 0x8000;
- sup->scc_rccm = 0xc0ff;
+ out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize);
+ out_be16(&sup->scc_maxidl, pinfo->rx_fifosize);
+ out_be16(&sup->scc_brkcr, 1);
+ out_be16(&sup->scc_parec, 0);
+ out_be16(&sup->scc_frmec, 0);
+ out_be16(&sup->scc_nosec, 0);
+ out_be16(&sup->scc_brkec, 0);
+ out_be16(&sup->scc_uaddr1, 0);
+ out_be16(&sup->scc_uaddr2, 0);
+ out_be16(&sup->scc_toseq, 0);
+ out_be16(&sup->scc_char1, 0x8000);
+ out_be16(&sup->scc_char2, 0x8000);
+ out_be16(&sup->scc_char3, 0x8000);
+ out_be16(&sup->scc_char4, 0x8000);
+ out_be16(&sup->scc_char5, 0x8000);
+ out_be16(&sup->scc_char6, 0x8000);
+ out_be16(&sup->scc_char7, 0x8000);
+ out_be16(&sup->scc_char8, 0x8000);
+ out_be16(&sup->scc_rccm, 0xc0ff);
/* Send the CPM an initialize command.
*/
@@ -788,23 +793,23 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
/* Set UART mode, 8 bit, no parity, one stop.
* Enable receive and transmit.
*/
- scp->scc_gsmrh = 0;
- scp->scc_gsmrl =
- (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+ out_be32(&scp->scc_gsmrh, 0);
+ out_be32(&scp->scc_gsmrl,
+ SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
/* Enable rx interrupts and clear all pending events. */
- scp->scc_sccm = 0;
- scp->scc_scce = 0xffff;
- scp->scc_dsr = 0x7e7e;
- scp->scc_psmr = 0x3000;
+ out_be16(&scp->scc_sccm, 0);
+ out_be16(&scp->scc_scce, 0xffff);
+ out_be16(&scp->scc_dsr, 0x7e7e);
+ out_be16(&scp->scc_psmr, 0x3000);
- scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+ setbits32(&scp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
{
- volatile smc_t *sp;
- volatile smc_uart_t *up;
+ smc_t __iomem *sp;
+ smc_uart_t __iomem *up;
pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line);
@@ -812,19 +817,21 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
up = pinfo->smcup;
/* Store address */
- pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE;
- pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE;
+ out_be16(&pinfo->smcup->smc_rbase,
+ (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE);
+ out_be16(&pinfo->smcup->smc_tbase,
+ (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);
/*
* In case SMC1 is being relocated...
*/
#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
- up->smc_rbptr = pinfo->smcup->smc_rbase;
- up->smc_tbptr = pinfo->smcup->smc_tbase;
- up->smc_rstate = 0;
- up->smc_tstate = 0;
- up->smc_brkcr = 1; /* number of break chars */
- up->smc_brkec = 0;
+ out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase));
+ out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase));
+ out_be32(&up->smc_rstate, 0);
+ out_be32(&up->smc_tstate, 0);
+ out_be16(&up->smc_brkcr, 1); /* number of break chars */
+ out_be16(&up->smc_brkec, 0);
#endif
/* Set up the uart parameters in the
@@ -833,24 +840,24 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
cpm_set_smc_fcr(up);
/* Using idle charater time requires some additional tuning. */
- up->smc_mrblr = pinfo->rx_fifosize;
- up->smc_maxidl = pinfo->rx_fifosize;
- up->smc_brklen = 0;
- up->smc_brkec = 0;
- up->smc_brkcr = 1;
+ out_be16(&up->smc_mrblr, pinfo->rx_fifosize);
+ out_be16(&up->smc_maxidl, pinfo->rx_fifosize);
+ out_be16(&up->smc_brklen, 0);
+ out_be16(&up->smc_brkec, 0);
+ out_be16(&up->smc_brkcr, 1);
cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
/* Set UART mode, 8 bit, no parity, one stop.
* Enable receive and transmit.
*/
- sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
+ out_be16(&sp->smc_smcmr, smcr_mk_clen(9) | SMCMR_SM_UART);
/* Enable only rx interrupts clear all pending events. */
- sp->smc_smcm = 0;
- sp->smc_smce = 0xff;
+ out_8(&sp->smc_smcm, 0);
+ out_8(&sp->smc_smce, 0xff);
- sp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
+ setbits16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
}
/*
@@ -868,11 +875,11 @@ static int cpm_uart_request_port(struct uart_port *port)
return 0;
if (IS_SMC(pinfo)) {
- pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
- pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+ clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
+ clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
} else {
- pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
- pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+ clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+ clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
ret = cpm_uart_allocbuf(pinfo, 0);
@@ -931,10 +938,11 @@ static struct uart_ops cpm_uart_pops = {
#ifdef CONFIG_PPC_CPM_NEW_BINDING
struct uart_cpm_port cpm_uart_ports[UART_NR];
-int cpm_uart_init_port(struct device_node *np, struct uart_cpm_port *pinfo)
+static int cpm_uart_init_port(struct device_node *np,
+ struct uart_cpm_port *pinfo)
{
const u32 *data;
- void __iomem *mem, __iomem *pram;
+ void __iomem *mem, *pram;
int len;
int ret;
@@ -1169,8 +1177,8 @@ static void cpm_uart_console_write(struct console *co, const char *s,
&cpm_uart_ports[cpm_uart_port_map[co->index]];
#endif
unsigned int i;
- volatile cbd_t *bdp, *bdbase;
- volatile unsigned char *cp;
+ cbd_t __iomem *bdp, *bdbase;
+ unsigned char *cp;
/* Get the address of the host memory buffer.
*/
@@ -1188,37 +1196,36 @@ static void cpm_uart_console_write(struct console *co, const char *s,
* Ready indicates output is ready, and xmt is doing
* that, not that it is ready for us to send.
*/
- while ((bdp->cbd_sc & BD_SC_READY) != 0)
+ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
;
/* Send the character out.
* If the buffer address is in the CPM DPRAM, don't
* convert it.
*/
- cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
-
+ cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
*cp = *s;
- bdp->cbd_datlen = 1;
- bdp->cbd_sc |= BD_SC_READY;
+ out_be16(&bdp->cbd_datlen, 1);
+ setbits16(&bdp->cbd_sc, BD_SC_READY);
- if (bdp->cbd_sc & BD_SC_WRAP)
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
bdp = bdbase;
else
bdp++;
/* if a LF, also do CR... */
if (*s == 10) {
- while ((bdp->cbd_sc & BD_SC_READY) != 0)
+ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
;
- cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
-
+ cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
*cp = 13;
- bdp->cbd_datlen = 1;
- bdp->cbd_sc |= BD_SC_READY;
- if (bdp->cbd_sc & BD_SC_WRAP)
+ out_be16(&bdp->cbd_datlen, 1);
+ setbits16(&bdp->cbd_sc, BD_SC_READY);
+
+ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
bdp = bdbase;
else
bdp++;
@@ -1229,10 +1236,10 @@ static void cpm_uart_console_write(struct console *co, const char *s,
* Finally, Wait for transmitter & holding register to empty
* and restore the IER
*/
- while ((bdp->cbd_sc & BD_SC_READY) != 0)
+ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
;
- pinfo->tx_cur = (volatile cbd_t *) bdp;
+ pinfo->tx_cur = bdp;
}
@@ -1319,11 +1326,11 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
#endif
if (IS_SMC(pinfo)) {
- pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
- pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+ clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
+ clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
} else {
- pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
- pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+ clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+ clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
ret = cpm_uart_allocbuf(pinfo, 1);
@@ -1354,7 +1361,7 @@ static struct console cpm_scc_uart_console = {
.data = &cpm_reg,
};
-int __init cpm_uart_console_init(void)
+static int __init cpm_uart_console_init(void)
{
register_console(&cpm_scc_uart_console);
return 0;
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 4647f55..52fb044 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -179,7 +179,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
* pinfo->rx_fifosize);
- pinfo->rx_bd_base = (volatile cbd_t *)dp_mem;
+ pinfo->rx_bd_base = (cbd_t __iomem __force *)dp_mem;
pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos;
return 0;
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
index cdc9b22..470b093 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
@@ -27,18 +27,18 @@ static inline void cpm_set_brg(int brg, int baud)
cpm_setbrg(brg, baud);
}
-static inline void cpm_set_scc_fcr(volatile scc_uart_t * sup)
+static inline void cpm_set_scc_fcr(scc_uart_t __iomem * sup)
{
- sup->scc_genscc.scc_rfcr = SMC_EB;
- sup->scc_genscc.scc_tfcr = SMC_EB;
+ out_8(&sup->scc_genscc.scc_rfcr, SMC_EB);
+ out_8(&sup->scc_genscc.scc_tfcr, SMC_EB);
}
-static inline void cpm_set_smc_fcr(volatile smc_uart_t * up)
+static inline void cpm_set_smc_fcr(smc_uart_t __iomem * up)
{
- up->smc_rfcr = SMC_EB;
- up->smc_tfcr = SMC_EB;
+ out_8(&up->smc_rfcr, SMC_EB);
+ out_8(&up->smc_tfcr, SMC_EB);
}
-#define DPRAM_BASE ((unsigned char *)&cpmp->cp_dpmem[0])
+#define DPRAM_BASE ((u8 __iomem __force *)&cpmp->cp_dpmem[0])
#endif
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index 7ebce26..5bd4508 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -278,7 +278,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
* pinfo->rx_fifosize);
- pinfo->rx_bd_base = (volatile cbd_t *)dp_mem;
+ pinfo->rx_bd_base = (cbd_t __iomem __force *)dp_mem;
pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos;
return 0;
@@ -289,7 +289,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos *
pinfo->rx_fifosize) +
L1_CACHE_ALIGN(pinfo->tx_nrfifos *
- pinfo->tx_fifosize), pinfo->mem_addr,
+ pinfo->tx_fifosize), (void __force *)pinfo->mem_addr,
pinfo->dma_addr);
cpm_dpfree(pinfo->dp_addr);
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
index e7717ec..40006a7 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
@@ -27,18 +27,18 @@ static inline void cpm_set_brg(int brg, int baud)
cpm_setbrg(brg, baud);
}
-static inline void cpm_set_scc_fcr(volatile scc_uart_t * sup)
+static inline void cpm_set_scc_fcr(scc_uart_t __iomem *sup)
{
- sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB;
- sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB;
+ out_8(&sup->scc_genscc.scc_rfcr, CPMFCR_GBL | CPMFCR_EB);
+ out_8(&sup->scc_genscc.scc_tfcr, CPMFCR_GBL | CPMFCR_EB);
}
-static inline void cpm_set_smc_fcr(volatile smc_uart_t * up)
+static inline void cpm_set_smc_fcr(smc_uart_t __iomem *up)
{
- up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB;
- up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB;
+ out_8(&up->smc_rfcr, CPMFCR_GBL | CPMFCR_EB);
+ out_8(&up->smc_tfcr, CPMFCR_GBL | CPMFCR_EB);
}
-#define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0))
+#define DPRAM_BASE ((u8 __iomem __force *)cpm_dpram_addr(0))
#endif
--
1.5.0.3
^ permalink raw reply related
* [PATCH 4/4] cpm_uart: Issue STOP_TX command before initializing console.
From: Scott Wood @ 2007-08-28 20:16 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
This prevents some bootloader/bootwrapper characters from being lost.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/serial/cpm_uart/cpm_uart_core.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index c43706e..336e05e 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -1325,6 +1325,8 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
udbg_putc = NULL;
#endif
+ cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
+
if (IS_SMC(pinfo)) {
clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
@@ -1346,6 +1348,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
cpm_uart_init_scc(pinfo);
uart_set_options(port, co, baud, parity, bits, flow);
+ cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX);
return 0;
}
--
1.5.0.3
^ permalink raw reply related
* [PATCH 2/4] cpm_uart: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set.
From: Scott Wood @ 2007-08-28 20:16 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
The existing OF glue code was crufty and broken. Rather than fix it,
it has been removed, and the serial driver now talks to the device tree
directly.
The non-CONFIG_PPC_CPM_NEW_BINDING code can go away once CPM platforms
are dropped from arch/ppc (which will hopefully be soon), and existing
arch/powerpc boards that I wasn't able to test on for this patchset get
converted (which should be even sooner).
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/serial/cpm_uart/cpm_uart.h | 6 +-
drivers/serial/cpm_uart/cpm_uart_core.c | 241 ++++++++++++++++++++++++++++---
drivers/serial/cpm_uart/cpm_uart_cpm1.c | 16 ++-
drivers/serial/cpm_uart/cpm_uart_cpm1.h | 2 +
drivers/serial/cpm_uart/cpm_uart_cpm2.c | 18 +++-
drivers/serial/cpm_uart/cpm_uart_cpm2.h | 2 +
6 files changed, 260 insertions(+), 25 deletions(-)
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index a8f894c..4e1987a 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -80,14 +80,18 @@ struct uart_cpm_port {
int is_portb;
/* wait on close if needed */
int wait_closing;
+ /* value to combine with opcode to form cpm command */
+ u32 command;
};
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
extern int cpm_uart_port_map[UART_NR];
+#endif
extern int cpm_uart_nr;
extern struct uart_cpm_port cpm_uart_ports[UART_NR];
/* these are located in their respective files */
-void cpm_line_cr_cmd(int line, int cmd);
+void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd);
int cpm_uart_init_portdesc(void);
int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con);
void cpm_uart_freebuf(struct uart_cpm_port *pinfo);
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index cefde58..78171d0 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -10,7 +10,7 @@
* Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
* Pantelis Antoniou (panto@intracom.gr) (CPM1)
*
- * Copyright (C) 2004 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004, 2007 Freescale Semiconductor, Inc.
* (C) 2004 Intracom, S.A.
* (C) 2005-2006 MontaVista Software, Inc.
* Vitaly Bordug <vbordug@ru.mvista.com>
@@ -47,6 +47,11 @@
#include <asm/irq.h>
#include <asm/delay.h>
#include <asm/fs_pd.h>
+#include <asm/udbg.h>
+
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_platform.h>
+#endif
#if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
@@ -57,12 +62,6 @@
#include "cpm_uart.h"
-/***********************************************************************/
-
-/* 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 = 0;
/**************************************************************/
@@ -73,6 +72,11 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo);
/**************************************************************/
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
+/* 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;
/* Place-holder for board-specific stuff */
struct platform_device* __attribute__ ((weak)) __init
@@ -119,6 +123,7 @@ static int cpm_uart_id2nr(int id)
/* not found or invalid argument */
return -1;
}
+#endif
/*
* Check, if transmit buffers are processed
@@ -232,15 +237,14 @@ static void cpm_uart_enable_ms(struct uart_port *port)
static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- int line = pinfo - cpm_uart_ports;
pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
break_state);
if (break_state)
- cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
+ cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
else
- cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);
+ cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX);
}
/*
@@ -407,7 +411,6 @@ static int cpm_uart_startup(struct uart_port *port)
{
int retval;
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- int line = pinfo - cpm_uart_ports;
pr_debug("CPM uart[%d]:startup\n", port->line);
@@ -426,7 +429,7 @@ static int cpm_uart_startup(struct uart_port *port)
}
if (!(pinfo->flags & FLAG_CONSOLE))
- cpm_line_cr_cmd(line,CPM_CR_INIT_TRX);
+ cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
return 0;
}
@@ -442,7 +445,6 @@ inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo)
static void cpm_uart_shutdown(struct uart_port *port)
{
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
- int line = pinfo - cpm_uart_ports;
pr_debug("CPM uart[%d]:shutdown\n", port->line);
@@ -473,9 +475,9 @@ static void cpm_uart_shutdown(struct uart_port *port)
/* Shut them really down and reinit buffer descriptors */
if (IS_SMC(pinfo))
- cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
+ cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
else
- cpm_line_cr_cmd(line, CPM_CR_GRA_STOP_TX);
+ cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
cpm_uart_initbd(pinfo);
}
@@ -595,7 +597,6 @@ static void cpm_uart_set_termios(struct uart_port *port,
cpm_set_brg(pinfo->brg - 1, baud);
spin_unlock_irqrestore(&port->lock, flags);
-
}
static const char *cpm_uart_type(struct uart_port *port)
@@ -742,7 +743,6 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
{
- int line = pinfo - cpm_uart_ports;
volatile scc_t *scp;
volatile scc_uart_t *sup;
@@ -783,7 +783,7 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
/* Send the CPM an initialize command.
*/
- cpm_line_cr_cmd(line, CPM_CR_INIT_TRX);
+ cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
/* Set UART mode, 8 bit, no parity, one stop.
* Enable receive and transmit.
@@ -803,7 +803,6 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
{
- int line = pinfo - cpm_uart_ports;
volatile smc_t *sp;
volatile smc_uart_t *up;
@@ -840,7 +839,7 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
up->smc_brkec = 0;
up->smc_brkcr = 1;
- cpm_line_cr_cmd(line, CPM_CR_INIT_TRX);
+ cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
/* Set UART mode, 8 bit, no parity, one stop.
* Enable receive and transmit.
@@ -929,6 +928,85 @@ static struct uart_ops cpm_uart_pops = {
.verify_port = cpm_uart_verify_port,
};
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+struct uart_cpm_port cpm_uart_ports[UART_NR];
+
+int cpm_uart_init_port(struct device_node *np, struct uart_cpm_port *pinfo)
+{
+ const u32 *data;
+ void __iomem *mem, __iomem *pram;
+ int len;
+ int ret;
+
+ data = of_get_property(np, "fsl,cpm-brg", &len);
+ if (!data || len != 4) {
+ printk(KERN_ERR "CPM UART %s has no/invalid "
+ "fsl,cpm-brg property.\n", np->name);
+ return -EINVAL;
+ }
+ pinfo->brg = *data;
+
+ data = of_get_property(np, "fsl,cpm-command", &len);
+ if (!data || len != 4) {
+ printk(KERN_ERR "CPM UART %s has no/invalid "
+ "fsl,cpm-command property.\n", np->name);
+ return -EINVAL;
+ }
+ pinfo->command = *data;
+
+ mem = of_iomap(np, 0);
+ if (!mem)
+ return -ENOMEM;
+
+ pram = of_iomap(np, 1);
+ if (!pram) {
+ ret = -ENOMEM;
+ goto out_mem;
+ }
+
+ if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") ||
+ of_device_is_compatible(np, "fsl,cpm2-scc-uart")) {
+ pinfo->sccp = mem;
+ pinfo->sccup = pram;
+ } else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") ||
+ of_device_is_compatible(np, "fsl,cpm2-smc-uart")) {
+ pinfo->flags |= FLAG_SMC;
+ pinfo->smcp = mem;
+ pinfo->smcup = pram;
+ } else {
+ ret = -ENODEV;
+ goto out_pram;
+ }
+
+ pinfo->tx_nrfifos = TX_NUM_FIFO;
+ pinfo->tx_fifosize = TX_BUF_SIZE;
+ pinfo->rx_nrfifos = RX_NUM_FIFO;
+ pinfo->rx_fifosize = RX_BUF_SIZE;
+
+ pinfo->port.uartclk = ppc_proc_freq;
+ pinfo->port.mapbase = (unsigned long)mem;
+ pinfo->port.type = PORT_CPM;
+ pinfo->port.ops = &cpm_uart_pops,
+ pinfo->port.iotype = UPIO_MEM;
+ spin_lock_init(&pinfo->port.lock);
+
+ pinfo->port.irq = of_irq_to_resource(np, 0, NULL);
+ if (pinfo->port.irq == NO_IRQ) {
+ ret = -EINVAL;
+ goto out_pram;
+ }
+
+ return cpm_uart_request_port(&pinfo->port);
+
+out_pram:
+ iounmap(pram);
+out_mem:
+ iounmap(mem);
+ return ret;
+}
+
+#else
+
struct uart_cpm_port cpm_uart_ports[UART_NR] = {
[UART_SMC1] = {
.port = {
@@ -1072,6 +1150,7 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
return 0;
}
+#endif
#ifdef CONFIG_SERIAL_CPM_CONSOLE
/*
@@ -1083,8 +1162,12 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
static void cpm_uart_console_write(struct console *co, const char *s,
u_int count)
{
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+ struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
+#else
struct uart_cpm_port *pinfo =
&cpm_uart_ports[cpm_uart_port_map[co->index]];
+#endif
unsigned int i;
volatile cbd_t *bdp, *bdbase;
volatile unsigned char *cp;
@@ -1155,13 +1238,47 @@ static void cpm_uart_console_write(struct console *co, const char *s,
static int __init cpm_uart_console_setup(struct console *co, char *options)
{
- struct uart_port *port;
- struct uart_cpm_port *pinfo;
int baud = 38400;
int bits = 8;
int parity = 'n';
int flow = 'n';
int ret;
+ struct uart_cpm_port *pinfo;
+ struct uart_port *port;
+
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+ struct device_node *np = NULL;
+ int i = 0;
+
+ if (co->index >= UART_NR) {
+ printk(KERN_ERR "cpm_uart: console index %d too high\n",
+ co->index);
+ return -ENODEV;
+ }
+
+ do {
+ np = of_find_node_by_type(np, "serial");
+ if (!np)
+ return -ENODEV;
+
+ if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") &&
+ !of_device_is_compatible(np, "fsl,cpm1-scc-uart") &&
+ !of_device_is_compatible(np, "fsl,cpm2-smc-uart") &&
+ !of_device_is_compatible(np, "fsl,cpm2-scc-uart"))
+ i--;
+ } while (i++ != co->index);
+
+ pinfo = &cpm_uart_ports[co->index];
+
+ pinfo->flags |= FLAG_CONSOLE;
+ port = &pinfo->port;
+
+ ret = cpm_uart_init_port(np, pinfo);
+ of_node_put(np);
+ if (ret)
+ return ret;
+
+#else
struct fs_uart_platform_info *pdata;
struct platform_device* pdev = early_uart_get_pdev(co->index);
@@ -1188,6 +1305,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
}
pinfo->flags |= FLAG_CONSOLE;
+#endif
if (options) {
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -1196,6 +1314,10 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
baud = 9600;
}
+#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
+ udbg_putc = NULL;
+#endif
+
if (IS_SMC(pinfo)) {
pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
@@ -1252,7 +1374,81 @@ static struct uart_driver cpm_reg = {
.major = SERIAL_CPM_MAJOR,
.minor = SERIAL_CPM_MINOR,
.cons = CPM_UART_CONSOLE,
+ .nr = UART_NR,
+};
+
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+static int probe_index;
+
+static int __devinit cpm_uart_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ int index = probe_index++;
+ struct uart_cpm_port *pinfo = &cpm_uart_ports[index];
+ int ret;
+
+ pinfo->port.line = index;
+
+ if (index >= UART_NR)
+ return -ENODEV;
+
+ dev_set_drvdata(&ofdev->dev, pinfo);
+
+ ret = cpm_uart_init_port(ofdev->node, pinfo);
+ if (ret)
+ return ret;
+
+ return uart_add_one_port(&cpm_reg, &pinfo->port);
+}
+
+static int __devexit cpm_uart_remove(struct of_device *ofdev)
+{
+ struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev);
+ return uart_remove_one_port(&cpm_reg, &pinfo->port);
+}
+
+static struct of_device_id cpm_uart_match[] = {
+ {
+ .compatible = "fsl,cpm1-smc-uart",
+ },
+ {
+ .compatible = "fsl,cpm1-scc-uart",
+ },
+ {
+ .compatible = "fsl,cpm2-smc-uart",
+ },
+ {
+ .compatible = "fsl,cpm2-scc-uart",
+ },
+ {}
};
+
+static struct of_platform_driver cpm_uart_driver = {
+ .name = "cpm_uart",
+ .match_table = cpm_uart_match,
+ .probe = cpm_uart_probe,
+ .remove = cpm_uart_remove,
+ };
+
+static int __init cpm_uart_init(void)
+{
+ int ret = uart_register_driver(&cpm_reg);
+ if (ret)
+ return ret;
+
+ ret = of_register_platform_driver(&cpm_uart_driver);
+ if (ret)
+ uart_unregister_driver(&cpm_reg);
+
+ return ret;
+}
+
+static void __exit cpm_uart_exit(void)
+{
+ of_unregister_platform_driver(&cpm_uart_driver);
+ uart_unregister_driver(&cpm_reg);
+}
+#else
static int cpm_uart_drv_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1380,6 +1576,7 @@ static void __exit cpm_uart_exit(void)
driver_unregister(&cpm_smc_uart_driver);
uart_unregister_driver(&cpm_reg);
}
+#endif
module_init(cpm_uart_init);
module_exit(cpm_uart_exit);
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 8c6324e..4647f55 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -49,9 +49,20 @@
/**************************************************************/
-void cpm_line_cr_cmd(int line, int cmd)
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
+{
+ u16 __iomem *cpcr = &cpmp->cp_cpcr;
+
+ out_be16(cpcr, port->command | (cmd << 8) | CPM_CR_FLG);
+ while (in_be16(cpcr) & CPM_CR_FLG)
+ ;
+}
+#else
+void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
{
ushort val;
+ int line = port - cpm_uart_ports;
volatile cpm8xx_t *cp = cpmp;
switch (line) {
@@ -114,6 +125,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo)
/* XXX SCC4: insert port configuration here */
pinfo->brg = 4;
}
+#endif
/*
* Allocate DP-Ram and memory buffers. We need to allocate a transmit and
@@ -184,6 +196,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
cpm_dpfree(pinfo->dp_addr);
}
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
/* Setup any dynamic params in the uart desc */
int cpm_uart_init_portdesc(void)
{
@@ -279,3 +292,4 @@ int cpm_uart_init_portdesc(void)
#endif
return 0;
}
+#endif
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
index a99e45e..cdc9b22 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h
@@ -13,12 +13,14 @@
#include <asm/commproc.h>
/* defines for IRQs */
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
#define SMC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC1)
#define SMC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC2)
#define SCC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC1)
#define SCC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC2)
#define SCC3_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC3)
#define SCC4_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC4)
+#endif
static inline void cpm_set_brg(int brg, int baud)
{
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index 7b61d80..7ebce26 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -49,9 +49,22 @@
/**************************************************************/
-void cpm_line_cr_cmd(int line, int cmd)
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
+{
+ cpm_cpm2_t __iomem *cp = cpm2_map(im_cpm);
+
+ out_be32(&cp->cp_cpcr, port->command | cmd | CPM_CR_FLG);
+ while (in_be32(&cp->cp_cpcr) & CPM_CR_FLG)
+ ;
+
+ cpm2_unmap(cp);
+}
+#else
+void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
{
ulong val;
+ int line = port - cpm_uart_ports;
volatile cpm_cpm2_t *cp = cpm2_map(im_cpm);
@@ -211,6 +224,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo)
cpm2_unmap(cpmux);
cpm2_unmap(io);
}
+#endif
/*
* Allocate DP-Ram and memory buffers. We need to allocate a transmit and
@@ -281,6 +295,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
cpm_dpfree(pinfo->dp_addr);
}
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
/* Setup any dynamic params in the uart desc */
int cpm_uart_init_portdesc(void)
{
@@ -386,3 +401,4 @@ int cpm_uart_init_portdesc(void)
return 0;
}
+#endif
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
index 1b3219f..e7717ec 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h
@@ -13,12 +13,14 @@
#include <asm/cpm2.h>
/* defines for IRQs */
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
#define SMC1_IRQ SIU_INT_SMC1
#define SMC2_IRQ SIU_INT_SMC2
#define SCC1_IRQ SIU_INT_SCC1
#define SCC2_IRQ SIU_INT_SCC2
#define SCC3_IRQ SIU_INT_SCC3
#define SCC4_IRQ SIU_INT_SCC4
+#endif
static inline void cpm_set_brg(int brg, int baud)
{
--
1.5.0.3
^ permalink raw reply related
* [PATCH 1/4] ppc: Add clrbits8 and setbits8.
From: Scott Wood @ 2007-08-28 20:16 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
These I/O accessors will be used in code under drivers/,
which is expected to still work in arch/ppc.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
include/asm-ppc/io.h | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 95d5904..f776c49 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -553,4 +553,7 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
#define setbits16(_addr, _v) out_be16((_addr), in_be16(_addr) | (_v))
#define clrbits16(_addr, _v) out_be16((_addr), in_be16(_addr) & ~(_v))
+#define setbits8(_addr, _v) out_8((_addr), in_8(_addr) | (_v))
+#define clrbits8(_addr, _v) out_8((_addr), in_8(_addr) & ~(_v))
+
#endif /* __KERNEL__ */
--
1.5.0.3
^ permalink raw reply related
* [PATCH 1/3] fsl_soc.c cleanup
From: Scott Wood @ 2007-08-28 20:16 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
1. Fix get_immrbase() to use ranges, rather than reg.
It is not always the case that the SoC's first reg property points
to the beginning of the entire SoC block.
2. Update the way get_brgfreq() finds things in the device tree.
It now uses names that are less namespace polluting. The old names
are supported until all boards are converted.
3. "size" is changed from unsigned int to int, to match what
of_get_property() expects.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/sysdev/fsl_soc.c | 38 +++++++++++++++++++++++++++-----------
1 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index f3abce1..63e2350 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -52,11 +52,20 @@ phys_addr_t get_immrbase(void)
soc = of_find_node_by_type(NULL, "soc");
if (soc) {
- unsigned int size;
- const void *prop = of_get_property(soc, "reg", &size);
+ int size;
+ u32 naddr;
+ const u32 *prop = of_get_property(soc, "#address-cells", &size);
+
+ if (prop && size == 4)
+ naddr = *prop;
+ else
+ naddr = 2;
+
+ prop = of_get_property(soc, "ranges", &size);
+
+ if (prop && size >= 12)
+ immrbase = of_translate_address(soc, prop + naddr);
- if (prop)
- immrbase = of_translate_address(soc, prop);
of_node_put(soc);
};
@@ -76,16 +85,23 @@ u32 get_brgfreq(void)
if (brgfreq != -1)
return brgfreq;
- node = of_find_node_by_type(NULL, "cpm");
+ node = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
+ if (!node)
+ node = of_find_compatible_node(NULL, NULL, "fsl,cpm2");
+ if (!node)
+ node = of_find_node_by_type(NULL, "cpm");
if (node) {
- unsigned int size;
- const unsigned int *prop = of_get_property(node,
- "brg-frequency", &size);
+ int size;
+ const unsigned int *prop;
- if (prop)
+ prop = of_get_property(node, "fsl,brg-frequency", &size);
+ if (!prop)
+ prop = of_get_property(node, "brg-frequency", &size);
+ if (prop && size == 4)
brgfreq = *prop;
+
of_node_put(node);
- };
+ }
return brgfreq;
}
@@ -103,7 +119,7 @@ u32 get_baudrate(void)
node = of_find_node_by_type(NULL, "serial");
if (node) {
- unsigned int size;
+ int size;
const unsigned int *prop = of_get_property(node,
"current-speed", &size);
--
1.5.0.3
^ permalink raw reply related
* [PATCH 2/3] Introduce new CPM device bindings.
From: Scott Wood @ 2007-08-28 20:16 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
This introduces a new device binding for the CPM and other devices on
these boards. Some of the changes include:
1. Proper namespace scoping for Freescale compatibles and properties.
2. Use compatible rather than things like device_type and model
to determine which particular variant of a device is present.
3. Give the drivers the relevant CPM command word directly, rather than
requiring it to have a lookup table based on device-id, SCC v. SMC, and
CPM version.
4. Specify the CPCR and the usable DPRAM region in the CPM's reg property.
Boards that do not require the legacy bindings should select
CONFIG_PPC_CPM_NEW_BINDING to enable the of_platform CPM devices. Once
all existing boards are converted and tested, the config option can
become default y to prevent new boards from using the old model. Once
arch/ppc is gone, the config option can be removed altogether.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
Documentation/powerpc/booting-without-of.txt | 169 +++++++++++++++++++++++++-
arch/powerpc/platforms/Kconfig | 11 ++
arch/powerpc/sysdev/fsl_soc.c | 2 +
3 files changed, 181 insertions(+), 1 deletions(-)
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 76733a3..2e0853b 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1510,7 +1510,10 @@ platforms are moved over to use the flattened-device-tree model.
i) Freescale QUICC Engine module (QE)
This represents qe module that is installed on PowerQUICC II Pro.
- Hopefully it will merge backward compatibility with CPM/CPM2.
+
+ NOTE: This is an interim binding; it should be updated to fit
+ in with the CPM binding later in this document.
+
Basically, it is a bus of devices, that could act more or less
as a complete entity (UCC, USB etc ). All of them should be siblings on
the "root" qe node, using the common properties from there.
@@ -1824,6 +1827,170 @@ platforms are moved over to use the flattened-device-tree model.
fsl,has-rstcr;
};
+ l) Freescale Communications Processor Module
+
+ NOTE: This is an interim binding, and will likely change slightly,
+ as more devices are supported. The QE bindings especially are
+ incomplete.
+
+ i) Root CPM node
+
+ Properties:
+ - compatible : "fsl,cpm1", "fsl,cpm2", or "fsl,qe".
+ - reg : The first resource is a 48-byte region beginning with
+ CPCR. The second is the available general-purpose
+ DPRAM.
+ - fsl,brg-frequency : the internal clock source frequency for baud-rate
+ generators in Hz.
+
+ Example:
+ cpm@119c0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ compatible = "fsl,mpc8272-cpm", "fsl,cpm2";
+ reg = <119c0 30 0 2000>;
+ bus-frequency = <d#25000000>;
+ }
+
+ ii) Properties common to mulitple CPM/QE devices
+
+ - fsl,cpm-command : This value is ORed with the opcode and command flag
+ to specify the device on which a CPM command operates.
+
+ - fsl,cpm-brg : Indicates which baud rate generator the device
+ is associated with. If absent, an unused BRG
+ should be dynamically allocated.
+
+ - reg : Unless otherwise specified, the first resource represents the
+ scc/fcc/ucc registers, and the second represents the device's
+ parameter RAM region (if it has one).
+
+ iii) Serial
+
+ Currently defined compatibles:
+ - fsl,cpm1-smc-uart
+ - fsl,cpm2-smc-uart
+ - fsl,cpm1-scc-uart
+ - fsl,cpm2-scc-uart
+ - fsl,qe-uart
+
+ Example:
+
+ serial@11a00 {
+ device_type = "serial";
+ compatible = "fsl,mpc8272-scc-uart",
+ "fsl,cpm2-scc-uart";
+ reg = <11a00 20 8000 100>;
+ interrupts = <28 8>;
+ interrupt-parent = <&PIC>;
+ fsl,cpm-brg = <1>;
+ fsl,cpm-command = <00800000>;
+ };
+
+ iii) Network
+
+ Currently defined compatibles:
+ - fsl,cpm1-scc-enet
+ - fsl,cpm2-scc-enet
+ - fsl,cpm1-fec-enet
+ - fsl,cpm2-fcc-enet (third resource is GFEMR)
+ - fsl,qe-enet
+
+ Example:
+
+ ethernet@11300 {
+ device_type = "network";
+ compatible = "fsl,mpc8272-fcc-enet",
+ "fsl,cpm2-fcc-enet";
+ reg = <11300 20 8400 100 11390 1>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <20 8>;
+ interrupt-parent = <&PIC>;
+ phy-handle = <&PHY0>;
+ linux,network-index = <0>;
+ fsl,cpm-command = <12000300>;
+ };
+
+ iv) MDIO
+
+ Currently defined compatibles:
+ fsl,pq1-fec-mdio (reg is same as first resource of FEC device)
+ fsl,cpm2-mdio-bitbang (reg is port C registers)
+
+ Properties for fsl,cpm2-mdio-bitbang:
+ fsl,mdio-pin : pin of port C controlling mdio data
+ fsl,mdc-pin : pin of port C controlling mdio clock
+
+ Example:
+
+ mdio@10d40 {
+ device_type = "mdio";
+ compatible = "fsl,mpc8272ads-mdio-bitbang",
+ "fsl,mpc8272-mdio-bitbang",
+ "fsl,cpm2-mdio-bitbang";
+ reg = <10d40 14>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fsl,mdio-pin = <12>;
+ fsl,mdc-pin = <13>;
+ };
+
+ v) Baud Rate Generators
+
+ There may be an arbitrary number of reg resources; BRG
+ numbers are assigned to these in order.
+
+ Currently defined compatibles:
+ fsl,cpm-brg
+ fsl,cpm1-brg
+ fsl,cpm2-brg
+
+ Example:
+
+ brg@119f0 {
+ compatible = "fsl,mpc8272-brg",
+ "fsl,cpm2-brg",
+ "fsl,cpm-brg";
+ reg = <119f0 10 115f0 10>;
+ };
+
+ vi) Interrupt Controllers
+
+ Currently defined compatibles:
+ - fsl,cpm1-pic
+ - only one interrupt cell
+ - fsl,pq1-pic
+ - fsl,pq2-pic
+ - second interrupt cell is level/sense:
+ - 2 is falling edge
+ - 8 is active low
+
+ Example:
+
+ interrupt-controller@10c00 {
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <10c00 80>;
+ compatible = "mpc8272-pic", "fsl,pq2-pic";
+ };
+
+ vii) USB (Universal Serial Bus Controller)
+
+ Properties:
+ - compatible : "fsl,cpm1-usb", "fsl,cpm2-usb", "fsl,qe-usb"
+
+ Example:
+ usb@11bc0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,cpm2-usb";
+ reg = <11b60 18 8b00 100>;
+ interrupts = <b 8>;
+ interrupt-parent = <&PIC>;
+ fsl,cpm-command = <2e600000>;
+ };
+
More devices will be defined as this spec matures.
VII - Specifying interrupt information for devices
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 041df77..8ddbd84 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -273,6 +273,17 @@ config CPM2
you wish to build a kernel for a machine with a CPM2 coprocessor
on it (826x, 827x, 8560).
+config PPC_CPM_NEW_BINDING
+ bool
+ depends on CPM1 || CPM2
+ help
+ Select this if your board has been converted to use the new
+ device tree bindings for CPM, and no longer needs the
+ ioport callbacks or the platform device glue code.
+
+ The fs_enet and cpm_uart drivers will be built as
+ of_platform devices.
+
config AXON_RAM
tristate "Axon DDR2 memory device driver"
depends on PPC_IBM_CELL_BLADE
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 63e2350..747448c 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -669,6 +669,7 @@ err:
arch_initcall(fsl_usb_of_init);
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
#ifdef CONFIG_CPM2
extern void init_scc_ioports(struct fs_uart_platform_info*);
@@ -1208,3 +1209,4 @@ err:
arch_initcall(cpm_smc_uart_of_init);
#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_CPM_NEW_BINDING */
--
1.5.0.3
^ permalink raw reply related
* [PATCH 3/3] Add early debug console for CPM serial ports.
From: Scott Wood @ 2007-08-28 20:16 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
This code assumes that the ports have been previously set up, with
buffers in DPRAM, and the descriptor address defined by platform code.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/Kconfig.debug | 9 +++++++
arch/powerpc/kernel/head_32.S | 16 +++++++++++++
arch/powerpc/kernel/udbg.c | 2 +
arch/powerpc/sysdev/Makefile | 1 +
arch/powerpc/sysdev/cpm_common.c | 44 ++++++++++++++++++++++++++++++++++++++
arch/powerpc/sysdev/cpm_common.h | 16 +++++++++++++
include/asm-powerpc/udbg.h | 1 +
7 files changed, 89 insertions(+), 0 deletions(-)
create mode 100644 arch/powerpc/sysdev/cpm_common.c
create mode 100644 arch/powerpc/sysdev/cpm_common.h
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 22acece..d471154 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -211,6 +211,15 @@ config PPC_EARLY_DEBUG_44x
Select this to enable early debugging for IBM 44x chips via the
inbuilt serial port.
+config PPC_EARLY_DEBUG_CPM
+ bool "Early serial debugging for Freescale CPM-based serial ports"
+ depends on SERIAL_CPM
+ select PIN_TLB if PPC_8xx
+ help
+ Select this to enable early debugging for Freescale chips
+ using a CPM-based serial port. This assumes that the bootwrapper
+ has run, and set up the CPM in a particular way.
+
endchoice
config PPC_EARLY_DEBUG_44x_PHYSLOW
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 7d73a13..e950a75 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -152,6 +152,9 @@ __after_mmu_off:
#if defined(CONFIG_BOOTX_TEXT)
bl setup_disp_bat
#endif
+#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
+ bl setup_cpm_bat
+#endif
/*
* Call setup_cpu for CPU 0 and initialize 6xx Idle
@@ -1248,6 +1251,19 @@ setup_disp_bat:
blr
#endif /* CONFIG_BOOTX_TEXT */
+#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
+setup_cpm_bat:
+ lis r8, 0xf000
+ ori r8, r8, 0x002a
+ mtspr SPRN_DBAT1L, r8
+
+ lis r11, 0xf000
+ ori r11, r11, (BL_1M << 2) | 2
+ mtspr SPRN_DBAT1U, r11
+
+ blr
+#endif
+
#ifdef CONFIG_8260
/* Jump into the system reset for the rom.
* We first disable the MMU, and then jump to the ROM reset address.
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 0f9b4ea..d723070 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -54,6 +54,8 @@ void __init udbg_early_init(void)
#elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
/* PPC44x debug */
udbg_init_44x_as1();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
+ udbg_init_cpm();
#endif
}
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 08ce31e..5063e74 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -34,6 +34,7 @@ endif
# Temporary hack until we have migrated to asm-powerpc
ifeq ($(ARCH),powerpc)
+obj-$(CONFIG_CPM1)$(CONFIG_CPM2) += cpm_common.o
obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
obj-$(CONFIG_8xx) += mpc8xx_pic.o commproc.o
obj-$(CONFIG_UCODE_PATCH) += micropatch.o
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
new file mode 100644
index 0000000..1972a8f
--- /dev/null
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -0,0 +1,44 @@
+/*
+ * Common CPM code
+ *
+ * Author: Scott Wood <scottwood@freescale.com>
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <asm/udbg.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <mm/mmu_decl.h>
+#include "cpm_common.h"
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
+static void udbg_putc_cpm(char c)
+{
+ u8 __iomem *txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
+
+ if (c == '\n')
+ udbg_putc('\r');
+
+ while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
+ ;
+
+ out_8(txbuf, c);
+ out_be32(&cpm_udbg_txdesc[0], 0xa0000001);
+}
+
+void __init udbg_init_cpm(void)
+{
+ if (cpm_udbg_txdesc) {
+#ifdef CONFIG_CPM2
+ setbat(1, 0xf0000000, 0xf0000000, 1024*1024, _PAGE_IO);
+#endif
+ udbg_putc = udbg_putc_cpm;
+ }
+}
+#endif
diff --git a/arch/powerpc/sysdev/cpm_common.h b/arch/powerpc/sysdev/cpm_common.h
new file mode 100644
index 0000000..f42343f
--- /dev/null
+++ b/arch/powerpc/sysdev/cpm_common.h
@@ -0,0 +1,16 @@
+#ifndef _POWERPC_SYSDEV_CPM_COMMON_H
+#define _POWERPC_SYSDEV_CPM_COMMON_H
+
+#include <linux/types.h>
+
+/*
+ * Board code must define this address if the early console is used.
+ *
+ * Note that this is not multi-platform safe, and thus the CPM
+ * UDBG console must only be enabled when only a single platform
+ * is selected. It is done this way because udbg init runs before
+ * platform probing.
+ */
+extern u32 __iomem *cpm_udbg_txdesc;
+
+#endif
diff --git a/include/asm-powerpc/udbg.h b/include/asm-powerpc/udbg.h
index ce9d82f..a9e0b0e 100644
--- a/include/asm-powerpc/udbg.h
+++ b/include/asm-powerpc/udbg.h
@@ -48,6 +48,7 @@ extern void __init udbg_init_rtas_console(void);
extern void __init udbg_init_debug_beat(void);
extern void __init udbg_init_btext(void);
extern void __init udbg_init_44x_as1(void);
+extern void __init udbg_init_cpm(void);
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_UDBG_H */
--
1.5.0.3
^ permalink raw reply related
* Re: RFC: issues concerning the next NAPI interface
From: David Miller @ 2007-08-28 20:21 UTC (permalink / raw)
To: ossthema
Cc: tklein, themann, stefan.roscher, netdev, jchapman, raisch,
linux-kernel, linuxppc-dev, akepner, meder, shemminger
In-Reply-To: <200708281319.03903.ossthema@de.ibm.com>
From: Jan-Bernd Themann <ossthema@de.ibm.com>
Date: Tue, 28 Aug 2007 13:19:03 +0200
> I will try the following scheme (once we get hrtimers): Each device
> (queue) has a hrtimer. Schedule the timer in the poll function
> instead of reactivating IRQs when a high load situation has been
> detected and all packets have been emptied from the receive queue.
> The timer function could then just call netif_rx_schedule to
> register the rx_queue for NAPI again.
Interrupt mitigation only works if it helps you avoid interrupts.
This scheme potentially makes more of them happen.
The hrtimer is just another interrupt, a cpu locally triggered one,
but it has much of the same costs nonetheless.
So if you set this timer, it triggers, and no packets arrive, you are
taking more interrupts and doing more work than if you had disabled
NAPI.
In fact, for certain packet rates, your scheme would result in
twice as many interrupts than the current scheme.
This is one of several reasons why hardware is the only truly proper
place for this kind of logic. Only the hardware can see the packet
arrive, and do the interrupt deferral without any cpu intervention
whatsoever.
^ permalink raw reply
* [PATCH v3 7/8] fs_enet: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set.
From: Scott Wood @ 2007-08-28 20:14 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
The existing OF glue code was crufty and broken. Rather than fix it, it
will be removed, and the ethernet driver now talks to the device tree
directly.
The old, non-CONFIG_PPC_CPM_NEW_BINDING code can go away once CPM
platforms are dropped from arch/ppc (which will hopefully be soon), and
existing arch/powerpc boards that I wasn't able to test on for this
patchset get converted (which should be even sooner).
mii-bitbang.c now also uses the generic bitbang code, and is generally
cleaned up,
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/net/fs_enet/Kconfig | 1 +
drivers/net/fs_enet/fs_enet-main.c | 259 ++++++++++++++++++++--
drivers/net/fs_enet/fs_enet.h | 55 +-----
drivers/net/fs_enet/mac-fcc.c | 89 ++++++--
drivers/net/fs_enet/mac-fec.c | 19 ++-
drivers/net/fs_enet/mac-scc.c | 53 +++--
drivers/net/fs_enet/mii-bitbang.c | 440 +++++++++++++++++-------------------
drivers/net/fs_enet/mii-fec.c | 144 ++++++++++++-
include/linux/fs_enet_pd.h | 5 +
9 files changed, 716 insertions(+), 349 deletions(-)
diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig
index e27ee21..2765e49 100644
--- a/drivers/net/fs_enet/Kconfig
+++ b/drivers/net/fs_enet/Kconfig
@@ -11,6 +11,7 @@ config FS_ENET_HAS_SCC
config FS_ENET_HAS_FCC
bool "Chip has an FCC usable for ethernet"
depends on FS_ENET && CPM2
+ select MDIO_BITBANG
default y
config FS_ENET_HAS_FEC
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index a4b76cd..281b7d7 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -44,12 +44,18 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_platform.h>
+#endif
+
#include "fs_enet.h"
/*************************************************/
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
static char version[] __devinitdata =
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n";
+#endif
MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>");
MODULE_DESCRIPTION("Freescale Ethernet Driver");
@@ -953,6 +959,7 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
extern int fs_mii_connect(struct net_device *dev);
extern void fs_mii_disconnect(struct net_device *dev);
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
static struct net_device *fs_init_instance(struct device *dev,
struct fs_platform_info *fpi)
{
@@ -1132,6 +1139,7 @@ static int fs_cleanup_instance(struct net_device *ndev)
return 0;
}
+#endif
/**************************************************************************************/
@@ -1140,35 +1148,250 @@ void *fs_enet_immap = NULL;
static int setup_immap(void)
{
- phys_addr_t paddr = 0;
- unsigned long size = 0;
-
#ifdef CONFIG_CPM1
- paddr = IMAP_ADDR;
- size = 0x10000; /* map 64K */
-#endif
-
-#ifdef CONFIG_CPM2
- paddr = CPM_MAP_ADDR;
- size = 0x40000; /* map 256 K */
+ fs_enet_immap = ioremap(IMAP_ADDR, 0x4000);
+ WARN_ON(!fs_enet_immap);
+#elif defined(CONFIG_CPM2)
+ fs_enet_immap = cpm2_immr;
#endif
- fs_enet_immap = ioremap(paddr, size);
- if (fs_enet_immap == NULL)
- return -EBADF; /* XXX ahem; maybe just BUG_ON? */
return 0;
}
static void cleanup_immap(void)
{
- if (fs_enet_immap != NULL) {
- iounmap(fs_enet_immap);
- fs_enet_immap = NULL;
- }
+#if defined(CONFIG_CPM1)
+ iounmap(fs_enet_immap);
+#endif
}
/**************************************************************************************/
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+static int __devinit find_phy(struct device_node *np,
+ struct fs_platform_info *fpi)
+{
+ struct device_node *phynode, *mdionode;
+ struct resource res;
+ int ret = 0, len;
+
+ const u32 *data = of_get_property(np, "phy-handle", &len);
+ if (!data || len != 4)
+ return -EINVAL;
+
+ phynode = of_find_node_by_phandle(*data);
+ if (!phynode)
+ return -EINVAL;
+
+ mdionode = of_get_parent(phynode);
+ if (!phynode)
+ goto out_put_phy;
+
+ ret = of_address_to_resource(mdionode, 0, &res);
+ if (ret)
+ goto out_put_mdio;
+
+ data = of_get_property(phynode, "reg", &len);
+ if (!data || len != 4)
+ goto out_put_mdio;
+
+ snprintf(fpi->bus_id, 16, PHY_ID_FMT, res.start, *data);
+
+out_put_mdio:
+ of_node_put(mdionode);
+out_put_phy:
+ of_node_put(phynode);
+ return ret;
+}
+
+#ifdef CONFIG_FS_ENET_HAS_FEC
+#define IS_FEC(match) ((match)->data == &fs_fec_ops)
+#else
+#define IS_FEC(match) 0
+#endif
+
+static int __devinit fs_enet_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct net_device *ndev;
+ struct fs_enet_private *fep;
+ struct fs_platform_info *fpi;
+ const u32 *data;
+ const u8 *mac_addr;
+ int privsize, len, ret = -ENODEV;
+
+ fpi = kzalloc(sizeof(*fpi), GFP_KERNEL);
+ if (!fpi)
+ return -ENOMEM;
+
+ if (!IS_FEC(match)) {
+ data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
+ if (!data || len != 4)
+ goto out_free_fpi;
+
+ fpi->cp_command = *data;
+ }
+
+ fpi->rx_ring = 32;
+ fpi->tx_ring = 32;
+ fpi->rx_copybreak = 240;
+ fpi->use_napi = 0;
+ fpi->napi_weight = 17;
+
+ ret = find_phy(ofdev->node, fpi);
+ if (ret)
+ goto out_free_fpi;
+
+ privsize = sizeof(*fep) +
+ sizeof(struct sk_buff **) *
+ (fpi->rx_ring + fpi->tx_ring);
+
+ ndev = alloc_etherdev(privsize);
+ if (!ndev) {
+ ret = -ENOMEM;
+ goto out_free_fpi;
+ }
+
+ SET_MODULE_OWNER(ndev);
+ dev_set_drvdata(&ofdev->dev, ndev);
+
+ fep = netdev_priv(ndev);
+ fep->dev = &ofdev->dev;
+ fep->fpi = fpi;
+ fep->ops = match->data;
+
+ ret = fep->ops->setup_data(ndev);
+ if (ret)
+ goto out_free_dev;
+
+ fep->rx_skbuff = (struct sk_buff **)&fep[1];
+ fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring;
+
+ spin_lock_init(&fep->lock);
+ spin_lock_init(&fep->tx_lock);
+
+ mac_addr = of_get_mac_address(ofdev->node);
+ if (mac_addr)
+ memcpy(ndev->dev_addr, mac_addr, 6);
+
+ ret = fep->ops->allocate_bd(ndev);
+ if (ret)
+ goto out_cleanup_data;
+
+ fep->rx_bd_base = fep->ring_base;
+ fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring;
+
+ fep->tx_ring = fpi->tx_ring;
+ fep->rx_ring = fpi->rx_ring;
+
+ ndev->open = fs_enet_open;
+ ndev->hard_start_xmit = fs_enet_start_xmit;
+ ndev->tx_timeout = fs_timeout;
+ ndev->watchdog_timeo = 2 * HZ;
+ ndev->stop = fs_enet_close;
+ ndev->get_stats = fs_enet_get_stats;
+ ndev->set_multicast_list = fs_set_multicast_list;
+ if (fpi->use_napi) {
+ ndev->poll = fs_enet_rx_napi;
+ ndev->weight = fpi->napi_weight;
+ }
+ ndev->ethtool_ops = &fs_ethtool_ops;
+ ndev->do_ioctl = fs_ioctl;
+
+ init_timer(&fep->phy_timer_list);
+
+ netif_carrier_off(ndev);
+
+ ret = register_netdev(ndev);
+ if (ret)
+ goto out_free_bd;
+
+ printk(KERN_INFO "%s: fs_enet: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ ndev->name,
+ ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
+ ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+
+ return 0;
+
+out_free_bd:
+ fep->ops->free_bd(ndev);
+out_cleanup_data:
+ fep->ops->cleanup_data(ndev);
+out_free_dev:
+ free_netdev(ndev);
+ dev_set_drvdata(&ofdev->dev, NULL);
+out_free_fpi:
+ kfree(fpi);
+ return ret;
+}
+
+static int fs_enet_remove(struct of_device *ofdev)
+{
+ struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+ struct fs_enet_private *fep = netdev_priv(ndev);
+
+ unregister_netdev(ndev);
+
+ fep->ops->free_bd(ndev);
+ fep->ops->cleanup_data(ndev);
+ dev_set_drvdata(fep->dev, NULL);
+
+ free_netdev(ndev);
+ return 0;
+}
+
+static struct of_device_id fs_enet_match[] = {
+#ifdef CONFIG_FS_ENET_HAS_SCC
+ {
+ .compatible = "fsl,cpm1-scc-enet",
+ .data = (void *)&fs_scc_ops,
+ },
+#endif
+#ifdef CONFIG_FS_ENET_HAS_FCC
+ {
+ .compatible = "fsl,cpm2-fcc-enet",
+ .data = (void *)&fs_fcc_ops,
+ },
+#endif
+#ifdef CONFIG_FS_ENET_HAS_FEC
+ {
+ .compatible = "fsl,pq1-fec-enet",
+ .data = (void *)&fs_fec_ops,
+ },
+#endif
+ {}
+};
+
+static struct of_platform_driver fs_enet_driver = {
+ .name = "fs_enet",
+ .match_table = fs_enet_match,
+ .probe = fs_enet_probe,
+ .remove = fs_enet_remove,
+};
+
+static int __init fs_init(void)
+{
+ int r = setup_immap();
+ if (r != 0)
+ return r;
+
+ r = of_register_platform_driver(&fs_enet_driver);
+ if (r != 0)
+ goto out;
+
+ return 0;
+
+out:
+ cleanup_immap();
+ return r;
+}
+
+static void __exit fs_cleanup(void)
+{
+ of_unregister_platform_driver(&fs_enet_driver);
+ cleanup_immap();
+}
+#else
static int __devinit fs_enet_probe(struct device *dev)
{
struct net_device *ndev;
@@ -1282,7 +1505,7 @@ static void __exit fs_cleanup(void)
driver_unregister(&fs_enet_scc_driver);
cleanup_immap();
}
-
+#endif
/**************************************************************************************/
module_init(fs_init);
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index f8c7ee8..14ebba8 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -24,19 +24,6 @@ struct fec_info {
#include <asm/cpm2.h>
#endif
-/* This is used to operate with pins.
- Note that the actual port size may
- be different; cpm(s) handle it OK */
-struct bb_info {
- u8 mdio_dat_msk;
- u8 mdio_dir_msk;
- u8 *mdio_dir;
- u8 *mdio_dat;
- u8 mdc_msk;
- u8 *mdc_dat;
- int delay;
-};
-
/* hw driver ops */
struct fs_ops {
int (*setup_data)(struct net_device *dev);
@@ -85,47 +72,11 @@ struct phy_info {
#define ENET_RX_ALIGN 16
#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE + ENET_RX_ALIGN - 1)
-struct fs_enet_mii_bus {
- struct list_head list;
- spinlock_t mii_lock;
- const struct fs_mii_bus_info *bus_info;
- int refs;
- u32 usage_map;
-
- int (*mii_read)(struct fs_enet_mii_bus *bus,
- int phy_id, int location);
-
- void (*mii_write)(struct fs_enet_mii_bus *bus,
- int phy_id, int location, int value);
-
- union {
- struct {
- unsigned int mii_speed;
- void *fecp;
- } fec;
-
- struct {
- /* note that the actual port size may */
- /* be different; cpm(s) handle it OK */
- u8 mdio_msk;
- u8 *mdio_dir;
- u8 *mdio_dat;
- u8 mdc_msk;
- u8 *mdc_dir;
- u8 *mdc_dat;
- } bitbang;
-
- struct {
- u16 lpa;
- } fixed;
- };
-};
-
struct fs_enet_private {
struct device *dev; /* pointer back to the device (must be initialized first) */
spinlock_t lock; /* during all ops except TX pckt processing */
spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */
- const struct fs_platform_info *fpi;
+ struct fs_platform_info *fpi;
const struct fs_ops *ops;
int rx_ring, tx_ring;
dma_addr_t ring_mem_addr;
@@ -144,7 +95,6 @@ struct fs_enet_private {
u32 msg_enable;
struct mii_if_info mii_if;
unsigned int last_mii_status;
- struct fs_enet_mii_bus *mii_bus;
int interrupt;
struct phy_device *phydev;
@@ -186,9 +136,10 @@ struct fs_enet_private {
};
/***************************************************************************/
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
int fs_enet_mdio_bb_init(void);
-int fs_mii_fixed_init(struct fs_enet_mii_bus *bus);
int fs_enet_mdio_fec_init(void);
+#endif
void fs_init_bds(struct net_device *dev);
void fs_cleanup_bds(struct net_device *dev);
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 8b30361..10e2a2b 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -42,6 +42,10 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_device.h>
+#endif
+
#include "fs_enet.h"
/*************************************************/
@@ -74,33 +78,64 @@
#define MAX_CR_CMD_LOOPS 10000
-static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op)
+static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op)
{
const struct fs_platform_info *fpi = fep->fpi;
cpm2_map_t *immap = fs_enet_immap;
cpm_cpm2_t *cpmp = &immap->im_cpm;
- u32 v;
int i;
- /* Currently I don't know what feature call will look like. But
- I guess there'd be something like do_cpm_cmd() which will require page & sblock */
- v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op);
- W32(cpmp, cp_cpcr, v | CPM_CR_FLG);
+ W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG);
for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
- break;
-
- if (i >= MAX_CR_CMD_LOOPS) {
- printk(KERN_ERR "%s(): Not able to issue CPM command\n",
- __FUNCTION__);
- return 1;
- }
+ return 0;
- return 0;
+ printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+ __FUNCTION__);
+ return 1;
}
static int do_pd_setup(struct fs_enet_private *fep)
{
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+ struct of_device *ofdev = to_of_device(fep->dev);
+ struct fs_platform_info *fpi = fep->fpi;
+ int ret = -EINVAL;
+
+ fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
+ if (fep->interrupt == NO_IRQ)
+ goto out;
+
+ fep->fcc.fccp = of_iomap(ofdev->node, 0);
+ if (!fep->fcc.fccp)
+ goto out;
+
+ fep->fcc.ep = of_iomap(ofdev->node, 1);
+ if (!fep->fcc.ep)
+ goto out_fccp;
+
+ fep->fcc.fcccp = of_iomap(ofdev->node, 2);
+ if (!fep->fcc.fcccp)
+ goto out_ep;
+
+ fep->fcc.mem = (void *)cpm_dpalloc(128, 8);
+ fpi->dpram_offset = (u32)cpm2_immr;
+ if (IS_ERR_VALUE(fpi->dpram_offset)) {
+ ret = fpi->dpram_offset;
+ goto out_fcccp;
+ }
+
+ return 0;
+
+out_fcccp:
+ iounmap(fep->fcc.fcccp);
+out_ep:
+ iounmap(fep->fcc.ep);
+out_fccp:
+ iounmap(fep->fcc.fccp);
+out:
+ return ret;
+#else
struct platform_device *pdev = to_platform_device(fep->dev);
struct resource *r;
@@ -138,6 +173,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
return -EINVAL;
return 0;
+#endif
}
#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB)
@@ -148,11 +184,17 @@ static int do_pd_setup(struct fs_enet_private *fep)
static int setup_data(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- const struct fs_platform_info *fpi = fep->fpi;
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
+ struct fs_platform_info *fpi = fep->fpi;
+
+ fpi->cp_command = (fpi->cp_page << 26) |
+ (fpi->cp_block << 21) |
+ (12 << 6);
fep->fcc.idx = fs_get_fcc_index(fpi->fs_no);
if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */
return -EINVAL;
+#endif
if (do_pd_setup(fep) != 0)
return -EINVAL;
@@ -226,7 +268,7 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac)
W16(ep, fen_taddrh, taddrh);
W16(ep, fen_taddrm, taddrm);
W16(ep, fen_taddrl, taddrl);
- fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR);
+ fcc_cr_cmd(fep, CPM_CR_SET_GADDR);
}
static void set_multicast_finish(struct net_device *dev)
@@ -281,7 +323,7 @@ static void restart(struct net_device *dev)
/* clear everything (slow & steady does it) */
for (i = 0; i < sizeof(*ep); i++)
- out_8((char *)ep + i, 0);
+ out_8((u8 __iomem *)ep + i, 0);
/* get physical address */
rx_bd_base_phys = fep->ring_mem_addr;
@@ -397,7 +439,7 @@ static void restart(struct net_device *dev)
S8(fcccp, fcc_gfemr, 0x20);
}
- fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX);
+ fcc_cr_cmd(fep, CPM_CR_INIT_TRX);
/* clear events */
W16(fccp, fcc_fcce, 0xffff);
@@ -515,23 +557,22 @@ int get_regs(struct net_device *dev, void *p, int *sizep)
{
struct fs_enet_private *fep = netdev_priv(dev);
- if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t))
+ if (*sizep < sizeof(fcc_t) + sizeof(fcc_enet_t) + 1)
return -EINVAL;
memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t));
p = (char *)p + sizeof(fcc_t);
- memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t));
- p = (char *)p + sizeof(fcc_c_t);
-
memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t));
+ p = (char *)p + sizeof(fcc_enet_t);
+ memcpy_fromio(p, fep->fcc.fcccp, 1);
return 0;
}
int get_regs_len(struct net_device *dev)
{
- return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t);
+ return sizeof(fcc_t) + sizeof(fcc_enet_t) + 1;
}
/* Some transmit errors cause the transmitter to shut
@@ -551,7 +592,7 @@ void tx_restart(struct net_device *dev)
udelay(10);
S32(fccp, fcc_gfmr, FCC_GFMR_ENT);
- fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX);
+ fcc_cr_cmd(fep, CPM_CR_RESTART_TX);
}
/*************************************************************************/
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 04b4f80..9a02312 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -43,6 +43,10 @@
#include <asm/commproc.h>
#endif
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_device.h>
+#endif
+
#include "fs_enet.h"
#include "fec.h"
@@ -95,6 +99,19 @@ static int whack_reset(fec_t * fecp)
static int do_pd_setup(struct fs_enet_private *fep)
{
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+ struct of_device *ofdev = to_of_device(fep->dev);
+
+ fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
+ if (fep->interrupt == NO_IRQ)
+ return -EINVAL;
+
+ fep->fec.fecp = of_iomap(ofdev->node, 0);
+ if (!fep->fcc.fccp)
+ return -EINVAL;
+
+ return 0;
+#else
struct platform_device *pdev = to_platform_device(fep->dev);
struct resource *r;
@@ -110,7 +127,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
return -EINVAL;
return 0;
-
+#endif
}
#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB)
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index 7540966..7352c61 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -43,6 +43,10 @@
#include <asm/commproc.h>
#endif
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_platform.h>
+#endif
+
#include "fs_enet.h"
/*************************************************/
@@ -89,27 +93,38 @@
static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
{
- cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm;
- u32 v, ch;
- int i = 0;
+ const struct fs_platform_info *fpi = fep->fpi;
+ int i;
- ch = fep->scc.idx << 2;
- v = mk_cr_cmd(ch, op);
- W16(cpmp, cp_cpcr, v | CPM_CR_FLG);
+ W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8));
for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
- break;
+ return 0;
- if (i >= MAX_CR_CMD_LOOPS) {
- printk(KERN_ERR "%s(): Not able to issue CPM command\n",
- __FUNCTION__);
- return 1;
- }
- return 0;
+ printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+ __FUNCTION__);
+ return 1;
}
static int do_pd_setup(struct fs_enet_private *fep)
{
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+ struct of_device *ofdev = to_of_device(fep->dev);
+
+ fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
+ if (fep->interrupt == NO_IRQ)
+ return -EINVAL;
+
+ fep->scc.sccp = of_iomap(ofdev->node, 0);
+ if (!fep->scc.sccp)
+ return -EINVAL;
+
+ fep->scc.ep = of_iomap(ofdev->node, 1);
+ if (!fep->scc.ep) {
+ iounmap(fep->scc.sccp);
+ return -EINVAL;
+ }
+#else
struct platform_device *pdev = to_platform_device(fep->dev);
struct resource *r;
@@ -129,6 +144,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
if (fep->scc.ep == NULL)
return -EINVAL;
+#endif
return 0;
}
@@ -141,12 +157,17 @@ static int do_pd_setup(struct fs_enet_private *fep)
static int setup_data(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- const struct fs_platform_info *fpi = fep->fpi;
+
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+ struct fs_platform_info *fpi = fep->fpi;
fep->scc.idx = fs_get_scc_index(fpi->fs_no);
- if ((unsigned int)fep->fcc.idx > 4) /* max 4 SCCs */
+ if ((unsigned int)fep->fcc.idx >= 4) /* max 4 SCCs */
return -EINVAL;
+ fpi->cp_command = fep->fcc.idx << 6;
+#endif
+
do_pd_setup(fep);
fep->scc.hthi = 0;
@@ -154,7 +175,7 @@ static int setup_data(struct net_device *dev)
fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK;
fep->ev_rx = SCC_RX_EVENT;
- fep->ev_tx = SCC_TX_EVENT;
+ fep->ev_tx = SCC_TX_EVENT | SCCE_ENET_TXE;
fep->ev_err = SCC_ERR_EVENT_MSK;
return 0;
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index d384010..9739985 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -14,301 +14,271 @@
#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/bitops.h>
#include <linux/platform_device.h>
+#include <linux/mdio-bitbang.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <linux/of_platform.h>
+#endif
#include "fs_enet.h"
-static int bitbang_prep_bit(u8 **datp, u8 *mskp,
- struct fs_mii_bit *mii_bit)
-{
- void *dat;
- int adv;
- u8 msk;
-
- dat = (void*) mii_bit->offset;
-
- adv = mii_bit->bit >> 3;
- dat = (char *)dat + adv;
-
- msk = 1 << (7 - (mii_bit->bit & 7));
-
- *datp = dat;
- *mskp = msk;
-
- return 0;
-}
+struct bb_info {
+ struct mdio_bitbang_ctrl ctrl;
+ __be32 __iomem *dir;
+ __be32 __iomem *dat;
+ u32 mdio_msk;
+ u32 mdc_msk;
+ int delay;
+};
-static inline void bb_set(u8 *p, u8 m)
+/* FIXME: If any other users of GPIO crop up, then these will have to
+ * have some sort of global synchronization to avoid races with other
+ * pins on the same port. The ideal solution would probably be to
+ * bind the ports to a GPIO driver, and have this be a client of it.
+ */
+static inline void bb_set(u32 __iomem *p, u32 m)
{
- out_8(p, in_8(p) | m);
+ out_be32(p, in_be32(p) | m);
}
-static inline void bb_clr(u8 *p, u8 m)
+static inline void bb_clr(u32 __iomem *p, u32 m)
{
- out_8(p, in_8(p) & ~m);
+ out_be32(p, in_be32(p) & ~m);
}
-static inline int bb_read(u8 *p, u8 m)
+static inline int bb_read(u32 __iomem *p, u32 m)
{
- return (in_8(p) & m) != 0;
+ return (in_be32(p) & m) != 0;
}
-static inline void mdio_active(struct bb_info *bitbang)
+static inline void mdio_dir(struct mdio_bitbang_ctrl *ctrl, int dir)
{
- bb_set(bitbang->mdio_dir, bitbang->mdio_dir_msk);
-}
+ struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
-static inline void mdio_tristate(struct bb_info *bitbang )
-{
- bb_clr(bitbang->mdio_dir, bitbang->mdio_dir_msk);
+ if (dir)
+ bb_set(bitbang->dir, bitbang->mdio_msk);
+ else
+ bb_clr(bitbang->dir, bitbang->mdio_msk);
}
-static inline int mdio_read(struct bb_info *bitbang )
+static inline int mdio_read(struct mdio_bitbang_ctrl *ctrl)
{
- return bb_read(bitbang->mdio_dat, bitbang->mdio_dat_msk);
+ struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+ return bb_read(bitbang->dat, bitbang->mdio_msk);
}
-static inline void mdio(struct bb_info *bitbang , int what)
+static inline void mdio(struct mdio_bitbang_ctrl *ctrl, int what)
{
+ struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
if (what)
- bb_set(bitbang->mdio_dat, bitbang->mdio_dat_msk);
+ bb_set(bitbang->dat, bitbang->mdio_msk);
else
- bb_clr(bitbang->mdio_dat, bitbang->mdio_dat_msk);
+ bb_clr(bitbang->dat, bitbang->mdio_msk);
}
-static inline void mdc(struct bb_info *bitbang , int what)
+static inline void mdc(struct mdio_bitbang_ctrl *ctrl, int what)
{
+ struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
if (what)
- bb_set(bitbang->mdc_dat, bitbang->mdc_msk);
+ bb_set(bitbang->dat, bitbang->mdc_msk);
else
- bb_clr(bitbang->mdc_dat, bitbang->mdc_msk);
+ bb_clr(bitbang->dat, bitbang->mdc_msk);
}
-static inline void mii_delay(struct bb_info *bitbang )
+static struct mdio_bitbang_ops bb_ops = {
+ .owner = THIS_MODULE,
+ .set_mdc = mdc,
+ .set_mdio_dir = mdio_dir,
+ .set_mdio_data = mdio,
+ .get_mdio_data = mdio_read,
+};
+
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
+ struct device_node *np)
{
- udelay(bitbang->delay);
+ struct resource res;
+ const u32 *data;
+ int mdio_pin, mdc_pin, len;
+ struct bb_info *bitbang = bus->priv;
+
+ int ret = of_address_to_resource(np, 0, &res);
+ if (ret)
+ return ret;
+
+ if (res.end - res.start < 13)
+ return -ENODEV;
+
+ /* This should really encode the pin number as well, but all
+ * we get is an int, and the odds of multiple bitbang mdio buses
+ * is low enough that it's not worth going too crazy.
+ */
+ bus->id = res.start;
+
+ data = of_get_property(np, "fsl,mdio-pin", &len);
+ if (!data || len != 4)
+ return -ENODEV;
+ mdio_pin = *data;
+
+ data = of_get_property(np, "fsl,mdc-pin", &len);
+ if (!data || len != 4)
+ return -ENODEV;
+ mdc_pin = *data;
+
+ bitbang->dir = ioremap(res.start, res.end - res.start + 1);
+ if (!bitbang->dir)
+ return -ENOMEM;
+
+ bitbang->dat = bitbang->dir + 4;
+ bitbang->mdio_msk = 1 << (31 - mdio_pin);
+ bitbang->mdc_msk = 1 << (31 - mdc_pin);
+ bitbang->delay = 1; /* 1 us between operations */
+
+ return 0;
}
-/* Utility to send the preamble, address, and register (common to read and write). */
-static void bitbang_pre(struct bb_info *bitbang , int read, u8 addr, u8 reg)
+static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
{
- int j;
-
- /*
- * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
- * The IEEE spec says this is a PHY optional requirement. The AMD
- * 79C874 requires one after power up and one after a MII communications
- * error. This means that we are doing more preambles than we need,
- * but it is safer and will be much more robust.
- */
+ const u32 *data;
+ int len, id, irq;
- mdio_active(bitbang);
- mdio(bitbang, 1);
- for (j = 0; j < 32; j++) {
- mdc(bitbang, 0);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
- }
+ data = of_get_property(np, "reg", &len);
+ if (!data || len != 4)
+ return;
- /* send the start bit (01) and the read opcode (10) or write (10) */
- mdc(bitbang, 0);
- mdio(bitbang, 0);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
- mdc(bitbang, 0);
- mdio(bitbang, 1);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
- mdc(bitbang, 0);
- mdio(bitbang, read);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
- mdc(bitbang, 0);
- mdio(bitbang, !read);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
-
- /* send the PHY address */
- for (j = 0; j < 5; j++) {
- mdc(bitbang, 0);
- mdio(bitbang, (addr & 0x10) != 0);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
- addr <<= 1;
- }
+ id = *data;
+ bus->phy_mask &= ~(1 << id);
- /* send the register address */
- for (j = 0; j < 5; j++) {
- mdc(bitbang, 0);
- mdio(bitbang, (reg & 0x10) != 0);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
- reg <<= 1;
- }
+ irq = of_irq_to_resource(np, 0, NULL);
+ if (irq != NO_IRQ)
+ bus->irq[id] = irq;
}
-static int fs_enet_mii_bb_read(struct mii_bus *bus , int phy_id, int location)
+static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
{
- u16 rdreg;
- int ret, j;
- u8 addr = phy_id & 0xff;
- u8 reg = location & 0xff;
- struct bb_info* bitbang = bus->priv;
-
- bitbang_pre(bitbang, 1, addr, reg);
-
- /* tri-state our MDIO I/O pin so we can read */
- mdc(bitbang, 0);
- mdio_tristate(bitbang);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
-
- /* check the turnaround bit: the PHY should be driving it to zero */
- if (mdio_read(bitbang) != 0) {
- /* PHY didn't drive TA low */
- for (j = 0; j < 32; j++) {
- mdc(bitbang, 0);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
- }
- ret = -1;
+ struct device_node *np = NULL;
+ struct mii_bus *new_bus;
+ struct bb_info *bitbang;
+ int ret = -ENOMEM;
+ int i;
+
+ bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
+ if (!bitbang)
goto out;
- }
- mdc(bitbang, 0);
- mii_delay(bitbang);
-
- /* read 16 bits of register data, MSB first */
- rdreg = 0;
- for (j = 0; j < 16; j++) {
- mdc(bitbang, 1);
- mii_delay(bitbang);
- rdreg <<= 1;
- rdreg |= mdio_read(bitbang);
- mdc(bitbang, 0);
- mii_delay(bitbang);
- }
+ bitbang->ctrl.ops = &bb_ops;
- mdc(bitbang, 1);
- mii_delay(bitbang);
- mdc(bitbang, 0);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
+ new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
+ if (!new_bus)
+ goto out_free_priv;
- ret = rdreg;
+ new_bus->name = "CPM2 Bitbanged MII",
+
+ ret = fs_mii_bitbang_init(new_bus, ofdev->node);
+ if (ret)
+ goto out_free_bus;
+
+ new_bus->phy_mask = ~0;
+ new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!new_bus->irq)
+ goto out_unmap_regs;
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ new_bus->irq[i] = -1;
+
+ while ((np = of_get_next_child(ofdev->node, np)))
+ if (!strcmp(np->type, "ethernet-phy"))
+ add_phy(new_bus, np);
+
+ new_bus->dev = &ofdev->dev;
+ dev_set_drvdata(&ofdev->dev, new_bus);
+
+ ret = mdiobus_register(new_bus);
+ if (ret)
+ goto out_free_irqs;
+
+ return 0;
+
+out_free_irqs:
+ dev_set_drvdata(&ofdev->dev, NULL);
+ kfree(new_bus->irq);
+out_unmap_regs:
+ iounmap(bitbang->dir);
+out_free_bus:
+ kfree(new_bus);
+out_free_priv:
+ free_mdio_bitbang(new_bus);
out:
return ret;
}
-static int fs_enet_mii_bb_write(struct mii_bus *bus, int phy_id, int location, u16 val)
+static int fs_enet_mdio_remove(struct of_device *ofdev)
{
- int j;
- struct bb_info* bitbang = bus->priv;
-
- u8 addr = phy_id & 0xff;
- u8 reg = location & 0xff;
- u16 value = val & 0xffff;
-
- bitbang_pre(bitbang, 0, addr, reg);
-
- /* send the turnaround (10) */
- mdc(bitbang, 0);
- mdio(bitbang, 1);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
- mdc(bitbang, 0);
- mdio(bitbang, 0);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
-
- /* write 16 bits of register data, MSB first */
- for (j = 0; j < 16; j++) {
- mdc(bitbang, 0);
- mdio(bitbang, (value & 0x8000) != 0);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
- value <<= 1;
- }
+ struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
+ struct bb_info *bitbang = bus->priv;
+
+ mdiobus_unregister(bus);
+ free_mdio_bitbang(bus);
+ dev_set_drvdata(&ofdev->dev, NULL);
+ kfree(bus->irq);
+ iounmap(bitbang->dir);
+ kfree(bitbang);
+ kfree(bus);
- /*
- * Tri-state the MDIO line.
- */
- mdio_tristate(bitbang);
- mdc(bitbang, 0);
- mii_delay(bitbang);
- mdc(bitbang, 1);
- mii_delay(bitbang);
return 0;
}
-static int fs_enet_mii_bb_reset(struct mii_bus *bus)
+static struct of_device_id fs_enet_mdio_bb_match[] = {
+ {
+ .compatible = "fsl,cpm2-mdio-bitbang",
+ },
+ {},
+};
+
+static struct of_platform_driver fs_enet_bb_mdio_driver = {
+ .name = "fsl-bb-mdio",
+ .match_table = fs_enet_mdio_bb_match,
+ .probe = fs_enet_mdio_probe,
+ .remove = fs_enet_mdio_remove,
+};
+
+static int fs_enet_mdio_bb_init(void)
+{
+ return of_register_platform_driver(&fs_enet_bb_mdio_driver);
+}
+
+static int fs_enet_mdio_bb_exit(void)
{
- /*nothing here - dunno how to reset it*/
+ of_unregister_platform_driver(&fs_enet_bb_mdio_driver);
return 0;
}
-static int fs_mii_bitbang_init(struct bb_info *bitbang, struct fs_mii_bb_platform_info* fmpi)
+module_init(fs_enet_mdio_bb_init);
+module_init(fs_enet_mdio_bb_exit);
+#else
+static int __devinit fs_mii_bitbang_init(struct bb_info *bitbang,
+ struct fs_mii_bb_platform_info *fmpi)
{
- int r;
-
+ bitbang->dir = (u32 __iomem *)fmpi->mdio_dir.offset;
+ bitbang->dat = (u32 __iomem *)fmpi->mdio_dat.offset;
+ bitbang->mdio_msk = 1U << (31 - fmpi->mdio_dat.bit);
+ bitbang->mdc_msk = 1U << (31 - fmpi->mdc_dat.bit);
bitbang->delay = fmpi->delay;
- r = bitbang_prep_bit(&bitbang->mdio_dir,
- &bitbang->mdio_dir_msk,
- &fmpi->mdio_dir);
- if (r != 0)
- return r;
-
- r = bitbang_prep_bit(&bitbang->mdio_dat,
- &bitbang->mdio_dat_msk,
- &fmpi->mdio_dat);
- if (r != 0)
- return r;
-
- r = bitbang_prep_bit(&bitbang->mdc_dat,
- &bitbang->mdc_msk,
- &fmpi->mdc_dat);
- if (r != 0)
- return r;
-
return 0;
}
-
static int __devinit fs_enet_mdio_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -320,20 +290,19 @@ static int __devinit fs_enet_mdio_probe(struct device *dev)
if (NULL == dev)
return -EINVAL;
- new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+ bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
- if (NULL == new_bus)
+ if (NULL == bitbang)
return -ENOMEM;
- bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
+ bitbang->ctrl.ops = &bb_ops;
- if (NULL == bitbang)
+ new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
+
+ if (NULL == new_bus)
return -ENOMEM;
new_bus->name = "BB MII Bus",
- new_bus->read = &fs_enet_mii_bb_read,
- new_bus->write = &fs_enet_mii_bb_write,
- new_bus->reset = &fs_enet_mii_bb_reset,
new_bus->id = pdev->id;
new_bus->phy_mask = ~0x9;
@@ -365,13 +334,12 @@ static int __devinit fs_enet_mdio_probe(struct device *dev)
return 0;
bus_register_fail:
+ free_mdio_bitbang(new_bus);
kfree(bitbang);
- kfree(new_bus);
return err;
}
-
static int fs_enet_mdio_remove(struct device *dev)
{
struct mii_bus *bus = dev_get_drvdata(dev);
@@ -380,9 +348,7 @@ static int fs_enet_mdio_remove(struct device *dev)
dev_set_drvdata(dev, NULL);
- iounmap((void *) (&bus->priv));
- bus->priv = NULL;
- kfree(bus);
+ free_mdio_bitbang(bus);
return 0;
}
@@ -403,4 +369,4 @@ void fs_enet_mdio_bb_exit(void)
{
driver_unregister(&fs_enet_bb_mdio_driver);
}
-
+#endif
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 53db696..2c1c242 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -36,6 +36,10 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_platform.h>
+#endif
+
#include "fs_enet.h"
#include "fec.h"
@@ -47,6 +51,7 @@
#define FEC_MII_LOOPS 10000
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
static int match_has_phy (struct device *dev, void* data)
{
struct platform_device* pdev = container_of(dev, struct platform_device, dev);
@@ -90,6 +95,7 @@ static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info
return 0;
}
+#endif
static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
{
@@ -145,6 +151,142 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
return 0;
}
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
+{
+ const u32 *data;
+ int len, id, irq;
+
+ data = of_get_property(np, "reg", &len);
+ if (!data || len != 4)
+ return;
+
+ id = *data;
+ bus->phy_mask &= ~(1 << id);
+
+ irq = of_irq_to_resource(np, 0, NULL);
+ if (irq != NO_IRQ)
+ bus->irq[id] = irq;
+}
+
+static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = NULL;
+ struct resource res;
+ struct mii_bus *new_bus;
+ struct fec_info *fec;
+ int ret = -ENOMEM, i;
+
+ new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+ if (!new_bus)
+ goto out;
+
+ fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL);
+ if (!fec)
+ goto out_mii;
+
+ new_bus->priv = fec;
+ new_bus->name = "FEC MII Bus";
+ new_bus->read = &fs_enet_fec_mii_read;
+ new_bus->write = &fs_enet_fec_mii_write;
+ new_bus->reset = &fs_enet_fec_mii_reset;
+
+ ret = of_address_to_resource(ofdev->node, 0, &res);
+ if (ret)
+ return ret;
+
+ new_bus->id = res.start;
+
+ fec->fecp = ioremap(res.start, res.end - res.start + 1);
+ if (!fec->fecp)
+ goto out_fec;
+
+ fec->mii_speed = ((ppc_proc_freq + 4999999) / 5000000) << 1;
+
+ setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
+ setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX |
+ FEC_ECNTRL_ETHER_EN);
+ out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII);
+ out_be32(&fec->fecp->fec_mii_speed, fec->mii_speed);
+
+ new_bus->phy_mask = ~0;
+ new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!new_bus->irq)
+ goto out_unmap_regs;
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ new_bus->irq[i] = -1;
+
+ while ((np = of_get_next_child(ofdev->node, np)))
+ if (!strcmp(np->type, "ethernet-phy"))
+ add_phy(new_bus, np);
+
+ new_bus->dev = &ofdev->dev;
+ dev_set_drvdata(&ofdev->dev, new_bus);
+
+ ret = mdiobus_register(new_bus);
+ if (ret)
+ goto out_free_irqs;
+
+ return 0;
+
+out_free_irqs:
+ dev_set_drvdata(&ofdev->dev, NULL);
+ kfree(new_bus->irq);
+out_unmap_regs:
+ iounmap(fec->fecp);
+out_fec:
+ kfree(fec);
+out_mii:
+ kfree(new_bus);
+out:
+ return ret;
+}
+
+static int fs_enet_mdio_remove(struct of_device *ofdev)
+{
+ struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
+ struct fec_info *fec = bus->priv;
+
+ mdiobus_unregister(bus);
+ dev_set_drvdata(&ofdev->dev, NULL);
+ kfree(bus->irq);
+ iounmap(fec->fecp);
+ kfree(fec);
+ kfree(bus);
+
+ return 0;
+}
+
+static struct of_device_id fs_enet_mdio_fec_match[] = {
+ {
+ .compatible = "fsl,pq1-fec-mdio",
+ },
+ {},
+};
+
+static struct of_platform_driver fs_enet_fec_mdio_driver = {
+ .name = "fsl-fec-mdio",
+ .match_table = fs_enet_mdio_fec_match,
+ .probe = fs_enet_mdio_probe,
+ .remove = fs_enet_mdio_remove,
+};
+
+static int fs_enet_mdio_fec_init(void)
+{
+ return of_register_platform_driver(&fs_enet_fec_mdio_driver);
+}
+
+static int fs_enet_mdio_fec_exit(void)
+{
+ of_unregister_platform_driver(&fs_enet_fec_mdio_driver);
+ return 0;
+}
+
+module_init(fs_enet_mdio_fec_init);
+module_init(fs_enet_mdio_fec_exit);
+#else
static int __devinit fs_enet_fec_mdio_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -235,4 +377,4 @@ void fs_enet_mdio_fec_exit(void)
{
driver_unregister(&fs_enet_fec_mdio_driver);
}
-
+#endif
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index 815c6f9..9bc045b 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -120,6 +120,7 @@ struct fs_platform_info {
u32 cp_page; /* CPM page */
u32 cp_block; /* CPM sblock */
+ u32 cp_command; /* CPM page/sblock/mcn */
u32 clk_trx; /* some stuff for pins & mux configuration*/
u32 clk_rx;
@@ -134,7 +135,11 @@ struct fs_platform_info {
u32 device_flags;
int phy_addr; /* the phy address (-1 no phy) */
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+ char bus_id[16];
+#else
const char* bus_id;
+#endif
int phy_irq; /* the phy irq (if it exists) */
const struct fs_mii_bus_info *bus_info;
--
1.5.0.3
^ permalink raw reply related
* [PATCH v3 8/8] fs_enet: sparse fixes
From: Scott Wood @ 2007-08-28 20:14 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
Mostly a bunch of __iomem annotations.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/net/fs_enet/fs_enet-main.c | 16 +++++-----
drivers/net/fs_enet/fs_enet.h | 30 +++++++++---------
drivers/net/fs_enet/mac-fcc.c | 60 ++++++++++++++++++++---------------
drivers/net/fs_enet/mac-fec.c | 34 ++++++++++----------
drivers/net/fs_enet/mac-scc.c | 37 +++++++++++-----------
drivers/net/fs_enet/mii-fec.c | 6 ++--
6 files changed, 96 insertions(+), 87 deletions(-)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 281b7d7..876de8c 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -62,7 +62,7 @@ MODULE_DESCRIPTION("Freescale Ethernet Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
-int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */
+static int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */
module_param(fs_enet_debug, int, 0);
MODULE_PARM_DESC(fs_enet_debug,
"Freescale bitmapped debugging message enable value");
@@ -88,7 +88,7 @@ static int fs_enet_rx_napi(struct net_device *dev, int *budget)
{
struct fs_enet_private *fep = netdev_priv(dev);
const struct fs_platform_info *fpi = fep->fpi;
- cbd_t *bdp;
+ cbd_t __iomem *bdp;
struct sk_buff *skb, *skbn, *skbt;
int received = 0;
u16 pkt_len, sc;
@@ -240,7 +240,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
const struct fs_platform_info *fpi = fep->fpi;
- cbd_t *bdp;
+ cbd_t __iomem *bdp;
struct sk_buff *skb, *skbn, *skbt;
int received = 0;
u16 pkt_len, sc;
@@ -365,7 +365,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
static void fs_enet_tx(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- cbd_t *bdp;
+ cbd_t __iomem *bdp;
struct sk_buff *skb;
int dirtyidx, do_wake, do_restart;
u16 sc;
@@ -513,7 +513,7 @@ fs_enet_interrupt(int irq, void *dev_id)
void fs_init_bds(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- cbd_t *bdp;
+ cbd_t __iomem *bdp;
struct sk_buff *skb;
int i;
@@ -567,7 +567,7 @@ void fs_cleanup_bds(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
struct sk_buff *skb;
- cbd_t *bdp;
+ cbd_t __iomem *bdp;
int i;
/*
@@ -608,7 +608,7 @@ void fs_cleanup_bds(struct net_device *dev)
static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- cbd_t *bdp;
+ cbd_t __iomem *bdp;
int curidx;
u16 sc;
unsigned long flags;
@@ -1144,7 +1144,7 @@ static int fs_cleanup_instance(struct net_device *ndev)
/**************************************************************************************/
/* handy pointer to the immap */
-void *fs_enet_immap = NULL;
+void __iomem *fs_enet_immap = NULL;
static int setup_immap(void)
{
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 14ebba8..4a8a101 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -15,7 +15,7 @@
#include <asm/commproc.h>
struct fec_info {
- fec_t *fecp;
+ fec_t __iomem *fecp;
u32 mii_speed;
};
#endif
@@ -80,14 +80,14 @@ struct fs_enet_private {
const struct fs_ops *ops;
int rx_ring, tx_ring;
dma_addr_t ring_mem_addr;
- void *ring_base;
+ void __iomem *ring_base;
struct sk_buff **rx_skbuff;
struct sk_buff **tx_skbuff;
- cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
- cbd_t *tx_bd_base;
- cbd_t *dirty_tx; /* ring entries to be free()ed. */
- cbd_t *cur_rx;
- cbd_t *cur_tx;
+ cbd_t __iomem *rx_bd_base; /* Address of Rx and Tx buffers. */
+ cbd_t __iomem *tx_bd_base;
+ cbd_t __iomem *dirty_tx; /* ring entries to be free()ed. */
+ cbd_t __iomem *cur_rx;
+ cbd_t __iomem *cur_tx;
int tx_free;
struct net_device_stats stats;
struct timer_list phy_timer_list;
@@ -112,23 +112,23 @@ struct fs_enet_private {
union {
struct {
int idx; /* FEC1 = 0, FEC2 = 1 */
- void *fecp; /* hw registers */
+ void __iomem *fecp; /* hw registers */
u32 hthi, htlo; /* state for multicast */
} fec;
struct {
int idx; /* FCC1-3 = 0-2 */
- void *fccp; /* hw registers */
- void *ep; /* parameter ram */
- void *fcccp; /* hw registers cont. */
- void *mem; /* FCC DPRAM */
+ void __iomem *fccp; /* hw registers */
+ void __iomem *ep; /* parameter ram */
+ void __iomem *fcccp; /* hw registers cont. */
+ void __iomem *mem; /* FCC DPRAM */
u32 gaddrh, gaddrl; /* group address */
} fcc;
struct {
int idx; /* FEC1 = 0, FEC2 = 1 */
- void *sccp; /* hw registers */
- void *ep; /* parameter ram */
+ void __iomem *sccp; /* hw registers */
+ void __iomem *ep; /* parameter ram */
u32 hthi, htlo; /* state for multicast */
} scc;
@@ -199,7 +199,7 @@ extern const struct fs_ops fs_scc_ops;
/*******************************************************************/
/* handy pointer to the immap */
-extern void *fs_enet_immap;
+extern void __iomem *fs_enet_immap;
/*******************************************************************/
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 10e2a2b..fe3e4c3 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -81,8 +81,6 @@
static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op)
{
const struct fs_platform_info *fpi = fep->fpi;
- cpm2_map_t *immap = fs_enet_immap;
- cpm_cpm2_t *cpmp = &immap->im_cpm;
int i;
W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG);
@@ -118,8 +116,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
if (!fep->fcc.fcccp)
goto out_ep;
- fep->fcc.mem = (void *)cpm_dpalloc(128, 8);
- fpi->dpram_offset = (u32)cpm2_immr;
+ fep->fcc.mem = (void __iomem *)cpm2_immr;
+ fpi->dpram_offset = cpm_dpalloc(128, 8);
if (IS_ERR_VALUE(fpi->dpram_offset)) {
ret = fpi->dpram_offset;
goto out_fcccp;
@@ -212,7 +210,7 @@ static int allocate_bd(struct net_device *dev)
struct fs_enet_private *fep = netdev_priv(dev);
const struct fs_platform_info *fpi = fep->fpi;
- fep->ring_base = dma_alloc_coherent(fep->dev,
+ fep->ring_base = (void __iomem __force *)dma_alloc_coherent(fep->dev,
(fpi->tx_ring + fpi->rx_ring) *
sizeof(cbd_t), &fep->ring_mem_addr,
GFP_KERNEL);
@@ -230,7 +228,7 @@ static void free_bd(struct net_device *dev)
if (fep->ring_base)
dma_free_coherent(fep->dev,
(fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
- fep->ring_base, fep->ring_mem_addr);
+ (void __force *)fep->ring_base, fep->ring_mem_addr);
}
static void cleanup_data(struct net_device *dev)
@@ -241,7 +239,7 @@ static void cleanup_data(struct net_device *dev)
static void set_promiscuous_mode(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
S32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
}
@@ -249,7 +247,7 @@ static void set_promiscuous_mode(struct net_device *dev)
static void set_multicast_start(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_enet_t *ep = fep->fcc.ep;
+ fcc_enet_t __iomem *ep = fep->fcc.ep;
W32(ep, fen_gaddrh, 0);
W32(ep, fen_gaddrl, 0);
@@ -258,7 +256,7 @@ static void set_multicast_start(struct net_device *dev)
static void set_multicast_one(struct net_device *dev, const u8 *mac)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_enet_t *ep = fep->fcc.ep;
+ fcc_enet_t __iomem *ep = fep->fcc.ep;
u16 taddrh, taddrm, taddrl;
taddrh = ((u16)mac[5] << 8) | mac[4];
@@ -274,8 +272,8 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac)
static void set_multicast_finish(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
- fcc_enet_t *ep = fep->fcc.ep;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
+ fcc_enet_t __iomem *ep = fep->fcc.ep;
/* clear promiscuous always */
C32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
@@ -310,12 +308,14 @@ static void restart(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
const struct fs_platform_info *fpi = fep->fpi;
- fcc_t *fccp = fep->fcc.fccp;
- fcc_c_t *fcccp = fep->fcc.fcccp;
- fcc_enet_t *ep = fep->fcc.ep;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
+ fcc_c_t __iomem *fcccp = fep->fcc.fcccp;
+ fcc_enet_t __iomem *ep = fep->fcc.ep;
dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
u16 paddrh, paddrm, paddrl;
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
u16 mem_addr;
+#endif
const unsigned char *mac;
int i;
@@ -347,14 +347,22 @@ static void restart(struct net_device *dev)
* this area.
*/
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+ W16(ep, fen_genfcc.fcc_riptr, fpi->dpram_offset);
+ W16(ep, fen_genfcc.fcc_tiptr, fpi->dpram_offset + 32);
+
+ W16(ep, fen_padptr, fpi->dpram_offset + 64);
+#else
mem_addr = (u32) fep->fcc.mem; /* de-fixup dpram offset */
W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff));
W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff));
+
W16(ep, fen_padptr, mem_addr + 64);
+#endif
/* fill with special symbol... */
- memset(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32);
+ memset_io(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32);
W32(ep, fen_genfcc.fcc_rbptr, 0);
W32(ep, fen_genfcc.fcc_tbptr, 0);
@@ -470,7 +478,7 @@ static void restart(struct net_device *dev)
static void stop(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
/* stop ethernet */
C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
@@ -497,7 +505,7 @@ static void post_free_irq(struct net_device *dev, int irq)
static void napi_clear_rx_event(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK);
}
@@ -505,7 +513,7 @@ static void napi_clear_rx_event(struct net_device *dev)
static void napi_enable_rx(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
}
@@ -513,7 +521,7 @@ static void napi_enable_rx(struct net_device *dev)
static void napi_disable_rx(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
}
@@ -526,7 +534,7 @@ static void rx_bd_done(struct net_device *dev)
static void tx_kickstart(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
S16(fccp, fcc_ftodr, 0x8000);
}
@@ -534,7 +542,7 @@ static void tx_kickstart(struct net_device *dev)
static u32 get_int_events(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
return (u32)R16(fccp, fcc_fcce);
}
@@ -542,7 +550,7 @@ static u32 get_int_events(struct net_device *dev)
static void clear_int_events(struct net_device *dev, u32 int_events)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
W16(fccp, fcc_fcce, int_events & 0xffff);
}
@@ -553,7 +561,7 @@ static void ev_error(struct net_device *dev, u32 int_events)
": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events);
}
-int get_regs(struct net_device *dev, void *p, int *sizep)
+static int get_regs(struct net_device *dev, void *p, int *sizep)
{
struct fs_enet_private *fep = netdev_priv(dev);
@@ -570,7 +578,7 @@ int get_regs(struct net_device *dev, void *p, int *sizep)
return 0;
}
-int get_regs_len(struct net_device *dev)
+static int get_regs_len(struct net_device *dev)
{
return sizeof(fcc_t) + sizeof(fcc_enet_t) + 1;
}
@@ -583,10 +591,10 @@ int get_regs_len(struct net_device *dev)
* CPM37, we must disable and then re-enable the transmitter
* following a Late Collision, Underrun, or Retry Limit error.
*/
-void tx_restart(struct net_device *dev)
+static void tx_restart(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fcc_t *fccp = fep->fcc.fccp;
+ fcc_t __iomem *fccp = fep->fcc.fccp;
C32(fccp, fcc_gfmr, FCC_GFMR_ENT);
udelay(10);
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 9a02312..4af6858 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -83,7 +83,7 @@
*/
#define FEC_RESET_DELAY 50
-static int whack_reset(fec_t * fecp)
+static int whack_reset(fec_t __iomem *fecp)
{
int i;
@@ -159,7 +159,7 @@ static int allocate_bd(struct net_device *dev)
struct fs_enet_private *fep = netdev_priv(dev);
const struct fs_platform_info *fpi = fep->fpi;
- fep->ring_base = dma_alloc_coherent(fep->dev,
+ fep->ring_base = (void __force __iomem *)dma_alloc_coherent(fep->dev,
(fpi->tx_ring + fpi->rx_ring) *
sizeof(cbd_t), &fep->ring_mem_addr,
GFP_KERNEL);
@@ -177,7 +177,7 @@ static void free_bd(struct net_device *dev)
if(fep->ring_base)
dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring)
* sizeof(cbd_t),
- fep->ring_base,
+ (void __force *)fep->ring_base,
fep->ring_mem_addr);
}
@@ -189,7 +189,7 @@ static void cleanup_data(struct net_device *dev)
static void set_promiscuous_mode(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
FS(fecp, r_cntrl, FEC_RCNTRL_PROM);
}
@@ -237,7 +237,7 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac)
static void set_multicast_finish(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
/* if all multi or too many multicasts; just enable all */
if ((dev->flags & IFF_ALLMULTI) != 0 ||
@@ -271,7 +271,7 @@ static void restart(struct net_device *dev)
u32 cptr;
#endif
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
const struct fs_platform_info *fpi = fep->fpi;
dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
int r;
@@ -399,7 +399,7 @@ static void stop(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
const struct fs_platform_info *fpi = fep->fpi;
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
struct fec_info* feci= fep->phydev->bus->priv;
@@ -461,7 +461,7 @@ static void post_free_irq(struct net_device *dev, int irq)
static void napi_clear_rx_event(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
}
@@ -469,7 +469,7 @@ static void napi_clear_rx_event(struct net_device *dev)
static void napi_enable_rx(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
}
@@ -477,7 +477,7 @@ static void napi_enable_rx(struct net_device *dev)
static void napi_disable_rx(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
}
@@ -485,7 +485,7 @@ static void napi_disable_rx(struct net_device *dev)
static void rx_bd_done(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
FW(fecp, r_des_active, 0x01000000);
}
@@ -493,7 +493,7 @@ static void rx_bd_done(struct net_device *dev)
static void tx_kickstart(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
FW(fecp, x_des_active, 0x01000000);
}
@@ -501,7 +501,7 @@ static void tx_kickstart(struct net_device *dev)
static u32 get_int_events(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
return FR(fecp, ievent) & FR(fecp, imask);
}
@@ -509,7 +509,7 @@ static u32 get_int_events(struct net_device *dev)
static void clear_int_events(struct net_device *dev, u32 int_events)
{
struct fs_enet_private *fep = netdev_priv(dev);
- fec_t *fecp = fep->fec.fecp;
+ fec_t __iomem *fecp = fep->fec.fecp;
FW(fecp, ievent, int_events);
}
@@ -520,7 +520,7 @@ static void ev_error(struct net_device *dev, u32 int_events)
": %s FEC ERROR(s) 0x%x\n", dev->name, int_events);
}
-int get_regs(struct net_device *dev, void *p, int *sizep)
+static int get_regs(struct net_device *dev, void *p, int *sizep)
{
struct fs_enet_private *fep = netdev_priv(dev);
@@ -532,12 +532,12 @@ int get_regs(struct net_device *dev, void *p, int *sizep)
return 0;
}
-int get_regs_len(struct net_device *dev)
+static int get_regs_len(struct net_device *dev)
{
return sizeof(fec_t);
}
-void tx_restart(struct net_device *dev)
+static void tx_restart(struct net_device *dev)
{
/* nothing */
}
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index 7352c61..880471f 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -191,7 +191,8 @@ static int allocate_bd(struct net_device *dev)
if (IS_ERR_VALUE(fep->ring_mem_addr))
return -ENOMEM;
- fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr);
+ fep->ring_base = (void __iomem __force*)
+ cpm_dpram_addr(fep->ring_mem_addr);
return 0;
}
@@ -212,7 +213,7 @@ static void cleanup_data(struct net_device *dev)
static void set_promiscuous_mode(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_t *sccp = fep->scc.sccp;
+ scc_t __iomem *sccp = fep->scc.sccp;
S16(sccp, scc_psmr, SCC_PSMR_PRO);
}
@@ -220,7 +221,7 @@ static void set_promiscuous_mode(struct net_device *dev)
static void set_multicast_start(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_enet_t *ep = fep->scc.ep;
+ scc_enet_t __iomem *ep = fep->scc.ep;
W16(ep, sen_gaddr1, 0);
W16(ep, sen_gaddr2, 0);
@@ -231,7 +232,7 @@ static void set_multicast_start(struct net_device *dev)
static void set_multicast_one(struct net_device *dev, const u8 * mac)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_enet_t *ep = fep->scc.ep;
+ scc_enet_t __iomem *ep = fep->scc.ep;
u16 taddrh, taddrm, taddrl;
taddrh = ((u16) mac[5] << 8) | mac[4];
@@ -247,8 +248,8 @@ static void set_multicast_one(struct net_device *dev, const u8 * mac)
static void set_multicast_finish(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_t *sccp = fep->scc.sccp;
- scc_enet_t *ep = fep->scc.ep;
+ scc_t __iomem *sccp = fep->scc.sccp;
+ scc_enet_t __iomem *ep = fep->scc.ep;
/* clear promiscuous always */
C16(sccp, scc_psmr, SCC_PSMR_PRO);
@@ -285,8 +286,8 @@ static void set_multicast_list(struct net_device *dev)
static void restart(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_t *sccp = fep->scc.sccp;
- scc_enet_t *ep = fep->scc.ep;
+ scc_t __iomem *sccp = fep->scc.sccp;
+ scc_enet_t __iomem *ep = fep->scc.ep;
const struct fs_platform_info *fpi = fep->fpi;
u16 paddrh, paddrm, paddrl;
const unsigned char *mac;
@@ -296,7 +297,7 @@ static void restart(struct net_device *dev)
/* clear everything (slow & steady does it) */
for (i = 0; i < sizeof(*ep); i++)
- __fs_out8((char *)ep + i, 0);
+ __fs_out8((u8 __iomem *)ep + i, 0);
/* point to bds */
W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr);
@@ -397,7 +398,7 @@ static void restart(struct net_device *dev)
static void stop(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_t *sccp = fep->scc.sccp;
+ scc_t __iomem *sccp = fep->scc.sccp;
int i;
for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++)
@@ -441,7 +442,7 @@ static void post_free_irq(struct net_device *dev, int irq)
static void napi_clear_rx_event(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_t *sccp = fep->scc.sccp;
+ scc_t __iomem *sccp = fep->scc.sccp;
W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK);
}
@@ -449,7 +450,7 @@ static void napi_clear_rx_event(struct net_device *dev)
static void napi_enable_rx(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_t *sccp = fep->scc.sccp;
+ scc_t __iomem *sccp = fep->scc.sccp;
S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
}
@@ -457,7 +458,7 @@ static void napi_enable_rx(struct net_device *dev)
static void napi_disable_rx(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_t *sccp = fep->scc.sccp;
+ scc_t __iomem *sccp = fep->scc.sccp;
C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
}
@@ -475,7 +476,7 @@ static void tx_kickstart(struct net_device *dev)
static u32 get_int_events(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_t *sccp = fep->scc.sccp;
+ scc_t __iomem *sccp = fep->scc.sccp;
return (u32) R16(sccp, scc_scce);
}
@@ -483,7 +484,7 @@ static u32 get_int_events(struct net_device *dev)
static void clear_int_events(struct net_device *dev, u32 int_events)
{
struct fs_enet_private *fep = netdev_priv(dev);
- scc_t *sccp = fep->scc.sccp;
+ scc_t __iomem *sccp = fep->scc.sccp;
W16(sccp, scc_scce, int_events & 0xffff);
}
@@ -498,20 +499,20 @@ static int get_regs(struct net_device *dev, void *p, int *sizep)
{
struct fs_enet_private *fep = netdev_priv(dev);
- if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t))
+ if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t __iomem *))
return -EINVAL;
memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t));
p = (char *)p + sizeof(scc_t);
- memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t));
+ memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t __iomem *));
return 0;
}
static int get_regs_len(struct net_device *dev)
{
- return sizeof(scc_t) + sizeof(scc_enet_t);
+ return sizeof(scc_t) + sizeof(scc_enet_t __iomem *);
}
static void tx_restart(struct net_device *dev)
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 2c1c242..0041ebb 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -70,7 +70,7 @@ static int match_has_phy (struct device *dev, void* data)
static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info *fmpi)
{
struct resource *r;
- fec_t *fecp;
+ fec_t __iomem *fecp;
char* name = "fsl-cpm-fec";
/* we need fec in order to be useful */
@@ -100,7 +100,7 @@ static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info
static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
{
struct fec_info* fec = bus->priv;
- fec_t *fecp = fec->fecp;
+ fec_t __iomem *fecp = fec->fecp;
int i, ret = -1;
if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
@@ -124,7 +124,7 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
{
struct fec_info* fec = bus->priv;
- fec_t *fecp = fec->fecp;
+ fec_t __iomem *fecp = fec->fecp;
int i;
/* this must never happen */
--
1.5.0.3
^ permalink raw reply related
* [PATCH v3 6/8] fs_enet: Align receive buffers.
From: Scott Wood @ 2007-08-28 20:14 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
At least some hardware driven by this driver needs receive buffers
to be aligned on a 16-byte boundary. This usually happens by chance,
but it breaks if slab debugging is enabled.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/net/fs_enet/fs_enet-main.c | 21 +++++++++++++++++++--
drivers/net/fs_enet/fs_enet.h | 3 ++-
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index da79a45..a4b76cd 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -69,6 +69,14 @@ static void fs_set_multicast_list(struct net_device *dev)
(*fep->ops->set_multicast_list)(dev);
}
+static void skb_align(struct sk_buff *skb, int align)
+{
+ int off = ((unsigned long)skb->data) & (align - 1);
+
+ if (off)
+ skb_reserve(skb, align - off);
+}
+
/* NAPI receive function */
static int fs_enet_rx_napi(struct net_device *dev, int *budget)
{
@@ -166,9 +174,13 @@ static int fs_enet_rx_napi(struct net_device *dev, int *budget)
skb = skbn;
skbn = skbt;
}
- } else
+ } else {
skbn = dev_alloc_skb(ENET_RX_FRSIZE);
+ if (skbn)
+ skb_align(skbn, ENET_RX_ALIGN);
+ }
+
if (skbn != NULL) {
skb_put(skb, pkt_len); /* Make room */
skb->protocol = eth_type_trans(skb, dev);
@@ -300,9 +312,13 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
skb = skbn;
skbn = skbt;
}
- } else
+ } else {
skbn = dev_alloc_skb(ENET_RX_FRSIZE);
+ if (skbn)
+ skb_align(skbn, ENET_RX_ALIGN);
+ }
+
if (skbn != NULL) {
skb_put(skb, pkt_len); /* Make room */
skb->protocol = eth_type_trans(skb, dev);
@@ -512,6 +528,7 @@ void fs_init_bds(struct net_device *dev)
dev->name);
break;
}
+ skb_align(skb, ENET_RX_ALIGN);
fep->rx_skbuff[i] = skb;
CBDW_BUFADDR(bdp,
dma_map_single(fep->dev, skb->data,
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 72a61e9..f8c7ee8 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -82,7 +82,8 @@ struct phy_info {
/* Must be a multiple of 32 (to cover both FEC & FCC) */
#define PKT_MAXBLR_SIZE ((PKT_MAXBUF_SIZE + 31) & ~31)
/* This is needed so that invalidate_xxx wont invalidate too much */
-#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE)
+#define ENET_RX_ALIGN 16
+#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE + ENET_RX_ALIGN - 1)
struct fs_enet_mii_bus {
struct list_head list;
--
1.5.0.3
^ permalink raw reply related
* [PATCH v3 5/8] fs_enet: mac-fcc: Eliminate __fcc-* macros.
From: Scott Wood @ 2007-08-28 20:14 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
These macros accomplish nothing other than defeating type checking.
This patch also fixes one instance of the wrong register size being
used that was revealed by enabling type checking.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/net/fs_enet/mac-fcc.c | 25 ++++++++-----------------
1 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index ad3c5fa..8b30361 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -48,28 +48,19 @@
/* FCC access macros */
-#define __fcc_out32(addr, x) out_be32((unsigned *)addr, x)
-#define __fcc_out16(addr, x) out_be16((unsigned short *)addr, x)
-#define __fcc_out8(addr, x) out_8((unsigned char *)addr, x)
-#define __fcc_in32(addr) in_be32((unsigned *)addr)
-#define __fcc_in16(addr) in_be16((unsigned short *)addr)
-#define __fcc_in8(addr) in_8((unsigned char *)addr)
-
-/* parameter space */
-
/* write, read, set bits, clear bits */
-#define W32(_p, _m, _v) __fcc_out32(&(_p)->_m, (_v))
-#define R32(_p, _m) __fcc_in32(&(_p)->_m)
+#define W32(_p, _m, _v) out_be32(&(_p)->_m, (_v))
+#define R32(_p, _m) in_be32(&(_p)->_m)
#define S32(_p, _m, _v) W32(_p, _m, R32(_p, _m) | (_v))
#define C32(_p, _m, _v) W32(_p, _m, R32(_p, _m) & ~(_v))
-#define W16(_p, _m, _v) __fcc_out16(&(_p)->_m, (_v))
-#define R16(_p, _m) __fcc_in16(&(_p)->_m)
+#define W16(_p, _m, _v) out_be16(&(_p)->_m, (_v))
+#define R16(_p, _m) in_be16(&(_p)->_m)
#define S16(_p, _m, _v) W16(_p, _m, R16(_p, _m) | (_v))
#define C16(_p, _m, _v) W16(_p, _m, R16(_p, _m) & ~(_v))
-#define W8(_p, _m, _v) __fcc_out8(&(_p)->_m, (_v))
-#define R8(_p, _m) __fcc_in8(&(_p)->_m)
+#define W8(_p, _m, _v) out_8(&(_p)->_m, (_v))
+#define R8(_p, _m) in_8(&(_p)->_m)
#define S8(_p, _m, _v) W8(_p, _m, R8(_p, _m) | (_v))
#define C8(_p, _m, _v) W8(_p, _m, R8(_p, _m) & ~(_v))
@@ -290,7 +281,7 @@ static void restart(struct net_device *dev)
/* clear everything (slow & steady does it) */
for (i = 0; i < sizeof(*ep); i++)
- __fcc_out8((char *)ep + i, 0);
+ out_8((char *)ep + i, 0);
/* get physical address */
rx_bd_base_phys = fep->ring_mem_addr;
@@ -495,7 +486,7 @@ static void tx_kickstart(struct net_device *dev)
struct fs_enet_private *fep = netdev_priv(dev);
fcc_t *fccp = fep->fcc.fccp;
- S32(fccp, fcc_ftodr, 0x80);
+ S16(fccp, fcc_ftodr, 0x8000);
}
static u32 get_int_events(struct net_device *dev)
--
1.5.0.3
^ permalink raw reply related
* [PATCH v3 4/8] fs_enet: Don't share the interrupt.
From: Scott Wood @ 2007-08-28 20:14 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
This driver can't handle an interrupt immediately after request_irq
(making it fail with CONFIG_DEBUG_SHIRQ), and has unshared interrupts
on all hardware I'm aware of.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/net/fs_enet/fs_enet-main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index f261b90..da79a45 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -667,7 +667,7 @@ static int fs_request_irq(struct net_device *dev, int irq, const char *name,
struct fs_enet_private *fep = netdev_priv(dev);
(*fep->ops->pre_request_irq)(dev, irq);
- return request_irq(irq, irqf, IRQF_SHARED, name, dev);
+ return request_irq(irq, irqf, 0, name, dev);
}
static void fs_free_irq(struct net_device *dev, int irq)
--
1.5.0.3
^ permalink raw reply related
* [PATCH v3 3/8] fs_enet: Include linux/string.h from linux/fs_enet_pd.h
From: Scott Wood @ 2007-08-28 20:14 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
It is needed for strstr().
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
include/linux/fs_enet_pd.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index 543cd3c..815c6f9 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -16,6 +16,7 @@
#ifndef FS_ENET_PD_H
#define FS_ENET_PD_H
+#include <linux/string.h>
#include <asm/types.h>
#define FS_ENET_NAME "fs_enet"
--
1.5.0.3
^ permalink raw reply related
* [PATCH v3 2/8] fs_enet: Whitespace cleanup.
From: Scott Wood @ 2007-08-28 20:14 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070828201127.GA24068@ld0162-tx32.am.freescale.net>
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/net/fs_enet/fs_enet-main.c | 85 ++++++++++++++++-------------------
drivers/net/fs_enet/fs_enet.h | 4 +-
drivers/net/fs_enet/mac-fcc.c | 1 -
drivers/net/fs_enet/mii-fec.c | 1 -
4 files changed, 41 insertions(+), 50 deletions(-)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index a4a2a0e..f261b90 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -353,7 +353,6 @@ static void fs_enet_tx(struct net_device *dev)
do_wake = do_restart = 0;
while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
-
dirtyidx = bdp - fep->tx_bd_base;
if (fep->tx_free == fep->tx_ring)
@@ -454,7 +453,6 @@ fs_enet_interrupt(int irq, void *dev_id)
nr = 0;
while ((int_events = (*fep->ops->get_int_events)(dev)) != 0) {
-
nr++;
int_clr_events = int_events;
@@ -710,45 +708,43 @@ static void fs_timeout(struct net_device *dev)
*-----------------------------------------------------------------------------*/
static void generic_adjust_link(struct net_device *dev)
{
- struct fs_enet_private *fep = netdev_priv(dev);
- struct phy_device *phydev = fep->phydev;
- int new_state = 0;
-
- if (phydev->link) {
-
- /* adjust to duplex mode */
- if (phydev->duplex != fep->oldduplex){
- new_state = 1;
- fep->oldduplex = phydev->duplex;
- }
-
- if (phydev->speed != fep->oldspeed) {
- new_state = 1;
- fep->oldspeed = phydev->speed;
- }
-
- if (!fep->oldlink) {
- new_state = 1;
- fep->oldlink = 1;
- netif_schedule(dev);
- netif_carrier_on(dev);
- netif_start_queue(dev);
- }
-
- if (new_state)
- fep->ops->restart(dev);
-
- } else if (fep->oldlink) {
- new_state = 1;
- fep->oldlink = 0;
- fep->oldspeed = 0;
- fep->oldduplex = -1;
- netif_carrier_off(dev);
- netif_stop_queue(dev);
- }
-
- if (new_state && netif_msg_link(fep))
- phy_print_status(phydev);
+ struct fs_enet_private *fep = netdev_priv(dev);
+ struct phy_device *phydev = fep->phydev;
+ int new_state = 0;
+
+ if (phydev->link) {
+ /* adjust to duplex mode */
+ if (phydev->duplex != fep->oldduplex) {
+ new_state = 1;
+ fep->oldduplex = phydev->duplex;
+ }
+
+ if (phydev->speed != fep->oldspeed) {
+ new_state = 1;
+ fep->oldspeed = phydev->speed;
+ }
+
+ if (!fep->oldlink) {
+ new_state = 1;
+ fep->oldlink = 1;
+ netif_schedule(dev);
+ netif_carrier_on(dev);
+ netif_start_queue(dev);
+ }
+
+ if (new_state)
+ fep->ops->restart(dev);
+ } else if (fep->oldlink) {
+ new_state = 1;
+ fep->oldlink = 0;
+ fep->oldspeed = 0;
+ fep->oldduplex = -1;
+ netif_carrier_off(dev);
+ netif_stop_queue(dev);
+ }
+
+ if (new_state && netif_msg_link(fep))
+ phy_print_status(phydev);
}
@@ -792,7 +788,6 @@ static int fs_init_phy(struct net_device *dev)
return 0;
}
-
static int fs_enet_open(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
@@ -978,7 +973,7 @@ static struct net_device *fs_init_instance(struct device *dev,
#endif
#ifdef CONFIG_FS_ENET_HAS_SCC
- if (fs_get_scc_index(fpi->fs_no) >=0 )
+ if (fs_get_scc_index(fpi->fs_no) >=0)
fep->ops = &fs_scc_ops;
#endif
@@ -1069,9 +1064,8 @@ static struct net_device *fs_init_instance(struct device *dev,
return ndev;
- err:
+err:
if (ndev != NULL) {
-
if (registered)
unregister_netdev(ndev);
@@ -1262,7 +1256,6 @@ static int __init fs_init(void)
err:
cleanup_immap();
return r;
-
}
static void __exit fs_cleanup(void)
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 569be22..72a61e9 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -15,8 +15,8 @@
#include <asm/commproc.h>
struct fec_info {
- fec_t* fecp;
- u32 mii_speed;
+ fec_t *fecp;
+ u32 mii_speed;
};
#endif
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 5603121..ad3c5fa 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -86,7 +86,6 @@
static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op)
{
const struct fs_platform_info *fpi = fep->fpi;
-
cpm2_map_t *immap = fs_enet_immap;
cpm_cpm2_t *cpmp = &immap->im_cpm;
u32 v;
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 0a563a8..53db696 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -113,7 +113,6 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
}
return ret;
-
}
static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
--
1.5.0.3
^ permalink raw reply related
* [PATCH v3 1/8] Generic bitbanged MDIO library
From: Scott Wood @ 2007-08-28 20:11 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Previously, bitbanged MDIO was only supported in individual
hardware-specific drivers. This code factors out the higher level
protocol implementation, reducing the hardware-specific portion to
functions setting direction, data, and clock.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
drivers/net/phy/Kconfig | 9 ++
drivers/net/phy/Makefile | 1 +
drivers/net/phy/mdio-bitbang.c | 187 ++++++++++++++++++++++++++++++++++++++++
include/linux/mdio-bitbang.h | 42 +++++++++
4 files changed, 239 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/phy/mdio-bitbang.c
create mode 100644 include/linux/mdio-bitbang.h
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index dd09011..72a98dd 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -76,4 +76,13 @@ config FIXED_MII_100_FDX
bool "Emulation for 100M Fdx fixed PHY behavior"
depends on FIXED_PHY
+config MDIO_BITBANG
+ tristate "Support for bitbanged MDIO buses"
+ help
+ This module implements the MDIO bus protocol in software,
+ for use by low level drivers that export the ability to
+ drive the relevant pins.
+
+ If in doubt, say N.
+
endif # PHYLIB
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 8885650..3d6cc7b 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_VITESSE_PHY) += vitesse.o
obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
+obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
new file mode 100644
index 0000000..9bfc9ce
--- /dev/null
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -0,0 +1,187 @@
+/*
+ * Bitbanged MDIO support.
+ *
+ * Author: Scott Wood <scottwood@freescale.com>
+ * Copyright (c) 2007 Freescale Semiconductor
+ *
+ * Based on CPM2 MDIO code which is:
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/mdio-bitbang.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+
+#define MDIO_READ 1
+#define MDIO_WRITE 0
+
+#define MDIO_SETUP_TIME 10
+#define MDIO_HOLD_TIME 10
+
+/* Minimum MDC period is 400 ns, plus some margin for error */
+#define MDIO_DELAY 250
+
+/* The PHY may take up to 300 ns to produce data, plus some margin
+ * for error.
+ */
+#define MDIO_READ_DELAY 350
+
+/* MDIO must already be configured as output. */
+static void mdio_bitbang_send_bit(struct mdio_bitbang_ctrl *ctrl, int val)
+{
+ const struct mdio_bitbang_ops *ops = ctrl->ops;
+
+ ops->set_mdio_data(ctrl, val);
+ ndelay(MDIO_DELAY);
+ ops->set_mdc(ctrl, 1);
+ ndelay(MDIO_DELAY);
+ ops->set_mdc(ctrl, 0);
+}
+
+/* MDIO must already be configured as input. */
+static int mdio_bitbang_get_bit(struct mdio_bitbang_ctrl *ctrl)
+{
+ const struct mdio_bitbang_ops *ops = ctrl->ops;
+
+ ndelay(MDIO_DELAY);
+ ops->set_mdc(ctrl, 1);
+ ndelay(MDIO_READ_DELAY);
+ ops->set_mdc(ctrl, 0);
+
+ return ops->get_mdio_data(ctrl);
+}
+
+/* MDIO must already be configured as output. */
+static void mdio_bitbang_send_num(struct mdio_bitbang_ctrl *ctrl,
+ u16 val, int bits)
+{
+ int i;
+
+ for (i = bits - 1; i >= 0; i--)
+ mdio_bitbang_send_bit(ctrl, (val >> i) & 1);
+}
+
+/* MDIO must already be configured as input. */
+static u16 mdio_bitbang_get_num(struct mdio_bitbang_ctrl *ctrl, int bits)
+{
+ int i;
+ u16 ret = 0;
+
+ for (i = bits - 1; i >= 0; i--) {
+ ret <<= 1;
+ ret |= mdio_bitbang_get_bit(ctrl);
+ }
+
+ return ret;
+}
+
+/* Utility to send the preamble, address, and
+ * register (common to read and write).
+ */
+static void mdio_bitbang_cmd(struct mdio_bitbang_ctrl *ctrl,
+ int read, u8 phy, u8 reg)
+{
+ const struct mdio_bitbang_ops *ops = ctrl->ops;
+ int i;
+
+ ops->set_mdio_dir(ctrl, 1);
+
+ /*
+ * Send a 32 bit preamble ('1's) with an extra '1' bit for good
+ * measure. The IEEE spec says this is a PHY optional
+ * requirement. The AMD 79C874 requires one after power up and
+ * one after a MII communications error. This means that we are
+ * doing more preambles than we need, but it is safer and will be
+ * much more robust.
+ */
+
+ for (i = 0; i < 32; i++)
+ mdio_bitbang_send_bit(ctrl, 1);
+
+ /* send the start bit (01) and the read opcode (10) or write (10) */
+ mdio_bitbang_send_bit(ctrl, 0);
+ mdio_bitbang_send_bit(ctrl, 1);
+ mdio_bitbang_send_bit(ctrl, read);
+ mdio_bitbang_send_bit(ctrl, !read);
+
+ mdio_bitbang_send_num(ctrl, phy, 5);
+ mdio_bitbang_send_num(ctrl, reg, 5);
+}
+
+
+static int mdio_bitbang_read(struct mii_bus *bus, int phy, int reg)
+{
+ struct mdio_bitbang_ctrl *ctrl = bus->priv;
+ int ret, i;
+
+ mdio_bitbang_cmd(ctrl, MDIO_READ, phy, reg);
+ ctrl->ops->set_mdio_dir(ctrl, 0);
+
+ /* check the turnaround bit: the PHY should be driving it to zero */
+ if (mdio_bitbang_get_bit(ctrl) != 0) {
+ /* PHY didn't drive TA low -- flush any bits it
+ * may be trying to send.
+ */
+ for (i = 0; i < 32; i++)
+ mdio_bitbang_get_bit(ctrl);
+
+ return 0xffff;
+ }
+
+ ret = mdio_bitbang_get_num(ctrl, 16);
+ mdio_bitbang_get_bit(ctrl);
+ return ret;
+}
+
+static int mdio_bitbang_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+ struct mdio_bitbang_ctrl *ctrl = bus->priv;
+
+ mdio_bitbang_cmd(ctrl, MDIO_WRITE, phy, reg);
+
+ /* send the turnaround (10) */
+ mdio_bitbang_send_bit(ctrl, 1);
+ mdio_bitbang_send_bit(ctrl, 0);
+
+ mdio_bitbang_send_num(ctrl, val, 16);
+
+ ctrl->ops->set_mdio_dir(ctrl, 0);
+ mdio_bitbang_get_bit(ctrl);
+ return 0;
+}
+
+struct mii_bus *alloc_mdio_bitbang(struct mdio_bitbang_ctrl *ctrl)
+{
+ struct mii_bus *bus;
+
+ bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+ if (!bus)
+ return NULL;
+
+ __module_get(ctrl->ops->owner);
+
+ bus->read = mdio_bitbang_read;
+ bus->write = mdio_bitbang_write;
+ bus->priv = ctrl;
+
+ return bus;
+}
+
+void free_mdio_bitbang(struct mii_bus *bus)
+{
+ struct mdio_bitbang_ctrl *ctrl = bus->priv;
+
+ module_put(ctrl->ops->owner);
+ kfree(bus);
+}
diff --git a/include/linux/mdio-bitbang.h b/include/linux/mdio-bitbang.h
new file mode 100644
index 0000000..63a11dd
--- /dev/null
+++ b/include/linux/mdio-bitbang.h
@@ -0,0 +1,42 @@
+#ifndef __LINUX_MDIO_BITBANG_H
+#define __LINUX_MDIO_BITBANG_H
+
+#include <linux/phy.h>
+#include <linux/module.h>
+
+struct mdio_bitbang_ctrl;
+
+struct mdio_bitbang_ops {
+ struct module *owner;
+
+ /* Set the Management Data Clock high if level is one,
+ * low if level is zero.
+ */
+ void (*set_mdc)(struct mdio_bitbang_ctrl *ctrl, int level);
+
+ /* Configure the Management Data I/O pin as an input if
+ * "output" is zero, or an output if "output" is one.
+ */
+ void (*set_mdio_dir)(struct mdio_bitbang_ctrl *ctrl, int output);
+
+ /* Set the Management Data I/O pin high if value is one,
+ * low if "value" is zero. This may only be called
+ * when the MDIO pin is configured as an output.
+ */
+ void (*set_mdio_data)(struct mdio_bitbang_ctrl *ctrl, int value);
+
+ /* Retrieve the state Management Data I/O pin. */
+ int (*get_mdio_data)(struct mdio_bitbang_ctrl *ctrl);
+};
+
+struct mdio_bitbang_ctrl {
+ const struct mdio_bitbang_ops *ops;
+};
+
+/* The returned bus is not yet registered with the phy layer. */
+struct mii_bus *alloc_mdio_bitbang(struct mdio_bitbang_ctrl *ctrl);
+
+/* The bus must already have been unregistered. */
+void free_mdio_bitbang(struct mii_bus *bus);
+
+#endif
--
1.5.0.3
^ permalink raw reply related
* Re: [PATCH 1/1] Fix bus probe on Bamboo board
From: Josh Boyer @ 2007-08-28 20:01 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070828125100.31b0ab98@weaponx.rchland.ibm.com>
On Tue, 28 Aug 2007 12:51:00 -0500
Josh Boyer <jwboyer@linux.vnet.ibm.com> wrote:
> Commit 804ace8881d21 changed the behavior of how compatible nodes are found.
> This highlighted a bug on the Bamboo board where it wasn't probing the bus
> specified in the DTS file. We fix it by being explicit about which bus to
> probe.
>
> Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Paul, this is 2.6.24 material. You can either pick it up, or get it
from my git tree later. I mostly sent it out now in case people were
using the bamboo patches already.
josh
^ permalink raw reply
* Re: [PATCH] PS3: fix the bug the major version part is not compared
From: Geoff Levand @ 2007-08-28 19:49 UTC (permalink / raw)
To: paulus; +Cc: Geert Uytterhoeven, linuxppc-dev
In-Reply-To: <20070828211415.C2B5.MOKUNO@sm.sony.co.jp>
Masakazu Mokuno wrote:
> Fix the bug that the major version part of the firmware
> is not compared.
>
> Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp>
> CC: Geoff Levand <geoffrey.levand@am.sony.com>
> ---
> arch/powerpc/platforms/ps3/setup.c | 2 +-
> include/asm-powerpc/ps3.h | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
Paul,
Firmware 2.0.x will be out in the coming months, so it would
be nice if this could go in for 2.6.23.
Acked-by: Geoff Levand <geoffrey.levand@am.sony.com>
^ permalink raw reply
* Re: [PATCH 3/4] PowerPC 440EPx: Sequoia board support
From: Josh Boyer @ 2007-08-28 19:13 UTC (permalink / raw)
To: Olof Johansson; +Cc: linuxppc-dev
In-Reply-To: <20070828181437.GA14905@lixom.net>
On Tue, 28 Aug 2007 13:14:37 -0500
Olof Johansson <olof@lixom.net> wrote:
> Hi,
>
> On Tue, Aug 28, 2007 at 09:50:22PM +0400, Valentine Barshak wrote:
>
> > diff -ruN linux-2.6.orig/arch/powerpc/kernel/head_44x.S linux-2.6/arch/powerpc/kernel/head_44x.S
> > --- linux-2.6.orig/arch/powerpc/kernel/head_44x.S 2007-08-27 14:08:43.000000000 +0400
> > +++ linux-2.6/arch/powerpc/kernel/head_44x.S 2007-08-28 17:04:51.000000000 +0400
> > @@ -217,7 +217,7 @@
> > lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
> > mtspr SPRN_IVPR,r4
> >
> > -#ifdef CONFIG_440EP
> > +#if defined(CONFIG_440EP) || defined(CONFIG_440EPX)
> > /* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */
> > mfspr r2,SPRN_CCR0
> > lis r3,0xffef
>
> This is obviously nothing urgent given that the ifdef already existed, but
> this looks like it really should be a runtime check instead. Multiplatform
> kernels will require it (if/whenever that becomes a priority for 44x).
Yep, indeed. It's on my todo list, hopefully before 2.6.24. Don't
think we need to hold up 440EPx in the meantime, since it's a slightly
larger issue. Thanks for the reminder!
josh
^ permalink raw reply
* Re: [PATCH 3/4] PowerPC 440EPx: Sequoia board support
From: Olof Johansson @ 2007-08-28 18:14 UTC (permalink / raw)
To: Valentine Barshak; +Cc: linuxppc-dev
In-Reply-To: <20070828175022.GA7556@ru.mvista.com>
Hi,
On Tue, Aug 28, 2007 at 09:50:22PM +0400, Valentine Barshak wrote:
> diff -ruN linux-2.6.orig/arch/powerpc/kernel/head_44x.S linux-2.6/arch/powerpc/kernel/head_44x.S
> --- linux-2.6.orig/arch/powerpc/kernel/head_44x.S 2007-08-27 14:08:43.000000000 +0400
> +++ linux-2.6/arch/powerpc/kernel/head_44x.S 2007-08-28 17:04:51.000000000 +0400
> @@ -217,7 +217,7 @@
> lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
> mtspr SPRN_IVPR,r4
>
> -#ifdef CONFIG_440EP
> +#if defined(CONFIG_440EP) || defined(CONFIG_440EPX)
> /* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */
> mfspr r2,SPRN_CCR0
> lis r3,0xffef
This is obviously nothing urgent given that the ifdef already existed, but
this looks like it really should be a runtime check instead. Multiplatform
kernels will require it (if/whenever that becomes a priority for 44x).
-Olof
^ permalink raw reply
* Re: ppc_8xx-gcc from eldk strange behaviour
From: Scott Wood @ 2007-08-28 19:01 UTC (permalink / raw)
To: DI BACCO ANTONIO - technolabs; +Cc: linuxppc-embedded
In-Reply-To: <F1F6EC0C8B75034F9E3A79FC85122E8E2649AF@aquib01a>
On Tue, Aug 28, 2007 at 08:56:10PM +0200, DI BACCO ANTONIO - technolabs wrote:
> If I compile it with host gcc, there is no warning and the message "x is negative" is printed.
> If I compile it with ppc_8xx-gcc there is a warning "main.c:11: warning: comparison is always false due to limited range of data type" and the program prints message "x is positive".
> To correct the problem I have to put signed before char.
C does not specify the signedness of char. If you care, you need to
explicitly specify.
-Scott
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox