Merge branch 'for-linus' of git://www.jni.nu/cris
* 'for-linus' of git://www.jni.nu/cris: (51 commits) CRIS: Fix alignment problem for older ld CRIS: Always dump registers for segfaulting process. CRIS: Add config for pausing a seg-faulting process CRIS: Don't take faults while in_atomic CRIS: Fixup lookup for delay slot faults CRIS: Discard exit.text and .data at runtime CRIS: Add cache aligned and read mostly data sections CRIS: Return something from profile write CRIS: Add ARTPEC-3 and timestamps for sync-serial CRIS: Better ARTPEC-3 support for gpio CRIS: Add include guard CRIS: Better handling of pinmux settings CRIS: New DMA defines for ARTPEC-3 CRIS: __do_strncpy_from_user: Don't read the byte beyond the nil CRIS: Pagetable for ARTPEC-3 CRIS: Machine dependent memmap.h CRIS: Check if pointer is set before using it CRIS: Machine dependent dma.h CRIS: Define __read_mostly for CRISv32 CRIS: Discard .note.gnu.build-id section ...
This commit is contained in:
commit
53bcef6063
|
@ -24,7 +24,7 @@ config GENERIC_CMOS_UPDATE
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config ARCH_USES_GETTIMEOFFSET
|
config ARCH_USES_GETTIMEOFFSET
|
||||||
def_bool y
|
def_bool n
|
||||||
|
|
||||||
config GENERIC_IOMAP
|
config GENERIC_IOMAP
|
||||||
bool
|
bool
|
||||||
|
@ -128,16 +128,19 @@ choice
|
||||||
|
|
||||||
config ETRAX100LX
|
config ETRAX100LX
|
||||||
bool "ETRAX-100LX-v1"
|
bool "ETRAX-100LX-v1"
|
||||||
|
select ARCH_USES_GETTIMEOFFSET
|
||||||
help
|
help
|
||||||
Support version 1 of the ETRAX 100LX.
|
Support version 1 of the ETRAX 100LX.
|
||||||
|
|
||||||
config ETRAX100LX_V2
|
config ETRAX100LX_V2
|
||||||
bool "ETRAX-100LX-v2"
|
bool "ETRAX-100LX-v2"
|
||||||
|
select ARCH_USES_GETTIMEOFFSET
|
||||||
help
|
help
|
||||||
Support version 2 of the ETRAX 100LX.
|
Support version 2 of the ETRAX 100LX.
|
||||||
|
|
||||||
config SVINTO_SIM
|
config SVINTO_SIM
|
||||||
bool "ETRAX-100LX-for-xsim-simulator"
|
bool "ETRAX-100LX-for-xsim-simulator"
|
||||||
|
select ARCH_USES_GETTIMEOFFSET
|
||||||
help
|
help
|
||||||
Support the xsim ETRAX Simulator.
|
Support the xsim ETRAX Simulator.
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,10 @@ config DEBUG_NMI_OOPS
|
||||||
If the system locks up without any debug information you can say Y
|
If the system locks up without any debug information you can say Y
|
||||||
here to make it possible to dump an OOPS with an external NMI.
|
here to make it possible to dump an OOPS with an external NMI.
|
||||||
|
|
||||||
|
config NO_SEGFAULT_TERMINATION
|
||||||
|
bool "Keep segfaulting processes"
|
||||||
|
help
|
||||||
|
Place segfaulting user mode processes on a wait queue instead of
|
||||||
|
delivering a terminating SIGSEGV to allow debugging with gdb.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -383,7 +383,7 @@ config ETRAX_RS485
|
||||||
depends on ETRAX_SERIAL
|
depends on ETRAX_SERIAL
|
||||||
help
|
help
|
||||||
Enables support for RS-485 serial communication. For a primer on
|
Enables support for RS-485 serial communication. For a primer on
|
||||||
RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>.
|
RS-485, see <http://en.wikipedia.org/wiki/Rs485>
|
||||||
|
|
||||||
config ETRAX_RS485_ON_PA
|
config ETRAX_RS485_ON_PA
|
||||||
bool "RS-485 mode on PA"
|
bool "RS-485 mode on PA"
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/smp_lock.h>
|
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
@ -376,7 +375,6 @@ int __init eeprom_init(void)
|
||||||
/* Opens the device. */
|
/* Opens the device. */
|
||||||
static int eeprom_open(struct inode * inode, struct file * file)
|
static int eeprom_open(struct inode * inode, struct file * file)
|
||||||
{
|
{
|
||||||
cycle_kernel_lock();
|
|
||||||
if(iminor(inode) != EEPROM_MINOR_NR)
|
if(iminor(inode) != EEPROM_MINOR_NR)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
if(imajor(inode) != EEPROM_MAJOR_NR)
|
if(imajor(inode) != EEPROM_MAJOR_NR)
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/smp_lock.h>
|
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
@ -46,8 +45,7 @@ static char gpio_name[] = "etrax gpio";
|
||||||
static wait_queue_head_t *gpio_wq;
|
static wait_queue_head_t *gpio_wq;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int gpio_ioctl(struct inode *inode, struct file *file,
|
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||||
unsigned int cmd, unsigned long arg);
|
|
||||||
static ssize_t gpio_write(struct file *file, const char __user *buf,
|
static ssize_t gpio_write(struct file *file, const char __user *buf,
|
||||||
size_t count, loff_t *off);
|
size_t count, loff_t *off);
|
||||||
static int gpio_open(struct inode *inode, struct file *filp);
|
static int gpio_open(struct inode *inode, struct file *filp);
|
||||||
|
@ -324,7 +322,6 @@ gpio_open(struct inode *inode, struct file *filp)
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
lock_kernel();
|
|
||||||
priv->minor = p;
|
priv->minor = p;
|
||||||
|
|
||||||
/* initialize the io/alarm struct */
|
/* initialize the io/alarm struct */
|
||||||
|
@ -359,7 +356,6 @@ gpio_open(struct inode *inode, struct file *filp)
|
||||||
alarmlist = priv;
|
alarmlist = priv;
|
||||||
spin_unlock_irqrestore(&gpio_lock, flags);
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
|
|
||||||
unlock_kernel();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,9 +500,7 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
|
||||||
static int
|
static int
|
||||||
gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
|
gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
|
||||||
|
|
||||||
static int
|
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
gpio_ioctl(struct inode *inode, struct file *file,
|
|
||||||
unsigned int cmd, unsigned long arg)
|
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
|
@ -516,54 +510,65 @@ gpio_ioctl(struct inode *inode, struct file *file,
|
||||||
if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
|
if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_irqsave(&gpio_lock, flags);
|
|
||||||
|
|
||||||
switch (_IOC_NR(cmd)) {
|
switch (_IOC_NR(cmd)) {
|
||||||
case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
|
case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
|
||||||
// read the port
|
// read the port
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
if (USE_PORTS(priv)) {
|
if (USE_PORTS(priv)) {
|
||||||
ret = *priv->port;
|
ret = *priv->port;
|
||||||
} else if (priv->minor == GPIO_MINOR_G) {
|
} else if (priv->minor == GPIO_MINOR_G) {
|
||||||
ret = (*R_PORT_G_DATA) & 0x7FFFFFFF;
|
ret = (*R_PORT_G_DATA) & 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IO_SETBITS:
|
case IO_SETBITS:
|
||||||
// set changeable bits with a 1 in arg
|
// set changeable bits with a 1 in arg
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
|
|
||||||
if (USE_PORTS(priv)) {
|
if (USE_PORTS(priv)) {
|
||||||
*priv->port = *priv->shadow |=
|
*priv->port = *priv->shadow |=
|
||||||
((unsigned char)arg & priv->changeable_bits);
|
((unsigned char)arg & priv->changeable_bits);
|
||||||
} else if (priv->minor == GPIO_MINOR_G) {
|
} else if (priv->minor == GPIO_MINOR_G) {
|
||||||
*R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
|
*R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IO_CLRBITS:
|
case IO_CLRBITS:
|
||||||
// clear changeable bits with a 1 in arg
|
// clear changeable bits with a 1 in arg
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
if (USE_PORTS(priv)) {
|
if (USE_PORTS(priv)) {
|
||||||
*priv->port = *priv->shadow &=
|
*priv->port = *priv->shadow &=
|
||||||
~((unsigned char)arg & priv->changeable_bits);
|
~((unsigned char)arg & priv->changeable_bits);
|
||||||
} else if (priv->minor == GPIO_MINOR_G) {
|
} else if (priv->minor == GPIO_MINOR_G) {
|
||||||
*R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
|
*R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_HIGHALARM:
|
case IO_HIGHALARM:
|
||||||
// set alarm when bits with 1 in arg go high
|
// set alarm when bits with 1 in arg go high
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
priv->highalarm |= arg;
|
priv->highalarm |= arg;
|
||||||
gpio_some_alarms = 1;
|
gpio_some_alarms = 1;
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_LOWALARM:
|
case IO_LOWALARM:
|
||||||
// set alarm when bits with 1 in arg go low
|
// set alarm when bits with 1 in arg go low
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
priv->lowalarm |= arg;
|
priv->lowalarm |= arg;
|
||||||
gpio_some_alarms = 1;
|
gpio_some_alarms = 1;
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_CLRALARM:
|
case IO_CLRALARM:
|
||||||
// clear alarm for bits with 1 in arg
|
/* clear alarm for bits with 1 in arg */
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
priv->highalarm &= ~arg;
|
priv->highalarm &= ~arg;
|
||||||
priv->lowalarm &= ~arg;
|
priv->lowalarm &= ~arg;
|
||||||
{
|
{
|
||||||
/* Must update gpio_some_alarms */
|
/* Must update gpio_some_alarms */
|
||||||
struct gpio_private *p = alarmlist;
|
struct gpio_private *p = alarmlist;
|
||||||
int some_alarms;
|
int some_alarms;
|
||||||
spin_lock_irq(&gpio_lock);
|
|
||||||
p = alarmlist;
|
p = alarmlist;
|
||||||
some_alarms = 0;
|
some_alarms = 0;
|
||||||
while (p) {
|
while (p) {
|
||||||
|
@ -574,11 +579,12 @@ gpio_ioctl(struct inode *inode, struct file *file,
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
gpio_some_alarms = some_alarms;
|
gpio_some_alarms = some_alarms;
|
||||||
spin_unlock_irq(&gpio_lock);
|
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
|
case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
|
||||||
/* Read direction 0=input 1=output */
|
/* Read direction 0=input 1=output */
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
if (USE_PORTS(priv)) {
|
if (USE_PORTS(priv)) {
|
||||||
ret = *priv->dir_shadow;
|
ret = *priv->dir_shadow;
|
||||||
} else if (priv->minor == GPIO_MINOR_G) {
|
} else if (priv->minor == GPIO_MINOR_G) {
|
||||||
|
@ -587,30 +593,40 @@ gpio_ioctl(struct inode *inode, struct file *file,
|
||||||
*/
|
*/
|
||||||
ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
|
ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
|
case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
|
||||||
/* Set direction 0=unchanged 1=input,
|
/* Set direction 0=unchanged 1=input,
|
||||||
* return mask with 1=input
|
* return mask with 1=input
|
||||||
*/
|
*/
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
ret = setget_input(priv, arg) & 0x7FFFFFFF;
|
ret = setget_input(priv, arg) & 0x7FFFFFFF;
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
|
case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
|
||||||
/* Set direction 0=unchanged 1=output,
|
/* Set direction 0=unchanged 1=output,
|
||||||
* return mask with 1=output
|
* return mask with 1=output
|
||||||
*/
|
*/
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
ret = setget_output(priv, arg) & 0x7FFFFFFF;
|
ret = setget_output(priv, arg) & 0x7FFFFFFF;
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_SHUTDOWN:
|
case IO_SHUTDOWN:
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
SOFT_SHUTDOWN();
|
SOFT_SHUTDOWN();
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_GET_PWR_BT:
|
case IO_GET_PWR_BT:
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
#if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
|
#if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
|
||||||
ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
|
ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
|
||||||
#else
|
#else
|
||||||
ret = 0;
|
ret = 0;
|
||||||
#endif
|
#endif
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_CFG_WRITE_MODE:
|
case IO_CFG_WRITE_MODE:
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
priv->clk_mask = arg & 0xFF;
|
priv->clk_mask = arg & 0xFF;
|
||||||
priv->data_mask = (arg >> 8) & 0xFF;
|
priv->data_mask = (arg >> 8) & 0xFF;
|
||||||
priv->write_msb = (arg >> 16) & 0x01;
|
priv->write_msb = (arg >> 16) & 0x01;
|
||||||
|
@ -626,28 +642,33 @@ gpio_ioctl(struct inode *inode, struct file *file,
|
||||||
priv->data_mask = 0;
|
priv->data_mask = 0;
|
||||||
ret = -EPERM;
|
ret = -EPERM;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
break;
|
break;
|
||||||
case IO_READ_INBITS:
|
case IO_READ_INBITS:
|
||||||
/* *arg is result of reading the input pins */
|
/* *arg is result of reading the input pins */
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
if (USE_PORTS(priv)) {
|
if (USE_PORTS(priv)) {
|
||||||
val = *priv->port;
|
val = *priv->port;
|
||||||
} else if (priv->minor == GPIO_MINOR_G) {
|
} else if (priv->minor == GPIO_MINOR_G) {
|
||||||
val = *R_PORT_G_DATA;
|
val = *R_PORT_G_DATA;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
|
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
break;
|
break;
|
||||||
case IO_READ_OUTBITS:
|
case IO_READ_OUTBITS:
|
||||||
/* *arg is result of reading the output shadow */
|
/* *arg is result of reading the output shadow */
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
if (USE_PORTS(priv)) {
|
if (USE_PORTS(priv)) {
|
||||||
val = *priv->shadow;
|
val = *priv->shadow;
|
||||||
} else if (priv->minor == GPIO_MINOR_G) {
|
} else if (priv->minor == GPIO_MINOR_G) {
|
||||||
val = port_g_data_shadow;
|
val = port_g_data_shadow;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
|
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
break;
|
break;
|
||||||
case IO_SETGET_INPUT:
|
case IO_SETGET_INPUT:
|
||||||
/* bits set in *arg is set to input,
|
/* bits set in *arg is set to input,
|
||||||
* *arg updated with current input pins.
|
* *arg updated with current input pins.
|
||||||
*/
|
*/
|
||||||
|
@ -656,7 +677,9 @@ gpio_ioctl(struct inode *inode, struct file *file,
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
val = setget_input(priv, val);
|
val = setget_input(priv, val);
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
|
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
break;
|
break;
|
||||||
|
@ -668,18 +691,21 @@ gpio_ioctl(struct inode *inode, struct file *file,
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
val = setget_output(priv, val);
|
val = setget_output(priv, val);
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
|
if (copy_to_user((void __user *)arg, &val, sizeof(val)))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
spin_lock_irqsave(&gpio_lock, flags);
|
||||||
if (priv->minor == GPIO_MINOR_LEDS)
|
if (priv->minor == GPIO_MINOR_LEDS)
|
||||||
ret = gpio_leds_ioctl(cmd, arg);
|
ret = gpio_leds_ioctl(cmd, arg);
|
||||||
else
|
else
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||||
} /* switch */
|
} /* switch */
|
||||||
|
|
||||||
spin_unlock_irqrestore(&gpio_lock, flags);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,12 +739,12 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations gpio_fops = {
|
static const struct file_operations gpio_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.poll = gpio_poll,
|
.poll = gpio_poll,
|
||||||
.ioctl = gpio_ioctl,
|
.unlocked_ioctl = gpio_ioctl,
|
||||||
.write = gpio_write,
|
.write = gpio_write,
|
||||||
.open = gpio_open,
|
.open = gpio_open,
|
||||||
.release = gpio_release,
|
.release = gpio_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ioif_watcher(const unsigned int gpio_in_available,
|
static void ioif_watcher(const unsigned int gpio_in_available,
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/smp_lock.h>
|
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
@ -60,8 +59,8 @@ static const char i2c_name[] = "i2c";
|
||||||
|
|
||||||
#define SDABIT CONFIG_ETRAX_I2C_DATA_PORT
|
#define SDABIT CONFIG_ETRAX_I2C_DATA_PORT
|
||||||
#define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT
|
#define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT
|
||||||
#define i2c_enable()
|
#define i2c_enable()
|
||||||
#define i2c_disable()
|
#define i2c_disable()
|
||||||
|
|
||||||
/* enable or disable output-enable, to select output or input on the i2c bus */
|
/* enable or disable output-enable, to select output or input on the i2c bus */
|
||||||
|
|
||||||
|
@ -91,7 +90,7 @@ static const char i2c_name[] = "i2c";
|
||||||
|
|
||||||
#define i2c_dir_out() \
|
#define i2c_dir_out() \
|
||||||
*R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \
|
*R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \
|
||||||
REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 1);
|
REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 1);
|
||||||
#define i2c_dir_in() \
|
#define i2c_dir_in() \
|
||||||
*R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \
|
*R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \
|
||||||
REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 0);
|
REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 0);
|
||||||
|
@ -189,7 +188,7 @@ i2c_outbyte(unsigned char x)
|
||||||
} else {
|
} else {
|
||||||
i2c_data(I2C_DATA_LOW);
|
i2c_data(I2C_DATA_LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
i2c_delay(CLOCK_LOW_TIME/2);
|
i2c_delay(CLOCK_LOW_TIME/2);
|
||||||
i2c_clk(I2C_CLOCK_HIGH);
|
i2c_clk(I2C_CLOCK_HIGH);
|
||||||
i2c_delay(CLOCK_HIGH_TIME);
|
i2c_delay(CLOCK_HIGH_TIME);
|
||||||
|
@ -416,7 +415,7 @@ i2c_sendnack(void)
|
||||||
*#
|
*#
|
||||||
*#--------------------------------------------------------------------------*/
|
*#--------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
i2c_writereg(unsigned char theSlave, unsigned char theReg,
|
i2c_writereg(unsigned char theSlave, unsigned char theReg,
|
||||||
unsigned char theValue)
|
unsigned char theValue)
|
||||||
{
|
{
|
||||||
int error, cntr = 3;
|
int error, cntr = 3;
|
||||||
|
@ -468,7 +467,7 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg,
|
||||||
* enable interrupt again
|
* enable interrupt again
|
||||||
*/
|
*/
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
} while(error && cntr--);
|
} while(error && cntr--);
|
||||||
|
|
||||||
i2c_delay(CLOCK_LOW_TIME);
|
i2c_delay(CLOCK_LOW_TIME);
|
||||||
|
@ -504,7 +503,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
|
||||||
* generate start condition
|
* generate start condition
|
||||||
*/
|
*/
|
||||||
i2c_start();
|
i2c_start();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* send slave address
|
* send slave address
|
||||||
*/
|
*/
|
||||||
|
@ -555,7 +554,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
|
||||||
* enable interrupt again
|
* enable interrupt again
|
||||||
*/
|
*/
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
} while(error && cntr--);
|
} while(error && cntr--);
|
||||||
|
|
||||||
spin_unlock(&i2c_lock);
|
spin_unlock(&i2c_lock);
|
||||||
|
@ -566,7 +565,6 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
|
||||||
static int
|
static int
|
||||||
i2c_open(struct inode *inode, struct file *filp)
|
i2c_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
cycle_kernel_lock();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,9 +577,7 @@ i2c_release(struct inode *inode, struct file *filp)
|
||||||
/* Main device API. ioctl's to write or read to/from i2c registers.
|
/* Main device API. ioctl's to write or read to/from i2c registers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static long i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
i2c_ioctl(struct inode *inode, struct file *file,
|
|
||||||
unsigned int cmd, unsigned long arg)
|
|
||||||
{
|
{
|
||||||
if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
|
if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -590,7 +586,7 @@ i2c_ioctl(struct inode *inode, struct file *file,
|
||||||
switch (_IOC_NR(cmd)) {
|
switch (_IOC_NR(cmd)) {
|
||||||
case I2C_WRITEREG:
|
case I2C_WRITEREG:
|
||||||
/* write to an i2c slave */
|
/* write to an i2c slave */
|
||||||
D(printk("i2cw %d %d %d\n",
|
D(printk(KERN_DEBUG "i2cw %d %d %d\n",
|
||||||
I2C_ARGSLAVE(arg),
|
I2C_ARGSLAVE(arg),
|
||||||
I2C_ARGREG(arg),
|
I2C_ARGREG(arg),
|
||||||
I2C_ARGVALUE(arg)));
|
I2C_ARGVALUE(arg)));
|
||||||
|
@ -602,26 +598,25 @@ i2c_ioctl(struct inode *inode, struct file *file,
|
||||||
{
|
{
|
||||||
unsigned char val;
|
unsigned char val;
|
||||||
/* read from an i2c slave */
|
/* read from an i2c slave */
|
||||||
D(printk("i2cr %d %d ",
|
D(printk(KERN_DEBUG "i2cr %d %d ",
|
||||||
I2C_ARGSLAVE(arg),
|
I2C_ARGSLAVE(arg),
|
||||||
I2C_ARGREG(arg)));
|
I2C_ARGREG(arg)));
|
||||||
val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
|
val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
|
||||||
D(printk("= %d\n", val));
|
D(printk(KERN_DEBUG "= %d\n", val));
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations i2c_fops = {
|
static const struct file_operations i2c_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.ioctl = i2c_ioctl,
|
.unlocked_ioctl = i2c_ioctl,
|
||||||
.open = i2c_open,
|
.open = i2c_open,
|
||||||
.release = i2c_release,
|
.release = i2c_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init
|
int __init
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/* $Id: i2c.h,v 1.3 2004/05/28 09:26:59 starvik Exp $ */
|
/* i2c.h */
|
||||||
|
|
||||||
int i2c_init(void);
|
int i2c_init(void);
|
||||||
|
|
||||||
/* High level I2C actions */
|
/* High level I2C actions */
|
||||||
|
|
|
@ -157,7 +157,7 @@ static int sync_serial_open(struct inode *inode, struct file *file);
|
||||||
static int sync_serial_release(struct inode *inode, struct file *file);
|
static int sync_serial_release(struct inode *inode, struct file *file);
|
||||||
static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
|
static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
|
||||||
|
|
||||||
static int sync_serial_ioctl(struct inode *inode, struct file *file,
|
static int sync_serial_ioctl(struct file *file,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
static ssize_t sync_serial_write(struct file *file, const char *buf,
|
static ssize_t sync_serial_write(struct file *file, const char *buf,
|
||||||
size_t count, loff_t *ppos);
|
size_t count, loff_t *ppos);
|
||||||
|
@ -244,13 +244,13 @@ static unsigned sync_serial_prescale_shadow;
|
||||||
#define NUMBER_OF_PORTS 2
|
#define NUMBER_OF_PORTS 2
|
||||||
|
|
||||||
static const struct file_operations sync_serial_fops = {
|
static const struct file_operations sync_serial_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.write = sync_serial_write,
|
.write = sync_serial_write,
|
||||||
.read = sync_serial_read,
|
.read = sync_serial_read,
|
||||||
.poll = sync_serial_poll,
|
.poll = sync_serial_poll,
|
||||||
.ioctl = sync_serial_ioctl,
|
.unlocked_ioctl = sync_serial_ioctl,
|
||||||
.open = sync_serial_open,
|
.open = sync_serial_open,
|
||||||
.release = sync_serial_release
|
.release = sync_serial_release
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init etrax_sync_serial_init(void)
|
static int __init etrax_sync_serial_init(void)
|
||||||
|
@ -678,7 +678,7 @@ static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sync_serial_ioctl(struct inode *inode, struct file *file,
|
static int sync_serial_ioctl_unlocked(struct file *file,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
int return_val = 0;
|
int return_val = 0;
|
||||||
|
@ -956,6 +956,18 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
|
||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long sync_serial_ioctl(struct file *file,
|
||||||
|
unsigned int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
ret = sync_serial_ioctl_unlocked(file, cmd, arg);
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssize_t sync_serial_write(struct file *file, const char *buf,
|
static ssize_t sync_serial_write(struct file *file, const char *buf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
|
|
|
@ -467,11 +467,7 @@ timer1_handler(int irq, void *dev_id)
|
||||||
|
|
||||||
static void wake_up_func(unsigned long data)
|
static void wake_up_func(unsigned long data)
|
||||||
{
|
{
|
||||||
#ifdef DECLARE_WAITQUEUE
|
wait_queue_head_t *sleep_wait_p = (wait_queue_head_t *)data;
|
||||||
wait_queue_head_t *sleep_wait_p = (wait_queue_head_t*)data;
|
|
||||||
#else
|
|
||||||
struct wait_queue **sleep_wait_p = (struct wait_queue **)data;
|
|
||||||
#endif
|
|
||||||
wake_up(sleep_wait_p);
|
wake_up(sleep_wait_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,7 @@ _no_romfs_in_flash:
|
||||||
;; the "rom fs" we'll possibly use in 2.4 if not JFFS (which does
|
;; the "rom fs" we'll possibly use in 2.4 if not JFFS (which does
|
||||||
;; not need this mechanism anyway)
|
;; not need this mechanism anyway)
|
||||||
|
|
||||||
move.d __vmlinux_end, $r0; the image will be after the vmlinux end address
|
move.d __init_end, $r0; the image will be after the end of init
|
||||||
move.d [$r0], $r1 ; cramfs assumes same endian on host/target
|
move.d [$r0], $r1 ; cramfs assumes same endian on host/target
|
||||||
cmp.d CRAMFS_MAGIC, $r1; magic value in cramfs superblock
|
cmp.d CRAMFS_MAGIC, $r1; magic value in cramfs superblock
|
||||||
bne 2f
|
bne 2f
|
||||||
|
|
|
@ -61,66 +61,16 @@ unsigned long get_ns_in_jiffie(void)
|
||||||
|
|
||||||
unsigned long do_slow_gettimeoffset(void)
|
unsigned long do_slow_gettimeoffset(void)
|
||||||
{
|
{
|
||||||
unsigned long count, t1;
|
unsigned long count;
|
||||||
unsigned long usec_count = 0;
|
|
||||||
unsigned short presc_count;
|
|
||||||
|
|
||||||
static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */
|
|
||||||
static unsigned long jiffies_p = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cache volatile jiffies temporarily; we have IRQs turned off.
|
|
||||||
*/
|
|
||||||
unsigned long jiffies_t;
|
|
||||||
|
|
||||||
/* The timer interrupt comes from Etrax timer 0. In order to get
|
/* The timer interrupt comes from Etrax timer 0. In order to get
|
||||||
* better precision, we check the current value. It might have
|
* better precision, we check the current value. It might have
|
||||||
* underflowed already though.
|
* underflowed already though.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONFIG_SVINTO_SIM
|
|
||||||
/* Not available in the xsim simulator. */
|
|
||||||
count = *R_TIMER0_DATA;
|
count = *R_TIMER0_DATA;
|
||||||
presc_count = *R_TIM_PRESC_STATUS;
|
|
||||||
/* presc_count might be wrapped */
|
|
||||||
t1 = *R_TIMER0_DATA;
|
|
||||||
if (count != t1){
|
|
||||||
/* it wrapped, read prescaler again... */
|
|
||||||
presc_count = *R_TIM_PRESC_STATUS;
|
|
||||||
count = t1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
count = 0;
|
|
||||||
presc_count = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jiffies_t = jiffies;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* avoiding timer inconsistencies (they are rare, but they happen)...
|
|
||||||
* there are one problem that must be avoided here:
|
|
||||||
* 1. the timer counter underflows
|
|
||||||
*/
|
|
||||||
if( jiffies_t == jiffies_p ) {
|
|
||||||
if( count > count_p ) {
|
|
||||||
/* Timer wrapped, use new count and prescale
|
|
||||||
* increase the time corresponding to one jiffie
|
|
||||||
*/
|
|
||||||
usec_count = 1000000/HZ;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
jiffies_p = jiffies_t;
|
|
||||||
count_p = count;
|
|
||||||
if (presc_count >= PRESCALE_VALUE/2 ){
|
|
||||||
presc_count = PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2;
|
|
||||||
} else {
|
|
||||||
presc_count = PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2;
|
|
||||||
}
|
|
||||||
/* Convert timer value to usec */
|
/* Convert timer value to usec */
|
||||||
usec_count += ( (TIMER0_DIV - count) * (1000000/HZ)/TIMER0_DIV ) +
|
return (TIMER0_DIV - count) * ((NSEC_PER_SEC/1000)/HZ)/TIMER0_DIV;
|
||||||
(( (presc_count) * (1000000000/PRESCALE_FREQ))/1000);
|
|
||||||
|
|
||||||
return usec_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Excerpt from the Etrax100 HSDD about the built-in watchdog:
|
/* Excerpt from the Etrax100 HSDD about the built-in watchdog:
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/smp_lock.h>
|
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/stddef.h>
|
#include <linux/stddef.h>
|
||||||
|
|
||||||
|
@ -217,7 +216,7 @@ static int cryptocop_open(struct inode *, struct file *);
|
||||||
|
|
||||||
static int cryptocop_release(struct inode *, struct file *);
|
static int cryptocop_release(struct inode *, struct file *);
|
||||||
|
|
||||||
static int cryptocop_ioctl(struct inode *inode, struct file *file,
|
static long cryptocop_ioctl(struct file *file,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
|
|
||||||
static void cryptocop_start_job(void);
|
static void cryptocop_start_job(void);
|
||||||
|
@ -279,10 +278,10 @@ static void print_user_dma_lists(struct cryptocop_dma_list_operation *dma_op);
|
||||||
|
|
||||||
|
|
||||||
const struct file_operations cryptocop_fops = {
|
const struct file_operations cryptocop_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = cryptocop_open,
|
.open = cryptocop_open,
|
||||||
.release = cryptocop_release,
|
.release = cryptocop_release,
|
||||||
.ioctl = cryptocop_ioctl
|
.unlocked_ioctl = cryptocop_ioctl
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2307,7 +2306,6 @@ static int cryptocop_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
int p = iminor(inode);
|
int p = iminor(inode);
|
||||||
|
|
||||||
cycle_kernel_lock();
|
|
||||||
if (p != CRYPTOCOP_MINOR) return -EINVAL;
|
if (p != CRYPTOCOP_MINOR) return -EINVAL;
|
||||||
|
|
||||||
filp->private_data = NULL;
|
filp->private_data = NULL;
|
||||||
|
@ -3102,7 +3100,8 @@ static int cryptocop_ioctl_create_session(struct inode *inode, struct file *filp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cryptocop_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
|
static long cryptocop_ioctl_unlocked(struct inode *inode,
|
||||||
|
struct file *filp, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if (_IOC_TYPE(cmd) != ETRAXCRYPTOCOP_IOCTYPE) {
|
if (_IOC_TYPE(cmd) != ETRAXCRYPTOCOP_IOCTYPE) {
|
||||||
|
@ -3134,6 +3133,19 @@ static int cryptocop_ioctl(struct inode *inode, struct file *filp, unsigned int
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
cryptocop_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
struct inode *inode = file->f_path.dentry->d_inode;
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
ret = cryptocop_ioctl_unlocked(inode, filp, cmd, arg);
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef LDEBUG
|
#ifdef LDEBUG
|
||||||
static void print_dma_descriptors(struct cryptocop_int_operation *iop)
|
static void print_dma_descriptors(struct cryptocop_int_operation *iop)
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/smp_lock.h>
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#include <asm/etraxi2c.h>
|
#include <asm/etraxi2c.h>
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@
|
||||||
#define D(x)
|
#define D(x)
|
||||||
|
|
||||||
#define I2C_MAJOR 123 /* LOCAL/EXPERIMENTAL */
|
#define I2C_MAJOR 123 /* LOCAL/EXPERIMENTAL */
|
||||||
|
static DEFINE_MUTEX(i2c_mutex);
|
||||||
static const char i2c_name[] = "i2c";
|
static const char i2c_name[] = "i2c";
|
||||||
|
|
||||||
#define CLOCK_LOW_TIME 8
|
#define CLOCK_LOW_TIME 8
|
||||||
|
@ -636,7 +637,6 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
|
||||||
static int
|
static int
|
||||||
i2c_open(struct inode *inode, struct file *filp)
|
i2c_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
cycle_kernel_lock();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,11 +665,11 @@ i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
I2C_ARGREG(arg),
|
I2C_ARGREG(arg),
|
||||||
I2C_ARGVALUE(arg)));
|
I2C_ARGVALUE(arg)));
|
||||||
|
|
||||||
lock_kernel();
|
mutex_lock(&i2c_mutex);
|
||||||
ret = i2c_writereg(I2C_ARGSLAVE(arg),
|
ret = i2c_writereg(I2C_ARGSLAVE(arg),
|
||||||
I2C_ARGREG(arg),
|
I2C_ARGREG(arg),
|
||||||
I2C_ARGVALUE(arg));
|
I2C_ARGVALUE(arg));
|
||||||
unlock_kernel();
|
mutex_unlock(&i2c_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
case I2C_READREG:
|
case I2C_READREG:
|
||||||
|
@ -679,9 +679,9 @@ i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
D(printk("i2cr %d %d ",
|
D(printk("i2cr %d %d ",
|
||||||
I2C_ARGSLAVE(arg),
|
I2C_ARGSLAVE(arg),
|
||||||
I2C_ARGREG(arg)));
|
I2C_ARGREG(arg)));
|
||||||
lock_kernel();
|
mutex_lock(&i2c_mutex);
|
||||||
val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
|
val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
|
||||||
unlock_kernel();
|
mutex_unlock(&i2c_mutex);
|
||||||
D(printk("= %d\n", val));
|
D(printk("= %d\n", val));
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,8 +72,7 @@ static char gpio_name[] = "etrax gpio";
|
||||||
static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
|
static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
|
||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
#endif
|
#endif
|
||||||
static int gpio_ioctl(struct inode *inode, struct file *file,
|
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||||
unsigned int cmd, unsigned long arg);
|
|
||||||
static ssize_t gpio_write(struct file *file, const char __user *buf,
|
static ssize_t gpio_write(struct file *file, const char __user *buf,
|
||||||
size_t count, loff_t *off);
|
size_t count, loff_t *off);
|
||||||
static int gpio_open(struct inode *inode, struct file *filp);
|
static int gpio_open(struct inode *inode, struct file *filp);
|
||||||
|
@ -521,7 +520,7 @@ static inline unsigned long setget_output(struct gpio_private *priv,
|
||||||
return dir_shadow;
|
return dir_shadow;
|
||||||
} /* setget_output */
|
} /* setget_output */
|
||||||
|
|
||||||
static int gpio_ioctl(struct inode *inode, struct file *file,
|
static long gpio_ioctl_unlocked(struct file *file,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -664,6 +663,17 @@ static int gpio_ioctl(struct inode *inode, struct file *file,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
ret = gpio_ioctl_unlocked(file, cmd, arg);
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
||||||
static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
|
static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
|
||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
|
@ -877,12 +887,12 @@ static int gpio_pwm_ioctl(struct gpio_private *priv, unsigned int cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations gpio_fops = {
|
static const struct file_operations gpio_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.poll = gpio_poll,
|
.poll = gpio_poll,
|
||||||
.ioctl = gpio_ioctl,
|
.unlocked_ioctl = gpio_ioctl,
|
||||||
.write = gpio_write,
|
.write = gpio_write,
|
||||||
.open = gpio_open,
|
.open = gpio_open,
|
||||||
.release = gpio_release,
|
.release = gpio_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
||||||
|
|
|
@ -74,8 +74,7 @@ static wait_queue_head_t *gpio_wq;
|
||||||
static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
|
static int virtual_gpio_ioctl(struct file *file, unsigned int cmd,
|
||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
#endif
|
#endif
|
||||||
static int gpio_ioctl(struct inode *inode, struct file *file,
|
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||||
unsigned int cmd, unsigned long arg);
|
|
||||||
static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
|
static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
|
||||||
loff_t *off);
|
loff_t *off);
|
||||||
static int gpio_open(struct inode *inode, struct file *filp);
|
static int gpio_open(struct inode *inode, struct file *filp);
|
||||||
|
@ -185,7 +184,7 @@ static volatile unsigned long *dir_oe[NUM_PORTS] = {
|
||||||
static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait)
|
static unsigned int gpio_poll(struct file *file, struct poll_table_struct *wait)
|
||||||
{
|
{
|
||||||
unsigned int mask = 0;
|
unsigned int mask = 0;
|
||||||
struct gpio_private *priv = (struct gpio_private *)file->private_data;
|
struct gpio_private *priv = file->private_data;
|
||||||
unsigned long data;
|
unsigned long data;
|
||||||
poll_wait(file, &priv->alarm_wq, wait);
|
poll_wait(file, &priv->alarm_wq, wait);
|
||||||
if (priv->minor == GPIO_MINOR_A) {
|
if (priv->minor == GPIO_MINOR_A) {
|
||||||
|
@ -353,7 +352,7 @@ gpio_pa_interrupt(int irq, void *dev_id)
|
||||||
static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
|
static ssize_t gpio_write(struct file *file, const char *buf, size_t count,
|
||||||
loff_t *off)
|
loff_t *off)
|
||||||
{
|
{
|
||||||
struct gpio_private *priv = (struct gpio_private *)file->private_data;
|
struct gpio_private *priv = file->private_data;
|
||||||
unsigned char data, clk_mask, data_mask, write_msb;
|
unsigned char data, clk_mask, data_mask, write_msb;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long shadow;
|
unsigned long shadow;
|
||||||
|
@ -468,7 +467,7 @@ gpio_release(struct inode *inode, struct file *filp)
|
||||||
|
|
||||||
spin_lock_irq(&alarm_lock);
|
spin_lock_irq(&alarm_lock);
|
||||||
p = alarmlist;
|
p = alarmlist;
|
||||||
todel = (struct gpio_private *)filp->private_data;
|
todel = filp->private_data;
|
||||||
|
|
||||||
if (p == todel) {
|
if (p == todel) {
|
||||||
alarmlist = todel->next;
|
alarmlist = todel->next;
|
||||||
|
@ -557,17 +556,15 @@ inline unsigned long setget_output(struct gpio_private *priv, unsigned long arg)
|
||||||
return dir_shadow;
|
return dir_shadow;
|
||||||
} /* setget_output */
|
} /* setget_output */
|
||||||
|
|
||||||
static int
|
static int gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
|
||||||
gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gpio_ioctl(struct inode *inode, struct file *file,
|
gpio_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
unsigned int cmd, unsigned long arg)
|
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
unsigned long shadow;
|
unsigned long shadow;
|
||||||
struct gpio_private *priv = (struct gpio_private *)file->private_data;
|
struct gpio_private *priv = file->private_data;
|
||||||
if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
|
if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -707,6 +704,17 @@ gpio_ioctl(struct inode *inode, struct file *file,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
ret = gpio_ioctl_unlocked(file, cmd, arg);
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
||||||
static int
|
static int
|
||||||
virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
|
@ -714,7 +722,7 @@ virtual_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned short val;
|
unsigned short val;
|
||||||
unsigned short shadow;
|
unsigned short shadow;
|
||||||
struct gpio_private *priv = (struct gpio_private *)file->private_data;
|
struct gpio_private *priv = file->private_data;
|
||||||
|
|
||||||
switch (_IOC_NR(cmd)) {
|
switch (_IOC_NR(cmd)) {
|
||||||
case IO_SETBITS:
|
case IO_SETBITS:
|
||||||
|
@ -856,12 +864,12 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations gpio_fops = {
|
static const struct file_operations gpio_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.poll = gpio_poll,
|
.poll = gpio_poll,
|
||||||
.ioctl = gpio_ioctl,
|
.unlocked_ioctl = gpio_ioctl,
|
||||||
.write = gpio_write,
|
.write = gpio_write,
|
||||||
.open = gpio_open,
|
.open = gpio_open,
|
||||||
.release = gpio_release,
|
.release = gpio_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
||||||
|
|
|
@ -153,7 +153,7 @@ static int sync_serial_open(struct inode *, struct file*);
|
||||||
static int sync_serial_release(struct inode*, struct file*);
|
static int sync_serial_release(struct inode*, struct file*);
|
||||||
static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
|
static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
|
||||||
|
|
||||||
static int sync_serial_ioctl(struct inode*, struct file*,
|
static int sync_serial_ioctl(struct file *,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
static ssize_t sync_serial_write(struct file * file, const char * buf,
|
static ssize_t sync_serial_write(struct file * file, const char * buf,
|
||||||
size_t count, loff_t *ppos);
|
size_t count, loff_t *ppos);
|
||||||
|
@ -241,13 +241,13 @@ static struct sync_port ports[]=
|
||||||
#define NBR_PORTS ARRAY_SIZE(ports)
|
#define NBR_PORTS ARRAY_SIZE(ports)
|
||||||
|
|
||||||
static const struct file_operations sync_serial_fops = {
|
static const struct file_operations sync_serial_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.write = sync_serial_write,
|
.write = sync_serial_write,
|
||||||
.read = sync_serial_read,
|
.read = sync_serial_read,
|
||||||
.poll = sync_serial_poll,
|
.poll = sync_serial_poll,
|
||||||
.ioctl = sync_serial_ioctl,
|
.unlocked_ioctl = sync_serial_ioctl,
|
||||||
.open = sync_serial_open,
|
.open = sync_serial_open,
|
||||||
.release = sync_serial_release
|
.release = sync_serial_release
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init etrax_sync_serial_init(void)
|
static int __init etrax_sync_serial_init(void)
|
||||||
|
@ -650,7 +650,7 @@ static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sync_serial_ioctl(struct inode *inode, struct file *file,
|
static int sync_serial_ioctl(struct file *file,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
int return_val = 0;
|
int return_val = 0;
|
||||||
|
@ -961,6 +961,18 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file,
|
||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long sync_serial_ioctl(struct file *file,
|
||||||
|
unsigned int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
lock_kernel();
|
||||||
|
ret = sync_serial_ioctl_unlocked(file, cmd, arg);
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* NOTE: sync_serial_write does not support concurrency */
|
/* NOTE: sync_serial_write does not support concurrency */
|
||||||
static ssize_t sync_serial_write(struct file *file, const char *buf,
|
static ssize_t sync_serial_write(struct file *file, const char *buf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
.global cris_flush_cache_range
|
.global cris_flush_cache_range
|
||||||
|
.type cris_flush_cache_range, @function
|
||||||
cris_flush_cache_range:
|
cris_flush_cache_range:
|
||||||
move.d 1024, $r12
|
move.d 1024, $r12
|
||||||
cmp.d $r11, $r12
|
cmp.d $r11, $r12
|
||||||
|
@ -80,8 +81,10 @@ cris_flush_1KB:
|
||||||
addq 32, $r10
|
addq 32, $r10
|
||||||
ba cris_flush_cache_range
|
ba cris_flush_cache_range
|
||||||
sub.d $r12, $r11
|
sub.d $r12, $r11
|
||||||
|
.size cris_flush_cache_range, . - cris_flush_cache_range
|
||||||
|
|
||||||
.global cris_flush_cache
|
.global cris_flush_cache
|
||||||
|
.type cris_flush_cache, @function
|
||||||
cris_flush_cache:
|
cris_flush_cache:
|
||||||
moveq 0, $r10
|
moveq 0, $r10
|
||||||
cris_flush_line:
|
cris_flush_line:
|
||||||
|
@ -92,3 +95,5 @@ cris_flush_line:
|
||||||
fidxd [$r10]
|
fidxd [$r10]
|
||||||
ret
|
ret
|
||||||
nop
|
nop
|
||||||
|
.size cris_flush_cache, . - cris_flush_cache
|
||||||
|
|
||||||
|
|
|
@ -76,12 +76,15 @@ _need_resched:
|
||||||
|
|
||||||
; Called at exit from fork. schedule_tail must be called to drop
|
; Called at exit from fork. schedule_tail must be called to drop
|
||||||
; spinlock if CONFIG_PREEMPT.
|
; spinlock if CONFIG_PREEMPT.
|
||||||
|
.type ret_from_fork,@function
|
||||||
ret_from_fork:
|
ret_from_fork:
|
||||||
jsr schedule_tail
|
jsr schedule_tail
|
||||||
nop
|
nop
|
||||||
ba ret_from_sys_call
|
ba ret_from_sys_call
|
||||||
nop
|
nop
|
||||||
|
.size ret_from_fork, . - ret_from_fork
|
||||||
|
|
||||||
|
.type ret_from_intr,@function
|
||||||
ret_from_intr:
|
ret_from_intr:
|
||||||
;; Check for resched if preemptive kernel, or if we're going back to
|
;; Check for resched if preemptive kernel, or if we're going back to
|
||||||
;; user-mode. This test matches the user_regs(regs) macro. Don't simply
|
;; user-mode. This test matches the user_regs(regs) macro. Don't simply
|
||||||
|
@ -91,9 +94,10 @@ ret_from_intr:
|
||||||
move.d [$acr], $r0
|
move.d [$acr], $r0
|
||||||
btstq 16, $r0 ; User-mode flag.
|
btstq 16, $r0 ; User-mode flag.
|
||||||
bpl _resume_kernel
|
bpl _resume_kernel
|
||||||
|
.size ret_from_intr, . - ret_from_intr + 2 ; +2 includes the dslot.
|
||||||
|
|
||||||
; Note that di below is in delay slot.
|
; Note that di below is in delay slot.
|
||||||
|
.type _resume_userspace,@function
|
||||||
_resume_userspace:
|
_resume_userspace:
|
||||||
di ; So need_resched and sigpending don't change.
|
di ; So need_resched and sigpending don't change.
|
||||||
|
|
||||||
|
@ -107,6 +111,7 @@ _resume_userspace:
|
||||||
nop
|
nop
|
||||||
ba _Rexit
|
ba _Rexit
|
||||||
nop
|
nop
|
||||||
|
.size _resume_userspace, . - _resume_userspace
|
||||||
|
|
||||||
;; The system_call is called by a BREAK instruction, which looks pretty
|
;; The system_call is called by a BREAK instruction, which looks pretty
|
||||||
;; much like any other exception.
|
;; much like any other exception.
|
||||||
|
@ -122,30 +127,28 @@ _resume_userspace:
|
||||||
;; non-used instructions. Only the non-common cases cause the outlined code
|
;; non-used instructions. Only the non-common cases cause the outlined code
|
||||||
;; to run..
|
;; to run..
|
||||||
|
|
||||||
|
.type system_call,@function
|
||||||
system_call:
|
system_call:
|
||||||
;; Stack-frame similar to the irq heads, which is reversed in
|
;; Stack-frame similar to the irq heads, which is reversed in
|
||||||
;; ret_from_sys_call.
|
;; ret_from_sys_call.
|
||||||
subq 12, $sp ; Skip EXS, EDA.
|
|
||||||
move $erp, [$sp]
|
|
||||||
subq 4, $sp
|
|
||||||
move $srp, [$sp]
|
|
||||||
subq 4, $sp
|
|
||||||
move $ccs, [$sp]
|
|
||||||
subq 4, $sp
|
|
||||||
ei ; Allow IRQs while handling system call
|
|
||||||
move $spc, [$sp]
|
|
||||||
subq 4, $sp
|
|
||||||
move $mof, [$sp]
|
|
||||||
subq 4, $sp
|
|
||||||
move $srs, [$sp]
|
|
||||||
subq 4, $sp
|
|
||||||
move.d $acr, [$sp]
|
|
||||||
subq 14*4, $sp ; Make room for R0-R13.
|
|
||||||
movem $r13, [$sp] ; Push R0-R13
|
|
||||||
subq 4, $sp
|
|
||||||
move.d $r10, [$sp] ; Push orig_r10.
|
|
||||||
|
|
||||||
; Set S-bit when kernel debugging to keep hardware breakpoints active.
|
sub.d 92, $sp ; Skip EXS and EDA.
|
||||||
|
movem $r13, [$sp]
|
||||||
|
move.d $sp, $r8
|
||||||
|
addq 14*4, $r8
|
||||||
|
move.d $acr, $r0
|
||||||
|
move $srs, $r1
|
||||||
|
move $mof, $r2
|
||||||
|
move $spc, $r3
|
||||||
|
move $ccs, $r4
|
||||||
|
move $srp, $r5
|
||||||
|
move $erp, $r6
|
||||||
|
subq 4, $sp
|
||||||
|
movem $r6, [$r8]
|
||||||
|
ei ; Enable interrupts while processing syscalls.
|
||||||
|
move.d $r10, [$sp]
|
||||||
|
|
||||||
|
; Set S-bit when kernel debugging to keep hardware breakpoints active.
|
||||||
#ifdef CONFIG_ETRAX_KGDB
|
#ifdef CONFIG_ETRAX_KGDB
|
||||||
move $ccs, $r0
|
move $ccs, $r0
|
||||||
or.d (1<<9), $r0
|
or.d (1<<9), $r0
|
||||||
|
@ -217,7 +220,9 @@ ret_from_sys_call:
|
||||||
and.d _TIF_ALLWORK_MASK, $r1
|
and.d _TIF_ALLWORK_MASK, $r1
|
||||||
bne _syscall_exit_work
|
bne _syscall_exit_work
|
||||||
nop
|
nop
|
||||||
|
.size system_call, . - system_call
|
||||||
|
|
||||||
|
.type _Rexit,@function
|
||||||
_Rexit:
|
_Rexit:
|
||||||
;; This epilogue MUST match the prologues in multiple_interrupt, irq.h
|
;; This epilogue MUST match the prologues in multiple_interrupt, irq.h
|
||||||
;; and ptregs.h.
|
;; and ptregs.h.
|
||||||
|
@ -234,10 +239,12 @@ _Rexit:
|
||||||
addq 8, $sp ; Skip EXS, EDA.
|
addq 8, $sp ; Skip EXS, EDA.
|
||||||
jump $erp
|
jump $erp
|
||||||
rfe ; Restore condition code stack in delay-slot.
|
rfe ; Restore condition code stack in delay-slot.
|
||||||
|
.size _Rexit, . - _Rexit
|
||||||
|
|
||||||
;; We get here after doing a syscall if extra work might need to be done
|
;; We get here after doing a syscall if extra work might need to be done
|
||||||
;; perform syscall exit tracing if needed.
|
;; perform syscall exit tracing if needed.
|
||||||
|
|
||||||
|
.type _syscall_exit_work,@function
|
||||||
_syscall_exit_work:
|
_syscall_exit_work:
|
||||||
;; R0 contains current at this point and irq's are disabled.
|
;; R0 contains current at this point and irq's are disabled.
|
||||||
|
|
||||||
|
@ -253,14 +260,18 @@ _syscall_exit_work:
|
||||||
move.d $r1, $r9
|
move.d $r1, $r9
|
||||||
ba _resume_userspace
|
ba _resume_userspace
|
||||||
nop
|
nop
|
||||||
|
.size _syscall_exit_work, . - _syscall_exit_work
|
||||||
|
|
||||||
|
.type _work_pending,@function
|
||||||
_work_pending:
|
_work_pending:
|
||||||
addoq +TI_flags, $r0, $acr
|
addoq +TI_flags, $r0, $acr
|
||||||
move.d [$acr], $r10
|
move.d [$acr], $r10
|
||||||
btstq TIF_NEED_RESCHED, $r10 ; Need resched?
|
btstq TIF_NEED_RESCHED, $r10 ; Need resched?
|
||||||
bpl _work_notifysig ; No, must be signal/notify.
|
bpl _work_notifysig ; No, must be signal/notify.
|
||||||
nop
|
nop
|
||||||
|
.size _work_pending, . - _work_pending
|
||||||
|
|
||||||
|
.type _work_resched,@function
|
||||||
_work_resched:
|
_work_resched:
|
||||||
move.d $r9, $r1 ; Preserve R9.
|
move.d $r9, $r1 ; Preserve R9.
|
||||||
jsr schedule
|
jsr schedule
|
||||||
|
@ -276,7 +287,9 @@ _work_resched:
|
||||||
btstq TIF_NEED_RESCHED, $r1
|
btstq TIF_NEED_RESCHED, $r1
|
||||||
bmi _work_resched ; current->work.need_resched.
|
bmi _work_resched ; current->work.need_resched.
|
||||||
nop
|
nop
|
||||||
|
.size _work_resched, . - _work_resched
|
||||||
|
|
||||||
|
.type _work_notifysig,@function
|
||||||
_work_notifysig:
|
_work_notifysig:
|
||||||
;; Deal with pending signals and notify-resume requests.
|
;; Deal with pending signals and notify-resume requests.
|
||||||
|
|
||||||
|
@ -288,6 +301,7 @@ _work_notifysig:
|
||||||
|
|
||||||
ba _Rexit
|
ba _Rexit
|
||||||
nop
|
nop
|
||||||
|
.size _work_notifysig, . - _work_notifysig
|
||||||
|
|
||||||
;; We get here as a sidetrack when we've entered a syscall with the
|
;; We get here as a sidetrack when we've entered a syscall with the
|
||||||
;; trace-bit set. We need to call do_syscall_trace and then continue
|
;; trace-bit set. We need to call do_syscall_trace and then continue
|
||||||
|
@ -329,41 +343,43 @@ _syscall_trace_entry:
|
||||||
;;
|
;;
|
||||||
;; Returns old current in R10.
|
;; Returns old current in R10.
|
||||||
|
|
||||||
|
.type resume,@function
|
||||||
resume:
|
resume:
|
||||||
subq 4, $sp
|
subq 4, $sp ; Make space for srp.
|
||||||
move $srp, [$sp] ; Keep old/new PC on the stack.
|
|
||||||
add.d $r12, $r10 ; R10 = current tasks tss.
|
add.d $r12, $r10 ; R10 = current tasks tss.
|
||||||
addoq +THREAD_ccs, $r10, $acr
|
addoq +THREAD_ccs, $r10, $acr
|
||||||
|
move $srp, [$sp] ; Keep old/new PC on the stack.
|
||||||
move $ccs, [$acr] ; Save IRQ enable state.
|
move $ccs, [$acr] ; Save IRQ enable state.
|
||||||
di
|
di
|
||||||
|
|
||||||
addoq +THREAD_usp, $r10, $acr
|
addoq +THREAD_usp, $r10, $acr
|
||||||
|
subq 10*4, $sp ; Make room for R9.
|
||||||
move $usp, [$acr] ; Save user-mode stackpointer.
|
move $usp, [$acr] ; Save user-mode stackpointer.
|
||||||
|
|
||||||
;; See copy_thread for the reason why register R9 is saved.
|
;; See copy_thread for the reason why register R9 is saved.
|
||||||
subq 10*4, $sp
|
|
||||||
movem $r9, [$sp] ; Save non-scratch registers and R9.
|
movem $r9, [$sp] ; Save non-scratch registers and R9.
|
||||||
|
|
||||||
addoq +THREAD_ksp, $r10, $acr
|
addoq +THREAD_ksp, $r10, $acr
|
||||||
|
move.d $sp, $r10 ; Return last running task in R10.
|
||||||
move.d $sp, [$acr] ; Save kernel SP for old task.
|
move.d $sp, [$acr] ; Save kernel SP for old task.
|
||||||
|
|
||||||
move.d $sp, $r10 ; Return last running task in R10.
|
|
||||||
and.d -8192, $r10 ; Get thread_info from stackpointer.
|
and.d -8192, $r10 ; Get thread_info from stackpointer.
|
||||||
addoq +TI_task, $r10, $acr
|
addoq +TI_task, $r10, $acr
|
||||||
move.d [$acr], $r10 ; Get task.
|
|
||||||
add.d $r12, $r11 ; Find the new tasks tss.
|
add.d $r12, $r11 ; Find the new tasks tss.
|
||||||
|
move.d [$acr], $r10 ; Get task.
|
||||||
addoq +THREAD_ksp, $r11, $acr
|
addoq +THREAD_ksp, $r11, $acr
|
||||||
move.d [$acr], $sp ; Switch to new stackframe.
|
move.d [$acr], $sp ; Switch to new stackframe.
|
||||||
|
addoq +THREAD_usp, $r11, $acr
|
||||||
movem [$sp+], $r9 ; Restore non-scratch registers and R9.
|
movem [$sp+], $r9 ; Restore non-scratch registers and R9.
|
||||||
|
|
||||||
addoq +THREAD_usp, $r11, $acr
|
|
||||||
move [$acr], $usp ; Restore user-mode stackpointer.
|
move [$acr], $usp ; Restore user-mode stackpointer.
|
||||||
|
|
||||||
addoq +THREAD_ccs, $r11, $acr
|
addoq +THREAD_ccs, $r11, $acr
|
||||||
|
move.d [$sp+], $r11
|
||||||
|
jump $r11 ; Restore PC.
|
||||||
move [$acr], $ccs ; Restore IRQ enable status.
|
move [$acr], $ccs ; Restore IRQ enable status.
|
||||||
move.d [$sp+], $acr
|
.size resume, . - resume
|
||||||
jump $acr ; Restore PC.
|
|
||||||
nop
|
|
||||||
|
|
||||||
nmi_interrupt:
|
nmi_interrupt:
|
||||||
|
|
||||||
|
@ -426,6 +442,7 @@ spurious_interrupt:
|
||||||
;; time. Jump to the first set interrupt bit in a priotiry fashion. The
|
;; time. Jump to the first set interrupt bit in a priotiry fashion. The
|
||||||
;; hardware will call the unserved interrupts after the handler
|
;; hardware will call the unserved interrupts after the handler
|
||||||
;; finishes.
|
;; finishes.
|
||||||
|
.type multiple_interrupt, @function
|
||||||
multiple_interrupt:
|
multiple_interrupt:
|
||||||
;; This prologue MUST match the one in irq.h and the struct in ptregs.h!
|
;; This prologue MUST match the one in irq.h and the struct in ptregs.h!
|
||||||
subq 12, $sp ; Skip EXS, EDA.
|
subq 12, $sp ; Skip EXS, EDA.
|
||||||
|
@ -458,6 +475,7 @@ multiple_interrupt:
|
||||||
move.d $sp, $r10
|
move.d $sp, $r10
|
||||||
jump ret_from_intr
|
jump ret_from_intr
|
||||||
nop
|
nop
|
||||||
|
.size multiple_interrupt, . - multiple_interrupt
|
||||||
|
|
||||||
do_sigtrap:
|
do_sigtrap:
|
||||||
;; Sigtraps the process that executed the BREAK instruction. Creates a
|
;; Sigtraps the process that executed the BREAK instruction. Creates a
|
||||||
|
@ -514,11 +532,13 @@ _ugdb_handle_exception:
|
||||||
move.d [$sp+], $r0 ; Restore R0 in delay slot.
|
move.d [$sp+], $r0 ; Restore R0 in delay slot.
|
||||||
|
|
||||||
.global kernel_execve
|
.global kernel_execve
|
||||||
|
.type kernel_execve,@function
|
||||||
kernel_execve:
|
kernel_execve:
|
||||||
move.d __NR_execve, $r9
|
move.d __NR_execve, $r9
|
||||||
break 13
|
break 13
|
||||||
ret
|
ret
|
||||||
nop
|
nop
|
||||||
|
.size kernel_execve, . - kernel_execve
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,13 @@ secondary_cpu_entry: /* Entry point for secondary CPUs */
|
||||||
;;
|
;;
|
||||||
;; Note; 3 cycles is needed for a bank-select to take effect. Further;
|
;; Note; 3 cycles is needed for a bank-select to take effect. Further;
|
||||||
;; bank 1 is the instruction MMU, bank 2 is the data MMU.
|
;; bank 1 is the instruction MMU, bank 2 is the data MMU.
|
||||||
#ifndef CONFIG_ETRAX_VCS_SIM
|
|
||||||
|
#ifdef CONFIG_CRIS_MACH_ARTPEC3
|
||||||
|
move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
|
||||||
|
| REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
|
||||||
|
| REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 5) \
|
||||||
|
| REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
|
||||||
|
#elif !defined(CONFIG_ETRAX_VCS_SIM)
|
||||||
move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
|
move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
|
||||||
| REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
|
| REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
|
||||||
| REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
|
| REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
|
||||||
|
@ -88,7 +94,39 @@ secondary_cpu_entry: /* Entry point for secondary CPUs */
|
||||||
|
|
||||||
;; Enable certain page protections and setup linear mapping
|
;; Enable certain page protections and setup linear mapping
|
||||||
;; for f,e,c,b,4,0.
|
;; for f,e,c,b,4,0.
|
||||||
#ifndef CONFIG_ETRAX_VCS_SIM
|
|
||||||
|
;; ARTPEC-3:
|
||||||
|
;; c,d used for linear kernel mapping, up to 512 MB
|
||||||
|
;; e used for vmalloc
|
||||||
|
;; f unused, but page mapped to get page faults
|
||||||
|
|
||||||
|
;; ETRAX FS:
|
||||||
|
;; c used for linear kernel mapping, up to 256 MB
|
||||||
|
;; d used for vmalloc
|
||||||
|
;; e,f used for memory-mapped NOR flash
|
||||||
|
|
||||||
|
#ifdef CONFIG_CRIS_MACH_ARTPEC3
|
||||||
|
move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, acc, on) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, ex, on) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, inv, on) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_f, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_e, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_d, linear) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_c, linear) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_b, linear) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_a, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_9, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_8, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_7, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_6, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_5, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_4, linear) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_3, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_2, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_1, page) \
|
||||||
|
| REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
|
||||||
|
#elif !defined(CONFIG_ETRAX_VCS_SIM)
|
||||||
move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
|
move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
|
||||||
| REG_STATE(mmu, rw_mm_cfg, acc, on) \
|
| REG_STATE(mmu, rw_mm_cfg, acc, on) \
|
||||||
| REG_STATE(mmu, rw_mm_cfg, ex, on) \
|
| REG_STATE(mmu, rw_mm_cfg, ex, on) \
|
||||||
|
@ -329,7 +367,7 @@ _no_romfs_in_flash:
|
||||||
;; For jffs2, a jhead is prepended which contains with magic and length.
|
;; For jffs2, a jhead is prepended which contains with magic and length.
|
||||||
;; The jhead is not part of the jffs2 partition however.
|
;; The jhead is not part of the jffs2 partition however.
|
||||||
#ifndef CONFIG_ETRAXFS_SIM
|
#ifndef CONFIG_ETRAXFS_SIM
|
||||||
move.d __vmlinux_end, $r0
|
move.d __bss_start, $r0
|
||||||
#else
|
#else
|
||||||
move.d __end, $r0
|
move.d __end, $r0
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -97,7 +97,11 @@ extern void breakh_BUG(void);
|
||||||
/*
|
/*
|
||||||
* Build the IRQ handler stubs using macros from irq.h.
|
* Build the IRQ handler stubs using macros from irq.h.
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONFIG_CRIS_MACH_ARTPEC3
|
||||||
|
BUILD_TIMER_IRQ(0x31, 0)
|
||||||
|
#else
|
||||||
BUILD_IRQ(0x31)
|
BUILD_IRQ(0x31)
|
||||||
|
#endif
|
||||||
BUILD_IRQ(0x32)
|
BUILD_IRQ(0x32)
|
||||||
BUILD_IRQ(0x33)
|
BUILD_IRQ(0x33)
|
||||||
BUILD_IRQ(0x34)
|
BUILD_IRQ(0x34)
|
||||||
|
@ -123,7 +127,11 @@ BUILD_IRQ(0x47)
|
||||||
BUILD_IRQ(0x48)
|
BUILD_IRQ(0x48)
|
||||||
BUILD_IRQ(0x49)
|
BUILD_IRQ(0x49)
|
||||||
BUILD_IRQ(0x4a)
|
BUILD_IRQ(0x4a)
|
||||||
|
#ifdef CONFIG_ETRAXFS
|
||||||
|
BUILD_TIMER_IRQ(0x4b, 0)
|
||||||
|
#else
|
||||||
BUILD_IRQ(0x4b)
|
BUILD_IRQ(0x4b)
|
||||||
|
#endif
|
||||||
BUILD_IRQ(0x4c)
|
BUILD_IRQ(0x4c)
|
||||||
BUILD_IRQ(0x4d)
|
BUILD_IRQ(0x4d)
|
||||||
BUILD_IRQ(0x4e)
|
BUILD_IRQ(0x4e)
|
||||||
|
@ -199,25 +207,20 @@ block_irq(int irq, int cpu)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&irq_lock, flags);
|
spin_lock_irqsave(&irq_lock, flags);
|
||||||
if (irq - FIRST_IRQ < 32)
|
/* Remember, 1 let thru, 0 block. */
|
||||||
|
if (irq - FIRST_IRQ < 32) {
|
||||||
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
|
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
|
||||||
rw_mask, 0);
|
rw_mask, 0);
|
||||||
else
|
|
||||||
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
|
|
||||||
rw_mask, 1);
|
|
||||||
|
|
||||||
/* Remember; 1 let thru, 0 block. */
|
|
||||||
if (irq - FIRST_IRQ < 32)
|
|
||||||
intr_mask &= ~(1 << (irq - FIRST_IRQ));
|
intr_mask &= ~(1 << (irq - FIRST_IRQ));
|
||||||
else
|
|
||||||
intr_mask &= ~(1 << (irq - FIRST_IRQ - 32));
|
|
||||||
|
|
||||||
if (irq - FIRST_IRQ < 32)
|
|
||||||
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
|
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
|
||||||
0, intr_mask);
|
0, intr_mask);
|
||||||
else
|
} else {
|
||||||
|
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
|
||||||
|
rw_mask, 1);
|
||||||
|
intr_mask &= ~(1 << (irq - FIRST_IRQ - 32));
|
||||||
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
|
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
|
||||||
1, intr_mask);
|
1, intr_mask);
|
||||||
|
}
|
||||||
spin_unlock_irqrestore(&irq_lock, flags);
|
spin_unlock_irqrestore(&irq_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,26 +231,20 @@ unblock_irq(int irq, int cpu)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&irq_lock, flags);
|
spin_lock_irqsave(&irq_lock, flags);
|
||||||
if (irq - FIRST_IRQ < 32)
|
/* Remember, 1 let thru, 0 block. */
|
||||||
|
if (irq - FIRST_IRQ < 32) {
|
||||||
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
|
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
|
||||||
rw_mask, 0);
|
rw_mask, 0);
|
||||||
else
|
|
||||||
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
|
|
||||||
rw_mask, 1);
|
|
||||||
|
|
||||||
/* Remember; 1 let thru, 0 block. */
|
|
||||||
if (irq - FIRST_IRQ < 32)
|
|
||||||
intr_mask |= (1 << (irq - FIRST_IRQ));
|
intr_mask |= (1 << (irq - FIRST_IRQ));
|
||||||
else
|
|
||||||
intr_mask |= (1 << (irq - FIRST_IRQ - 32));
|
|
||||||
|
|
||||||
if (irq - FIRST_IRQ < 32)
|
|
||||||
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
|
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
|
||||||
0, intr_mask);
|
0, intr_mask);
|
||||||
else
|
} else {
|
||||||
|
intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu],
|
||||||
|
rw_mask, 1);
|
||||||
|
intr_mask |= (1 << (irq - FIRST_IRQ - 32));
|
||||||
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
|
REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask,
|
||||||
1, intr_mask);
|
1, intr_mask);
|
||||||
|
}
|
||||||
spin_unlock_irqrestore(&irq_lock, flags);
|
spin_unlock_irqrestore(&irq_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,10 +174,10 @@
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
|
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <arch/hwregs/reg_map.h>
|
#include <hwregs/reg_map.h>
|
||||||
#include <arch/hwregs/reg_rdwr.h>
|
#include <hwregs/reg_rdwr.h>
|
||||||
#include <arch/hwregs/intr_vect_defs.h>
|
#include <hwregs/intr_vect_defs.h>
|
||||||
#include <arch/hwregs/ser_defs.h>
|
#include <hwregs/ser_defs.h>
|
||||||
|
|
||||||
/* From entry.S. */
|
/* From entry.S. */
|
||||||
extern void gdb_handle_exception(void);
|
extern void gdb_handle_exception(void);
|
||||||
|
@ -988,26 +988,26 @@ stub_is_stopped(int sigval)
|
||||||
}
|
}
|
||||||
/* Only send PC, frame and stack pointer. */
|
/* Only send PC, frame and stack pointer. */
|
||||||
read_register(PC, ®_cont);
|
read_register(PC, ®_cont);
|
||||||
ptr = pack_hex_byte(PC);
|
ptr = pack_hex_byte(ptr, PC);
|
||||||
*ptr++ = ':';
|
*ptr++ = ':';
|
||||||
ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[PC]);
|
ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[PC]);
|
||||||
*ptr++ = ';';
|
*ptr++ = ';';
|
||||||
|
|
||||||
read_register(R8, ®_cont);
|
read_register(R8, ®_cont);
|
||||||
ptr = pack_hex_byte(R8);
|
ptr = pack_hex_byte(ptr, R8);
|
||||||
*ptr++ = ':';
|
*ptr++ = ':';
|
||||||
ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[R8]);
|
ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[R8]);
|
||||||
*ptr++ = ';';
|
*ptr++ = ';';
|
||||||
|
|
||||||
read_register(SP, ®_cont);
|
read_register(SP, ®_cont);
|
||||||
ptr = pack_hex_byte(SP);
|
ptr = pack_hex_byte(ptr, SP);
|
||||||
*ptr++ = ':';
|
*ptr++ = ':';
|
||||||
ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[SP]);
|
ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[SP]);
|
||||||
*ptr++ = ';';
|
*ptr++ = ';';
|
||||||
|
|
||||||
/* Send ERP as well; this will save us an entire register fetch in some cases. */
|
/* Send ERP as well; this will save us an entire register fetch in some cases. */
|
||||||
read_register(ERP, ®_cont);
|
read_register(ERP, ®_cont);
|
||||||
ptr = pack_hex_byte(ERP);
|
ptr = pack_hex_byte(ptr, ERP);
|
||||||
*ptr++ = ':';
|
*ptr++ = ':';
|
||||||
ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[ERP]);
|
ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[ERP]);
|
||||||
*ptr++ = ';';
|
*ptr++ = ';';
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* port exceptions for kernel debugging purposes.
|
* port exceptions for kernel debugging purposes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <arch/hwregs/intr_vect.h>
|
#include <hwregs/intr_vect.h>
|
||||||
|
|
||||||
;; Exported functions.
|
;; Exported functions.
|
||||||
.globl kgdb_handle_exception
|
.globl kgdb_handle_exception
|
||||||
|
|
|
@ -1,229 +0,0 @@
|
||||||
/*
|
|
||||||
* Allocator for I/O pins. All pins are allocated to GPIO at bootup.
|
|
||||||
* Unassigned pins and GPIO pins can be allocated to a fixed interface
|
|
||||||
* or the I/O processor instead.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2004 Axis Communications AB.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <arch/hwregs/reg_map.h>
|
|
||||||
#include <arch/hwregs/reg_rdwr.h>
|
|
||||||
#include <arch/pinmux.h>
|
|
||||||
#include <arch/hwregs/pinmux_defs.h>
|
|
||||||
|
|
||||||
#undef DEBUG
|
|
||||||
|
|
||||||
#define PORT_PINS 18
|
|
||||||
#define PORTS 4
|
|
||||||
|
|
||||||
static char pins[PORTS][PORT_PINS];
|
|
||||||
static DEFINE_SPINLOCK(pinmux_lock);
|
|
||||||
|
|
||||||
static void crisv32_pinmux_set(int port);
|
|
||||||
|
|
||||||
int
|
|
||||||
crisv32_pinmux_init(void)
|
|
||||||
{
|
|
||||||
static int initialized = 0;
|
|
||||||
|
|
||||||
if (!initialized) {
|
|
||||||
reg_pinmux_rw_pa pa = REG_RD(pinmux, regi_pinmux, rw_pa);
|
|
||||||
initialized = 1;
|
|
||||||
pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 =
|
|
||||||
pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes;
|
|
||||||
REG_WR(pinmux, regi_pinmux, rw_pa, pa);
|
|
||||||
crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio);
|
|
||||||
crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio);
|
|
||||||
crisv32_pinmux_alloc(PORT_D, 0, PORT_PINS - 1, pinmux_gpio);
|
|
||||||
crisv32_pinmux_alloc(PORT_E, 0, PORT_PINS - 1, pinmux_gpio);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
crisv32_pinmux_init();
|
|
||||||
|
|
||||||
if (port > PORTS || port < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&pinmux_lock, flags);
|
|
||||||
|
|
||||||
for (i = first_pin; i <= last_pin; i++)
|
|
||||||
{
|
|
||||||
if ((pins[port][i] != pinmux_none) && (pins[port][i] != pinmux_gpio) &&
|
|
||||||
(pins[port][i] != mode))
|
|
||||||
{
|
|
||||||
spin_unlock_irqrestore(&pinmux_lock, flags);
|
|
||||||
#ifdef DEBUG
|
|
||||||
panic("Pinmux alloc failed!\n");
|
|
||||||
#endif
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = first_pin; i <= last_pin; i++)
|
|
||||||
pins[port][i] = mode;
|
|
||||||
|
|
||||||
crisv32_pinmux_set(port);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pinmux_lock, flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
crisv32_pinmux_alloc_fixed(enum fixed_function function)
|
|
||||||
{
|
|
||||||
int ret = -EINVAL;
|
|
||||||
char saved[sizeof pins];
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&pinmux_lock, flags);
|
|
||||||
|
|
||||||
/* Save internal data for recovery */
|
|
||||||
memcpy(saved, pins, sizeof pins);
|
|
||||||
|
|
||||||
reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
|
|
||||||
|
|
||||||
switch(function)
|
|
||||||
{
|
|
||||||
case pinmux_ser1:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
|
|
||||||
hwprot.ser1 = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_ser2:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
|
|
||||||
hwprot.ser2 = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_ser3:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
|
|
||||||
hwprot.ser3 = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_sser0:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed);
|
|
||||||
ret |= crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
|
|
||||||
hwprot.sser0 = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_sser1:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
|
|
||||||
hwprot.sser1 = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_ata0:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed);
|
|
||||||
ret |= crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed);
|
|
||||||
hwprot.ata0 = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_ata1:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
|
|
||||||
ret |= crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed);
|
|
||||||
hwprot.ata1 = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_ata2:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed);
|
|
||||||
ret |= crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed);
|
|
||||||
hwprot.ata2 = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_ata3:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed);
|
|
||||||
ret |= crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed);
|
|
||||||
hwprot.ata2 = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_ata:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed);
|
|
||||||
ret |= crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed);
|
|
||||||
hwprot.ata = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_eth1:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
|
|
||||||
hwprot.eth1 = regk_pinmux_yes;
|
|
||||||
hwprot.eth1_mgm = regk_pinmux_yes;
|
|
||||||
break;
|
|
||||||
case pinmux_timer:
|
|
||||||
ret = crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
|
|
||||||
hwprot.timer = regk_pinmux_yes;
|
|
||||||
spin_unlock_irqrestore(&pinmux_lock, flags);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
|
|
||||||
else
|
|
||||||
memcpy(pins, saved, sizeof pins);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pinmux_lock, flags);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
crisv32_pinmux_set(int port)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int gpio_val = 0;
|
|
||||||
int iop_val = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < PORT_PINS; i++)
|
|
||||||
{
|
|
||||||
if (pins[port][i] == pinmux_gpio)
|
|
||||||
gpio_val |= (1 << i);
|
|
||||||
else if (pins[port][i] == pinmux_iop)
|
|
||||||
iop_val |= (1 << i);
|
|
||||||
}
|
|
||||||
|
|
||||||
REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_gio + 8*port, gpio_val);
|
|
||||||
REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_iop + 8*port, iop_val);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
crisv32_pinmux_dump();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
crisv32_pinmux_init();
|
|
||||||
|
|
||||||
if (port > PORTS || port < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&pinmux_lock, flags);
|
|
||||||
|
|
||||||
for (i = first_pin; i <= last_pin; i++)
|
|
||||||
pins[port][i] = pinmux_none;
|
|
||||||
|
|
||||||
crisv32_pinmux_set(port);
|
|
||||||
spin_unlock_irqrestore(&pinmux_lock, flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
crisv32_pinmux_dump(void)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
crisv32_pinmux_init();
|
|
||||||
|
|
||||||
for (i = 0; i < PORTS; i++)
|
|
||||||
{
|
|
||||||
printk("Port %c\n", 'B'+i);
|
|
||||||
for (j = 0; j < PORT_PINS; j++)
|
|
||||||
printk(" Pin %d = %d\n", j, pins[i][j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__initcall(crisv32_pinmux_init);
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/param.h>
|
#include <linux/param.h>
|
||||||
|
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
|
|
||||||
#define HAS_FPU 0x0001
|
#define HAS_FPU 0x0001
|
||||||
|
@ -43,14 +46,15 @@ static struct cpu_info cpinfo[] = {
|
||||||
|
|
||||||
{"ETRAX 100LX v2", 11, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
|
{"ETRAX 100LX v2", 11, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
|
||||||
| HAS_MMU},
|
| HAS_MMU},
|
||||||
|
#ifdef CONFIG_ETRAXFS
|
||||||
{"ETRAX FS", 32, 32, HAS_ETHERNET100 | HAS_ATA | HAS_MMU},
|
{"ETRAX FS", 32, 32, HAS_ETHERNET100 | HAS_ATA | HAS_MMU},
|
||||||
|
#else
|
||||||
|
{"ARTPEC-3", 32, 32, HAS_ETHERNET100 | HAS_MMU},
|
||||||
|
#endif
|
||||||
{"Unknown", 0, 0, 0}
|
{"Unknown", 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int show_cpuinfo(struct seq_file *m, void *v)
|
||||||
show_cpuinfo(struct seq_file *m, void *v)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int cpu = (int)v - 1;
|
int cpu = (int)v - 1;
|
||||||
|
@ -107,9 +111,63 @@ show_cpuinfo(struct seq_file *m, void *v)
|
||||||
|
|
||||||
#endif /* CONFIG_PROC_FS */
|
#endif /* CONFIG_PROC_FS */
|
||||||
|
|
||||||
void
|
void show_etrax_copyright(void)
|
||||||
show_etrax_copyright(void)
|
|
||||||
{
|
{
|
||||||
printk(KERN_INFO
|
#ifdef CONFIG_ETRAXFS
|
||||||
"Linux/CRISv32 port on ETRAX FS (C) 2003, 2004 Axis Communications AB\n");
|
printk(KERN_INFO "Linux/CRISv32 port on ETRAX FS "
|
||||||
|
"(C) 2003, 2004 Axis Communications AB\n");
|
||||||
|
#else
|
||||||
|
printk(KERN_INFO "Linux/CRISv32 port on ARTPEC-3 "
|
||||||
|
"(C) 2003-2009 Axis Communications AB\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct i2c_board_info __initdata i2c_info[] = {
|
||||||
|
{I2C_BOARD_INFO("camblock", 0x43)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x48)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x4A)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x4C)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x4D)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x4E)},
|
||||||
|
#ifdef CONFIG_RTC_DRV_PCF8563
|
||||||
|
{I2C_BOARD_INFO("pcf8563", 0x51)},
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
||||||
|
{I2C_BOARD_INFO("vgpio", 0x20)},
|
||||||
|
{I2C_BOARD_INFO("vgpio", 0x21)},
|
||||||
|
#endif
|
||||||
|
{I2C_BOARD_INFO("pca9536", 0x41)},
|
||||||
|
{I2C_BOARD_INFO("fnp300", 0x40)},
|
||||||
|
{I2C_BOARD_INFO("fnp300", 0x42)},
|
||||||
|
{I2C_BOARD_INFO("adc101", 0x54)},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_board_info __initdata i2c_info2[] = {
|
||||||
|
{I2C_BOARD_INFO("camblock", 0x43)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x48)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x4A)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x4C)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x4D)},
|
||||||
|
{I2C_BOARD_INFO("tmp100", 0x4E)},
|
||||||
|
#ifdef CONFIG_ETRAX_VIRTUAL_GPIO
|
||||||
|
{I2C_BOARD_INFO("vgpio", 0x20)},
|
||||||
|
{I2C_BOARD_INFO("vgpio", 0x21)},
|
||||||
|
#endif
|
||||||
|
{I2C_BOARD_INFO("pca9536", 0x41)},
|
||||||
|
{I2C_BOARD_INFO("fnp300", 0x40)},
|
||||||
|
{I2C_BOARD_INFO("fnp300", 0x42)},
|
||||||
|
{I2C_BOARD_INFO("adc101", 0x54)},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_board_info __initdata i2c_info3[] = {
|
||||||
|
{I2C_BOARD_INFO("adc101", 0x54)},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init etrax_init(void)
|
||||||
|
{
|
||||||
|
i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
|
||||||
|
i2c_register_board_info(1, i2c_info2, ARRAY_SIZE(i2c_info2));
|
||||||
|
i2c_register_board_info(2, i2c_info3, ARRAY_SIZE(i2c_info3));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
arch_initcall(etrax_init);
|
||||||
|
|
|
@ -587,7 +587,7 @@ do_signal(int canrestart, struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regs->r10 == -ERESTART_RESTARTBLOCK){
|
if (regs->r10 == -ERESTART_RESTARTBLOCK){
|
||||||
regs->r10 = __NR_restart_syscall;
|
regs->r9 = __NR_restart_syscall;
|
||||||
regs->erp -= 2;
|
regs->erp -= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* linux/arch/cris/arch-v32/kernel/time.c
|
* linux/arch/cris/arch-v32/kernel/time.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2003-2007 Axis Communications AB
|
* Copyright (C) 2003-2010 Axis Communications AB
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/timex.h>
|
#include <linux/timex.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/clocksource.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
@ -36,6 +36,30 @@
|
||||||
/* Number of 763 counts before watchdog bites */
|
/* Number of 763 counts before watchdog bites */
|
||||||
#define ETRAX_WD_CNT ((2*ETRAX_WD_HZ)/HZ + 1)
|
#define ETRAX_WD_CNT ((2*ETRAX_WD_HZ)/HZ + 1)
|
||||||
|
|
||||||
|
/* Register the continuos readonly timer available in FS and ARTPEC-3. */
|
||||||
|
static cycle_t read_cont_rotime(struct clocksource *cs)
|
||||||
|
{
|
||||||
|
return (u32)REG_RD(timer, regi_timer0, r_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct clocksource cont_rotime = {
|
||||||
|
.name = "crisv32_rotime",
|
||||||
|
.rating = 300,
|
||||||
|
.read = read_cont_rotime,
|
||||||
|
.mask = CLOCKSOURCE_MASK(32),
|
||||||
|
.shift = 10,
|
||||||
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init etrax_init_cont_rotime(void)
|
||||||
|
{
|
||||||
|
cont_rotime.mult = clocksource_khz2mult(100000, cont_rotime.shift);
|
||||||
|
clocksource_register(&cont_rotime);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
arch_initcall(etrax_init_cont_rotime);
|
||||||
|
|
||||||
|
|
||||||
unsigned long timer_regs[NR_CPUS] =
|
unsigned long timer_regs[NR_CPUS] =
|
||||||
{
|
{
|
||||||
regi_timer0,
|
regi_timer0,
|
||||||
|
@ -67,43 +91,6 @@ unsigned long get_ns_in_jiffie(void)
|
||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long do_slow_gettimeoffset(void)
|
|
||||||
{
|
|
||||||
unsigned long count;
|
|
||||||
unsigned long usec_count = 0;
|
|
||||||
|
|
||||||
/* For the first call after boot */
|
|
||||||
static unsigned long count_p = TIMER0_DIV;
|
|
||||||
static unsigned long jiffies_p = 0;
|
|
||||||
|
|
||||||
/* Cache volatile jiffies temporarily; we have IRQs turned off. */
|
|
||||||
unsigned long jiffies_t;
|
|
||||||
|
|
||||||
/* The timer interrupt comes from Etrax timer 0. In order to get
|
|
||||||
* better precision, we check the current value. It might have
|
|
||||||
* underflowed already though. */
|
|
||||||
count = REG_RD(timer, regi_timer0, r_tmr0_data);
|
|
||||||
jiffies_t = jiffies;
|
|
||||||
|
|
||||||
/* Avoiding timer inconsistencies (they are rare, but they happen)
|
|
||||||
* There is one problem that must be avoided here:
|
|
||||||
* 1. the timer counter underflows
|
|
||||||
*/
|
|
||||||
if( jiffies_t == jiffies_p ) {
|
|
||||||
if( count > count_p ) {
|
|
||||||
/* Timer wrapped, use new count and prescale.
|
|
||||||
* Increase the time corresponding to one jiffy.
|
|
||||||
*/
|
|
||||||
usec_count = 1000000/HZ;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
jiffies_p = jiffies_t;
|
|
||||||
count_p = count;
|
|
||||||
/* Convert timer value to usec */
|
|
||||||
/* 100 MHz timer, divide by 100 to get usec */
|
|
||||||
usec_count += (TIMER0_DIV - count) / 100;
|
|
||||||
return usec_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* From timer MDS describing the hardware watchdog:
|
/* From timer MDS describing the hardware watchdog:
|
||||||
* 4.3.1 Watchdog Operation
|
* 4.3.1 Watchdog Operation
|
||||||
|
@ -126,8 +113,7 @@ static short int watchdog_key = 42; /* arbitrary 7 bit number */
|
||||||
* is used though, so set this really low. */
|
* is used though, so set this really low. */
|
||||||
#define WATCHDOG_MIN_FREE_PAGES 8
|
#define WATCHDOG_MIN_FREE_PAGES 8
|
||||||
|
|
||||||
void
|
void reset_watchdog(void)
|
||||||
reset_watchdog(void)
|
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_ETRAX_WATCHDOG)
|
#if defined(CONFIG_ETRAX_WATCHDOG)
|
||||||
reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
|
reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
|
||||||
|
@ -147,8 +133,7 @@ reset_watchdog(void)
|
||||||
|
|
||||||
/* stop the watchdog - we still need the correct key */
|
/* stop the watchdog - we still need the correct key */
|
||||||
|
|
||||||
void
|
void stop_watchdog(void)
|
||||||
stop_watchdog(void)
|
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_ETRAX_WATCHDOG)
|
#if defined(CONFIG_ETRAX_WATCHDOG)
|
||||||
reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
|
reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
|
||||||
|
@ -162,8 +147,7 @@ stop_watchdog(void)
|
||||||
|
|
||||||
extern void show_registers(struct pt_regs *regs);
|
extern void show_registers(struct pt_regs *regs);
|
||||||
|
|
||||||
void
|
void handle_watchdog_bite(struct pt_regs *regs)
|
||||||
handle_watchdog_bite(struct pt_regs* regs)
|
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_ETRAX_WATCHDOG)
|
#if defined(CONFIG_ETRAX_WATCHDOG)
|
||||||
extern int cause_of_death;
|
extern int cause_of_death;
|
||||||
|
@ -203,8 +187,7 @@ handle_watchdog_bite(struct pt_regs* regs)
|
||||||
*/
|
*/
|
||||||
extern void cris_do_profile(struct pt_regs *regs);
|
extern void cris_do_profile(struct pt_regs *regs);
|
||||||
|
|
||||||
static inline irqreturn_t
|
static inline irqreturn_t timer_interrupt(int irq, void *dev_id)
|
||||||
timer_interrupt(int irq, void *dev_id)
|
|
||||||
{
|
{
|
||||||
struct pt_regs *regs = get_irq_regs();
|
struct pt_regs *regs = get_irq_regs();
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
@ -233,7 +216,9 @@ timer_interrupt(int irq, void *dev_id)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
|
||||||
/* Call the real timer interrupt handler */
|
/* Call the real timer interrupt handler */
|
||||||
|
write_seqlock(&xtime_lock);
|
||||||
do_timer(1);
|
do_timer(1);
|
||||||
|
write_sequnlock(&xtime_lock);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,8 +231,7 @@ static struct irqaction irq_timer = {
|
||||||
.name = "timer"
|
.name = "timer"
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init
|
void __init cris_timer_init(void)
|
||||||
cris_timer_init(void)
|
|
||||||
{
|
{
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 };
|
reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 };
|
||||||
|
@ -273,8 +257,7 @@ cris_timer_init(void)
|
||||||
REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask);
|
REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init
|
void __init time_init(void)
|
||||||
time_init(void)
|
|
||||||
{
|
{
|
||||||
reg_intr_vect_rw_mask intr_mask;
|
reg_intr_vect_rw_mask intr_mask;
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
#include <hwregs/intr_vect_defs.h>
|
#include <hwregs/intr_vect_defs.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
void
|
void show_registers(struct pt_regs *regs)
|
||||||
show_registers(struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* It's possible to use either the USP register or current->thread.usp.
|
* It's possible to use either the USP register or current->thread.usp.
|
||||||
|
@ -101,8 +100,7 @@ bad_value:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void arch_enable_nmi(void)
|
||||||
arch_enable_nmi(void)
|
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.globl csum_partial
|
.globl csum_partial
|
||||||
|
.type csum_partial,@function
|
||||||
csum_partial:
|
csum_partial:
|
||||||
|
|
||||||
;; r10 - src
|
;; r10 - src
|
||||||
|
@ -83,3 +84,5 @@ _do_byte:
|
||||||
addu.b [$r10],$r12
|
addu.b [$r10],$r12
|
||||||
ret
|
ret
|
||||||
move.d $r12,$r10
|
move.d $r12,$r10
|
||||||
|
|
||||||
|
.size csum_partial, .-csum_partial
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.globl csum_partial_copy_nocheck
|
.globl csum_partial_copy_nocheck
|
||||||
|
.type csum_partial_copy_nocheck,@function
|
||||||
csum_partial_copy_nocheck:
|
csum_partial_copy_nocheck:
|
||||||
|
|
||||||
;; r10 - src
|
;; r10 - src
|
||||||
|
@ -89,3 +90,5 @@ _do_byte:
|
||||||
move.b $r9,[$r11]
|
move.b $r9,[$r11]
|
||||||
ret
|
ret
|
||||||
move.d $r13,$r10
|
move.d $r13,$r10
|
||||||
|
|
||||||
|
.size csum_partial_copy_nocheck, . - csum_partial_copy_nocheck
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
|
|
||||||
.global cris_spin_lock
|
.global cris_spin_lock
|
||||||
|
.type cris_spin_lock,@function
|
||||||
.global cris_spin_trylock
|
.global cris_spin_trylock
|
||||||
|
.type cris_spin_trylock,@function
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
@ -22,6 +24,8 @@ cris_spin_lock:
|
||||||
ret
|
ret
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
.size cris_spin_lock, . - cris_spin_lock
|
||||||
|
|
||||||
cris_spin_trylock:
|
cris_spin_trylock:
|
||||||
clearf p
|
clearf p
|
||||||
1: move.b [$r10], $r11
|
1: move.b [$r10], $r11
|
||||||
|
@ -31,3 +35,6 @@ cris_spin_trylock:
|
||||||
clearf p
|
clearf p
|
||||||
ret
|
ret
|
||||||
movu.b $r11,$r10
|
movu.b $r11,$r10
|
||||||
|
|
||||||
|
.size cris_spin_trylock, . - cris_spin_trylock
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,10 @@ config ETRAX_DDR2_CONFIG
|
||||||
hex "DDR2 config"
|
hex "DDR2 config"
|
||||||
default "0"
|
default "0"
|
||||||
|
|
||||||
|
config ETRAX_DDR2_LATENCY
|
||||||
|
hex "DDR2 latency"
|
||||||
|
default "0"
|
||||||
|
|
||||||
config ETRAX_PIO_CE0_CFG
|
config ETRAX_PIO_CE0_CFG
|
||||||
hex "PIO CE0 configuration"
|
hex "PIO CE0 configuration"
|
||||||
default "0"
|
default "0"
|
||||||
|
|
|
@ -24,11 +24,21 @@
|
||||||
|
|
||||||
;; Refer to ddr2 MDS for initialization sequence
|
;; Refer to ddr2 MDS for initialization sequence
|
||||||
|
|
||||||
|
; 2. Wait 200us
|
||||||
|
move.d 10000, $r2
|
||||||
|
1: bne 1b
|
||||||
|
subq 1, $r2
|
||||||
|
|
||||||
; Start clock
|
; Start clock
|
||||||
move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_phy_cfg), $r0
|
move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_phy_cfg), $r0
|
||||||
move.d REG_STATE(ddr2, rw_phy_cfg, en, yes), $r1
|
move.d REG_STATE(ddr2, rw_phy_cfg, en, yes), $r1
|
||||||
move.d $r1, [$r0]
|
move.d $r1, [$r0]
|
||||||
|
|
||||||
|
; 2. Wait 200us
|
||||||
|
move.d 10000, $r2
|
||||||
|
1: bne 1b
|
||||||
|
subq 1, $r2
|
||||||
|
|
||||||
; Reset phy and start calibration
|
; Reset phy and start calibration
|
||||||
move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_phy_ctrl), $r0
|
move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_phy_ctrl), $r0
|
||||||
move.d REG_STATE(ddr2, rw_phy_ctrl, rst, yes) | \
|
move.d REG_STATE(ddr2, rw_phy_ctrl, rst, yes) | \
|
||||||
|
@ -52,6 +62,10 @@ do_cmd:
|
||||||
lslq 16, $r1
|
lslq 16, $r1
|
||||||
or.d $r3, $r1
|
or.d $r3, $r1
|
||||||
move.d $r1, [$r0]
|
move.d $r1, [$r0]
|
||||||
|
; 2. Wait 200us
|
||||||
|
move.d 10000, $r4
|
||||||
|
1: bne 1b
|
||||||
|
subq 1, $r4
|
||||||
cmp.d sdram_commands_end, $r2
|
cmp.d sdram_commands_end, $r2
|
||||||
blo command_loop
|
blo command_loop
|
||||||
nop
|
nop
|
||||||
|
@ -63,7 +77,7 @@ do_cmd:
|
||||||
|
|
||||||
; Set latency
|
; Set latency
|
||||||
move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_latency), $r0
|
move.d REG_ADDR(ddr2, regi_ddr2_ctrl, rw_latency), $r0
|
||||||
move.d 0x13, $r1
|
move.d CONFIG_ETRAX_DDR2_LATENCY, $r1
|
||||||
move.d $r1, [$r0]
|
move.d $r1, [$r0]
|
||||||
|
|
||||||
; Set configuration
|
; Set configuration
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
; Register values
|
; Register values
|
||||||
.dword REG_ADDR(ddr2, regi_ddr2_ctrl, rw_cfg)
|
.dword REG_ADDR(ddr2, regi_ddr2_ctrl, rw_cfg)
|
||||||
.dword CONFIG_ETRAX_DDR2_CONFIG
|
.dword CONFIG_ETRAX_DDR2_CONFIG
|
||||||
|
.dword REG_ADDR(ddr2, regi_ddr2_ctrl, rw_latency)
|
||||||
|
.dword CONFIG_ETRAX_DDR2_LATENCY
|
||||||
.dword REG_ADDR(ddr2, regi_ddr2_ctrl, rw_timing)
|
.dword REG_ADDR(ddr2, regi_ddr2_ctrl, rw_timing)
|
||||||
.dword CONFIG_ETRAX_DDR2_TIMING
|
.dword CONFIG_ETRAX_DDR2_TIMING
|
||||||
.dword CONFIG_ETRAX_DDR2_MRS
|
.dword CONFIG_ETRAX_DDR2_MRS
|
||||||
|
|
|
@ -27,8 +27,7 @@ extern void tlb_init(void);
|
||||||
* at kseg_4 thus the ksegs are set up again. Also clear the TLB and do various
|
* at kseg_4 thus the ksegs are set up again. Also clear the TLB and do various
|
||||||
* other paging stuff.
|
* other paging stuff.
|
||||||
*/
|
*/
|
||||||
void __init
|
void __init cris_mmu_init(void)
|
||||||
cris_mmu_init(void)
|
|
||||||
{
|
{
|
||||||
unsigned long mmu_config;
|
unsigned long mmu_config;
|
||||||
unsigned long mmu_kbase_hi;
|
unsigned long mmu_kbase_hi;
|
||||||
|
@ -55,14 +54,23 @@ cris_mmu_init(void)
|
||||||
/* Initialise the TLB. Function found in tlb.c. */
|
/* Initialise the TLB. Function found in tlb.c. */
|
||||||
tlb_init();
|
tlb_init();
|
||||||
|
|
||||||
/* Enable exceptions and initialize the kernel segments. */
|
/*
|
||||||
|
* Enable exceptions and initialize the kernel segments.
|
||||||
|
* See head.S for differences between ARTPEC-3 and ETRAX FS.
|
||||||
|
*/
|
||||||
mmu_config = ( REG_STATE(mmu, rw_mm_cfg, we, on) |
|
mmu_config = ( REG_STATE(mmu, rw_mm_cfg, we, on) |
|
||||||
REG_STATE(mmu, rw_mm_cfg, acc, on) |
|
REG_STATE(mmu, rw_mm_cfg, acc, on) |
|
||||||
REG_STATE(mmu, rw_mm_cfg, ex, on) |
|
REG_STATE(mmu, rw_mm_cfg, ex, on) |
|
||||||
REG_STATE(mmu, rw_mm_cfg, inv, on) |
|
REG_STATE(mmu, rw_mm_cfg, inv, on) |
|
||||||
|
#ifdef CONFIG_CRIS_MACH_ARTPEC3
|
||||||
|
REG_STATE(mmu, rw_mm_cfg, seg_f, page) |
|
||||||
|
REG_STATE(mmu, rw_mm_cfg, seg_e, page) |
|
||||||
|
REG_STATE(mmu, rw_mm_cfg, seg_d, linear) |
|
||||||
|
#else
|
||||||
REG_STATE(mmu, rw_mm_cfg, seg_f, linear) |
|
REG_STATE(mmu, rw_mm_cfg, seg_f, linear) |
|
||||||
REG_STATE(mmu, rw_mm_cfg, seg_e, linear) |
|
REG_STATE(mmu, rw_mm_cfg, seg_e, linear) |
|
||||||
REG_STATE(mmu, rw_mm_cfg, seg_d, page) |
|
REG_STATE(mmu, rw_mm_cfg, seg_d, page) |
|
||||||
|
#endif
|
||||||
REG_STATE(mmu, rw_mm_cfg, seg_c, linear) |
|
REG_STATE(mmu, rw_mm_cfg, seg_c, linear) |
|
||||||
REG_STATE(mmu, rw_mm_cfg, seg_b, linear) |
|
REG_STATE(mmu, rw_mm_cfg, seg_b, linear) |
|
||||||
#ifndef CONFIG_ETRAX_VCS_SIM
|
#ifndef CONFIG_ETRAX_VCS_SIM
|
||||||
|
@ -81,9 +89,15 @@ cris_mmu_init(void)
|
||||||
REG_STATE(mmu, rw_mm_cfg, seg_1, page) |
|
REG_STATE(mmu, rw_mm_cfg, seg_1, page) |
|
||||||
REG_STATE(mmu, rw_mm_cfg, seg_0, page));
|
REG_STATE(mmu, rw_mm_cfg, seg_0, page));
|
||||||
|
|
||||||
|
/* See head.S for differences between ARTPEC-3 and ETRAX FS. */
|
||||||
mmu_kbase_hi = ( REG_FIELD(mmu, rw_mm_kbase_hi, base_f, 0x0) |
|
mmu_kbase_hi = ( REG_FIELD(mmu, rw_mm_kbase_hi, base_f, 0x0) |
|
||||||
|
#ifdef CONFIG_CRIS_MACH_ARTPEC3
|
||||||
|
REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x0) |
|
||||||
|
REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x5) |
|
||||||
|
#else
|
||||||
REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x8) |
|
REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x8) |
|
||||||
REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x0) |
|
REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x0) |
|
||||||
|
#endif
|
||||||
REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x4) |
|
REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x4) |
|
||||||
REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) |
|
REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) |
|
||||||
#ifndef CONFIG_ETRAX_VCS_SIM
|
#ifndef CONFIG_ETRAX_VCS_SIM
|
||||||
|
@ -129,8 +143,7 @@ cris_mmu_init(void)
|
||||||
SUPP_REG_WR(RW_GC_CFG, 0xf); /* IMMU, DMMU, ICache, DCache on */
|
SUPP_REG_WR(RW_GC_CFG, 0xf); /* IMMU, DMMU, ICache, DCache on */
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init
|
void __init paging_init(void)
|
||||||
paging_init(void)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned long zones_size[MAX_NR_ZONES];
|
unsigned long zones_size[MAX_NR_ZONES];
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
; to handle the fault.
|
; to handle the fault.
|
||||||
.macro MMU_BUS_FAULT_HANDLER handler, mmu, we, ex
|
.macro MMU_BUS_FAULT_HANDLER handler, mmu, we, ex
|
||||||
.globl \handler
|
.globl \handler
|
||||||
|
.type \handler,"function"
|
||||||
\handler:
|
\handler:
|
||||||
SAVE_ALL
|
SAVE_ALL
|
||||||
move \mmu, $srs ; Select MMU support register bank
|
move \mmu, $srs ; Select MMU support register bank
|
||||||
|
@ -52,6 +53,7 @@
|
||||||
nop
|
nop
|
||||||
ba ret_from_intr
|
ba ret_from_intr
|
||||||
nop
|
nop
|
||||||
|
.size \handler, . - \handler
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
; Refill handler. Three cases may occur:
|
; Refill handler. Three cases may occur:
|
||||||
|
@ -84,6 +86,7 @@
|
||||||
2: .dword 0 ; last_refill_cause
|
2: .dword 0 ; last_refill_cause
|
||||||
.text
|
.text
|
||||||
.globl \handler
|
.globl \handler
|
||||||
|
.type \handler, "function"
|
||||||
\handler:
|
\handler:
|
||||||
subq 4, $sp
|
subq 4, $sp
|
||||||
; (The pipeline stalls for one cycle; $sp used as address in the next cycle.)
|
; (The pipeline stalls for one cycle; $sp used as address in the next cycle.)
|
||||||
|
@ -196,6 +199,7 @@
|
||||||
; Return
|
; Return
|
||||||
ba ret_from_intr
|
ba ret_from_intr
|
||||||
nop
|
nop
|
||||||
|
.size \handler, . - \handler
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
; This is the MMU bus fault handlers.
|
; This is the MMU bus fault handlers.
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
objcopyflags-$(CONFIG_ETRAX_ARCH_V10) += -R .note -R .comment
|
objcopyflags-$(CONFIG_ETRAX_ARCH_V10) += -R .note -R .comment
|
||||||
objcopyflags-$(CONFIG_ETRAX_ARCH_V32) += --remove-section=.bss
|
objcopyflags-$(CONFIG_ETRAX_ARCH_V32) += --remove-section=.bss --remove-section=.note.gnu.build-id
|
||||||
|
|
||||||
OBJCOPYFLAGS = -O binary $(objcopyflags-y)
|
OBJCOPYFLAGS = -O binary $(objcopyflags-y)
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ static unsigned outcnt = 0; /* bytes in output buffer */
|
||||||
|
|
||||||
static void flush_window(void);
|
static void flush_window(void);
|
||||||
static void error(char *m);
|
static void error(char *m);
|
||||||
static void puts(const char *);
|
static void aputs(const char *s);
|
||||||
|
|
||||||
extern char *input_data; /* lives in head.S */
|
extern char *input_data; /* lives in head.S */
|
||||||
|
|
||||||
|
@ -137,52 +137,37 @@ static inline void serout(const char *s, reg_scope_instances regi_ser)
|
||||||
|
|
||||||
REG_WR(ser, regi_ser, rw_dout, dout);
|
REG_WR(ser, regi_ser, rw_dout, dout);
|
||||||
}
|
}
|
||||||
|
#define SEROUT(S, N) \
|
||||||
|
do { \
|
||||||
|
serout(S, regi_ser ## N); \
|
||||||
|
s++; \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define SEROUT(S, N) do { \
|
||||||
|
while (!(*R_SERIAL ## N ## _STATUS & (1 << 5))) \
|
||||||
|
; \
|
||||||
|
*R_SERIAL ## N ## _TR_DATA = *s++; \
|
||||||
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void puts(const char *s)
|
static void aputs(const char *s)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
|
#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
|
||||||
while (*s) {
|
while (*s) {
|
||||||
#ifdef CONFIG_ETRAX_DEBUG_PORT0
|
#ifdef CONFIG_ETRAX_DEBUG_PORT0
|
||||||
#ifdef CONFIG_ETRAX_ARCH_V32
|
SEROUT(s, 0);
|
||||||
serout(s, regi_ser0);
|
|
||||||
#else
|
|
||||||
while (!(*R_SERIAL0_STATUS & (1 << 5)))
|
|
||||||
;
|
|
||||||
*R_SERIAL0_TR_DATA = *s++;
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ETRAX_DEBUG_PORT1
|
#ifdef CONFIG_ETRAX_DEBUG_PORT1
|
||||||
#ifdef CONFIG_ETRAX_ARCH_V32
|
SEROUT(s, 1);
|
||||||
serout(s, regi_ser1);
|
|
||||||
#else
|
|
||||||
while (!(*R_SERIAL1_STATUS & (1 << 5)))
|
|
||||||
;
|
|
||||||
*R_SERIAL1_TR_DATA = *s++;
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ETRAX_DEBUG_PORT2
|
#ifdef CONFIG_ETRAX_DEBUG_PORT2
|
||||||
#ifdef CONFIG_ETRAX_ARCH_V32
|
SEROUT(s, 2);
|
||||||
serout(s, regi_ser2);
|
|
||||||
#else
|
|
||||||
while (!(*R_SERIAL2_STATUS & (1 << 5)))
|
|
||||||
;
|
|
||||||
*R_SERIAL2_TR_DATA = *s++;
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ETRAX_DEBUG_PORT3
|
#ifdef CONFIG_ETRAX_DEBUG_PORT3
|
||||||
#ifdef CONFIG_ETRAX_ARCH_V32
|
SEROUT(s, 3);
|
||||||
serout(s, regi_ser3);
|
|
||||||
#else
|
|
||||||
while (!(*R_SERIAL3_STATUS & (1 << 5)))
|
|
||||||
;
|
|
||||||
*R_SERIAL3_TR_DATA = *s++;
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
*s++;
|
|
||||||
}
|
}
|
||||||
/* CONFIG_ETRAX_DEBUG_PORT_NULL */
|
#endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memset(void *s, int c, size_t n)
|
void *memset(void *s, int c, size_t n)
|
||||||
|
@ -233,9 +218,9 @@ static void flush_window(void)
|
||||||
|
|
||||||
static void error(char *x)
|
static void error(char *x)
|
||||||
{
|
{
|
||||||
puts("\n\n");
|
aputs("\n\n");
|
||||||
puts(x);
|
aputs(x);
|
||||||
puts("\n\n -- System halted\n");
|
aputs("\n\n -- System halted\n");
|
||||||
|
|
||||||
while(1); /* Halt */
|
while(1); /* Halt */
|
||||||
}
|
}
|
||||||
|
@ -378,14 +363,14 @@ void decompress_kernel(void)
|
||||||
__asm__ volatile ("move $vr,%0" : "=rm" (revision));
|
__asm__ volatile ("move $vr,%0" : "=rm" (revision));
|
||||||
if (revision < compile_rev) {
|
if (revision < compile_rev) {
|
||||||
#ifdef CONFIG_ETRAX_ARCH_V32
|
#ifdef CONFIG_ETRAX_ARCH_V32
|
||||||
puts("You need an ETRAX FS to run Linux 2.6/crisv32\n");
|
aputs("You need at least ETRAX FS to run Linux 2.6/crisv32\n");
|
||||||
#else
|
#else
|
||||||
puts("You need an ETRAX 100LX to run linux 2.6\n");
|
aputs("You need an ETRAX 100LX to run linux 2.6/crisv10\n");
|
||||||
#endif
|
#endif
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
puts("Uncompressing Linux...\n");
|
aputs("Uncompressing Linux...\n");
|
||||||
gunzip();
|
gunzip();
|
||||||
puts("Done. Now booting the kernel\n");
|
aputs("Done. Now booting the kernel\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#define L1_CACHE_BYTES 32
|
#define L1_CACHE_BYTES 32
|
||||||
#define L1_CACHE_SHIFT 5
|
#define L1_CACHE_SHIFT 5
|
||||||
|
|
||||||
|
#define __read_mostly __attribute__((__section__(".data.read_mostly")))
|
||||||
|
|
||||||
void flush_dma_list(dma_descr_data *descr);
|
void flush_dma_list(dma_descr_data *descr);
|
||||||
void flush_dma_descr(dma_descr_data *descr, int flush_buf);
|
void flush_dma_descr(dma_descr_data *descr, int flush_buf);
|
||||||
|
|
||||||
|
|
|
@ -1,79 +1 @@
|
||||||
#ifndef _ASM_ARCH_CRIS_DMA_H
|
#include "mach/dma.h"
|
||||||
#define _ASM_ARCH_CRIS_DMA_H
|
|
||||||
|
|
||||||
/* Defines for using and allocating dma channels. */
|
|
||||||
|
|
||||||
#define MAX_DMA_CHANNELS 10
|
|
||||||
|
|
||||||
#define NETWORK_ETH0_TX_DMA_NBR 0 /* Ethernet 0 out. */
|
|
||||||
#define NETWORK_ETH0 RX_DMA_NBR 1 /* Ethernet 0 in. */
|
|
||||||
|
|
||||||
#define IO_PROC_DMA0_TX_DMA_NBR 2 /* IO processor DMA0 out. */
|
|
||||||
#define IO_PROC_DMA0_RX_DMA_NBR 3 /* IO processor DMA0 in. */
|
|
||||||
|
|
||||||
#define ATA_TX_DMA_NBR 2 /* ATA interface out. */
|
|
||||||
#define ATA_RX_DMA_NBR 3 /* ATA interface in. */
|
|
||||||
|
|
||||||
#define ASYNC_SER2_TX_DMA_NBR 2 /* Asynchronous serial port 2 out. */
|
|
||||||
#define ASYNC_SER2_RX_DMA_NBR 3 /* Asynchronous serial port 2 in. */
|
|
||||||
|
|
||||||
#define IO_PROC_DMA1_TX_DMA_NBR 4 /* IO processor DMA1 out. */
|
|
||||||
#define IO_PROC_DMA1_RX_DMA_NBR 5 /* IO processor DMA1 in. */
|
|
||||||
|
|
||||||
#define ASYNC_SER1_TX_DMA_NBR 4 /* Asynchronous serial port 1 out. */
|
|
||||||
#define ASYNC_SER1_RX_DMA_NBR 5 /* Asynchronous serial port 1 in. */
|
|
||||||
|
|
||||||
#define SYNC_SER0_TX_DMA_NBR 4 /* Synchronous serial port 0 out. */
|
|
||||||
#define SYNC_SER0_RX_DMA_NBR 5 /* Synchronous serial port 0 in. */
|
|
||||||
|
|
||||||
#define EXTDMA0_TX_DMA_NBR 6 /* External DMA 0 out. */
|
|
||||||
#define EXTDMA1_RX_DMA_NBR 7 /* External DMA 1 in. */
|
|
||||||
|
|
||||||
#define ASYNC_SER0_TX_DMA_NBR 6 /* Asynchronous serial port 0 out. */
|
|
||||||
#define ASYNC_SER0_RX_DMA_NBR 7 /* Asynchronous serial port 0 in. */
|
|
||||||
|
|
||||||
#define SYNC_SER1_TX_DMA_NBR 6 /* Synchronous serial port 1 out. */
|
|
||||||
#define SYNC_SER1_RX_DMA_NBR 7 /* Synchronous serial port 1 in. */
|
|
||||||
|
|
||||||
#define NETWORK_ETH1_TX_DMA_NBR 6 /* Ethernet 1 out. */
|
|
||||||
#define NETWORK_ETH1_RX_DMA_NBR 7 /* Ethernet 1 in. */
|
|
||||||
|
|
||||||
#define EXTDMA2_TX_DMA_NBR 8 /* External DMA 2 out. */
|
|
||||||
#define EXTDMA3_RX_DMA_NBR 9 /* External DMA 3 in. */
|
|
||||||
|
|
||||||
#define STRCOP_TX_DMA_NBR 8 /* Stream co-processor out. */
|
|
||||||
#define STRCOP_RX_DMA_NBR 9 /* Stream co-processor in. */
|
|
||||||
|
|
||||||
#define ASYNC_SER3_TX_DMA_NBR 8 /* Asynchronous serial port 3 out. */
|
|
||||||
#define ASYNC_SER3_RX_DMA_NBR 9 /* Asynchronous serial port 3 in. */
|
|
||||||
|
|
||||||
enum dma_owner
|
|
||||||
{
|
|
||||||
dma_eth0,
|
|
||||||
dma_eth1,
|
|
||||||
dma_iop0,
|
|
||||||
dma_iop1,
|
|
||||||
dma_ser0,
|
|
||||||
dma_ser1,
|
|
||||||
dma_ser2,
|
|
||||||
dma_ser3,
|
|
||||||
dma_sser0,
|
|
||||||
dma_sser1,
|
|
||||||
dma_ata,
|
|
||||||
dma_strp,
|
|
||||||
dma_ext0,
|
|
||||||
dma_ext1,
|
|
||||||
dma_ext2,
|
|
||||||
dma_ext3
|
|
||||||
};
|
|
||||||
|
|
||||||
int crisv32_request_dma(unsigned int dmanr, const char * device_id,
|
|
||||||
unsigned options, unsigned bandwidth, enum dma_owner owner);
|
|
||||||
void crisv32_free_dma(unsigned int dmanr);
|
|
||||||
|
|
||||||
/* Masks used by crisv32_request_dma options: */
|
|
||||||
#define DMA_VERBOSE_ON_ERROR 1
|
|
||||||
#define DMA_PANIC_ON_ERROR (2|DMA_VERBOSE_ON_ERROR)
|
|
||||||
#define DMA_INT_MEM 4
|
|
||||||
|
|
||||||
#endif /* _ASM_ARCH_CRIS_DMA_H */
|
|
||||||
|
|
|
@ -46,10 +46,12 @@ static inline void crisv32_io_set(struct crisv32_iopin *iopin, int val)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
spin_lock_irqsave(&iopin->port->lock, flags);
|
spin_lock_irqsave(&iopin->port->lock, flags);
|
||||||
|
|
||||||
if (val)
|
if (iopin->port->data) {
|
||||||
*iopin->port->data |= iopin->bit;
|
if (val)
|
||||||
else
|
*iopin->port->data |= iopin->bit;
|
||||||
*iopin->port->data &= ~iopin->bit;
|
else
|
||||||
|
*iopin->port->data &= ~iopin->bit;
|
||||||
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&iopin->port->lock, flags);
|
spin_unlock_irqrestore(&iopin->port->lock, flags);
|
||||||
}
|
}
|
||||||
|
@ -60,10 +62,12 @@ static inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
spin_lock_irqsave(&iopin->port->lock, flags);
|
spin_lock_irqsave(&iopin->port->lock, flags);
|
||||||
|
|
||||||
if (dir == crisv32_io_dir_in)
|
if (iopin->port->oe) {
|
||||||
*iopin->port->oe &= ~iopin->bit;
|
if (dir == crisv32_io_dir_in)
|
||||||
else
|
*iopin->port->oe &= ~iopin->bit;
|
||||||
*iopin->port->oe |= iopin->bit;
|
else
|
||||||
|
*iopin->port->oe |= iopin->bit;
|
||||||
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&iopin->port->lock, flags);
|
spin_unlock_irqrestore(&iopin->port->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1 @@
|
||||||
#ifndef _ASM_ARCH_MEMMAP_H
|
#include <mach/memmap.h>
|
||||||
#define _ASM_ARCH_MEMMAP_H
|
|
||||||
|
|
||||||
#define MEM_CSE0_START (0x00000000)
|
|
||||||
#define MEM_CSE0_SIZE (0x04000000)
|
|
||||||
#define MEM_CSE1_START (0x04000000)
|
|
||||||
#define MEM_CSE1_SIZE (0x04000000)
|
|
||||||
#define MEM_CSR0_START (0x08000000)
|
|
||||||
#define MEM_CSR1_START (0x0c000000)
|
|
||||||
#define MEM_CSP0_START (0x10000000)
|
|
||||||
#define MEM_CSP1_START (0x14000000)
|
|
||||||
#define MEM_CSP2_START (0x18000000)
|
|
||||||
#define MEM_CSP3_START (0x1c000000)
|
|
||||||
#define MEM_CSP4_START (0x20000000)
|
|
||||||
#define MEM_CSP5_START (0x24000000)
|
|
||||||
#define MEM_CSP6_START (0x28000000)
|
|
||||||
#define MEM_CSP7_START (0x2c000000)
|
|
||||||
#define MEM_INTMEM_START (0x38000000)
|
|
||||||
#define MEM_INTMEM_SIZE (0x00020000)
|
|
||||||
#define MEM_DRAM_START (0x40000000)
|
|
||||||
|
|
||||||
#define MEM_NON_CACHEABLE (0x80000000)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -2,8 +2,16 @@
|
||||||
#define _ASM_CRIS_ARCH_PGTABLE_H
|
#define _ASM_CRIS_ARCH_PGTABLE_H
|
||||||
|
|
||||||
/* Define the kernels virtual memory area. */
|
/* Define the kernels virtual memory area. */
|
||||||
|
|
||||||
|
/* See head.S for differences between ARTPEC-3 and ETRAX FS. */
|
||||||
|
#ifdef CONFIG_CRIS_MACH_ARTPEC3
|
||||||
|
#define VMALLOC_START KSEG_E
|
||||||
|
#define VMALLOC_END KSEG_F
|
||||||
|
#else
|
||||||
#define VMALLOC_START KSEG_D
|
#define VMALLOC_START KSEG_D
|
||||||
#define VMALLOC_END KSEG_E
|
#define VMALLOC_END KSEG_E
|
||||||
|
#endif
|
||||||
|
|
||||||
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
|
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
|
||||||
|
|
||||||
#endif /* _ASM_CRIS_ARCH_PGTABLE_H */
|
#endif /* _ASM_CRIS_ARCH_PGTABLE_H */
|
||||||
|
|
|
@ -122,14 +122,14 @@ __do_strncpy_from_user(char *dst, const char *src, long count)
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
" move.d %3,%0\n"
|
" move.d %3,%0\n"
|
||||||
"5: move.b [%2+],$acr\n"
|
"5: move.b [%2+],$acr\n"
|
||||||
"1: beq 2f\n"
|
"1: beq 6f\n"
|
||||||
" move.b $acr,[%1+]\n"
|
" move.b $acr,[%1+]\n"
|
||||||
|
|
||||||
" subq 1,%0\n"
|
" subq 1,%0\n"
|
||||||
"2: bne 1b\n"
|
"2: bne 1b\n"
|
||||||
" move.b [%2+],$acr\n"
|
" move.b [%2+],$acr\n"
|
||||||
|
|
||||||
" sub.d %3,%0\n"
|
"6: sub.d %3,%0\n"
|
||||||
" neg.d %0,%0\n"
|
" neg.d %0,%0\n"
|
||||||
"3:\n"
|
"3:\n"
|
||||||
" .section .fixup,\"ax\"\n"
|
" .section .fixup,\"ax\"\n"
|
||||||
|
@ -140,8 +140,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count)
|
||||||
/* The address for a fault at the first move is trivial.
|
/* The address for a fault at the first move is trivial.
|
||||||
The address for a fault at the second move is that of
|
The address for a fault at the second move is that of
|
||||||
the preceding branch insn, since the move insn is in
|
the preceding branch insn, since the move insn is in
|
||||||
its delay-slot. That address is also a branch
|
its delay-slot. Just so you don't get confused... */
|
||||||
target. Just so you don't get confused... */
|
|
||||||
" .previous\n"
|
" .previous\n"
|
||||||
" .section __ex_table,\"a\"\n"
|
" .section __ex_table,\"a\"\n"
|
||||||
" .dword 5b,4b\n"
|
" .dword 5b,4b\n"
|
||||||
|
|
|
@ -5,6 +5,33 @@
|
||||||
|
|
||||||
#define MAX_DMA_CHANNELS 12 /* 8 and 10 not used. */
|
#define MAX_DMA_CHANNELS 12 /* 8 and 10 not used. */
|
||||||
|
|
||||||
|
#define NETWORK_ETH_TX_DMA_NBR 0 /* Ethernet 0 out. */
|
||||||
|
#define NETWORK_ETH_RX_DMA_NBR 1 /* Ethernet 0 in. */
|
||||||
|
|
||||||
|
#define IO_PROC_DMA_TX_DMA_NBR 4 /* IO processor DMA0 out. */
|
||||||
|
#define IO_PROC_DMA_RX_DMA_NBR 5 /* IO processor DMA0 in. */
|
||||||
|
|
||||||
|
#define ASYNC_SER3_TX_DMA_NBR 2 /* Asynchronous serial port 3 out. */
|
||||||
|
#define ASYNC_SER3_RX_DMA_NBR 3 /* Asynchronous serial port 3 in. */
|
||||||
|
|
||||||
|
#define ASYNC_SER2_TX_DMA_NBR 6 /* Asynchronous serial port 2 out. */
|
||||||
|
#define ASYNC_SER2_RX_DMA_NBR 7 /* Asynchronous serial port 2 in. */
|
||||||
|
|
||||||
|
#define ASYNC_SER1_TX_DMA_NBR 4 /* Asynchronous serial port 1 out. */
|
||||||
|
#define ASYNC_SER1_RX_DMA_NBR 5 /* Asynchronous serial port 1 in. */
|
||||||
|
|
||||||
|
#define SYNC_SER_TX_DMA_NBR 6 /* Synchronous serial port 0 out. */
|
||||||
|
#define SYNC_SER_RX_DMA_NBR 7 /* Synchronous serial port 0 in. */
|
||||||
|
|
||||||
|
#define ASYNC_SER0_TX_DMA_NBR 0 /* Asynchronous serial port 0 out. */
|
||||||
|
#define ASYNC_SER0_RX_DMA_NBR 1 /* Asynchronous serial port 0 in. */
|
||||||
|
|
||||||
|
#define STRCOP_TX_DMA_NBR 2 /* Stream co-processor out. */
|
||||||
|
#define STRCOP_RX_DMA_NBR 3 /* Stream co-processor in. */
|
||||||
|
|
||||||
|
#define dma_eth0 dma_eth
|
||||||
|
#define dma_eth1 dma_eth
|
||||||
|
|
||||||
enum dma_owner {
|
enum dma_owner {
|
||||||
dma_eth,
|
dma_eth,
|
||||||
dma_ser0,
|
dma_ser0,
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
|
#ifndef STARTUP_INC_INCLUDED
|
||||||
|
#define STARTUP_INC_INCLUDED
|
||||||
|
|
||||||
#include <hwregs/asm/reg_map_asm.h>
|
#include <hwregs/asm/reg_map_asm.h>
|
||||||
#include <hwregs/asm/gio_defs_asm.h>
|
#include <hwregs/asm/gio_defs_asm.h>
|
||||||
#include <hwregs/asm/pio_defs_asm.h>
|
#include <hwregs/asm/pio_defs_asm.h>
|
||||||
#include <hwregs/asm/clkgen_defs_asm.h>
|
#include <hwregs/asm/clkgen_defs_asm.h>
|
||||||
#include <hwregs/asm/pinmux_defs_asm.h>
|
#include <hwregs/asm/pinmux_defs_asm.h>
|
||||||
|
|
||||||
|
.macro GIO_SET_P BITS, OUTREG
|
||||||
|
bmi 1f ; btstq: bit -> N flag
|
||||||
|
nop
|
||||||
|
or.d \BITS, \OUTREG
|
||||||
|
1:
|
||||||
|
.endm
|
||||||
|
|
||||||
.macro GIO_INIT
|
.macro GIO_INIT
|
||||||
move.d CONFIG_ETRAX_DEF_GIO_PA_OUT, $r0
|
move.d CONFIG_ETRAX_DEF_GIO_PA_OUT, $r0
|
||||||
move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r1
|
move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r1
|
||||||
|
@ -32,10 +42,23 @@
|
||||||
move.d 0xFFFFFFFF, $r0
|
move.d 0xFFFFFFFF, $r0
|
||||||
move.d REG_ADDR(pinmux, regi_pinmux, rw_gio_pa), $r1
|
move.d REG_ADDR(pinmux, regi_pinmux, rw_gio_pa), $r1
|
||||||
move.d $r0, [$r1]
|
move.d $r0, [$r1]
|
||||||
move.d REG_ADDR(pinmux, regi_pinmux, rw_gio_pb), $r1
|
|
||||||
move.d $r0, [$r1]
|
|
||||||
move.d REG_ADDR(pinmux, regi_pinmux, rw_gio_pc), $r1
|
move.d REG_ADDR(pinmux, regi_pinmux, rw_gio_pc), $r1
|
||||||
move.d $r0, [$r1]
|
move.d $r0, [$r1]
|
||||||
|
|
||||||
|
;; If eth_mdio, eth, geth bits are set in hwprot, don't
|
||||||
|
;; set them to gpio, as this means they have been configured
|
||||||
|
;; earlier and shouldn't be changed.
|
||||||
|
move.d 0xFC000000, $r2 ; pins 25..0 are eth_mdio, eth, geth
|
||||||
|
move.d REG_ADDR(pinmux, regi_pinmux, rw_hwprot), $r1
|
||||||
|
move.d [$r1], $r0
|
||||||
|
btstq REG_BIT(pinmux, rw_hwprot, eth), $r0
|
||||||
|
GIO_SET_P 0x00FFFF00, $r2 ;; pins 8..23 are eth
|
||||||
|
btstq REG_BIT(pinmux, rw_hwprot, eth_mdio), $r0
|
||||||
|
GIO_SET_P 0x03000000, $r2 ;; pins 24..25 are eth_mdio
|
||||||
|
btstq REG_BIT(pinmux, rw_hwprot, geth), $r0
|
||||||
|
GIO_SET_P 0x000000FF, $r2 ;; pins 0..7 are geth
|
||||||
|
move.d REG_ADDR(pinmux, regi_pinmux, rw_gio_pb), $r1
|
||||||
|
move.d $r2, [$r1]
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro START_CLOCKS
|
.macro START_CLOCKS
|
||||||
|
@ -58,3 +81,4 @@
|
||||||
move.d CONFIG_ETRAX_PIO_CE2_CFG, $r1
|
move.d CONFIG_ETRAX_PIO_CE2_CFG, $r1
|
||||||
move.d $r1, [$r0]
|
move.d $r1, [$r0]
|
||||||
.endm
|
.endm
|
||||||
|
#endif
|
||||||
|
|
79
arch/cris/include/arch-v32/mach-fs/mach/dma.h
Normal file
79
arch/cris/include/arch-v32/mach-fs/mach/dma.h
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#ifndef _ASM_ARCH_CRIS_DMA_H
|
||||||
|
#define _ASM_ARCH_CRIS_DMA_H
|
||||||
|
|
||||||
|
/* Defines for using and allocating dma channels. */
|
||||||
|
|
||||||
|
#define MAX_DMA_CHANNELS 10
|
||||||
|
|
||||||
|
#define NETWORK_ETH0_TX_DMA_NBR 0 /* Ethernet 0 out. */
|
||||||
|
#define NETWORK_ETH0 RX_DMA_NBR 1 /* Ethernet 0 in. */
|
||||||
|
|
||||||
|
#define IO_PROC_DMA0_TX_DMA_NBR 2 /* IO processor DMA0 out. */
|
||||||
|
#define IO_PROC_DMA0_RX_DMA_NBR 3 /* IO processor DMA0 in. */
|
||||||
|
|
||||||
|
#define ATA_TX_DMA_NBR 2 /* ATA interface out. */
|
||||||
|
#define ATA_RX_DMA_NBR 3 /* ATA interface in. */
|
||||||
|
|
||||||
|
#define ASYNC_SER2_TX_DMA_NBR 2 /* Asynchronous serial port 2 out. */
|
||||||
|
#define ASYNC_SER2_RX_DMA_NBR 3 /* Asynchronous serial port 2 in. */
|
||||||
|
|
||||||
|
#define IO_PROC_DMA1_TX_DMA_NBR 4 /* IO processor DMA1 out. */
|
||||||
|
#define IO_PROC_DMA1_RX_DMA_NBR 5 /* IO processor DMA1 in. */
|
||||||
|
|
||||||
|
#define ASYNC_SER1_TX_DMA_NBR 4 /* Asynchronous serial port 1 out. */
|
||||||
|
#define ASYNC_SER1_RX_DMA_NBR 5 /* Asynchronous serial port 1 in. */
|
||||||
|
|
||||||
|
#define SYNC_SER0_TX_DMA_NBR 4 /* Synchronous serial port 0 out. */
|
||||||
|
#define SYNC_SER0_RX_DMA_NBR 5 /* Synchronous serial port 0 in. */
|
||||||
|
|
||||||
|
#define EXTDMA0_TX_DMA_NBR 6 /* External DMA 0 out. */
|
||||||
|
#define EXTDMA1_RX_DMA_NBR 7 /* External DMA 1 in. */
|
||||||
|
|
||||||
|
#define ASYNC_SER0_TX_DMA_NBR 6 /* Asynchronous serial port 0 out. */
|
||||||
|
#define ASYNC_SER0_RX_DMA_NBR 7 /* Asynchronous serial port 0 in. */
|
||||||
|
|
||||||
|
#define SYNC_SER1_TX_DMA_NBR 6 /* Synchronous serial port 1 out. */
|
||||||
|
#define SYNC_SER1_RX_DMA_NBR 7 /* Synchronous serial port 1 in. */
|
||||||
|
|
||||||
|
#define NETWORK_ETH1_TX_DMA_NBR 6 /* Ethernet 1 out. */
|
||||||
|
#define NETWORK_ETH1_RX_DMA_NBR 7 /* Ethernet 1 in. */
|
||||||
|
|
||||||
|
#define EXTDMA2_TX_DMA_NBR 8 /* External DMA 2 out. */
|
||||||
|
#define EXTDMA3_RX_DMA_NBR 9 /* External DMA 3 in. */
|
||||||
|
|
||||||
|
#define STRCOP_TX_DMA_NBR 8 /* Stream co-processor out. */
|
||||||
|
#define STRCOP_RX_DMA_NBR 9 /* Stream co-processor in. */
|
||||||
|
|
||||||
|
#define ASYNC_SER3_TX_DMA_NBR 8 /* Asynchronous serial port 3 out. */
|
||||||
|
#define ASYNC_SER3_RX_DMA_NBR 9 /* Asynchronous serial port 3 in. */
|
||||||
|
|
||||||
|
enum dma_owner {
|
||||||
|
dma_eth0,
|
||||||
|
dma_eth1,
|
||||||
|
dma_iop0,
|
||||||
|
dma_iop1,
|
||||||
|
dma_ser0,
|
||||||
|
dma_ser1,
|
||||||
|
dma_ser2,
|
||||||
|
dma_ser3,
|
||||||
|
dma_sser0,
|
||||||
|
dma_sser1,
|
||||||
|
dma_ata,
|
||||||
|
dma_strp,
|
||||||
|
dma_ext0,
|
||||||
|
dma_ext1,
|
||||||
|
dma_ext2,
|
||||||
|
dma_ext3
|
||||||
|
};
|
||||||
|
|
||||||
|
int crisv32_request_dma(unsigned int dmanr, const char *device_id,
|
||||||
|
unsigned options, unsigned bandwidth,
|
||||||
|
enum dma_owner owner);
|
||||||
|
void crisv32_free_dma(unsigned int dmanr);
|
||||||
|
|
||||||
|
/* Masks used by crisv32_request_dma options: */
|
||||||
|
#define DMA_VERBOSE_ON_ERROR 1
|
||||||
|
#define DMA_PANIC_ON_ERROR (2|DMA_VERBOSE_ON_ERROR)
|
||||||
|
#define DMA_INT_MEM 4
|
||||||
|
|
||||||
|
#endif /* _ASM_ARCH_CRIS_DMA_H */
|
24
arch/cris/include/arch-v32/mach-fs/mach/memmap.h
Normal file
24
arch/cris/include/arch-v32/mach-fs/mach/memmap.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef _ASM_ARCH_MEMMAP_H
|
||||||
|
#define _ASM_ARCH_MEMMAP_H
|
||||||
|
|
||||||
|
#define MEM_CSE0_START (0x00000000)
|
||||||
|
#define MEM_CSE0_SIZE (0x04000000)
|
||||||
|
#define MEM_CSE1_START (0x04000000)
|
||||||
|
#define MEM_CSE1_SIZE (0x04000000)
|
||||||
|
#define MEM_CSR0_START (0x08000000)
|
||||||
|
#define MEM_CSR1_START (0x0c000000)
|
||||||
|
#define MEM_CSP0_START (0x10000000)
|
||||||
|
#define MEM_CSP1_START (0x14000000)
|
||||||
|
#define MEM_CSP2_START (0x18000000)
|
||||||
|
#define MEM_CSP3_START (0x1c000000)
|
||||||
|
#define MEM_CSP4_START (0x20000000)
|
||||||
|
#define MEM_CSP5_START (0x24000000)
|
||||||
|
#define MEM_CSP6_START (0x28000000)
|
||||||
|
#define MEM_CSP7_START (0x2c000000)
|
||||||
|
#define MEM_INTMEM_START (0x38000000)
|
||||||
|
#define MEM_INTMEM_SIZE (0x00020000)
|
||||||
|
#define MEM_DRAM_START (0x40000000)
|
||||||
|
|
||||||
|
#define MEM_NON_CACHEABLE (0x80000000)
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef STARTUP_INC_INCLUDED
|
||||||
|
#define STARTUP_INC_INCLUDED
|
||||||
|
|
||||||
#include <hwregs/asm/reg_map_asm.h>
|
#include <hwregs/asm/reg_map_asm.h>
|
||||||
#include <hwregs/asm/bif_core_defs_asm.h>
|
#include <hwregs/asm/bif_core_defs_asm.h>
|
||||||
#include <hwregs/asm/gio_defs_asm.h>
|
#include <hwregs/asm/gio_defs_asm.h>
|
||||||
|
@ -75,3 +78,5 @@
|
||||||
move.d $r10, [$r11]
|
move.d $r10, [$r11]
|
||||||
#endif
|
#endif
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -21,31 +21,35 @@
|
||||||
* /dev/leds minor 2, Access to leds depending on kernelconfig
|
* /dev/leds minor 2, Access to leds depending on kernelconfig
|
||||||
*
|
*
|
||||||
* For ARTPEC-3 (CONFIG_CRIS_MACH_ARTPEC3):
|
* For ARTPEC-3 (CONFIG_CRIS_MACH_ARTPEC3):
|
||||||
* /dev/gpioa minor 0, 8 bit GPIO, each bit can change direction
|
* /dev/gpioa minor 0, 32 bit GPIO, each bit can change direction
|
||||||
* /dev/gpiob minor 1, 18 bit GPIO, each bit can change direction
|
* /dev/gpiob minor 1, 32 bit GPIO, each bit can change direction
|
||||||
* /dev/gpioc minor 3, 18 bit GPIO, each bit can change direction
|
* /dev/gpioc minor 3, 16 bit GPIO, each bit can change direction
|
||||||
* /dev/gpiod minor 4, 18 bit GPIO, each bit can change direction
|
* /dev/gpiod minor 4, 32 bit GPIO, input only
|
||||||
* /dev/leds minor 2, Access to leds depending on kernelconfig
|
* /dev/leds minor 2, Access to leds depending on kernelconfig
|
||||||
* /dev/pwm0 minor 16, PWM channel 0 on PA30
|
* /dev/pwm0 minor 16, PWM channel 0 on PA30
|
||||||
* /dev/pwm1 minor 17, PWM channel 1 on PA31
|
* /dev/pwm1 minor 17, PWM channel 1 on PA31
|
||||||
* /dev/pwm2 minor 18, PWM channel 2 on PB26
|
* /dev/pwm2 minor 18, PWM channel 2 on PB26
|
||||||
|
* /dev/ppwm minor 19, PPWM channel
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef _ASM_ETRAXGPIO_H
|
#ifndef _ASM_ETRAXGPIO_H
|
||||||
#define _ASM_ETRAXGPIO_H
|
#define _ASM_ETRAXGPIO_H
|
||||||
|
|
||||||
|
#define GPIO_MINOR_FIRST 0
|
||||||
|
|
||||||
|
#define ETRAXGPIO_IOCTYPE 43
|
||||||
|
|
||||||
/* etraxgpio _IOC_TYPE, bits 8 to 15 in ioctl cmd */
|
/* etraxgpio _IOC_TYPE, bits 8 to 15 in ioctl cmd */
|
||||||
#ifdef CONFIG_ETRAX_ARCH_V10
|
#ifdef CONFIG_ETRAX_ARCH_V10
|
||||||
#define ETRAXGPIO_IOCTYPE 43
|
|
||||||
#define GPIO_MINOR_A 0
|
#define GPIO_MINOR_A 0
|
||||||
#define GPIO_MINOR_B 1
|
#define GPIO_MINOR_B 1
|
||||||
#define GPIO_MINOR_LEDS 2
|
#define GPIO_MINOR_LEDS 2
|
||||||
#define GPIO_MINOR_G 3
|
#define GPIO_MINOR_G 3
|
||||||
#define GPIO_MINOR_LAST 3
|
#define GPIO_MINOR_LAST 3
|
||||||
|
#define GPIO_MINOR_LAST_REAL GPIO_MINOR_LAST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ETRAXFS
|
#ifdef CONFIG_ETRAXFS
|
||||||
#define ETRAXGPIO_IOCTYPE 43
|
|
||||||
#define GPIO_MINOR_A 0
|
#define GPIO_MINOR_A 0
|
||||||
#define GPIO_MINOR_B 1
|
#define GPIO_MINOR_B 1
|
||||||
#define GPIO_MINOR_LEDS 2
|
#define GPIO_MINOR_LEDS 2
|
||||||
|
@ -58,10 +62,10 @@
|
||||||
#else
|
#else
|
||||||
#define GPIO_MINOR_LAST 5
|
#define GPIO_MINOR_LAST 5
|
||||||
#endif
|
#endif
|
||||||
|
#define GPIO_MINOR_LAST_REAL GPIO_MINOR_LAST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_CRIS_MACH_ARTPEC3
|
#ifdef CONFIG_CRIS_MACH_ARTPEC3
|
||||||
#define ETRAXGPIO_IOCTYPE 43
|
|
||||||
#define GPIO_MINOR_A 0
|
#define GPIO_MINOR_A 0
|
||||||
#define GPIO_MINOR_B 1
|
#define GPIO_MINOR_B 1
|
||||||
#define GPIO_MINOR_LEDS 2
|
#define GPIO_MINOR_LEDS 2
|
||||||
|
@ -73,12 +77,17 @@
|
||||||
#else
|
#else
|
||||||
#define GPIO_MINOR_LAST 4
|
#define GPIO_MINOR_LAST 4
|
||||||
#endif
|
#endif
|
||||||
#define GPIO_MINOR_PWM0 16
|
#define GPIO_MINOR_FIRST_PWM 16
|
||||||
#define GPIO_MINOR_PWM1 17
|
#define GPIO_MINOR_PWM0 (GPIO_MINOR_FIRST_PWM+0)
|
||||||
#define GPIO_MINOR_PWM2 18
|
#define GPIO_MINOR_PWM1 (GPIO_MINOR_FIRST_PWM+1)
|
||||||
#define GPIO_MINOR_LAST_PWM GPIO_MINOR_PWM2
|
#define GPIO_MINOR_PWM2 (GPIO_MINOR_FIRST_PWM+2)
|
||||||
|
#define GPIO_MINOR_PPWM (GPIO_MINOR_FIRST_PWM+3)
|
||||||
|
#define GPIO_MINOR_LAST_PWM GPIO_MINOR_PPWM
|
||||||
|
#define GPIO_MINOR_LAST_REAL GPIO_MINOR_LAST_PWM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* supported ioctl _IOC_NR's */
|
/* supported ioctl _IOC_NR's */
|
||||||
|
|
||||||
#define IO_READBITS 0x1 /* read and return current port bits (obsolete) */
|
#define IO_READBITS 0x1 /* read and return current port bits (obsolete) */
|
||||||
|
@ -125,12 +134,10 @@
|
||||||
*/
|
*/
|
||||||
#define IO_READ_INBITS 0x10 /* *arg is result of reading the input pins */
|
#define IO_READ_INBITS 0x10 /* *arg is result of reading the input pins */
|
||||||
#define IO_READ_OUTBITS 0x11 /* *arg is result of reading the output shadow */
|
#define IO_READ_OUTBITS 0x11 /* *arg is result of reading the output shadow */
|
||||||
#define IO_SETGET_INPUT 0x12 /* bits set in *arg is set to input,
|
#define IO_SETGET_INPUT 0x12 /* bits set in *arg is set to input, */
|
||||||
* *arg updated with current input pins.
|
/* *arg updated with current input pins. */
|
||||||
*/
|
#define IO_SETGET_OUTPUT 0x13 /* bits set in *arg is set to output, */
|
||||||
#define IO_SETGET_OUTPUT 0x13 /* bits set in *arg is set to output,
|
/* *arg updated with current output pins. */
|
||||||
* *arg updated with current output pins.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* The following ioctl's are applicable to the PWM channels only */
|
/* The following ioctl's are applicable to the PWM channels only */
|
||||||
|
|
||||||
|
@ -140,7 +147,8 @@ enum io_pwm_mode {
|
||||||
PWM_OFF = 0, /* disabled, deallocated */
|
PWM_OFF = 0, /* disabled, deallocated */
|
||||||
PWM_STANDARD = 1, /* 390 kHz, duty cycle 0..255/256 */
|
PWM_STANDARD = 1, /* 390 kHz, duty cycle 0..255/256 */
|
||||||
PWM_FAST = 2, /* variable freq, w/ 10ns active pulse len */
|
PWM_FAST = 2, /* variable freq, w/ 10ns active pulse len */
|
||||||
PWM_VARFREQ = 3 /* individually configurable high/low periods */
|
PWM_VARFREQ = 3, /* individually configurable high/low periods */
|
||||||
|
PWM_SOFT = 4 /* software generated */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct io_pwm_set_mode {
|
struct io_pwm_set_mode {
|
||||||
|
@ -176,4 +184,56 @@ struct io_pwm_set_duty {
|
||||||
int duty; /* 0..255 */
|
int duty; /* 0..255 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Returns information about the latest PWM pulse.
|
||||||
|
* lo: Length of the latest low period, in units of 10ns.
|
||||||
|
* hi: Length of the latest high period, in units of 10ns.
|
||||||
|
* cnt: Time since last detected edge, in units of 10ns.
|
||||||
|
*
|
||||||
|
* The input source to PWM is decied by IO_PWM_SET_INPUT_SRC.
|
||||||
|
*
|
||||||
|
* NOTE: All PWM devices is connected to the same input source.
|
||||||
|
*/
|
||||||
|
#define IO_PWM_GET_PERIOD 0x23
|
||||||
|
|
||||||
|
struct io_pwm_get_period {
|
||||||
|
unsigned int lo;
|
||||||
|
unsigned int hi;
|
||||||
|
unsigned int cnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Sets the input source for the PWM input. For the src value see the
|
||||||
|
* register description for gio:rw_pwm_in_cfg.
|
||||||
|
*
|
||||||
|
* NOTE: All PWM devices is connected to the same input source.
|
||||||
|
*/
|
||||||
|
#define IO_PWM_SET_INPUT_SRC 0x24
|
||||||
|
struct io_pwm_set_input_src {
|
||||||
|
unsigned int src; /* 0..7 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Sets the duty cycles in steps of 1/256, 0 = 0%, 255 = 100% duty cycle */
|
||||||
|
#define IO_PPWM_SET_DUTY 0x25
|
||||||
|
|
||||||
|
struct io_ppwm_set_duty {
|
||||||
|
int duty; /* 0..255 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Configuraton struct for the IO_PWMCLK_SET_CONFIG ioctl to configure
|
||||||
|
* PWM capable gpio pins:
|
||||||
|
*/
|
||||||
|
#define IO_PWMCLK_SETGET_CONFIG 0x26
|
||||||
|
struct gpio_pwmclk_conf {
|
||||||
|
unsigned int gpiopin; /* The pin number based on the opened device */
|
||||||
|
unsigned int baseclk; /* The base clock to use, or sw will select one close*/
|
||||||
|
unsigned int low; /* The number of low periods of the baseclk */
|
||||||
|
unsigned int high; /* The number of high periods of the baseclk */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Examples:
|
||||||
|
* To get a symmetric 12 MHz clock without knowing anything about the hardware:
|
||||||
|
* baseclk = 12000000, low = 0, high = 0
|
||||||
|
* To just get info of current setting:
|
||||||
|
* baseclk = 0, low = 0, high = 0, the values will be updated by driver.
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define SSP_OPOLARITY _IOR('S', 4, unsigned int)
|
#define SSP_OPOLARITY _IOR('S', 4, unsigned int)
|
||||||
#define SSP_SPI _IOR('S', 5, unsigned int)
|
#define SSP_SPI _IOR('S', 5, unsigned int)
|
||||||
#define SSP_INBUFCHUNK _IOR('S', 6, unsigned int)
|
#define SSP_INBUFCHUNK _IOR('S', 6, unsigned int)
|
||||||
|
#define SSP_INPUT _IOR('S', 7, unsigned int)
|
||||||
|
|
||||||
/* Values for SSP_SPEED */
|
/* Values for SSP_SPEED */
|
||||||
#define SSP150 0
|
#define SSP150 0
|
||||||
|
@ -37,6 +38,7 @@
|
||||||
#define SSP921600 13
|
#define SSP921600 13
|
||||||
#define SSP3125000 14
|
#define SSP3125000 14
|
||||||
#define CODEC 15
|
#define CODEC 15
|
||||||
|
#define CODEC_f32768 16
|
||||||
|
|
||||||
#define FREQ_4MHz 0
|
#define FREQ_4MHz 0
|
||||||
#define FREQ_2MHz 1
|
#define FREQ_2MHz 1
|
||||||
|
@ -46,9 +48,14 @@
|
||||||
#define FREQ_128kHz 5
|
#define FREQ_128kHz 5
|
||||||
#define FREQ_64kHz 6
|
#define FREQ_64kHz 6
|
||||||
#define FREQ_32kHz 7
|
#define FREQ_32kHz 7
|
||||||
|
/* FREQ_* with values where bit (value & 0x10) is set are */
|
||||||
|
/* used for CODEC_f32768 */
|
||||||
|
#define FREQ_4096kHz 16 /* CODEC_f32768 */
|
||||||
|
|
||||||
/* Used by application to set CODEC divider, word rate and frame rate */
|
/* Used by application to set CODEC divider, word rate and frame rate */
|
||||||
#define CODEC_VAL(freq, clk_per_sync, sync_per_frame) (CODEC | (freq << 8) | (clk_per_sync << 16) | (sync_per_frame << 28))
|
#define CODEC_VAL(freq, clk_per_sync, sync_per_frame) \
|
||||||
|
((CODEC + ((freq & 0x10) >> 4)) | (freq << 8) | \
|
||||||
|
(clk_per_sync << 16) | (sync_per_frame << 28))
|
||||||
|
|
||||||
/* Used by driver to extract speed */
|
/* Used by driver to extract speed */
|
||||||
#define GET_SPEED(x) (x & 0xff)
|
#define GET_SPEED(x) (x & 0xff)
|
||||||
|
@ -68,6 +75,7 @@
|
||||||
#define NORMAL_SYNC 1
|
#define NORMAL_SYNC 1
|
||||||
#define EARLY_SYNC 2
|
#define EARLY_SYNC 2
|
||||||
#define SECOND_WORD_SYNC 0x40000
|
#define SECOND_WORD_SYNC 0x40000
|
||||||
|
#define LATE_SYNC 0x80000
|
||||||
|
|
||||||
#define BIT_SYNC 4
|
#define BIT_SYNC 4
|
||||||
#define WORD_SYNC 8
|
#define WORD_SYNC 8
|
||||||
|
@ -104,4 +112,21 @@
|
||||||
/* Values for SSP_INBUFCHUNK */
|
/* Values for SSP_INBUFCHUNK */
|
||||||
/* plain integer with the size of DMA chunks */
|
/* plain integer with the size of DMA chunks */
|
||||||
|
|
||||||
|
/* To ensure that the timestamps are aligned with the data being read
|
||||||
|
* the read length MUST be a multiple of the length of the DMA buffers.
|
||||||
|
*
|
||||||
|
* Use a multiple of SSP_INPUT_CHUNK_SIZE defined below.
|
||||||
|
*/
|
||||||
|
#define SSP_INPUT_CHUNK_SIZE 256
|
||||||
|
|
||||||
|
/* Request struct to pass through the ioctl interface to read
|
||||||
|
* data with timestamps.
|
||||||
|
*/
|
||||||
|
struct ssp_request {
|
||||||
|
char __user *buf; /* Where to put the data. */
|
||||||
|
size_t len; /* Size of buf. MUST be a multiple of */
|
||||||
|
/* SSP_INPUT_CHUNK_SIZE! */
|
||||||
|
struct timespec ts; /* The time the data was sampled. */
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,12 +9,11 @@
|
||||||
|
|
||||||
#define SAMPLE_BUFFER_SIZE 8192
|
#define SAMPLE_BUFFER_SIZE 8192
|
||||||
|
|
||||||
static char* sample_buffer;
|
static char *sample_buffer;
|
||||||
static char* sample_buffer_pos;
|
static char *sample_buffer_pos;
|
||||||
static int prof_running = 0;
|
static int prof_running = 0;
|
||||||
|
|
||||||
void
|
void cris_profile_sample(struct pt_regs *regs)
|
||||||
cris_profile_sample(struct pt_regs* regs)
|
|
||||||
{
|
{
|
||||||
if (!prof_running)
|
if (!prof_running)
|
||||||
return;
|
return;
|
||||||
|
@ -24,7 +23,7 @@ cris_profile_sample(struct pt_regs* regs)
|
||||||
else
|
else
|
||||||
*(unsigned int*)sample_buffer_pos = 0;
|
*(unsigned int*)sample_buffer_pos = 0;
|
||||||
|
|
||||||
*(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs);
|
*(unsigned int *)(sample_buffer_pos + 4) = instruction_pointer(regs);
|
||||||
sample_buffer_pos += 8;
|
sample_buffer_pos += 8;
|
||||||
|
|
||||||
if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE)
|
if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE)
|
||||||
|
@ -54,6 +53,7 @@ write_cris_profile(struct file *file, const char __user *buf,
|
||||||
{
|
{
|
||||||
sample_buffer_pos = sample_buffer;
|
sample_buffer_pos = sample_buffer;
|
||||||
memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE);
|
memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE);
|
||||||
|
return count < SAMPLE_BUFFER_SIZE ? count : SAMPLE_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations cris_proc_profile_operations = {
|
static const struct file_operations cris_proc_profile_operations = {
|
||||||
|
@ -61,8 +61,7 @@ static const struct file_operations cris_proc_profile_operations = {
|
||||||
.write = write_cris_profile,
|
.write = write_cris_profile,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int __init init_cris_profile(void)
|
||||||
__init init_cris_profile(void)
|
|
||||||
{
|
{
|
||||||
struct proc_dir_entry *entry;
|
struct proc_dir_entry *entry;
|
||||||
|
|
||||||
|
@ -82,5 +81,5 @@ __init init_cris_profile(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__initcall(init_cris_profile);
|
__initcall(init_cris_profile);
|
||||||
|
|
||||||
|
|
|
@ -39,13 +39,16 @@ int have_rtc; /* used to remember if we have an RTC or not */;
|
||||||
extern unsigned long loops_per_jiffy; /* init/main.c */
|
extern unsigned long loops_per_jiffy; /* init/main.c */
|
||||||
unsigned long loops_per_usec;
|
unsigned long loops_per_usec;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
|
||||||
extern unsigned long do_slow_gettimeoffset(void);
|
extern unsigned long do_slow_gettimeoffset(void);
|
||||||
static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
|
static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
|
||||||
|
|
||||||
u32 arch_gettimeoffset(void)
|
u32 arch_gettimeoffset(void)
|
||||||
{
|
{
|
||||||
return do_gettimeoffset() * 1000;
|
return do_gettimeoffset() * 1000;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BUG: This routine does not handle hour overflow properly; it just
|
* BUG: This routine does not handle hour overflow properly; it just
|
||||||
|
@ -151,7 +154,7 @@ cris_do_profile(struct pt_regs* regs)
|
||||||
|
|
||||||
unsigned long long sched_clock(void)
|
unsigned long long sched_clock(void)
|
||||||
{
|
{
|
||||||
return (unsigned long long)jiffies * (1000000000 / HZ) +
|
return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ) +
|
||||||
get_ns_in_jiffie();
|
get_ns_in_jiffie();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,8 @@ SECTIONS
|
||||||
___data_start = . ;
|
___data_start = . ;
|
||||||
__Sdata = . ;
|
__Sdata = . ;
|
||||||
.data : { /* Data */
|
.data : { /* Data */
|
||||||
|
CACHELINE_ALIGNED_DATA(32)
|
||||||
|
READ_MOSTLY_DATA(32)
|
||||||
DATA_DATA
|
DATA_DATA
|
||||||
}
|
}
|
||||||
__edata = . ; /* End of data section. */
|
__edata = . ; /* End of data section. */
|
||||||
|
@ -84,6 +86,16 @@ SECTIONS
|
||||||
}
|
}
|
||||||
SECURITY_INIT
|
SECURITY_INIT
|
||||||
|
|
||||||
|
/* .exit.text is discarded at runtime, not link time,
|
||||||
|
* to deal with references from __bug_table
|
||||||
|
*/
|
||||||
|
.exit.text : {
|
||||||
|
EXIT_TEXT
|
||||||
|
}
|
||||||
|
.exit.data : {
|
||||||
|
EXIT_DATA
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ETRAX_ARCH_V10
|
#ifdef CONFIG_ETRAX_ARCH_V10
|
||||||
#ifdef CONFIG_BLK_DEV_INITRD
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||||||
.init.ramfs : {
|
.init.ramfs : {
|
||||||
|
@ -112,7 +124,7 @@ SECTIONS
|
||||||
__init_end = .;
|
__init_end = .;
|
||||||
|
|
||||||
__data_end = . ; /* Move to _edata ? */
|
__data_end = . ; /* Move to _edata ? */
|
||||||
BSS_SECTION(0, 0, 0)
|
BSS_SECTION(1, 1, 1)
|
||||||
|
|
||||||
. = ALIGN (0x20);
|
. = ALIGN (0x20);
|
||||||
_end = .;
|
_end = .;
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
/*
|
/*
|
||||||
* linux/arch/cris/mm/fault.c
|
* arch/cris/mm/fault.c
|
||||||
*
|
|
||||||
* Copyright (C) 2000-2006 Axis Communications AB
|
|
||||||
*
|
|
||||||
* Authors: Bjorn Wesen
|
|
||||||
*
|
*
|
||||||
|
* Copyright (C) 2000-2010 Axis Communications AB
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/wait.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
extern int find_fixup_code(struct pt_regs *);
|
extern int find_fixup_code(struct pt_regs *);
|
||||||
extern void die_if_kernel(const char *, struct pt_regs *, long);
|
extern void die_if_kernel(const char *, struct pt_regs *, long);
|
||||||
|
extern void show_registers(struct pt_regs *regs);
|
||||||
|
|
||||||
/* debug of low-level TLB reload */
|
/* debug of low-level TLB reload */
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
@ -108,11 +107,11 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
|
||||||
info.si_code = SEGV_MAPERR;
|
info.si_code = SEGV_MAPERR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're in an interrupt or have no user
|
* If we're in an interrupt or "atomic" operation or have no
|
||||||
* context, we must not take the fault..
|
* user context, we must not take the fault.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (in_interrupt() || !mm)
|
if (in_atomic() || !mm)
|
||||||
goto no_context;
|
goto no_context;
|
||||||
|
|
||||||
down_read(&mm->mmap_sem);
|
down_read(&mm->mmap_sem);
|
||||||
|
@ -193,14 +192,25 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
|
||||||
/* User mode accesses just cause a SIGSEGV */
|
/* User mode accesses just cause a SIGSEGV */
|
||||||
|
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
|
printk(KERN_NOTICE "%s (pid %d) segfaults for page "
|
||||||
|
"address %08lx at pc %08lx\n",
|
||||||
|
tsk->comm, tsk->pid,
|
||||||
|
address, instruction_pointer(regs));
|
||||||
|
|
||||||
|
/* With DPG on, we've already dumped registers above. */
|
||||||
|
DPG(if (0))
|
||||||
|
show_registers(regs);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NO_SEGFAULT_TERMINATION
|
||||||
|
DECLARE_WAIT_QUEUE_HEAD(wq);
|
||||||
|
wait_event_interruptible(wq, 0 == 1);
|
||||||
|
#else
|
||||||
info.si_signo = SIGSEGV;
|
info.si_signo = SIGSEGV;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
/* info.si_code has been set above */
|
/* info.si_code has been set above */
|
||||||
info.si_addr = (void *)address;
|
info.si_addr = (void *)address;
|
||||||
force_sig_info(SIGSEGV, &info, tsk);
|
force_sig_info(SIGSEGV, &info, tsk);
|
||||||
printk(KERN_NOTICE "%s (pid %d) segfaults for page "
|
#endif
|
||||||
"address %08lx at pc %08lx\n",
|
|
||||||
tsk->comm, tsk->pid, address, instruction_pointer(regs));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,10 +255,10 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
|
||||||
|
|
||||||
out_of_memory:
|
out_of_memory:
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
printk("VM: killing process %s\n", tsk->comm);
|
if (!user_mode(regs))
|
||||||
if (user_mode(regs))
|
goto no_context;
|
||||||
do_exit(SIGKILL);
|
pagefault_out_of_memory();
|
||||||
goto no_context;
|
return;
|
||||||
|
|
||||||
do_sigbus:
|
do_sigbus:
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
|
@ -334,8 +344,11 @@ int
|
||||||
find_fixup_code(struct pt_regs *regs)
|
find_fixup_code(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
const struct exception_table_entry *fixup;
|
const struct exception_table_entry *fixup;
|
||||||
|
/* in case of delay slot fault (v32) */
|
||||||
|
unsigned long ip = (instruction_pointer(regs) & ~0x1);
|
||||||
|
|
||||||
if ((fixup = search_exception_tables(instruction_pointer(regs))) != 0) {
|
fixup = search_exception_tables(ip);
|
||||||
|
if (fixup != 0) {
|
||||||
/* Adjust the instruction pointer in the stackframe. */
|
/* Adjust the instruction pointer in the stackframe. */
|
||||||
instruction_pointer(regs) = fixup->fixup;
|
instruction_pointer(regs) = fixup->fixup;
|
||||||
arch_fixup(regs);
|
arch_fixup(regs);
|
||||||
|
|
Loading…
Reference in a new issue