Skip to content

Commit

Permalink
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/paulus/powerpc

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc:
  [PATCH] powerpc: Use the ibm,pa-features property if available
  powerpc: Fix incorrect might_sleep in __get_user/__put_user on kernel addresses
  [PATCH] ppc32 CPM_UART: fixes and improvements
  [PATCH] ppc32 CPM_UART: Fixed break send on SCC
  [PATCH] powerpc/kprobes: fix singlestep out-of-line
  [PATCH] powerpc/pseries: avoid crash in PCI code if mem system not up
  • Loading branch information
Linus Torvalds committed May 4, 2006
2 parents f9cc847 + d205819 commit d98550e
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 27 deletions.
14 changes: 7 additions & 7 deletions arch/powerpc/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)

static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
kprobe_opcode_t insn = *p->ainsn.insn;

regs->msr |= MSR_SE;

/* single step inline if it is a trap variant */
if (is_trap(insn))
regs->nip = (unsigned long)p->addr;
else
regs->nip = (unsigned long)p->ainsn.insn;
/*
* On powerpc we should single step on the original
* instruction even if the probed insn is a trap
* variant as values in regs could play a part in
* if the trap is taken or not
*/
regs->nip = (unsigned long)p->ainsn.insn;
}

static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
Expand Down
70 changes: 70 additions & 0 deletions arch/powerpc/kernel/prom.c
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,74 @@ void __init unflatten_device_tree(void)
DBG(" <- unflatten_device_tree()\n");
}

/*
* ibm,pa-features is a per-cpu property that contains a string of
* attribute descriptors, each of which has a 2 byte header plus up
* to 254 bytes worth of processor attribute bits. First header
* byte specifies the number of bytes following the header.
* Second header byte is an "attribute-specifier" type, of which
* zero is the only currently-defined value.
* Implementation: Pass in the byte and bit offset for the feature
* that we are interested in. The function will return -1 if the
* pa-features property is missing, or a 1/0 to indicate if the feature
* is supported/not supported. Note that the bit numbers are
* big-endian to match the definition in PAPR.
*/
static struct ibm_pa_feature {
unsigned long cpu_features; /* CPU_FTR_xxx bit */
unsigned int cpu_user_ftrs; /* PPC_FEATURE_xxx bit */
unsigned char pabyte; /* byte number in ibm,pa-features */
unsigned char pabit; /* bit number (big-endian) */
unsigned char invert; /* if 1, pa bit set => clear feature */
} ibm_pa_features[] __initdata = {
{0, PPC_FEATURE_HAS_MMU, 0, 0, 0},
{0, PPC_FEATURE_HAS_FPU, 0, 1, 0},
{CPU_FTR_SLB, 0, 0, 2, 0},
{CPU_FTR_CTRL, 0, 0, 3, 0},
{CPU_FTR_NOEXECUTE, 0, 0, 6, 0},
{CPU_FTR_NODSISRALIGN, 0, 1, 1, 1},
{CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0},
};

static void __init check_cpu_pa_features(unsigned long node)
{
unsigned char *pa_ftrs;
unsigned long len, tablelen, i, bit;

pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
if (pa_ftrs == NULL)
return;

/* find descriptor with type == 0 */
for (;;) {
if (tablelen < 3)
return;
len = 2 + pa_ftrs[0];
if (tablelen < len)
return; /* descriptor 0 not found */
if (pa_ftrs[1] == 0)
break;
tablelen -= len;
pa_ftrs += len;
}

/* loop over bits we know about */
for (i = 0; i < ARRAY_SIZE(ibm_pa_features); ++i) {
struct ibm_pa_feature *fp = &ibm_pa_features[i];

if (fp->pabyte >= pa_ftrs[0])
continue;
bit = (pa_ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
if (bit ^ fp->invert) {
cur_cpu_spec->cpu_features |= fp->cpu_features;
cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
} else {
cur_cpu_spec->cpu_features &= ~fp->cpu_features;
cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
}
}
}

static int __init early_init_dt_scan_cpus(unsigned long node,
const char *uname, int depth,
void *data)
Expand Down Expand Up @@ -969,6 +1037,8 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
}
#endif /* CONFIG_ALTIVEC */

check_cpu_pa_features(node);

#ifdef CONFIG_PPC_PSERIES
if (nthreads > 1)
cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
Expand Down
8 changes: 8 additions & 0 deletions arch/powerpc/platforms/pseries/eeh_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,15 @@ int eeh_send_failure_event (struct device_node *dn,
{
unsigned long flags;
struct eeh_event *event;
char *location;

if (!mem_init_done) {
printk(KERN_ERR "EEH: event during early boot not handled\n");
location = (char *) get_property(dn, "ibm,loc-code", NULL);
printk(KERN_ERR "EEH: device node = %s\n", dn->full_name);
printk(KERN_ERR "EEH: PCI location = %s\n", location);
return 1;
}
event = kmalloc(sizeof(*event), GFP_ATOMIC);
if (event == NULL) {
printk (KERN_ERR "EEH: out of memory, event not handled\n");
Expand Down
2 changes: 1 addition & 1 deletion arch/ppc/platforms/mpc866ads_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ int __init mpc866ads_init(void)
ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
#endif

#ifdef CONFIG_SERIAL_CPM_SMCer
#ifdef CONFIG_SERIAL_CPM_SMC
ppc_sys_device_enable(MPC8xx_CPM_SMC2);
ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
#endif
Expand Down
19 changes: 14 additions & 5 deletions drivers/serial/cpm_uart/cpm_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
*
* 2006 (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.
*
*/
#ifndef CPM_UART_H
#define CPM_UART_H
Expand Down Expand Up @@ -101,12 +108,13 @@ static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo
int offset;
u32 val = (u32)addr;
/* sane check */
if ((val >= (u32)pinfo->mem_addr) &&
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;
}
printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
/* something nasty happened */
BUG();
return 0;
}

Expand All @@ -115,12 +123,13 @@ static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo
int offset;
u32 val = addr;
/* sane check */
if ((val >= pinfo->dma_addr) &&
(val<(pinfo->dma_addr + pinfo->mem_size))) {
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);
}
printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
/* something nasty happened */
BUG();
return 0;
}

Expand Down
37 changes: 30 additions & 7 deletions drivers/serial/cpm_uart/cpm_uart_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
* (C) 2004 Intracom, S.A.
* (C) 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
* (C) 2005-2006 MontaVista Software, Inc.
* Vitaly Bordug <vbordug@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -81,7 +82,7 @@ early_uart_get_pdev(int index)
}


void cpm_uart_count(void)
static void cpm_uart_count(void)
{
cpm_uart_nr = 0;
#ifdef CONFIG_SERIAL_CPM_SMC1
Expand All @@ -104,6 +105,21 @@ void cpm_uart_count(void)
#endif
}

/* Get UART number by its id */
static int cpm_uart_id2nr(int id)
{
int i;
if (id < UART_NR) {
for (i=0; i<UART_NR; i++) {
if (cpm_uart_port_map[i] == id)
return i;
}
}

/* not found or invalid argument */
return -1;
}

/*
* Check, if transmit buffers are processed
*/
Expand Down Expand Up @@ -457,7 +473,11 @@ static void cpm_uart_shutdown(struct uart_port *port)
}

/* Shut them really down and reinit buffer descriptors */
cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
if (IS_SMC(pinfo))
cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
else
cpm_line_cr_cmd(line, CPM_CR_GRA_STOP_TX);

cpm_uart_initbd(pinfo);
}
}
Expand Down Expand Up @@ -1008,7 +1028,11 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
int line;
u32 mem, pram;

for (line=0; line<UART_NR && cpm_uart_port_map[line]!=pdata->fs_no; line++);
line = cpm_uart_id2nr(idx);
if(line < 0) {
printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx);
return -1;
}

pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];

Expand Down Expand Up @@ -1241,8 +1265,7 @@ static int cpm_uart_drv_probe(struct device *dev)
}

pdata = pdev->dev.platform_data;
pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n",
cpm_uart_port_map[pdata->fs_no]);
pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));

if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
return ret;
Expand All @@ -1261,7 +1284,7 @@ static int cpm_uart_drv_remove(struct device *dev)
struct fs_uart_platform_info *pdata = pdev->dev.platform_data;

pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n",
cpm_uart_port_map[pdata->fs_no]);
cpm_uart_id2nr(pdata->fs_no));

uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
return 0;
Expand Down
2 changes: 2 additions & 0 deletions drivers/serial/cpm_uart/cpm_uart_cpm1.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
* (C) 2004 Intracom, S.A.
* (C) 2006 MontaVista Software, Inc.
* Vitaly Bordug <vbordug@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 2 additions & 0 deletions drivers/serial/cpm_uart/cpm_uart_cpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
*
* Copyright (C) 2004 Freescale Semiconductor, Inc.
* (C) 2004 Intracom, S.A.
* (C) 2006 MontaVista Software, Inc.
* Vitaly Bordug <vbordug@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down
19 changes: 13 additions & 6 deletions include/asm-powerpc/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/processor.h>
#include <asm/page.h>

#define VERIFY_READ 0
#define VERIFY_WRITE 1
Expand Down Expand Up @@ -179,9 +180,11 @@ do { \
#define __put_user_nocheck(x, ptr, size) \
({ \
long __pu_err; \
might_sleep(); \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
if (!is_kernel_addr((unsigned long)__pu_addr)) \
might_sleep(); \
__chk_user_ptr(ptr); \
__put_user_size((x), (ptr), (size), __pu_err); \
__put_user_size((x), __pu_addr, (size), __pu_err); \
__pu_err; \
})

Expand Down Expand Up @@ -258,9 +261,11 @@ do { \
({ \
long __gu_err; \
unsigned long __gu_val; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
__chk_user_ptr(ptr); \
might_sleep(); \
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
if (!is_kernel_addr((unsigned long)__gu_addr)) \
might_sleep(); \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
Expand All @@ -270,9 +275,11 @@ do { \
({ \
long __gu_err; \
long long __gu_val; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
__chk_user_ptr(ptr); \
might_sleep(); \
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
if (!is_kernel_addr((unsigned long)__gu_addr)) \
might_sleep(); \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
Expand Down
1 change: 1 addition & 0 deletions include/asm-ppc/commproc.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define CPM_CR_INIT_TX ((ushort)0x0002)
#define CPM_CR_HUNT_MODE ((ushort)0x0003)
#define CPM_CR_STOP_TX ((ushort)0x0004)
#define CPM_CR_GRA_STOP_TX ((ushort)0x0005)
#define CPM_CR_RESTART_TX ((ushort)0x0006)
#define CPM_CR_CLOSE_RX_BD ((ushort)0x0007)
#define CPM_CR_SET_GADDR ((ushort)0x0008)
Expand Down
2 changes: 1 addition & 1 deletion include/asm-ppc/cpm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
#define CPM_CR_INIT_TX ((ushort)0x0002)
#define CPM_CR_HUNT_MODE ((ushort)0x0003)
#define CPM_CR_STOP_TX ((ushort)0x0004)
#define CPM_CR_GRA_STOP_TX ((ushort)0x0005)
#define CPM_CR_GRA_STOP_TX ((ushort)0x0005)
#define CPM_CR_RESTART_TX ((ushort)0x0006)
#define CPM_CR_SET_GADDR ((ushort)0x0008)
#define CPM_CR_START_IDMA ((ushort)0x0009)
Expand Down
Loading

0 comments on commit d98550e

Please sign in to comment.