Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu
Pull m68knommu arch updates from Greg Ungerer: "Includes a cleanup of the non-MMU linker script (it now almost exclusively uses the well defined linker script support macros and definitions). Some more merging of MMU and non-MMU common files (specifically the arch process.c, ptrace and time.c). And a big cleanup of the massively duplicated ColdFire device definition code. Overall we remove about 2000 lines of code, and end up with a single set of platform device definitions for the serial ports, ethernet ports and QSPI ports common in most ColdFire SoCs. I expect you will get a merge conflict on arch/m68k/kernel/process.c, in cpu_idle(). It should be relatively strait forward to fixup." And cpu_idle() conflict resolution was indeed trivial (merging the nommu/mmu versions of process.c trivially conflicting with the conversion to use the schedule_preempt_disabled() helper function) * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu: (57 commits) m68knommu: factor more common ColdFire cpu reset code m68knommu: make 528x CPU reset register addressing consistent m68knommu: make 527x CPU reset register addressing consistent m68knommu: make 523x CPU reset register addressing consistent m68knommu: factor some common ColdFire cpu reset code m68knommu: move old ColdFire timers init from CPU init to timers code m68knommu: clean up init code in ColdFire 532x startup m68knommu: clean up init code in ColdFire 528x startup m68knommu: clean up init code in ColdFire 523x startup m68knommu: merge common ColdFire QSPI platform setup code m68knommu: make 532x QSPI platform addressing consistent m68knommu: make 528x QSPI platform addressing consistent m68knommu: make 527x QSPI platform addressing consistent m68knommu: make 5249 QSPI platform addressing consistent m68knommu: make 523x QSPI platform addressing consistent m68knommu: make 520x QSPI platform addressing consistent m68knommu: merge common ColdFire FEC platform setup code m68knommu: make 532x FEC platform addressing consistent m68knommu: make 528x FEC platform addressing consistent m68knommu: make 527x FEC platform addressing consistent ...
This commit is contained in:
@@ -7,6 +7,7 @@ config M68K
|
|||||||
select GENERIC_IRQ_SHOW
|
select GENERIC_IRQ_SHOW
|
||||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
|
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
|
||||||
select GENERIC_CPU_DEVICES
|
select GENERIC_CPU_DEVICES
|
||||||
|
select FPU if MMU
|
||||||
|
|
||||||
config RWSEM_GENERIC_SPINLOCK
|
config RWSEM_GENERIC_SPINLOCK
|
||||||
bool
|
bool
|
||||||
@@ -24,9 +25,6 @@ config ARCH_HAS_ILOG2_U64
|
|||||||
config GENERIC_CLOCKEVENTS
|
config GENERIC_CLOCKEVENTS
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config GENERIC_CMOS_UPDATE
|
|
||||||
def_bool !MMU
|
|
||||||
|
|
||||||
config GENERIC_GPIO
|
config GENERIC_GPIO
|
||||||
bool
|
bool
|
||||||
|
|
||||||
@@ -67,6 +65,9 @@ config CPU_HAS_NO_MULDIV64
|
|||||||
config CPU_HAS_ADDRESS_SPACES
|
config CPU_HAS_ADDRESS_SPACES
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config FPU
|
||||||
|
bool
|
||||||
|
|
||||||
config HZ
|
config HZ
|
||||||
int
|
int
|
||||||
default 1000 if CLEOPATRA
|
default 1000 if CLEOPATRA
|
||||||
|
@@ -100,11 +100,11 @@
|
|||||||
#define MCFDMA_BASE1 (MCF_MBAR + 0x240) /* Base address DMA 1 */
|
#define MCFDMA_BASE1 (MCF_MBAR + 0x240) /* Base address DMA 1 */
|
||||||
|
|
||||||
#if defined(CONFIG_NETtel)
|
#if defined(CONFIG_NETtel)
|
||||||
#define MCFUART_BASE1 0x180 /* Base address of UART1 */
|
#define MCFUART_BASE0 (MCF_MBAR + 0x180) /* Base address UART0 */
|
||||||
#define MCFUART_BASE2 0x140 /* Base address of UART2 */
|
#define MCFUART_BASE1 (MCF_MBAR + 0x140) /* Base address UART1 */
|
||||||
#else
|
#else
|
||||||
#define MCFUART_BASE1 0x140 /* Base address of UART1 */
|
#define MCFUART_BASE0 (MCF_MBAR + 0x140) /* Base address UART0 */
|
||||||
#define MCFUART_BASE2 0x180 /* Base address of UART2 */
|
#define MCFUART_BASE1 (MCF_MBAR + 0x180) /* Base address UART1 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -112,6 +112,8 @@
|
|||||||
*/
|
*/
|
||||||
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
||||||
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
||||||
|
#define MCF_IRQ_UART0 73 /* UART0 */
|
||||||
|
#define MCF_IRQ_UART1 74 /* UART1 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic GPIO
|
* Generic GPIO
|
||||||
|
@@ -48,8 +48,21 @@
|
|||||||
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
|
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
|
||||||
#define MCFINT_UART2 28 /* Interrupt number for UART2 */
|
#define MCFINT_UART2 28 /* Interrupt number for UART2 */
|
||||||
#define MCFINT_QSPI 31 /* Interrupt number for QSPI */
|
#define MCFINT_QSPI 31 /* Interrupt number for QSPI */
|
||||||
|
#define MCFINT_FECRX0 36 /* Interrupt number for FEC RX */
|
||||||
|
#define MCFINT_FECTX0 40 /* Interrupt number for FEC RX */
|
||||||
|
#define MCFINT_FECENTC0 42 /* Interrupt number for FEC RX */
|
||||||
#define MCFINT_PIT1 4 /* Interrupt number for PIT1 (PIT0 in processor) */
|
#define MCFINT_PIT1 4 /* Interrupt number for PIT1 (PIT0 in processor) */
|
||||||
|
|
||||||
|
#define MCF_IRQ_UART0 (MCFINT_VECBASE + MCFINT_UART0)
|
||||||
|
#define MCF_IRQ_UART1 (MCFINT_VECBASE + MCFINT_UART1)
|
||||||
|
#define MCF_IRQ_UART2 (MCFINT_VECBASE + MCFINT_UART2)
|
||||||
|
|
||||||
|
#define MCF_IRQ_FECRX0 (MCFINT_VECBASE + MCFINT_FECRX0)
|
||||||
|
#define MCF_IRQ_FECTX0 (MCFINT_VECBASE + MCFINT_FECTX0)
|
||||||
|
#define MCF_IRQ_FECENTC0 (MCFINT_VECBASE + MCFINT_FECENTC0)
|
||||||
|
|
||||||
|
#define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SDRAM configuration registers.
|
* SDRAM configuration registers.
|
||||||
*/
|
*/
|
||||||
@@ -144,15 +157,25 @@
|
|||||||
/*
|
/*
|
||||||
* UART module.
|
* UART module.
|
||||||
*/
|
*/
|
||||||
#define MCFUART_BASE1 0xFC060000 /* Base address of UART1 */
|
#define MCFUART_BASE0 0xFC060000 /* Base address of UART0 */
|
||||||
#define MCFUART_BASE2 0xFC064000 /* Base address of UART2 */
|
#define MCFUART_BASE1 0xFC064000 /* Base address of UART1 */
|
||||||
#define MCFUART_BASE3 0xFC068000 /* Base address of UART2 */
|
#define MCFUART_BASE2 0xFC068000 /* Base address of UART2 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FEC module.
|
* FEC module.
|
||||||
*/
|
*/
|
||||||
#define MCFFEC_BASE 0xFC030000 /* Base of FEC ethernet */
|
#define MCFFEC_BASE0 0xFC030000 /* Base of FEC ethernet */
|
||||||
#define MCFFEC_SIZE 0x800 /* Register set size */
|
#define MCFFEC_SIZE0 0x800 /* Register set size */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QSPI module.
|
||||||
|
*/
|
||||||
|
#define MCFQSPI_BASE 0xFC05C000 /* Base of QSPI module */
|
||||||
|
#define MCFQSPI_SIZE 0x40 /* Register set size */
|
||||||
|
|
||||||
|
#define MCFQSPI_CS0 46
|
||||||
|
#define MCFQSPI_CS1 47
|
||||||
|
#define MCFQSPI_CS2 27
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset Control Unit.
|
* Reset Control Unit.
|
||||||
|
@@ -35,8 +35,23 @@
|
|||||||
|
|
||||||
#define MCFINT_VECBASE 64 /* Vector base number */
|
#define MCFINT_VECBASE 64 /* Vector base number */
|
||||||
#define MCFINT_UART0 13 /* Interrupt number for UART0 */
|
#define MCFINT_UART0 13 /* Interrupt number for UART0 */
|
||||||
#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */
|
#define MCFINT_UART1 14 /* Interrupt number for UART1 */
|
||||||
|
#define MCFINT_UART2 15 /* Interrupt number for UART2 */
|
||||||
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
|
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
|
||||||
|
#define MCFINT_FECRX0 23 /* Interrupt number for FEC */
|
||||||
|
#define MCFINT_FECTX0 27 /* Interrupt number for FEC */
|
||||||
|
#define MCFINT_FECENTC0 29 /* Interrupt number for FEC */
|
||||||
|
#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */
|
||||||
|
|
||||||
|
#define MCF_IRQ_UART0 (MCFINT_VECBASE + MCFINT_UART0)
|
||||||
|
#define MCF_IRQ_UART1 (MCFINT_VECBASE + MCFINT_UART1)
|
||||||
|
#define MCF_IRQ_UART2 (MCFINT_VECBASE + MCFINT_UART2)
|
||||||
|
|
||||||
|
#define MCF_IRQ_FECRX0 (MCFINT_VECBASE + MCFINT_FECRX0)
|
||||||
|
#define MCF_IRQ_FECTX0 (MCFINT_VECBASE + MCFINT_FECTX0)
|
||||||
|
#define MCF_IRQ_FECENTC0 (MCFINT_VECBASE + MCFINT_FECENTC0)
|
||||||
|
|
||||||
|
#define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SDRAM configuration registers.
|
* SDRAM configuration registers.
|
||||||
@@ -50,8 +65,8 @@
|
|||||||
/*
|
/*
|
||||||
* Reset Control Unit (relative to IPSBAR).
|
* Reset Control Unit (relative to IPSBAR).
|
||||||
*/
|
*/
|
||||||
#define MCF_RCR 0x110000
|
#define MCF_RCR (MCF_IPSBAR + 0x110000)
|
||||||
#define MCF_RSR 0x110001
|
#define MCF_RSR (MCF_IPSBAR + 0x110001)
|
||||||
|
|
||||||
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
|
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
|
||||||
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
|
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
|
||||||
@@ -59,15 +74,26 @@
|
|||||||
/*
|
/*
|
||||||
* UART module.
|
* UART module.
|
||||||
*/
|
*/
|
||||||
#define MCFUART_BASE1 (MCF_IPSBAR + 0x200)
|
#define MCFUART_BASE0 (MCF_IPSBAR + 0x200)
|
||||||
#define MCFUART_BASE2 (MCF_IPSBAR + 0x240)
|
#define MCFUART_BASE1 (MCF_IPSBAR + 0x240)
|
||||||
#define MCFUART_BASE3 (MCF_IPSBAR + 0x280)
|
#define MCFUART_BASE2 (MCF_IPSBAR + 0x280)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FEC ethernet module.
|
* FEC ethernet module.
|
||||||
*/
|
*/
|
||||||
#define MCFFEC_BASE (MCF_IPSBAR + 0x1000)
|
#define MCFFEC_BASE0 (MCF_IPSBAR + 0x1000)
|
||||||
#define MCFFEC_SIZE 0x800
|
#define MCFFEC_SIZE0 0x800
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QSPI module.
|
||||||
|
*/
|
||||||
|
#define MCFQSPI_BASE (MCF_IPSBAR + 0x340)
|
||||||
|
#define MCFQSPI_SIZE 0x40
|
||||||
|
|
||||||
|
#define MCFQSPI_CS0 91
|
||||||
|
#define MCFQSPI_CS1 92
|
||||||
|
#define MCFQSPI_CS2 103
|
||||||
|
#define MCFQSPI_CS3 99
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPIO module.
|
* GPIO module.
|
||||||
|
@@ -76,8 +76,19 @@
|
|||||||
/*
|
/*
|
||||||
* UART module.
|
* UART module.
|
||||||
*/
|
*/
|
||||||
#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
|
#define MCFUART_BASE0 (MCF_MBAR + 0x1c0) /* Base address UART0 */
|
||||||
#define MCFUART_BASE2 0x200 /* Base address of UART2 */
|
#define MCFUART_BASE1 (MCF_MBAR + 0x200) /* Base address UART1 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QSPI module.
|
||||||
|
*/
|
||||||
|
#define MCFQSPI_BASE (MCF_MBAR + 0x300) /* Base address QSPI */
|
||||||
|
#define MCFQSPI_SIZE 0x40 /* Register set size */
|
||||||
|
|
||||||
|
#define MCFQSPI_CS0 29
|
||||||
|
#define MCFQSPI_CS1 24
|
||||||
|
#define MCFQSPI_CS2 21
|
||||||
|
#define MCFQSPI_CS3 22
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DMA unit base addresses.
|
* DMA unit base addresses.
|
||||||
@@ -108,6 +119,9 @@
|
|||||||
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
||||||
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
||||||
|
|
||||||
|
#define MCF_IRQ_UART0 73 /* UART0 */
|
||||||
|
#define MCF_IRQ_UART1 74 /* UART1 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* General purpose IO registers (in MBAR2).
|
* General purpose IO registers (in MBAR2).
|
||||||
*/
|
*/
|
||||||
|
@@ -68,8 +68,8 @@
|
|||||||
#define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */
|
#define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */
|
||||||
#define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */
|
#define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */
|
||||||
|
|
||||||
#define MCFUART_BASE1 0x100 /* Base address of UART1 */
|
#define MCFUART_BASE0 (MCF_MBAR + 0x100) /* Base address UART0 */
|
||||||
#define MCFUART_BASE2 0x140 /* Base address of UART2 */
|
#define MCFUART_BASE1 (MCF_MBAR + 0x140) /* Base address UART1 */
|
||||||
|
|
||||||
#define MCFSIM_PACNT (MCF_MBAR + 0x80) /* Port A Control (r/w) */
|
#define MCFSIM_PACNT (MCF_MBAR + 0x80) /* Port A Control (r/w) */
|
||||||
#define MCFSIM_PADDR (MCF_MBAR + 0x84) /* Port A Direction (r/w) */
|
#define MCFSIM_PADDR (MCF_MBAR + 0x84) /* Port A Direction (r/w) */
|
||||||
@@ -88,6 +88,9 @@
|
|||||||
#define MCFTIMER_BASE3 (MCF_MBAR + 0x240) /* Base address TIMER4 */
|
#define MCFTIMER_BASE3 (MCF_MBAR + 0x240) /* Base address TIMER4 */
|
||||||
#define MCFTIMER_BASE4 (MCF_MBAR + 0x260) /* Base address TIMER3 */
|
#define MCFTIMER_BASE4 (MCF_MBAR + 0x260) /* Base address TIMER3 */
|
||||||
|
|
||||||
|
#define MCFFEC_BASE0 (MCF_MBAR + 0x840) /* Base FEC ethernet */
|
||||||
|
#define MCFFEC_SIZE0 0x1d0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define system peripheral IRQ usage.
|
* Define system peripheral IRQ usage.
|
||||||
*/
|
*/
|
||||||
@@ -101,8 +104,8 @@
|
|||||||
#define MCF_IRQ_TIMER2 70 /* Timer 2 */
|
#define MCF_IRQ_TIMER2 70 /* Timer 2 */
|
||||||
#define MCF_IRQ_TIMER3 71 /* Timer 3 */
|
#define MCF_IRQ_TIMER3 71 /* Timer 3 */
|
||||||
#define MCF_IRQ_TIMER4 72 /* Timer 4 */
|
#define MCF_IRQ_TIMER4 72 /* Timer 4 */
|
||||||
#define MCF_IRQ_UART1 73 /* UART 1 */
|
#define MCF_IRQ_UART0 73 /* UART 0 */
|
||||||
#define MCF_IRQ_UART2 74 /* UART 2 */
|
#define MCF_IRQ_UART1 74 /* UART 1 */
|
||||||
#define MCF_IRQ_PLIP 75 /* PLIC 2Khz Periodic */
|
#define MCF_IRQ_PLIP 75 /* PLIC 2Khz Periodic */
|
||||||
#define MCF_IRQ_PLIA 76 /* PLIC Asynchronous */
|
#define MCF_IRQ_PLIA 76 /* PLIC Asynchronous */
|
||||||
#define MCF_IRQ_USB0 77 /* USB Endpoint 0 */
|
#define MCF_IRQ_USB0 77 /* USB Endpoint 0 */
|
||||||
@@ -114,9 +117,9 @@
|
|||||||
#define MCF_IRQ_USB6 83 /* USB Endpoint 6 */
|
#define MCF_IRQ_USB6 83 /* USB Endpoint 6 */
|
||||||
#define MCF_IRQ_USB7 84 /* USB Endpoint 7 */
|
#define MCF_IRQ_USB7 84 /* USB Endpoint 7 */
|
||||||
#define MCF_IRQ_DMA 85 /* DMA Controller */
|
#define MCF_IRQ_DMA 85 /* DMA Controller */
|
||||||
#define MCF_IRQ_ERX 86 /* Ethernet Receiver */
|
#define MCF_IRQ_FECRX0 86 /* Ethernet Receiver */
|
||||||
#define MCF_IRQ_ETX 87 /* Ethernet Transmitter */
|
#define MCF_IRQ_FECTX0 87 /* Ethernet Transmitter */
|
||||||
#define MCF_IRQ_ENTC 88 /* Ethernet Non-Time Critical */
|
#define MCF_IRQ_FECENTC0 88 /* Ethernet Non-Time Critical */
|
||||||
#define MCF_IRQ_QSPI 89 /* Queued Serial Interface */
|
#define MCF_IRQ_QSPI 89 /* Queued Serial Interface */
|
||||||
#define MCF_IRQ_EINT5 90 /* External Interrupt 5 */
|
#define MCF_IRQ_EINT5 90 /* External Interrupt 5 */
|
||||||
#define MCF_IRQ_EINT6 91 /* External Interrupt 6 */
|
#define MCF_IRQ_EINT6 91 /* External Interrupt 6 */
|
||||||
|
@@ -38,8 +38,29 @@
|
|||||||
#define MCFINT_UART1 14 /* Interrupt number for UART1 */
|
#define MCFINT_UART1 14 /* Interrupt number for UART1 */
|
||||||
#define MCFINT_UART2 15 /* Interrupt number for UART2 */
|
#define MCFINT_UART2 15 /* Interrupt number for UART2 */
|
||||||
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
|
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
|
||||||
|
#define MCFINT_FECRX0 23 /* Interrupt number for FEC0 */
|
||||||
|
#define MCFINT_FECTX0 27 /* Interrupt number for FEC0 */
|
||||||
|
#define MCFINT_FECENTC0 29 /* Interrupt number for FEC0 */
|
||||||
#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */
|
#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */
|
||||||
|
|
||||||
|
#define MCFINT2_VECBASE 128 /* Vector base number 2 */
|
||||||
|
#define MCFINT2_FECRX1 23 /* Interrupt number for FEC1 */
|
||||||
|
#define MCFINT2_FECTX1 27 /* Interrupt number for FEC1 */
|
||||||
|
#define MCFINT2_FECENTC1 29 /* Interrupt number for FEC1 */
|
||||||
|
|
||||||
|
#define MCF_IRQ_UART0 (MCFINT_VECBASE + MCFINT_UART0)
|
||||||
|
#define MCF_IRQ_UART1 (MCFINT_VECBASE + MCFINT_UART1)
|
||||||
|
#define MCF_IRQ_UART2 (MCFINT_VECBASE + MCFINT_UART2)
|
||||||
|
|
||||||
|
#define MCF_IRQ_FECRX0 (MCFINT_VECBASE + MCFINT_FECRX0)
|
||||||
|
#define MCF_IRQ_FECTX0 (MCFINT_VECBASE + MCFINT_FECTX0)
|
||||||
|
#define MCF_IRQ_FECENTC0 (MCFINT_VECBASE + MCFINT_FECENTC0)
|
||||||
|
#define MCF_IRQ_FECRX1 (MCFINT2_VECBASE + MCFINT2_FECRX1)
|
||||||
|
#define MCF_IRQ_FECTX1 (MCFINT2_VECBASE + MCFINT2_FECTX1)
|
||||||
|
#define MCF_IRQ_FECENTC1 (MCFINT2_VECBASE + MCFINT2_FECENTC1)
|
||||||
|
|
||||||
|
#define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SDRAM configuration registers.
|
* SDRAM configuration registers.
|
||||||
*/
|
*/
|
||||||
@@ -72,9 +93,9 @@
|
|||||||
/*
|
/*
|
||||||
* UART module.
|
* UART module.
|
||||||
*/
|
*/
|
||||||
#define MCFUART_BASE1 (MCF_IPSBAR + 0x200)
|
#define MCFUART_BASE0 (MCF_IPSBAR + 0x200)
|
||||||
#define MCFUART_BASE2 (MCF_IPSBAR + 0x240)
|
#define MCFUART_BASE1 (MCF_IPSBAR + 0x240)
|
||||||
#define MCFUART_BASE3 (MCF_IPSBAR + 0x280)
|
#define MCFUART_BASE2 (MCF_IPSBAR + 0x280)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FEC ethernet module.
|
* FEC ethernet module.
|
||||||
@@ -84,6 +105,28 @@
|
|||||||
#define MCFFEC_BASE1 (MCF_IPSBAR + 0x1800)
|
#define MCFFEC_BASE1 (MCF_IPSBAR + 0x1800)
|
||||||
#define MCFFEC_SIZE1 0x800
|
#define MCFFEC_SIZE1 0x800
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QSPI module.
|
||||||
|
*/
|
||||||
|
#define MCFQSPI_BASE (MCF_IPSBAR + 0x340)
|
||||||
|
#define MCFQSPI_SIZE 0x40
|
||||||
|
|
||||||
|
#ifdef CONFIG_M5271
|
||||||
|
#define MCFQSPI_CS0 91
|
||||||
|
#define MCFQSPI_CS1 92
|
||||||
|
#define MCFQSPI_CS2 99
|
||||||
|
#define MCFQSPI_CS3 103
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_M5275
|
||||||
|
#define MCFQSPI_CS0 59
|
||||||
|
#define MCFQSPI_CS1 60
|
||||||
|
#define MCFQSPI_CS2 61
|
||||||
|
#define MCFQSPI_CS3 62
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO module.
|
||||||
|
*/
|
||||||
#ifdef CONFIG_M5271
|
#ifdef CONFIG_M5271
|
||||||
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000)
|
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000)
|
||||||
#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001)
|
#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001)
|
||||||
@@ -285,8 +328,8 @@
|
|||||||
/*
|
/*
|
||||||
* Reset Control Unit (relative to IPSBAR).
|
* Reset Control Unit (relative to IPSBAR).
|
||||||
*/
|
*/
|
||||||
#define MCF_RCR 0x110000
|
#define MCF_RCR (MCF_IPSBAR + 0x110000)
|
||||||
#define MCF_RSR 0x110001
|
#define MCF_RSR (MCF_IPSBAR + 0x110001)
|
||||||
|
|
||||||
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
|
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
|
||||||
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
|
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
|
||||||
|
@@ -35,9 +35,24 @@
|
|||||||
|
|
||||||
#define MCFINT_VECBASE 64 /* Vector base number */
|
#define MCFINT_VECBASE 64 /* Vector base number */
|
||||||
#define MCFINT_UART0 13 /* Interrupt number for UART0 */
|
#define MCFINT_UART0 13 /* Interrupt number for UART0 */
|
||||||
|
#define MCFINT_UART1 14 /* Interrupt number for UART1 */
|
||||||
|
#define MCFINT_UART2 15 /* Interrupt number for UART2 */
|
||||||
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
|
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
|
||||||
|
#define MCFINT_FECRX0 23 /* Interrupt number for FEC */
|
||||||
|
#define MCFINT_FECTX0 27 /* Interrupt number for FEC */
|
||||||
|
#define MCFINT_FECENTC0 29 /* Interrupt number for FEC */
|
||||||
#define MCFINT_PIT1 55 /* Interrupt number for PIT1 */
|
#define MCFINT_PIT1 55 /* Interrupt number for PIT1 */
|
||||||
|
|
||||||
|
#define MCF_IRQ_UART0 (MCFINT_VECBASE + MCFINT_UART0)
|
||||||
|
#define MCF_IRQ_UART1 (MCFINT_VECBASE + MCFINT_UART1)
|
||||||
|
#define MCF_IRQ_UART2 (MCFINT_VECBASE + MCFINT_UART2)
|
||||||
|
|
||||||
|
#define MCF_IRQ_FECRX0 (MCFINT_VECBASE + MCFINT_FECRX0)
|
||||||
|
#define MCF_IRQ_FECTX0 (MCFINT_VECBASE + MCFINT_FECTX0)
|
||||||
|
#define MCF_IRQ_FECENTC0 (MCFINT_VECBASE + MCFINT_FECENTC0)
|
||||||
|
|
||||||
|
#define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SDRAM configuration registers.
|
* SDRAM configuration registers.
|
||||||
*/
|
*/
|
||||||
@@ -58,15 +73,26 @@
|
|||||||
/*
|
/*
|
||||||
* UART module.
|
* UART module.
|
||||||
*/
|
*/
|
||||||
#define MCFUART_BASE1 (MCF_IPSBAR + 0x00000200)
|
#define MCFUART_BASE0 (MCF_IPSBAR + 0x00000200)
|
||||||
#define MCFUART_BASE2 (MCF_IPSBAR + 0x00000240)
|
#define MCFUART_BASE1 (MCF_IPSBAR + 0x00000240)
|
||||||
#define MCFUART_BASE3 (MCF_IPSBAR + 0x00000280)
|
#define MCFUART_BASE2 (MCF_IPSBAR + 0x00000280)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FEC ethernet module.
|
* FEC ethernet module.
|
||||||
*/
|
*/
|
||||||
#define MCFFEC_BASE (MCF_IPSBAR + 0x00001000)
|
#define MCFFEC_BASE0 (MCF_IPSBAR + 0x00001000)
|
||||||
#define MCFFEC_SIZE 0x800
|
#define MCFFEC_SIZE0 0x800
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QSPI module.
|
||||||
|
*/
|
||||||
|
#define MCFQSPI_IOBASE (MCF_IPSBAR + 0x340)
|
||||||
|
#define MCFQSPI_SIZE 0x40
|
||||||
|
|
||||||
|
#define MCFQSPI_CS0 147
|
||||||
|
#define MCFQSPI_CS1 148
|
||||||
|
#define MCFQSPI_CS2 149
|
||||||
|
#define MCFQSPI_CS3 150
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPIO registers
|
* GPIO registers
|
||||||
@@ -246,8 +272,8 @@
|
|||||||
/*
|
/*
|
||||||
* Reset Control Unit (relative to IPSBAR).
|
* Reset Control Unit (relative to IPSBAR).
|
||||||
*/
|
*/
|
||||||
#define MCF_RCR 0x110000
|
#define MCF_RCR (MCF_IPSBAR + 0x110000)
|
||||||
#define MCF_RSR 0x110001
|
#define MCF_RSR (MCF_IPSBAR + 0x110001)
|
||||||
|
|
||||||
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
|
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
|
||||||
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
|
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
|
||||||
|
@@ -117,11 +117,11 @@
|
|||||||
* UART module.
|
* UART module.
|
||||||
*/
|
*/
|
||||||
#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
|
#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
|
||||||
#define MCFUART_BASE1 0x200 /* Base address of UART1 */
|
#define MCFUART_BASE0 (MCF_MBAR + 0x200) /* Base address UART0 */
|
||||||
#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */
|
#define MCFUART_BASE1 (MCF_MBAR + 0x1c0) /* Base address UART1 */
|
||||||
#else
|
#else
|
||||||
#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
|
#define MCFUART_BASE0 (MCF_MBAR + 0x1c0) /* Base address UART0 */
|
||||||
#define MCFUART_BASE2 0x200 /* Base address of UART2 */
|
#define MCFUART_BASE1 (MCF_MBAR + 0x200) /* Base address UART1 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -176,6 +176,8 @@
|
|||||||
*/
|
*/
|
||||||
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
||||||
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
||||||
|
#define MCF_IRQ_UART0 73 /* UART0 */
|
||||||
|
#define MCF_IRQ_UART1 74 /* UART1 */
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
#endif /* m5307sim_h */
|
#endif /* m5307sim_h */
|
||||||
|
@@ -24,6 +24,19 @@
|
|||||||
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
|
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
|
||||||
#define MCFINT_UART2 28 /* Interrupt number for UART2 */
|
#define MCFINT_UART2 28 /* Interrupt number for UART2 */
|
||||||
#define MCFINT_QSPI 31 /* Interrupt number for QSPI */
|
#define MCFINT_QSPI 31 /* Interrupt number for QSPI */
|
||||||
|
#define MCFINT_FECRX0 36 /* Interrupt number for FEC */
|
||||||
|
#define MCFINT_FECTX0 40 /* Interrupt number for FEC */
|
||||||
|
#define MCFINT_FECENTC0 42 /* Interrupt number for FEC */
|
||||||
|
|
||||||
|
#define MCF_IRQ_UART0 (MCFINT_VECBASE + MCFINT_UART0)
|
||||||
|
#define MCF_IRQ_UART1 (MCFINT_VECBASE + MCFINT_UART1)
|
||||||
|
#define MCF_IRQ_UART2 (MCFINT_VECBASE + MCFINT_UART2)
|
||||||
|
|
||||||
|
#define MCF_IRQ_FECRX0 (MCFINT_VECBASE + MCFINT_FECRX0)
|
||||||
|
#define MCF_IRQ_FECTX0 (MCFINT_VECBASE + MCFINT_FECTX0)
|
||||||
|
#define MCF_IRQ_FECENTC0 (MCFINT_VECBASE + MCFINT_FECENTC0)
|
||||||
|
|
||||||
|
#define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI)
|
||||||
|
|
||||||
#define MCF_WTM_WCR MCF_REG16(0xFC098000)
|
#define MCF_WTM_WCR MCF_REG16(0xFC098000)
|
||||||
|
|
||||||
@@ -82,9 +95,25 @@
|
|||||||
/*
|
/*
|
||||||
* UART module.
|
* UART module.
|
||||||
*/
|
*/
|
||||||
#define MCFUART_BASE1 0xFC060000 /* Base address of UART1 */
|
#define MCFUART_BASE0 0xFC060000 /* Base address of UART1 */
|
||||||
#define MCFUART_BASE2 0xFC064000 /* Base address of UART2 */
|
#define MCFUART_BASE1 0xFC064000 /* Base address of UART2 */
|
||||||
#define MCFUART_BASE3 0xFC068000 /* Base address of UART3 */
|
#define MCFUART_BASE2 0xFC068000 /* Base address of UART3 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FEC module.
|
||||||
|
*/
|
||||||
|
#define MCFFEC_BASE0 0xFC030000 /* Base address of FEC0 */
|
||||||
|
#define MCFFEC_SIZE0 0x800 /* Size of FEC0 region */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QSPI module.
|
||||||
|
*/
|
||||||
|
#define MCFQSPI_BASE 0xFC058000 /* Base address of QSPI */
|
||||||
|
#define MCFQSPI_SIZE 0x40 /* Size of QSPI region */
|
||||||
|
|
||||||
|
#define MCFQSPI_CS0 84
|
||||||
|
#define MCFQSPI_CS1 85
|
||||||
|
#define MCFQSPI_CS2 86
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Timer module.
|
* Timer module.
|
||||||
|
@@ -85,8 +85,8 @@
|
|||||||
#define MCFTIMER_BASE1 (MCF_MBAR + 0x140) /* Base of TIMER1 */
|
#define MCFTIMER_BASE1 (MCF_MBAR + 0x140) /* Base of TIMER1 */
|
||||||
#define MCFTIMER_BASE2 (MCF_MBAR + 0x180) /* Base of TIMER2 */
|
#define MCFTIMER_BASE2 (MCF_MBAR + 0x180) /* Base of TIMER2 */
|
||||||
|
|
||||||
#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
|
#define MCFUART_BASE0 (MCF_MBAR + 0x1c0) /* Base address UART0 */
|
||||||
#define MCFUART_BASE2 0x200 /* Base address of UART2 */
|
#define MCFUART_BASE1 (MCF_MBAR + 0x200) /* Base address UART1 */
|
||||||
|
|
||||||
#define MCFSIM_PADDR (MCF_MBAR + 0x244)
|
#define MCFSIM_PADDR (MCF_MBAR + 0x244)
|
||||||
#define MCFSIM_PADAT (MCF_MBAR + 0x248)
|
#define MCFSIM_PADAT (MCF_MBAR + 0x248)
|
||||||
@@ -139,6 +139,8 @@
|
|||||||
*/
|
*/
|
||||||
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
||||||
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
||||||
|
#define MCF_IRQ_UART0 73 /* UART0 */
|
||||||
|
#define MCF_IRQ_UART1 74 /* UART1 */
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
#endif /* m5407sim_h */
|
#endif /* m5407sim_h */
|
||||||
|
@@ -31,16 +31,20 @@
|
|||||||
/*
|
/*
|
||||||
* UART module.
|
* UART module.
|
||||||
*/
|
*/
|
||||||
#define MCFUART_BASE1 0x8600 /* Base address of UART1 */
|
#define MCFUART_BASE0 (MCF_MBAR + 0x8600) /* Base address UART0 */
|
||||||
#define MCFUART_BASE2 0x8700 /* Base address of UART2 */
|
#define MCFUART_BASE1 (MCF_MBAR + 0x8700) /* Base address UART1 */
|
||||||
#define MCFUART_BASE3 0x8800 /* Base address of UART3 */
|
#define MCFUART_BASE2 (MCF_MBAR + 0x8800) /* Base address UART2 */
|
||||||
#define MCFUART_BASE4 0x8900 /* Base address of UART4 */
|
#define MCFUART_BASE3 (MCF_MBAR + 0x8900) /* Base address UART3 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define system peripheral IRQ usage.
|
* Define system peripheral IRQ usage.
|
||||||
*/
|
*/
|
||||||
#define MCF_IRQ_TIMER (64 + 54) /* Slice Timer 0 */
|
#define MCF_IRQ_TIMER (MCFINT_VECBASE + 54) /* Slice Timer 0 */
|
||||||
#define MCF_IRQ_PROFILER (64 + 53) /* Slice Timer 1 */
|
#define MCF_IRQ_PROFILER (MCFINT_VECBASE + 53) /* Slice Timer 1 */
|
||||||
|
#define MCF_IRQ_UART0 (MCFINT_VECBASE + 35)
|
||||||
|
#define MCF_IRQ_UART1 (MCFINT_VECBASE + 34)
|
||||||
|
#define MCF_IRQ_UART2 (MCFINT_VECBASE + 33)
|
||||||
|
#define MCF_IRQ_UART3 (MCFINT_VECBASE + 32)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic GPIO support
|
* Generic GPIO support
|
||||||
|
@@ -22,8 +22,6 @@ extern unsigned int (*mach_get_ss)(void);
|
|||||||
extern int (*mach_get_rtc_pll)(struct rtc_pll_info *);
|
extern int (*mach_get_rtc_pll)(struct rtc_pll_info *);
|
||||||
extern int (*mach_set_rtc_pll)(struct rtc_pll_info *);
|
extern int (*mach_set_rtc_pll)(struct rtc_pll_info *);
|
||||||
extern int (*mach_set_clock_mmss)(unsigned long);
|
extern int (*mach_set_clock_mmss)(unsigned long);
|
||||||
extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
|
|
||||||
int *min, int *sec);
|
|
||||||
extern void (*mach_reset)( void );
|
extern void (*mach_reset)( void );
|
||||||
extern void (*mach_halt)( void );
|
extern void (*mach_halt)( void );
|
||||||
extern void (*mach_power_off)( void );
|
extern void (*mach_power_off)( void );
|
||||||
@@ -35,9 +33,8 @@ extern void (*mach_l2_flush) (int);
|
|||||||
extern void (*mach_beep) (unsigned int, unsigned int);
|
extern void (*mach_beep) (unsigned int, unsigned int);
|
||||||
|
|
||||||
/* Hardware clock functions */
|
/* Hardware clock functions */
|
||||||
extern void hw_timer_init(void);
|
extern void hw_timer_init(irq_handler_t handler);
|
||||||
extern unsigned long hw_timer_offset(void);
|
extern unsigned long hw_timer_offset(void);
|
||||||
extern irqreturn_t arch_timer_interrupt(int irq, void *dummy);
|
|
||||||
|
|
||||||
extern void config_BSP(char *command, int len);
|
extern void config_BSP(char *command, int len);
|
||||||
|
|
||||||
|
@@ -21,17 +21,6 @@
|
|||||||
#ifndef mcfqspi_h
|
#ifndef mcfqspi_h
|
||||||
#define mcfqspi_h
|
#define mcfqspi_h
|
||||||
|
|
||||||
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
|
|
||||||
#define MCFQSPI_IOBASE (MCF_IPSBAR + 0x340)
|
|
||||||
#elif defined(CONFIG_M5249)
|
|
||||||
#define MCFQSPI_IOBASE (MCF_MBAR + 0x300)
|
|
||||||
#elif defined(CONFIG_M520x)
|
|
||||||
#define MCFQSPI_IOBASE 0xFC05C000
|
|
||||||
#elif defined(CONFIG_M532x)
|
|
||||||
#define MCFQSPI_IOBASE 0xFC058000
|
|
||||||
#endif
|
|
||||||
#define MCFQSPI_IOSIZE 0x40
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct mcfqspi_cs_control - chip select control for the coldfire qspi driver
|
* struct mcfqspi_cs_control - chip select control for the coldfire qspi driver
|
||||||
* @setup: setup the control; allocate gpio's, etc. May be NULL.
|
* @setup: setup the control; allocate gpio's, etc. May be NULL.
|
||||||
|
@@ -41,7 +41,10 @@ struct mcf_platform_uart {
|
|||||||
#define MCFUART_UTF 0x28 /* Transmitter FIFO (r/w) */
|
#define MCFUART_UTF 0x28 /* Transmitter FIFO (r/w) */
|
||||||
#define MCFUART_URF 0x2c /* Receiver FIFO (r/w) */
|
#define MCFUART_URF 0x2c /* Receiver FIFO (r/w) */
|
||||||
#define MCFUART_UFPD 0x30 /* Frac Prec. Divider (r/w) */
|
#define MCFUART_UFPD 0x30 /* Frac Prec. Divider (r/w) */
|
||||||
#else
|
#endif
|
||||||
|
#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
|
||||||
|
defined(CONFIG_M5249) || defined(CONFIG_M5307) || \
|
||||||
|
defined(CONFIG_M5407)
|
||||||
#define MCFUART_UIVR 0x30 /* Interrupt Vector (r/w) */
|
#define MCFUART_UIVR 0x30 /* Interrupt Vector (r/w) */
|
||||||
#endif
|
#endif
|
||||||
#define MCFUART_UIPR 0x34 /* Input Port (r) */
|
#define MCFUART_UIPR 0x34 /* Input Port (r) */
|
||||||
|
@@ -1,5 +1,378 @@
|
|||||||
#ifdef CONFIG_MMU
|
/*
|
||||||
#include "process_mm.c"
|
* linux/arch/m68k/kernel/process.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995 Hamish Macdonald
|
||||||
|
*
|
||||||
|
* 68060 fixes by Jesper Skov
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file handles the architecture-dependent parts of process handling..
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/smp.h>
|
||||||
|
#include <linux/stddef.h>
|
||||||
|
#include <linux/unistd.h>
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
#include <linux/user.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/init_task.h>
|
||||||
|
#include <linux/mqueue.h>
|
||||||
|
|
||||||
|
#include <asm/uaccess.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
#include <asm/traps.h>
|
||||||
|
#include <asm/machdep.h>
|
||||||
|
#include <asm/setup.h>
|
||||||
|
#include <asm/pgtable.h>
|
||||||
|
|
||||||
|
|
||||||
|
asmlinkage void ret_from_fork(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return saved PC from a blocked thread
|
||||||
|
*/
|
||||||
|
unsigned long thread_saved_pc(struct task_struct *tsk)
|
||||||
|
{
|
||||||
|
struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
|
||||||
|
/* Check whether the thread is blocked in resume() */
|
||||||
|
if (in_sched_functions(sw->retpc))
|
||||||
|
return ((unsigned long *)sw->a6)[1];
|
||||||
|
else
|
||||||
|
return sw->retpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The idle loop on an m68k..
|
||||||
|
*/
|
||||||
|
static void default_idle(void)
|
||||||
|
{
|
||||||
|
if (!need_resched())
|
||||||
|
#if defined(MACH_ATARI_ONLY)
|
||||||
|
/* block out HSYNC on the atari (falcon) */
|
||||||
|
__asm__("stop #0x2200" : : : "cc");
|
||||||
#else
|
#else
|
||||||
#include "process_no.c"
|
__asm__("stop #0x2000" : : : "cc");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*idle)(void) = default_idle;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The idle thread. There's no useful work to be
|
||||||
|
* done, so just try to conserve power and have a
|
||||||
|
* low exit latency (ie sit in a loop waiting for
|
||||||
|
* somebody to say that they'd like to reschedule)
|
||||||
|
*/
|
||||||
|
void cpu_idle(void)
|
||||||
|
{
|
||||||
|
/* endless idle loop with no priority at all */
|
||||||
|
while (1) {
|
||||||
|
while (!need_resched())
|
||||||
|
idle();
|
||||||
|
schedule_preempt_disabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void machine_restart(char * __unused)
|
||||||
|
{
|
||||||
|
if (mach_reset)
|
||||||
|
mach_reset();
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
void machine_halt(void)
|
||||||
|
{
|
||||||
|
if (mach_halt)
|
||||||
|
mach_halt();
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
void machine_power_off(void)
|
||||||
|
{
|
||||||
|
if (mach_power_off)
|
||||||
|
mach_power_off();
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*pm_power_off)(void) = machine_power_off;
|
||||||
|
EXPORT_SYMBOL(pm_power_off);
|
||||||
|
|
||||||
|
void show_regs(struct pt_regs * regs)
|
||||||
|
{
|
||||||
|
printk("\n");
|
||||||
|
printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
|
||||||
|
regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
|
||||||
|
printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
|
||||||
|
regs->orig_d0, regs->d0, regs->a2, regs->a1);
|
||||||
|
printk("A0: %08lx D5: %08lx D4: %08lx\n",
|
||||||
|
regs->a0, regs->d5, regs->d4);
|
||||||
|
printk("D3: %08lx D2: %08lx D1: %08lx\n",
|
||||||
|
regs->d3, regs->d2, regs->d1);
|
||||||
|
if (!(regs->sr & PS_S))
|
||||||
|
printk("USP: %08lx\n", rdusp());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a kernel thread
|
||||||
|
*/
|
||||||
|
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
mm_segment_t fs;
|
||||||
|
|
||||||
|
fs = get_fs();
|
||||||
|
set_fs (KERNEL_DS);
|
||||||
|
|
||||||
|
{
|
||||||
|
register long retval __asm__ ("d0");
|
||||||
|
register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
|
||||||
|
|
||||||
|
retval = __NR_clone;
|
||||||
|
__asm__ __volatile__
|
||||||
|
("clrl %%d2\n\t"
|
||||||
|
"trap #0\n\t" /* Linux/m68k system call */
|
||||||
|
"tstl %0\n\t" /* child or parent */
|
||||||
|
"jne 1f\n\t" /* parent - jump */
|
||||||
|
#ifdef CONFIG_MMU
|
||||||
|
"lea %%sp@(%c7),%6\n\t" /* reload current */
|
||||||
|
"movel %6@,%6\n\t"
|
||||||
|
#endif
|
||||||
|
"movel %3,%%sp@-\n\t" /* push argument */
|
||||||
|
"jsr %4@\n\t" /* call fn */
|
||||||
|
"movel %0,%%d1\n\t" /* pass exit value */
|
||||||
|
"movel %2,%%d0\n\t" /* exit */
|
||||||
|
"trap #0\n"
|
||||||
|
"1:"
|
||||||
|
: "+d" (retval)
|
||||||
|
: "i" (__NR_clone), "i" (__NR_exit),
|
||||||
|
"r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
|
||||||
|
"i" (-THREAD_SIZE)
|
||||||
|
: "d2");
|
||||||
|
|
||||||
|
pid = retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_fs (fs);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(kernel_thread);
|
||||||
|
|
||||||
|
void flush_thread(void)
|
||||||
|
{
|
||||||
|
current->thread.fs = __USER_DS;
|
||||||
|
#ifdef CONFIG_FPU
|
||||||
|
if (!FPU_IS_EMU) {
|
||||||
|
unsigned long zero = 0;
|
||||||
|
asm volatile("frestore %0": :"m" (zero));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "m68k_fork()".. By the time we get here, the
|
||||||
|
* non-volatile registers have also been saved on the
|
||||||
|
* stack. We do some ugly pointer stuff here.. (see
|
||||||
|
* also copy_thread)
|
||||||
|
*/
|
||||||
|
|
||||||
|
asmlinkage int m68k_fork(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MMU
|
||||||
|
return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);
|
||||||
|
#else
|
||||||
|
return -EINVAL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
asmlinkage int m68k_vfork(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
asmlinkage int m68k_clone(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
unsigned long clone_flags;
|
||||||
|
unsigned long newsp;
|
||||||
|
int __user *parent_tidptr, *child_tidptr;
|
||||||
|
|
||||||
|
/* syscall2 puts clone_flags in d1 and usp in d2 */
|
||||||
|
clone_flags = regs->d1;
|
||||||
|
newsp = regs->d2;
|
||||||
|
parent_tidptr = (int __user *)regs->d3;
|
||||||
|
child_tidptr = (int __user *)regs->d4;
|
||||||
|
if (!newsp)
|
||||||
|
newsp = rdusp();
|
||||||
|
return do_fork(clone_flags, newsp, regs, 0,
|
||||||
|
parent_tidptr, child_tidptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||||
|
unsigned long unused,
|
||||||
|
struct task_struct * p, struct pt_regs * regs)
|
||||||
|
{
|
||||||
|
struct pt_regs * childregs;
|
||||||
|
struct switch_stack * childstack, *stack;
|
||||||
|
unsigned long *retp;
|
||||||
|
|
||||||
|
childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
|
||||||
|
|
||||||
|
*childregs = *regs;
|
||||||
|
childregs->d0 = 0;
|
||||||
|
|
||||||
|
retp = ((unsigned long *) regs);
|
||||||
|
stack = ((struct switch_stack *) retp) - 1;
|
||||||
|
|
||||||
|
childstack = ((struct switch_stack *) childregs) - 1;
|
||||||
|
*childstack = *stack;
|
||||||
|
childstack->retpc = (unsigned long)ret_from_fork;
|
||||||
|
|
||||||
|
p->thread.usp = usp;
|
||||||
|
p->thread.ksp = (unsigned long)childstack;
|
||||||
|
|
||||||
|
if (clone_flags & CLONE_SETTLS)
|
||||||
|
task_thread_info(p)->tp_value = regs->d5;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must save the current SFC/DFC value, NOT the value when
|
||||||
|
* the parent was last descheduled - RGH 10-08-96
|
||||||
|
*/
|
||||||
|
p->thread.fs = get_fs().seg;
|
||||||
|
|
||||||
|
#ifdef CONFIG_FPU
|
||||||
|
if (!FPU_IS_EMU) {
|
||||||
|
/* Copy the current fpu state */
|
||||||
|
asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
|
||||||
|
|
||||||
|
if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) {
|
||||||
|
if (CPU_IS_COLDFIRE) {
|
||||||
|
asm volatile ("fmovemd %/fp0-%/fp7,%0\n\t"
|
||||||
|
"fmovel %/fpiar,%1\n\t"
|
||||||
|
"fmovel %/fpcr,%2\n\t"
|
||||||
|
"fmovel %/fpsr,%3"
|
||||||
|
:
|
||||||
|
: "m" (p->thread.fp[0]),
|
||||||
|
"m" (p->thread.fpcntl[0]),
|
||||||
|
"m" (p->thread.fpcntl[1]),
|
||||||
|
"m" (p->thread.fpcntl[2])
|
||||||
|
: "memory");
|
||||||
|
} else {
|
||||||
|
asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
|
||||||
|
"fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
|
||||||
|
:
|
||||||
|
: "m" (p->thread.fp[0]),
|
||||||
|
"m" (p->thread.fpcntl[0])
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore the state in case the fpu was busy */
|
||||||
|
asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FPU */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in the fpu structure for a core dump. */
|
||||||
|
#ifdef CONFIG_FPU
|
||||||
|
int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
|
||||||
|
{
|
||||||
|
char fpustate[216];
|
||||||
|
|
||||||
|
if (FPU_IS_EMU) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
|
||||||
|
memcpy(fpu->fpregs, current->thread.fp, 96);
|
||||||
|
/* Convert internal fpu reg representation
|
||||||
|
* into long double format
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 24; i += 3)
|
||||||
|
fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
|
||||||
|
((fpu->fpregs[i] & 0x0000ffff) << 16);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First dump the fpu context to avoid protocol violation. */
|
||||||
|
asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
|
||||||
|
if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (CPU_IS_COLDFIRE) {
|
||||||
|
asm volatile ("fmovel %/fpiar,%0\n\t"
|
||||||
|
"fmovel %/fpcr,%1\n\t"
|
||||||
|
"fmovel %/fpsr,%2\n\t"
|
||||||
|
"fmovemd %/fp0-%/fp7,%3"
|
||||||
|
:
|
||||||
|
: "m" (fpu->fpcntl[0]),
|
||||||
|
"m" (fpu->fpcntl[1]),
|
||||||
|
"m" (fpu->fpcntl[2]),
|
||||||
|
"m" (fpu->fpregs[0])
|
||||||
|
: "memory");
|
||||||
|
} else {
|
||||||
|
asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
|
||||||
|
:
|
||||||
|
: "m" (fpu->fpcntl[0])
|
||||||
|
: "memory");
|
||||||
|
asm volatile ("fmovemx %/fp0-%/fp7,%0"
|
||||||
|
:
|
||||||
|
: "m" (fpu->fpregs[0])
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(dump_fpu);
|
||||||
|
#endif /* CONFIG_FPU */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sys_execve() executes a new program.
|
||||||
|
*/
|
||||||
|
asmlinkage int sys_execve(const char __user *name,
|
||||||
|
const char __user *const __user *argv,
|
||||||
|
const char __user *const __user *envp)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
char * filename;
|
||||||
|
struct pt_regs *regs = (struct pt_regs *) &name;
|
||||||
|
|
||||||
|
filename = getname(name);
|
||||||
|
error = PTR_ERR(filename);
|
||||||
|
if (IS_ERR(filename))
|
||||||
|
return error;
|
||||||
|
error = do_execve(filename, argv, envp, regs);
|
||||||
|
putname(filename);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long get_wchan(struct task_struct *p)
|
||||||
|
{
|
||||||
|
unsigned long fp, pc;
|
||||||
|
unsigned long stack_page;
|
||||||
|
int count = 0;
|
||||||
|
if (!p || p == current || p->state == TASK_RUNNING)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
stack_page = (unsigned long)task_stack_page(p);
|
||||||
|
fp = ((struct switch_stack *)p->thread.ksp)->a6;
|
||||||
|
do {
|
||||||
|
if (fp < stack_page+sizeof(struct thread_info) ||
|
||||||
|
fp >= 8184+stack_page)
|
||||||
|
return 0;
|
||||||
|
pc = ((unsigned long *)fp)[1];
|
||||||
|
if (!in_sched_functions(pc))
|
||||||
|
return pc;
|
||||||
|
fp = *(unsigned long *) fp;
|
||||||
|
} while (count++ < 16);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1,367 +0,0 @@
|
|||||||
/*
|
|
||||||
* linux/arch/m68k/kernel/process.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1995 Hamish Macdonald
|
|
||||||
*
|
|
||||||
* 68060 fixes by Jesper Skov
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file handles the architecture-dependent parts of process handling..
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/stddef.h>
|
|
||||||
#include <linux/unistd.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/user.h>
|
|
||||||
#include <linux/reboot.h>
|
|
||||||
#include <linux/init_task.h>
|
|
||||||
#include <linux/mqueue.h>
|
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
|
||||||
#include <asm/system.h>
|
|
||||||
#include <asm/traps.h>
|
|
||||||
#include <asm/machdep.h>
|
|
||||||
#include <asm/setup.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
|
|
||||||
|
|
||||||
asmlinkage void ret_from_fork(void);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return saved PC from a blocked thread
|
|
||||||
*/
|
|
||||||
unsigned long thread_saved_pc(struct task_struct *tsk)
|
|
||||||
{
|
|
||||||
struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
|
|
||||||
/* Check whether the thread is blocked in resume() */
|
|
||||||
if (in_sched_functions(sw->retpc))
|
|
||||||
return ((unsigned long *)sw->a6)[1];
|
|
||||||
else
|
|
||||||
return sw->retpc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The idle loop on an m68k..
|
|
||||||
*/
|
|
||||||
static void default_idle(void)
|
|
||||||
{
|
|
||||||
if (!need_resched())
|
|
||||||
#if defined(MACH_ATARI_ONLY)
|
|
||||||
/* block out HSYNC on the atari (falcon) */
|
|
||||||
__asm__("stop #0x2200" : : : "cc");
|
|
||||||
#else
|
|
||||||
__asm__("stop #0x2000" : : : "cc");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void (*idle)(void) = default_idle;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The idle thread. There's no useful work to be
|
|
||||||
* done, so just try to conserve power and have a
|
|
||||||
* low exit latency (ie sit in a loop waiting for
|
|
||||||
* somebody to say that they'd like to reschedule)
|
|
||||||
*/
|
|
||||||
void cpu_idle(void)
|
|
||||||
{
|
|
||||||
/* endless idle loop with no priority at all */
|
|
||||||
while (1) {
|
|
||||||
while (!need_resched())
|
|
||||||
idle();
|
|
||||||
schedule_preempt_disabled();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void machine_restart(char * __unused)
|
|
||||||
{
|
|
||||||
if (mach_reset)
|
|
||||||
mach_reset();
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
void machine_halt(void)
|
|
||||||
{
|
|
||||||
if (mach_halt)
|
|
||||||
mach_halt();
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
void machine_power_off(void)
|
|
||||||
{
|
|
||||||
if (mach_power_off)
|
|
||||||
mach_power_off();
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
void (*pm_power_off)(void) = machine_power_off;
|
|
||||||
EXPORT_SYMBOL(pm_power_off);
|
|
||||||
|
|
||||||
void show_regs(struct pt_regs * regs)
|
|
||||||
{
|
|
||||||
printk("\n");
|
|
||||||
printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
|
|
||||||
regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
|
|
||||||
printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
|
|
||||||
regs->orig_d0, regs->d0, regs->a2, regs->a1);
|
|
||||||
printk("A0: %08lx D5: %08lx D4: %08lx\n",
|
|
||||||
regs->a0, regs->d5, regs->d4);
|
|
||||||
printk("D3: %08lx D2: %08lx D1: %08lx\n",
|
|
||||||
regs->d3, regs->d2, regs->d1);
|
|
||||||
if (!(regs->sr & PS_S))
|
|
||||||
printk("USP: %08lx\n", rdusp());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a kernel thread
|
|
||||||
*/
|
|
||||||
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
|
||||||
{
|
|
||||||
int pid;
|
|
||||||
mm_segment_t fs;
|
|
||||||
|
|
||||||
fs = get_fs();
|
|
||||||
set_fs (KERNEL_DS);
|
|
||||||
|
|
||||||
{
|
|
||||||
register long retval __asm__ ("d0");
|
|
||||||
register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
|
|
||||||
|
|
||||||
retval = __NR_clone;
|
|
||||||
__asm__ __volatile__
|
|
||||||
("clrl %%d2\n\t"
|
|
||||||
"trap #0\n\t" /* Linux/m68k system call */
|
|
||||||
"tstl %0\n\t" /* child or parent */
|
|
||||||
"jne 1f\n\t" /* parent - jump */
|
|
||||||
"lea %%sp@(%c7),%6\n\t" /* reload current */
|
|
||||||
"movel %6@,%6\n\t"
|
|
||||||
"movel %3,%%sp@-\n\t" /* push argument */
|
|
||||||
"jsr %4@\n\t" /* call fn */
|
|
||||||
"movel %0,%%d1\n\t" /* pass exit value */
|
|
||||||
"movel %2,%%d0\n\t" /* exit */
|
|
||||||
"trap #0\n"
|
|
||||||
"1:"
|
|
||||||
: "+d" (retval)
|
|
||||||
: "i" (__NR_clone), "i" (__NR_exit),
|
|
||||||
"r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
|
|
||||||
"i" (-THREAD_SIZE)
|
|
||||||
: "d2");
|
|
||||||
|
|
||||||
pid = retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_fs (fs);
|
|
||||||
return pid;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(kernel_thread);
|
|
||||||
|
|
||||||
void flush_thread(void)
|
|
||||||
{
|
|
||||||
unsigned long zero = 0;
|
|
||||||
|
|
||||||
current->thread.fs = __USER_DS;
|
|
||||||
if (!FPU_IS_EMU)
|
|
||||||
asm volatile("frestore %0": :"m" (zero));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "m68k_fork()".. By the time we get here, the
|
|
||||||
* non-volatile registers have also been saved on the
|
|
||||||
* stack. We do some ugly pointer stuff here.. (see
|
|
||||||
* also copy_thread)
|
|
||||||
*/
|
|
||||||
|
|
||||||
asmlinkage int m68k_fork(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int m68k_vfork(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0,
|
|
||||||
NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int m68k_clone(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
unsigned long clone_flags;
|
|
||||||
unsigned long newsp;
|
|
||||||
int __user *parent_tidptr, *child_tidptr;
|
|
||||||
|
|
||||||
/* syscall2 puts clone_flags in d1 and usp in d2 */
|
|
||||||
clone_flags = regs->d1;
|
|
||||||
newsp = regs->d2;
|
|
||||||
parent_tidptr = (int __user *)regs->d3;
|
|
||||||
child_tidptr = (int __user *)regs->d4;
|
|
||||||
if (!newsp)
|
|
||||||
newsp = rdusp();
|
|
||||||
return do_fork(clone_flags, newsp, regs, 0,
|
|
||||||
parent_tidptr, child_tidptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int copy_thread(unsigned long clone_flags, unsigned long usp,
|
|
||||||
unsigned long unused,
|
|
||||||
struct task_struct * p, struct pt_regs * regs)
|
|
||||||
{
|
|
||||||
struct pt_regs * childregs;
|
|
||||||
struct switch_stack * childstack, *stack;
|
|
||||||
unsigned long *retp;
|
|
||||||
|
|
||||||
childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
|
|
||||||
|
|
||||||
*childregs = *regs;
|
|
||||||
childregs->d0 = 0;
|
|
||||||
|
|
||||||
retp = ((unsigned long *) regs);
|
|
||||||
stack = ((struct switch_stack *) retp) - 1;
|
|
||||||
|
|
||||||
childstack = ((struct switch_stack *) childregs) - 1;
|
|
||||||
*childstack = *stack;
|
|
||||||
childstack->retpc = (unsigned long)ret_from_fork;
|
|
||||||
|
|
||||||
p->thread.usp = usp;
|
|
||||||
p->thread.ksp = (unsigned long)childstack;
|
|
||||||
|
|
||||||
if (clone_flags & CLONE_SETTLS)
|
|
||||||
task_thread_info(p)->tp_value = regs->d5;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Must save the current SFC/DFC value, NOT the value when
|
|
||||||
* the parent was last descheduled - RGH 10-08-96
|
|
||||||
*/
|
|
||||||
p->thread.fs = get_fs().seg;
|
|
||||||
|
|
||||||
if (!FPU_IS_EMU) {
|
|
||||||
/* Copy the current fpu state */
|
|
||||||
asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
|
|
||||||
|
|
||||||
if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) {
|
|
||||||
if (CPU_IS_COLDFIRE) {
|
|
||||||
asm volatile ("fmovemd %/fp0-%/fp7,%0\n\t"
|
|
||||||
"fmovel %/fpiar,%1\n\t"
|
|
||||||
"fmovel %/fpcr,%2\n\t"
|
|
||||||
"fmovel %/fpsr,%3"
|
|
||||||
:
|
|
||||||
: "m" (p->thread.fp[0]),
|
|
||||||
"m" (p->thread.fpcntl[0]),
|
|
||||||
"m" (p->thread.fpcntl[1]),
|
|
||||||
"m" (p->thread.fpcntl[2])
|
|
||||||
: "memory");
|
|
||||||
} else {
|
|
||||||
asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
|
|
||||||
"fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
|
|
||||||
:
|
|
||||||
: "m" (p->thread.fp[0]),
|
|
||||||
"m" (p->thread.fpcntl[0])
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore the state in case the fpu was busy */
|
|
||||||
asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in the fpu structure for a core dump. */
|
|
||||||
|
|
||||||
int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
|
|
||||||
{
|
|
||||||
char fpustate[216];
|
|
||||||
|
|
||||||
if (FPU_IS_EMU) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
|
|
||||||
memcpy(fpu->fpregs, current->thread.fp, 96);
|
|
||||||
/* Convert internal fpu reg representation
|
|
||||||
* into long double format
|
|
||||||
*/
|
|
||||||
for (i = 0; i < 24; i += 3)
|
|
||||||
fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
|
|
||||||
((fpu->fpregs[i] & 0x0000ffff) << 16);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First dump the fpu context to avoid protocol violation. */
|
|
||||||
asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
|
|
||||||
if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (CPU_IS_COLDFIRE) {
|
|
||||||
asm volatile ("fmovel %/fpiar,%0\n\t"
|
|
||||||
"fmovel %/fpcr,%1\n\t"
|
|
||||||
"fmovel %/fpsr,%2\n\t"
|
|
||||||
"fmovemd %/fp0-%/fp7,%3"
|
|
||||||
:
|
|
||||||
: "m" (fpu->fpcntl[0]),
|
|
||||||
"m" (fpu->fpcntl[1]),
|
|
||||||
"m" (fpu->fpcntl[2]),
|
|
||||||
"m" (fpu->fpregs[0])
|
|
||||||
: "memory");
|
|
||||||
} else {
|
|
||||||
asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
|
|
||||||
:
|
|
||||||
: "m" (fpu->fpcntl[0])
|
|
||||||
: "memory");
|
|
||||||
asm volatile ("fmovemx %/fp0-%/fp7,%0"
|
|
||||||
:
|
|
||||||
: "m" (fpu->fpregs[0])
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dump_fpu);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sys_execve() executes a new program.
|
|
||||||
*/
|
|
||||||
asmlinkage int sys_execve(const char __user *name,
|
|
||||||
const char __user *const __user *argv,
|
|
||||||
const char __user *const __user *envp)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
char * filename;
|
|
||||||
struct pt_regs *regs = (struct pt_regs *) &name;
|
|
||||||
|
|
||||||
filename = getname(name);
|
|
||||||
error = PTR_ERR(filename);
|
|
||||||
if (IS_ERR(filename))
|
|
||||||
return error;
|
|
||||||
error = do_execve(filename, argv, envp, regs);
|
|
||||||
putname(filename);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long get_wchan(struct task_struct *p)
|
|
||||||
{
|
|
||||||
unsigned long fp, pc;
|
|
||||||
unsigned long stack_page;
|
|
||||||
int count = 0;
|
|
||||||
if (!p || p == current || p->state == TASK_RUNNING)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
stack_page = (unsigned long)task_stack_page(p);
|
|
||||||
fp = ((struct switch_stack *)p->thread.ksp)->a6;
|
|
||||||
do {
|
|
||||||
if (fp < stack_page+sizeof(struct thread_info) ||
|
|
||||||
fp >= 8184+stack_page)
|
|
||||||
return 0;
|
|
||||||
pc = ((unsigned long *)fp)[1];
|
|
||||||
if (!in_sched_functions(pc))
|
|
||||||
return pc;
|
|
||||||
fp = *(unsigned long *) fp;
|
|
||||||
} while (count++ < 16);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@@ -1,404 +0,0 @@
|
|||||||
/*
|
|
||||||
* linux/arch/m68knommu/kernel/process.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1995 Hamish Macdonald
|
|
||||||
*
|
|
||||||
* 68060 fixes by Jesper Skov
|
|
||||||
*
|
|
||||||
* uClinux changes
|
|
||||||
* Copyright (C) 2000-2002, David McCullough <davidm@snapgear.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file handles the architecture-dependent parts of process handling..
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/stddef.h>
|
|
||||||
#include <linux/unistd.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/user.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/reboot.h>
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
|
||||||
#include <asm/system.h>
|
|
||||||
#include <asm/traps.h>
|
|
||||||
#include <asm/machdep.h>
|
|
||||||
#include <asm/setup.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
|
|
||||||
asmlinkage void ret_from_fork(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following aren't currently used.
|
|
||||||
*/
|
|
||||||
void (*pm_idle)(void);
|
|
||||||
EXPORT_SYMBOL(pm_idle);
|
|
||||||
|
|
||||||
void (*pm_power_off)(void);
|
|
||||||
EXPORT_SYMBOL(pm_power_off);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The idle loop on an m68knommu..
|
|
||||||
*/
|
|
||||||
static void default_idle(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
while (!need_resched()) {
|
|
||||||
/* This stop will re-enable interrupts */
|
|
||||||
__asm__("stop #0x2000" : : : "cc");
|
|
||||||
local_irq_disable();
|
|
||||||
}
|
|
||||||
local_irq_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void (*idle)(void) = default_idle;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The idle thread. There's no useful work to be
|
|
||||||
* done, so just try to conserve power and have a
|
|
||||||
* low exit latency (ie sit in a loop waiting for
|
|
||||||
* somebody to say that they'd like to reschedule)
|
|
||||||
*/
|
|
||||||
void cpu_idle(void)
|
|
||||||
{
|
|
||||||
/* endless idle loop with no priority at all */
|
|
||||||
while (1) {
|
|
||||||
idle();
|
|
||||||
schedule_preempt_disabled();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void machine_restart(char * __unused)
|
|
||||||
{
|
|
||||||
if (mach_reset)
|
|
||||||
mach_reset();
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
void machine_halt(void)
|
|
||||||
{
|
|
||||||
if (mach_halt)
|
|
||||||
mach_halt();
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
void machine_power_off(void)
|
|
||||||
{
|
|
||||||
if (mach_power_off)
|
|
||||||
mach_power_off();
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
void show_regs(struct pt_regs * regs)
|
|
||||||
{
|
|
||||||
printk(KERN_NOTICE "\n");
|
|
||||||
printk(KERN_NOTICE "Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
|
|
||||||
regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
|
|
||||||
printk(KERN_NOTICE "ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
|
|
||||||
regs->orig_d0, regs->d0, regs->a2, regs->a1);
|
|
||||||
printk(KERN_NOTICE "A0: %08lx D5: %08lx D4: %08lx\n",
|
|
||||||
regs->a0, regs->d5, regs->d4);
|
|
||||||
printk(KERN_NOTICE "D3: %08lx D2: %08lx D1: %08lx\n",
|
|
||||||
regs->d3, regs->d2, regs->d1);
|
|
||||||
if (!(regs->sr & PS_S))
|
|
||||||
printk(KERN_NOTICE "USP: %08lx\n", rdusp());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a kernel thread
|
|
||||||
*/
|
|
||||||
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
|
||||||
{
|
|
||||||
int retval;
|
|
||||||
long clone_arg = flags | CLONE_VM;
|
|
||||||
mm_segment_t fs;
|
|
||||||
|
|
||||||
fs = get_fs();
|
|
||||||
set_fs(KERNEL_DS);
|
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"movel %%sp, %%d2\n\t"
|
|
||||||
"movel %5, %%d1\n\t"
|
|
||||||
"movel %1, %%d0\n\t"
|
|
||||||
"trap #0\n\t"
|
|
||||||
"cmpl %%sp, %%d2\n\t"
|
|
||||||
"jeq 1f\n\t"
|
|
||||||
"movel %3, %%sp@-\n\t"
|
|
||||||
"jsr %4@\n\t"
|
|
||||||
"movel %2, %%d0\n\t"
|
|
||||||
"trap #0\n"
|
|
||||||
"1:\n\t"
|
|
||||||
"movel %%d0, %0\n"
|
|
||||||
: "=d" (retval)
|
|
||||||
: "i" (__NR_clone),
|
|
||||||
"i" (__NR_exit),
|
|
||||||
"a" (arg),
|
|
||||||
"a" (fn),
|
|
||||||
"a" (clone_arg)
|
|
||||||
: "cc", "%d0", "%d1", "%d2");
|
|
||||||
|
|
||||||
set_fs(fs);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(kernel_thread);
|
|
||||||
|
|
||||||
void flush_thread(void)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_FPU
|
|
||||||
unsigned long zero = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
current->thread.fs = __USER_DS;
|
|
||||||
#ifdef CONFIG_FPU
|
|
||||||
if (!FPU_IS_EMU)
|
|
||||||
asm volatile (".chip 68k/68881\n\t"
|
|
||||||
"frestore %0\n\t"
|
|
||||||
".chip 68k" : : "m" (zero));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "m68k_fork()".. By the time we get here, the
|
|
||||||
* non-volatile registers have also been saved on the
|
|
||||||
* stack. We do some ugly pointer stuff here.. (see
|
|
||||||
* also copy_thread)
|
|
||||||
*/
|
|
||||||
|
|
||||||
asmlinkage int m68k_fork(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
/* fork almost works, enough to trick you into looking elsewhere :-( */
|
|
||||||
return(-EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int m68k_vfork(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int m68k_clone(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
unsigned long clone_flags;
|
|
||||||
unsigned long newsp;
|
|
||||||
|
|
||||||
/* syscall2 puts clone_flags in d1 and usp in d2 */
|
|
||||||
clone_flags = regs->d1;
|
|
||||||
newsp = regs->d2;
|
|
||||||
if (!newsp)
|
|
||||||
newsp = rdusp();
|
|
||||||
return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int copy_thread(unsigned long clone_flags,
|
|
||||||
unsigned long usp, unsigned long topstk,
|
|
||||||
struct task_struct * p, struct pt_regs * regs)
|
|
||||||
{
|
|
||||||
struct pt_regs * childregs;
|
|
||||||
struct switch_stack * childstack, *stack;
|
|
||||||
unsigned long *retp;
|
|
||||||
|
|
||||||
childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
|
|
||||||
|
|
||||||
*childregs = *regs;
|
|
||||||
childregs->d0 = 0;
|
|
||||||
|
|
||||||
retp = ((unsigned long *) regs);
|
|
||||||
stack = ((struct switch_stack *) retp) - 1;
|
|
||||||
|
|
||||||
childstack = ((struct switch_stack *) childregs) - 1;
|
|
||||||
*childstack = *stack;
|
|
||||||
childstack->retpc = (unsigned long)ret_from_fork;
|
|
||||||
|
|
||||||
p->thread.usp = usp;
|
|
||||||
p->thread.ksp = (unsigned long)childstack;
|
|
||||||
|
|
||||||
if (clone_flags & CLONE_SETTLS)
|
|
||||||
task_thread_info(p)->tp_value = regs->d5;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Must save the current SFC/DFC value, NOT the value when
|
|
||||||
* the parent was last descheduled - RGH 10-08-96
|
|
||||||
*/
|
|
||||||
p->thread.fs = get_fs().seg;
|
|
||||||
|
|
||||||
#ifdef CONFIG_FPU
|
|
||||||
if (!FPU_IS_EMU) {
|
|
||||||
/* Copy the current fpu state */
|
|
||||||
asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
|
|
||||||
|
|
||||||
if (p->thread.fpstate[0])
|
|
||||||
asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
|
|
||||||
"fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
|
|
||||||
: : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])
|
|
||||||
: "memory");
|
|
||||||
/* Restore the state in case the fpu was busy */
|
|
||||||
asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in the fpu structure for a core dump. */
|
|
||||||
|
|
||||||
int dump_fpu(struct pt_regs *regs, struct user_m68kfp_struct *fpu)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_FPU
|
|
||||||
char fpustate[216];
|
|
||||||
|
|
||||||
if (FPU_IS_EMU) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
|
|
||||||
memcpy(fpu->fpregs, current->thread.fp, 96);
|
|
||||||
/* Convert internal fpu reg representation
|
|
||||||
* into long double format
|
|
||||||
*/
|
|
||||||
for (i = 0; i < 24; i += 3)
|
|
||||||
fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
|
|
||||||
((fpu->fpregs[i] & 0x0000ffff) << 16);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First dump the fpu context to avoid protocol violation. */
|
|
||||||
asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
|
|
||||||
if (!fpustate[0])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
|
|
||||||
:: "m" (fpu->fpcntl[0])
|
|
||||||
: "memory");
|
|
||||||
asm volatile ("fmovemx %/fp0-%/fp7,%0"
|
|
||||||
:: "m" (fpu->fpregs[0])
|
|
||||||
: "memory");
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dump_fpu);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generic dumping code. Used for panic and debug.
|
|
||||||
*/
|
|
||||||
void dump(struct pt_regs *fp)
|
|
||||||
{
|
|
||||||
unsigned long *sp;
|
|
||||||
unsigned char *tp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
printk(KERN_EMERG "\nCURRENT PROCESS:\n\n");
|
|
||||||
printk(KERN_EMERG "COMM=%s PID=%d\n", current->comm, current->pid);
|
|
||||||
|
|
||||||
if (current->mm) {
|
|
||||||
printk(KERN_EMERG "TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
|
|
||||||
(int) current->mm->start_code,
|
|
||||||
(int) current->mm->end_code,
|
|
||||||
(int) current->mm->start_data,
|
|
||||||
(int) current->mm->end_data,
|
|
||||||
(int) current->mm->end_data,
|
|
||||||
(int) current->mm->brk);
|
|
||||||
printk(KERN_EMERG "USER-STACK=%08x KERNEL-STACK=%08x\n\n",
|
|
||||||
(int) current->mm->start_stack,
|
|
||||||
(int)(((unsigned long) current) + THREAD_SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
printk(KERN_EMERG "PC: %08lx\n", fp->pc);
|
|
||||||
printk(KERN_EMERG "SR: %08lx SP: %08lx\n", (long) fp->sr, (long) fp);
|
|
||||||
printk(KERN_EMERG "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
|
|
||||||
fp->d0, fp->d1, fp->d2, fp->d3);
|
|
||||||
printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
|
|
||||||
fp->d4, fp->d5, fp->a0, fp->a1);
|
|
||||||
printk(KERN_EMERG "\nUSP: %08x TRAPFRAME: %p\n",
|
|
||||||
(unsigned int) rdusp(), fp);
|
|
||||||
|
|
||||||
printk(KERN_EMERG "\nCODE:");
|
|
||||||
tp = ((unsigned char *) fp->pc) - 0x20;
|
|
||||||
for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) {
|
|
||||||
if ((i % 0x10) == 0)
|
|
||||||
printk(KERN_EMERG "%p: ", tp + i);
|
|
||||||
printk("%08x ", (int) *sp++);
|
|
||||||
}
|
|
||||||
printk(KERN_EMERG "\n");
|
|
||||||
|
|
||||||
printk(KERN_EMERG "KERNEL STACK:");
|
|
||||||
tp = ((unsigned char *) fp) - 0x40;
|
|
||||||
for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
|
|
||||||
if ((i % 0x10) == 0)
|
|
||||||
printk(KERN_EMERG "%p: ", tp + i);
|
|
||||||
printk("%08x ", (int) *sp++);
|
|
||||||
}
|
|
||||||
printk(KERN_EMERG "\n");
|
|
||||||
|
|
||||||
printk(KERN_EMERG "USER STACK:");
|
|
||||||
tp = (unsigned char *) (rdusp() - 0x10);
|
|
||||||
for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
|
|
||||||
if ((i % 0x10) == 0)
|
|
||||||
printk(KERN_EMERG "%p: ", tp + i);
|
|
||||||
printk("%08x ", (int) *sp++);
|
|
||||||
}
|
|
||||||
printk(KERN_EMERG "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sys_execve() executes a new program.
|
|
||||||
*/
|
|
||||||
asmlinkage int sys_execve(const char *name,
|
|
||||||
const char *const *argv,
|
|
||||||
const char *const *envp)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
char * filename;
|
|
||||||
struct pt_regs *regs = (struct pt_regs *) &name;
|
|
||||||
|
|
||||||
filename = getname(name);
|
|
||||||
error = PTR_ERR(filename);
|
|
||||||
if (IS_ERR(filename))
|
|
||||||
return error;
|
|
||||||
error = do_execve(filename, argv, envp, regs);
|
|
||||||
putname(filename);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long get_wchan(struct task_struct *p)
|
|
||||||
{
|
|
||||||
unsigned long fp, pc;
|
|
||||||
unsigned long stack_page;
|
|
||||||
int count = 0;
|
|
||||||
if (!p || p == current || p->state == TASK_RUNNING)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
stack_page = (unsigned long)p;
|
|
||||||
fp = ((struct switch_stack *)p->thread.ksp)->a6;
|
|
||||||
do {
|
|
||||||
if (fp < stack_page+sizeof(struct thread_info) ||
|
|
||||||
fp >= THREAD_SIZE-8+stack_page)
|
|
||||||
return 0;
|
|
||||||
pc = ((unsigned long *)fp)[1];
|
|
||||||
if (!in_sched_functions(pc))
|
|
||||||
return pc;
|
|
||||||
fp = *(unsigned long *) fp;
|
|
||||||
} while (count++ < 16);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return saved PC of a blocked thread.
|
|
||||||
*/
|
|
||||||
unsigned long thread_saved_pc(struct task_struct *tsk)
|
|
||||||
{
|
|
||||||
struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
|
|
||||||
|
|
||||||
/* Check whether the thread is blocked in resume() */
|
|
||||||
if (in_sched_functions(sw->retpc))
|
|
||||||
return ((unsigned long *)sw->a6)[1];
|
|
||||||
else
|
|
||||||
return sw->retpc;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,5 +1,305 @@
|
|||||||
|
/*
|
||||||
|
* linux/arch/m68k/kernel/ptrace.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1994 by Hamish Macdonald
|
||||||
|
* Taken from linux/kernel/ptrace.c and modified for M680x0.
|
||||||
|
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General
|
||||||
|
* Public License. See the file COPYING in the main directory of
|
||||||
|
* this archive for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/smp.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
#include <linux/user.h>
|
||||||
|
#include <linux/signal.h>
|
||||||
|
#include <linux/tracehook.h>
|
||||||
|
|
||||||
|
#include <asm/uaccess.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
#include <asm/pgtable.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
#include <asm/processor.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* does not yet catch signals sent when the child dies.
|
||||||
|
* in exit.c or in signal.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* determines which bits in the SR the user has access to. */
|
||||||
|
/* 1 = access 0 = no access */
|
||||||
|
#define SR_MASK 0x001f
|
||||||
|
|
||||||
|
/* sets the trace bits. */
|
||||||
|
#define TRACE_BITS 0xC000
|
||||||
|
#define T1_BIT 0x8000
|
||||||
|
#define T0_BIT 0x4000
|
||||||
|
|
||||||
|
/* Find the stack offset for a register, relative to thread.esp0. */
|
||||||
|
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
|
||||||
|
#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
|
||||||
|
- sizeof(struct switch_stack))
|
||||||
|
/* Mapping from PT_xxx to the stack offset at which the register is
|
||||||
|
saved. Notice that usp has no stack-slot and needs to be treated
|
||||||
|
specially (see get_reg/put_reg below). */
|
||||||
|
static const int regoff[] = {
|
||||||
|
[0] = PT_REG(d1),
|
||||||
|
[1] = PT_REG(d2),
|
||||||
|
[2] = PT_REG(d3),
|
||||||
|
[3] = PT_REG(d4),
|
||||||
|
[4] = PT_REG(d5),
|
||||||
|
[5] = SW_REG(d6),
|
||||||
|
[6] = SW_REG(d7),
|
||||||
|
[7] = PT_REG(a0),
|
||||||
|
[8] = PT_REG(a1),
|
||||||
|
[9] = PT_REG(a2),
|
||||||
|
[10] = SW_REG(a3),
|
||||||
|
[11] = SW_REG(a4),
|
||||||
|
[12] = SW_REG(a5),
|
||||||
|
[13] = SW_REG(a6),
|
||||||
|
[14] = PT_REG(d0),
|
||||||
|
[15] = -1,
|
||||||
|
[16] = PT_REG(orig_d0),
|
||||||
|
[17] = PT_REG(sr),
|
||||||
|
[18] = PT_REG(pc),
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get contents of register REGNO in task TASK.
|
||||||
|
*/
|
||||||
|
static inline long get_reg(struct task_struct *task, int regno)
|
||||||
|
{
|
||||||
|
unsigned long *addr;
|
||||||
|
|
||||||
|
if (regno == PT_USP)
|
||||||
|
addr = &task->thread.usp;
|
||||||
|
else if (regno < ARRAY_SIZE(regoff))
|
||||||
|
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
/* Need to take stkadj into account. */
|
||||||
|
if (regno == PT_SR || regno == PT_PC) {
|
||||||
|
long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
|
||||||
|
addr = (unsigned long *) ((unsigned long)addr + stkadj);
|
||||||
|
/* The sr is actually a 16 bit register. */
|
||||||
|
if (regno == PT_SR)
|
||||||
|
return *(unsigned short *)addr;
|
||||||
|
}
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write contents of register REGNO in task TASK.
|
||||||
|
*/
|
||||||
|
static inline int put_reg(struct task_struct *task, int regno,
|
||||||
|
unsigned long data)
|
||||||
|
{
|
||||||
|
unsigned long *addr;
|
||||||
|
|
||||||
|
if (regno == PT_USP)
|
||||||
|
addr = &task->thread.usp;
|
||||||
|
else if (regno < ARRAY_SIZE(regoff))
|
||||||
|
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
/* Need to take stkadj into account. */
|
||||||
|
if (regno == PT_SR || regno == PT_PC) {
|
||||||
|
long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
|
||||||
|
addr = (unsigned long *) ((unsigned long)addr + stkadj);
|
||||||
|
/* The sr is actually a 16 bit register. */
|
||||||
|
if (regno == PT_SR) {
|
||||||
|
*(unsigned short *)addr = data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*addr = data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure the single step bit is not set.
|
||||||
|
*/
|
||||||
|
static inline void singlestep_disable(struct task_struct *child)
|
||||||
|
{
|
||||||
|
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
|
||||||
|
put_reg(child, PT_SR, tmp);
|
||||||
|
clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by kernel/ptrace.c when detaching..
|
||||||
|
*/
|
||||||
|
void ptrace_disable(struct task_struct *child)
|
||||||
|
{
|
||||||
|
singlestep_disable(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
void user_enable_single_step(struct task_struct *child)
|
||||||
|
{
|
||||||
|
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
|
||||||
|
put_reg(child, PT_SR, tmp | T1_BIT);
|
||||||
|
set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MMU
|
#ifdef CONFIG_MMU
|
||||||
#include "ptrace_mm.c"
|
void user_enable_block_step(struct task_struct *child)
|
||||||
#else
|
{
|
||||||
#include "ptrace_no.c"
|
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
|
||||||
|
put_reg(child, PT_SR, tmp | T0_BIT);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void user_disable_single_step(struct task_struct *child)
|
||||||
|
{
|
||||||
|
singlestep_disable(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
long arch_ptrace(struct task_struct *child, long request,
|
||||||
|
unsigned long addr, unsigned long data)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
int i, ret = 0;
|
||||||
|
int regno = addr >> 2; /* temporary hack. */
|
||||||
|
unsigned long __user *datap = (unsigned long __user *) data;
|
||||||
|
|
||||||
|
switch (request) {
|
||||||
|
/* read the word at location addr in the USER area. */
|
||||||
|
case PTRACE_PEEKUSR:
|
||||||
|
if (addr & 3)
|
||||||
|
goto out_eio;
|
||||||
|
|
||||||
|
if (regno >= 0 && regno < 19) {
|
||||||
|
tmp = get_reg(child, regno);
|
||||||
|
} else if (regno >= 21 && regno < 49) {
|
||||||
|
tmp = child->thread.fp[regno - 21];
|
||||||
|
/* Convert internal fpu reg representation
|
||||||
|
* into long double format
|
||||||
|
*/
|
||||||
|
if (FPU_IS_EMU && (regno < 45) && !(regno % 3))
|
||||||
|
tmp = ((tmp & 0xffff0000) << 15) |
|
||||||
|
((tmp & 0x0000ffff) << 16);
|
||||||
|
#ifndef CONFIG_MMU
|
||||||
|
} else if (regno == 49) {
|
||||||
|
tmp = child->mm->start_code;
|
||||||
|
} else if (regno == 50) {
|
||||||
|
tmp = child->mm->start_data;
|
||||||
|
} else if (regno == 51) {
|
||||||
|
tmp = child->mm->end_code;
|
||||||
|
#endif
|
||||||
|
} else
|
||||||
|
goto out_eio;
|
||||||
|
ret = put_user(tmp, datap);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PTRACE_POKEUSR:
|
||||||
|
/* write the word at location addr in the USER area */
|
||||||
|
if (addr & 3)
|
||||||
|
goto out_eio;
|
||||||
|
|
||||||
|
if (regno == PT_SR) {
|
||||||
|
data &= SR_MASK;
|
||||||
|
data |= get_reg(child, PT_SR) & ~SR_MASK;
|
||||||
|
}
|
||||||
|
if (regno >= 0 && regno < 19) {
|
||||||
|
if (put_reg(child, regno, data))
|
||||||
|
goto out_eio;
|
||||||
|
} else if (regno >= 21 && regno < 48) {
|
||||||
|
/* Convert long double format
|
||||||
|
* into internal fpu reg representation
|
||||||
|
*/
|
||||||
|
if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {
|
||||||
|
data <<= 15;
|
||||||
|
data = (data & 0xffff0000) |
|
||||||
|
((data & 0x0000ffff) >> 1);
|
||||||
|
}
|
||||||
|
child->thread.fp[regno - 21] = data;
|
||||||
|
} else
|
||||||
|
goto out_eio;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PTRACE_GETREGS: /* Get all gp regs from the child. */
|
||||||
|
for (i = 0; i < 19; i++) {
|
||||||
|
tmp = get_reg(child, i);
|
||||||
|
ret = put_user(tmp, datap);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
datap++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PTRACE_SETREGS: /* Set all gp regs in the child. */
|
||||||
|
for (i = 0; i < 19; i++) {
|
||||||
|
ret = get_user(tmp, datap);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
if (i == PT_SR) {
|
||||||
|
tmp &= SR_MASK;
|
||||||
|
tmp |= get_reg(child, PT_SR) & ~SR_MASK;
|
||||||
|
}
|
||||||
|
put_reg(child, i, tmp);
|
||||||
|
datap++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PTRACE_GETFPREGS: /* Get the child FPU state. */
|
||||||
|
if (copy_to_user(datap, &child->thread.fp,
|
||||||
|
sizeof(struct user_m68kfp_struct)))
|
||||||
|
ret = -EFAULT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PTRACE_SETFPREGS: /* Set the child FPU state. */
|
||||||
|
if (copy_from_user(&child->thread.fp, datap,
|
||||||
|
sizeof(struct user_m68kfp_struct)))
|
||||||
|
ret = -EFAULT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PTRACE_GET_THREAD_AREA:
|
||||||
|
ret = put_user(task_thread_info(child)->tp_value, datap);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = ptrace_request(child, request, addr, data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
out_eio:
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
asmlinkage void syscall_trace(void)
|
||||||
|
{
|
||||||
|
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
|
||||||
|
? 0x80 : 0));
|
||||||
|
/*
|
||||||
|
* this isn't the same as continuing with a signal, but it will do
|
||||||
|
* for normal use. strace only continues with a signal if the
|
||||||
|
* stopping signal is not SIGTRAP. -brl
|
||||||
|
*/
|
||||||
|
if (current->exit_code) {
|
||||||
|
send_sig(current->exit_code, current, 1);
|
||||||
|
current->exit_code = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_COLDFIRE
|
||||||
|
asmlinkage int syscall_trace_enter(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||||
|
ret = tracehook_report_syscall_entry(task_pt_regs(current));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
asmlinkage void syscall_trace_leave(void)
|
||||||
|
{
|
||||||
|
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||||
|
tracehook_report_syscall_exit(task_pt_regs(current), 0);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_COLDFIRE */
|
||||||
|
@@ -1,295 +0,0 @@
|
|||||||
/*
|
|
||||||
* linux/arch/m68k/kernel/ptrace.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994 by Hamish Macdonald
|
|
||||||
* Taken from linux/kernel/ptrace.c and modified for M680x0.
|
|
||||||
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
|
|
||||||
*
|
|
||||||
* This file is subject to the terms and conditions of the GNU General
|
|
||||||
* Public License. See the file COPYING in the main directory of
|
|
||||||
* this archive for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/user.h>
|
|
||||||
#include <linux/signal.h>
|
|
||||||
#include <linux/tracehook.h>
|
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
|
||||||
#include <asm/page.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
#include <asm/system.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* does not yet catch signals sent when the child dies.
|
|
||||||
* in exit.c or in signal.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* determines which bits in the SR the user has access to. */
|
|
||||||
/* 1 = access 0 = no access */
|
|
||||||
#define SR_MASK 0x001f
|
|
||||||
|
|
||||||
/* sets the trace bits. */
|
|
||||||
#define TRACE_BITS 0xC000
|
|
||||||
#define T1_BIT 0x8000
|
|
||||||
#define T0_BIT 0x4000
|
|
||||||
|
|
||||||
/* Find the stack offset for a register, relative to thread.esp0. */
|
|
||||||
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
|
|
||||||
#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
|
|
||||||
- sizeof(struct switch_stack))
|
|
||||||
/* Mapping from PT_xxx to the stack offset at which the register is
|
|
||||||
saved. Notice that usp has no stack-slot and needs to be treated
|
|
||||||
specially (see get_reg/put_reg below). */
|
|
||||||
static const int regoff[] = {
|
|
||||||
[0] = PT_REG(d1),
|
|
||||||
[1] = PT_REG(d2),
|
|
||||||
[2] = PT_REG(d3),
|
|
||||||
[3] = PT_REG(d4),
|
|
||||||
[4] = PT_REG(d5),
|
|
||||||
[5] = SW_REG(d6),
|
|
||||||
[6] = SW_REG(d7),
|
|
||||||
[7] = PT_REG(a0),
|
|
||||||
[8] = PT_REG(a1),
|
|
||||||
[9] = PT_REG(a2),
|
|
||||||
[10] = SW_REG(a3),
|
|
||||||
[11] = SW_REG(a4),
|
|
||||||
[12] = SW_REG(a5),
|
|
||||||
[13] = SW_REG(a6),
|
|
||||||
[14] = PT_REG(d0),
|
|
||||||
[15] = -1,
|
|
||||||
[16] = PT_REG(orig_d0),
|
|
||||||
[17] = PT_REG(sr),
|
|
||||||
[18] = PT_REG(pc),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get contents of register REGNO in task TASK.
|
|
||||||
*/
|
|
||||||
static inline long get_reg(struct task_struct *task, int regno)
|
|
||||||
{
|
|
||||||
unsigned long *addr;
|
|
||||||
|
|
||||||
if (regno == PT_USP)
|
|
||||||
addr = &task->thread.usp;
|
|
||||||
else if (regno < ARRAY_SIZE(regoff))
|
|
||||||
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
/* Need to take stkadj into account. */
|
|
||||||
if (regno == PT_SR || regno == PT_PC) {
|
|
||||||
long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
|
|
||||||
addr = (unsigned long *) ((unsigned long)addr + stkadj);
|
|
||||||
/* The sr is actually a 16 bit register. */
|
|
||||||
if (regno == PT_SR)
|
|
||||||
return *(unsigned short *)addr;
|
|
||||||
}
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write contents of register REGNO in task TASK.
|
|
||||||
*/
|
|
||||||
static inline int put_reg(struct task_struct *task, int regno,
|
|
||||||
unsigned long data)
|
|
||||||
{
|
|
||||||
unsigned long *addr;
|
|
||||||
|
|
||||||
if (regno == PT_USP)
|
|
||||||
addr = &task->thread.usp;
|
|
||||||
else if (regno < ARRAY_SIZE(regoff))
|
|
||||||
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
/* Need to take stkadj into account. */
|
|
||||||
if (regno == PT_SR || regno == PT_PC) {
|
|
||||||
long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
|
|
||||||
addr = (unsigned long *) ((unsigned long)addr + stkadj);
|
|
||||||
/* The sr is actually a 16 bit register. */
|
|
||||||
if (regno == PT_SR) {
|
|
||||||
*(unsigned short *)addr = data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*addr = data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure the single step bit is not set.
|
|
||||||
*/
|
|
||||||
static inline void singlestep_disable(struct task_struct *child)
|
|
||||||
{
|
|
||||||
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
|
|
||||||
put_reg(child, PT_SR, tmp);
|
|
||||||
clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called by kernel/ptrace.c when detaching..
|
|
||||||
*/
|
|
||||||
void ptrace_disable(struct task_struct *child)
|
|
||||||
{
|
|
||||||
singlestep_disable(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
void user_enable_single_step(struct task_struct *child)
|
|
||||||
{
|
|
||||||
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
|
|
||||||
put_reg(child, PT_SR, tmp | T1_BIT);
|
|
||||||
set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void user_enable_block_step(struct task_struct *child)
|
|
||||||
{
|
|
||||||
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
|
|
||||||
put_reg(child, PT_SR, tmp | T0_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void user_disable_single_step(struct task_struct *child)
|
|
||||||
{
|
|
||||||
singlestep_disable(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
long arch_ptrace(struct task_struct *child, long request,
|
|
||||||
unsigned long addr, unsigned long data)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
int i, ret = 0;
|
|
||||||
int regno = addr >> 2; /* temporary hack. */
|
|
||||||
unsigned long __user *datap = (unsigned long __user *) data;
|
|
||||||
|
|
||||||
switch (request) {
|
|
||||||
/* read the word at location addr in the USER area. */
|
|
||||||
case PTRACE_PEEKUSR:
|
|
||||||
if (addr & 3)
|
|
||||||
goto out_eio;
|
|
||||||
|
|
||||||
if (regno >= 0 && regno < 19) {
|
|
||||||
tmp = get_reg(child, regno);
|
|
||||||
} else if (regno >= 21 && regno < 49) {
|
|
||||||
tmp = child->thread.fp[regno - 21];
|
|
||||||
/* Convert internal fpu reg representation
|
|
||||||
* into long double format
|
|
||||||
*/
|
|
||||||
if (FPU_IS_EMU && (regno < 45) && !(regno % 3))
|
|
||||||
tmp = ((tmp & 0xffff0000) << 15) |
|
|
||||||
((tmp & 0x0000ffff) << 16);
|
|
||||||
} else
|
|
||||||
goto out_eio;
|
|
||||||
ret = put_user(tmp, datap);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_POKEUSR:
|
|
||||||
/* write the word at location addr in the USER area */
|
|
||||||
if (addr & 3)
|
|
||||||
goto out_eio;
|
|
||||||
|
|
||||||
if (regno == PT_SR) {
|
|
||||||
data &= SR_MASK;
|
|
||||||
data |= get_reg(child, PT_SR) & ~SR_MASK;
|
|
||||||
}
|
|
||||||
if (regno >= 0 && regno < 19) {
|
|
||||||
if (put_reg(child, regno, data))
|
|
||||||
goto out_eio;
|
|
||||||
} else if (regno >= 21 && regno < 48) {
|
|
||||||
/* Convert long double format
|
|
||||||
* into internal fpu reg representation
|
|
||||||
*/
|
|
||||||
if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {
|
|
||||||
data <<= 15;
|
|
||||||
data = (data & 0xffff0000) |
|
|
||||||
((data & 0x0000ffff) >> 1);
|
|
||||||
}
|
|
||||||
child->thread.fp[regno - 21] = data;
|
|
||||||
} else
|
|
||||||
goto out_eio;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_GETREGS: /* Get all gp regs from the child. */
|
|
||||||
for (i = 0; i < 19; i++) {
|
|
||||||
tmp = get_reg(child, i);
|
|
||||||
ret = put_user(tmp, datap);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
datap++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_SETREGS: /* Set all gp regs in the child. */
|
|
||||||
for (i = 0; i < 19; i++) {
|
|
||||||
ret = get_user(tmp, datap);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
if (i == PT_SR) {
|
|
||||||
tmp &= SR_MASK;
|
|
||||||
tmp |= get_reg(child, PT_SR) & ~SR_MASK;
|
|
||||||
}
|
|
||||||
put_reg(child, i, tmp);
|
|
||||||
datap++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_GETFPREGS: /* Get the child FPU state. */
|
|
||||||
if (copy_to_user(datap, &child->thread.fp,
|
|
||||||
sizeof(struct user_m68kfp_struct)))
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_SETFPREGS: /* Set the child FPU state. */
|
|
||||||
if (copy_from_user(&child->thread.fp, datap,
|
|
||||||
sizeof(struct user_m68kfp_struct)))
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_GET_THREAD_AREA:
|
|
||||||
ret = put_user(task_thread_info(child)->tp_value, datap);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = ptrace_request(child, request, addr, data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
out_eio:
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage void syscall_trace(void)
|
|
||||||
{
|
|
||||||
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
|
|
||||||
? 0x80 : 0));
|
|
||||||
/*
|
|
||||||
* this isn't the same as continuing with a signal, but it will do
|
|
||||||
* for normal use. strace only continues with a signal if the
|
|
||||||
* stopping signal is not SIGTRAP. -brl
|
|
||||||
*/
|
|
||||||
if (current->exit_code) {
|
|
||||||
send_sig(current->exit_code, current, 1);
|
|
||||||
current->exit_code = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_COLDFIRE
|
|
||||||
asmlinkage int syscall_trace_enter(void)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
|
||||||
ret = tracehook_report_syscall_entry(task_pt_regs(current));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage void syscall_trace_leave(void)
|
|
||||||
{
|
|
||||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
|
||||||
tracehook_report_syscall_exit(task_pt_regs(current), 0);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_COLDFIRE */
|
|
@@ -1,255 +0,0 @@
|
|||||||
/*
|
|
||||||
* linux/arch/m68knommu/kernel/ptrace.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994 by Hamish Macdonald
|
|
||||||
* Taken from linux/kernel/ptrace.c and modified for M680x0.
|
|
||||||
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
|
|
||||||
*
|
|
||||||
* This file is subject to the terms and conditions of the GNU General
|
|
||||||
* Public License. See the file COPYING in the main directory of
|
|
||||||
* this archive for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/user.h>
|
|
||||||
#include <linux/signal.h>
|
|
||||||
#include <linux/tracehook.h>
|
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
|
||||||
#include <asm/page.h>
|
|
||||||
#include <asm/pgtable.h>
|
|
||||||
#include <asm/system.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* does not yet catch signals sent when the child dies.
|
|
||||||
* in exit.c or in signal.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* determines which bits in the SR the user has access to. */
|
|
||||||
/* 1 = access 0 = no access */
|
|
||||||
#define SR_MASK 0x001f
|
|
||||||
|
|
||||||
/* sets the trace bits. */
|
|
||||||
#define TRACE_BITS 0x8000
|
|
||||||
|
|
||||||
/* Find the stack offset for a register, relative to thread.esp0. */
|
|
||||||
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
|
|
||||||
#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
|
|
||||||
- sizeof(struct switch_stack))
|
|
||||||
/* Mapping from PT_xxx to the stack offset at which the register is
|
|
||||||
saved. Notice that usp has no stack-slot and needs to be treated
|
|
||||||
specially (see get_reg/put_reg below). */
|
|
||||||
static int regoff[] = {
|
|
||||||
PT_REG(d1), PT_REG(d2), PT_REG(d3), PT_REG(d4),
|
|
||||||
PT_REG(d5), SW_REG(d6), SW_REG(d7), PT_REG(a0),
|
|
||||||
PT_REG(a1), PT_REG(a2), SW_REG(a3), SW_REG(a4),
|
|
||||||
SW_REG(a5), SW_REG(a6), PT_REG(d0), -1,
|
|
||||||
PT_REG(orig_d0), PT_REG(sr), PT_REG(pc),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get contents of register REGNO in task TASK.
|
|
||||||
*/
|
|
||||||
static inline long get_reg(struct task_struct *task, int regno)
|
|
||||||
{
|
|
||||||
unsigned long *addr;
|
|
||||||
|
|
||||||
if (regno == PT_USP)
|
|
||||||
addr = &task->thread.usp;
|
|
||||||
else if (regno < ARRAY_SIZE(regoff))
|
|
||||||
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write contents of register REGNO in task TASK.
|
|
||||||
*/
|
|
||||||
static inline int put_reg(struct task_struct *task, int regno,
|
|
||||||
unsigned long data)
|
|
||||||
{
|
|
||||||
unsigned long *addr;
|
|
||||||
|
|
||||||
if (regno == PT_USP)
|
|
||||||
addr = &task->thread.usp;
|
|
||||||
else if (regno < ARRAY_SIZE(regoff))
|
|
||||||
addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
*addr = data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void user_enable_single_step(struct task_struct *task)
|
|
||||||
{
|
|
||||||
unsigned long srflags;
|
|
||||||
srflags = get_reg(task, PT_SR) | (TRACE_BITS << 16);
|
|
||||||
put_reg(task, PT_SR, srflags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void user_disable_single_step(struct task_struct *task)
|
|
||||||
{
|
|
||||||
unsigned long srflags;
|
|
||||||
srflags = get_reg(task, PT_SR) & ~(TRACE_BITS << 16);
|
|
||||||
put_reg(task, PT_SR, srflags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called by kernel/ptrace.c when detaching..
|
|
||||||
*
|
|
||||||
* Make sure the single step bit is not set.
|
|
||||||
*/
|
|
||||||
void ptrace_disable(struct task_struct *child)
|
|
||||||
{
|
|
||||||
/* make sure the single step bit is not set. */
|
|
||||||
user_disable_single_step(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
long arch_ptrace(struct task_struct *child, long request,
|
|
||||||
unsigned long addr, unsigned long data)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int regno = addr >> 2;
|
|
||||||
unsigned long __user *datap = (unsigned long __user *) data;
|
|
||||||
|
|
||||||
switch (request) {
|
|
||||||
/* read the word at location addr in the USER area. */
|
|
||||||
case PTRACE_PEEKUSR: {
|
|
||||||
unsigned long tmp;
|
|
||||||
|
|
||||||
ret = -EIO;
|
|
||||||
if ((addr & 3) || addr > sizeof(struct user) - 3)
|
|
||||||
break;
|
|
||||||
|
|
||||||
tmp = 0; /* Default return condition */
|
|
||||||
ret = -EIO;
|
|
||||||
if (regno < 19) {
|
|
||||||
tmp = get_reg(child, regno);
|
|
||||||
if (regno == PT_SR)
|
|
||||||
tmp >>= 16;
|
|
||||||
} else if (regno >= 21 && regno < 49) {
|
|
||||||
tmp = child->thread.fp[regno - 21];
|
|
||||||
} else if (regno == 49) {
|
|
||||||
tmp = child->mm->start_code;
|
|
||||||
} else if (regno == 50) {
|
|
||||||
tmp = child->mm->start_data;
|
|
||||||
} else if (regno == 51) {
|
|
||||||
tmp = child->mm->end_code;
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
ret = put_user(tmp, datap);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
|
|
||||||
ret = -EIO;
|
|
||||||
if ((addr & 3) || addr > sizeof(struct user) - 3)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (regno == PT_SR) {
|
|
||||||
data &= SR_MASK;
|
|
||||||
data <<= 16;
|
|
||||||
data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
|
|
||||||
}
|
|
||||||
if (regno < 19) {
|
|
||||||
if (put_reg(child, regno, data))
|
|
||||||
break;
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (regno >= 21 && regno < 48)
|
|
||||||
{
|
|
||||||
child->thread.fp[regno - 21] = data;
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
|
|
||||||
int i;
|
|
||||||
unsigned long tmp;
|
|
||||||
for (i = 0; i < 19; i++) {
|
|
||||||
tmp = get_reg(child, i);
|
|
||||||
if (i == PT_SR)
|
|
||||||
tmp >>= 16;
|
|
||||||
if (put_user(tmp, datap)) {
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
datap++;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PTRACE_SETREGS: { /* Set all gp regs in the child. */
|
|
||||||
int i;
|
|
||||||
unsigned long tmp;
|
|
||||||
for (i = 0; i < 19; i++) {
|
|
||||||
if (get_user(tmp, datap)) {
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i == PT_SR) {
|
|
||||||
tmp &= SR_MASK;
|
|
||||||
tmp <<= 16;
|
|
||||||
tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
|
|
||||||
}
|
|
||||||
put_reg(child, i, tmp);
|
|
||||||
datap++;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PTRACE_GETFPREGS
|
|
||||||
case PTRACE_GETFPREGS: { /* Get the child FPU state. */
|
|
||||||
ret = 0;
|
|
||||||
if (copy_to_user(datap, &child->thread.fp,
|
|
||||||
sizeof(struct user_m68kfp_struct)))
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PTRACE_SETFPREGS
|
|
||||||
case PTRACE_SETFPREGS: { /* Set the child FPU state. */
|
|
||||||
ret = 0;
|
|
||||||
if (copy_from_user(&child->thread.fp, datap,
|
|
||||||
sizeof(struct user_m68kfp_struct)))
|
|
||||||
ret = -EFAULT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case PTRACE_GET_THREAD_AREA:
|
|
||||||
ret = put_user(task_thread_info(child)->tp_value, datap);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = ptrace_request(child, request, addr, data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int syscall_trace_enter(void)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
|
||||||
ret = tracehook_report_syscall_entry(task_pt_regs(current));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage void syscall_trace_leave(void)
|
|
||||||
{
|
|
||||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
|
||||||
tracehook_report_syscall_exit(task_pt_regs(current), 0);
|
|
||||||
}
|
|
@@ -31,6 +31,7 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/initrd.h>
|
#include <linux/initrd.h>
|
||||||
#include <linux/root_dev.h>
|
#include <linux/root_dev.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
|
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
@@ -47,7 +48,9 @@ EXPORT_SYMBOL(memory_end);
|
|||||||
char __initdata command_line[COMMAND_LINE_SIZE];
|
char __initdata command_line[COMMAND_LINE_SIZE];
|
||||||
|
|
||||||
/* machine dependent timer functions */
|
/* machine dependent timer functions */
|
||||||
|
void (*mach_sched_init)(irq_handler_t handler) __initdata = NULL;
|
||||||
int (*mach_set_clock_mmss)(unsigned long);
|
int (*mach_set_clock_mmss)(unsigned long);
|
||||||
|
int (*mach_hwclk) (int, struct rtc_time*);
|
||||||
|
|
||||||
/* machine dependent reboot functions */
|
/* machine dependent reboot functions */
|
||||||
void (*mach_reset)(void);
|
void (*mach_reset)(void);
|
||||||
|
@@ -1,5 +1,111 @@
|
|||||||
#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
|
/*
|
||||||
#include "time_mm.c"
|
* linux/arch/m68k/kernel/time.c
|
||||||
#else
|
*
|
||||||
#include "time_no.c"
|
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
|
||||||
#endif
|
*
|
||||||
|
* This file contains the m68k-specific time handling details.
|
||||||
|
* Most of the stuff is located in the machine specific files.
|
||||||
|
*
|
||||||
|
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
|
||||||
|
* "A Kernel Model for Precision Timekeeping" by Dave Mills
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/param.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
#include <asm/machdep.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/irq_regs.h>
|
||||||
|
|
||||||
|
#include <linux/time.h>
|
||||||
|
#include <linux/timex.h>
|
||||||
|
#include <linux/profile.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* timer_interrupt() needs to keep up the real-time clock,
|
||||||
|
* as well as call the "xtime_update()" routine every clocktick
|
||||||
|
*/
|
||||||
|
static irqreturn_t timer_interrupt(int irq, void *dummy)
|
||||||
|
{
|
||||||
|
xtime_update(1);
|
||||||
|
update_process_times(user_mode(get_irq_regs()));
|
||||||
|
profile_tick(CPU_PROFILING);
|
||||||
|
|
||||||
|
#ifdef CONFIG_HEARTBEAT
|
||||||
|
/* use power LED as a heartbeat instead -- much more useful
|
||||||
|
for debugging -- based on the version for PReP by Cort */
|
||||||
|
/* acts like an actual heart beat -- ie thump-thump-pause... */
|
||||||
|
if (mach_heartbeat) {
|
||||||
|
static unsigned cnt = 0, period = 0, dist = 0;
|
||||||
|
|
||||||
|
if (cnt == 0 || cnt == dist)
|
||||||
|
mach_heartbeat( 1 );
|
||||||
|
else if (cnt == 7 || cnt == dist+7)
|
||||||
|
mach_heartbeat( 0 );
|
||||||
|
|
||||||
|
if (++cnt > period) {
|
||||||
|
cnt = 0;
|
||||||
|
/* The hyperbolic function below modifies the heartbeat period
|
||||||
|
* length in dependency of the current (5min) load. It goes
|
||||||
|
* through the points f(0)=126, f(1)=86, f(5)=51,
|
||||||
|
* f(inf)->30. */
|
||||||
|
period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
|
||||||
|
dist = period / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_HEARTBEAT */
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_persistent_clock(struct timespec *ts)
|
||||||
|
{
|
||||||
|
struct rtc_time time;
|
||||||
|
ts->tv_sec = 0;
|
||||||
|
ts->tv_nsec = 0;
|
||||||
|
|
||||||
|
if (mach_hwclk) {
|
||||||
|
mach_hwclk(0, &time);
|
||||||
|
|
||||||
|
if ((time.tm_year += 1900) < 1970)
|
||||||
|
time.tm_year += 100;
|
||||||
|
ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
|
||||||
|
time.tm_hour, time.tm_min, time.tm_sec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init time_init(void)
|
||||||
|
{
|
||||||
|
mach_sched_init(timer_interrupt);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_M68KCLASSIC
|
||||||
|
|
||||||
|
u32 arch_gettimeoffset(void)
|
||||||
|
{
|
||||||
|
return mach_gettimeoffset() * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init rtc_init(void)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev;
|
||||||
|
|
||||||
|
if (!mach_hwclk)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
|
||||||
|
if (IS_ERR(pdev))
|
||||||
|
return PTR_ERR(pdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(rtc_init);
|
||||||
|
|
||||||
|
#endif /* CONFIG_M68KCLASSIC */
|
||||||
|
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* linux/arch/m68k/kernel/time.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
|
|
||||||
*
|
|
||||||
* This file contains the m68k-specific time handling details.
|
|
||||||
* Most of the stuff is located in the machine specific files.
|
|
||||||
*
|
|
||||||
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
|
|
||||||
* "A Kernel Model for Precision Timekeeping" by Dave Mills
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/param.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/rtc.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
|
|
||||||
#include <asm/machdep.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include <asm/irq_regs.h>
|
|
||||||
|
|
||||||
#include <linux/time.h>
|
|
||||||
#include <linux/timex.h>
|
|
||||||
#include <linux/profile.h>
|
|
||||||
|
|
||||||
static inline int set_rtc_mmss(unsigned long nowtime)
|
|
||||||
{
|
|
||||||
if (mach_set_clock_mmss)
|
|
||||||
return mach_set_clock_mmss (nowtime);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* timer_interrupt() needs to keep up the real-time clock,
|
|
||||||
* as well as call the "xtime_update()" routine every clocktick
|
|
||||||
*/
|
|
||||||
static irqreturn_t timer_interrupt(int irq, void *dummy)
|
|
||||||
{
|
|
||||||
xtime_update(1);
|
|
||||||
update_process_times(user_mode(get_irq_regs()));
|
|
||||||
profile_tick(CPU_PROFILING);
|
|
||||||
|
|
||||||
#ifdef CONFIG_HEARTBEAT
|
|
||||||
/* use power LED as a heartbeat instead -- much more useful
|
|
||||||
for debugging -- based on the version for PReP by Cort */
|
|
||||||
/* acts like an actual heart beat -- ie thump-thump-pause... */
|
|
||||||
if (mach_heartbeat) {
|
|
||||||
static unsigned cnt = 0, period = 0, dist = 0;
|
|
||||||
|
|
||||||
if (cnt == 0 || cnt == dist)
|
|
||||||
mach_heartbeat( 1 );
|
|
||||||
else if (cnt == 7 || cnt == dist+7)
|
|
||||||
mach_heartbeat( 0 );
|
|
||||||
|
|
||||||
if (++cnt > period) {
|
|
||||||
cnt = 0;
|
|
||||||
/* The hyperbolic function below modifies the heartbeat period
|
|
||||||
* length in dependency of the current (5min) load. It goes
|
|
||||||
* through the points f(0)=126, f(1)=86, f(5)=51,
|
|
||||||
* f(inf)->30. */
|
|
||||||
period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
|
|
||||||
dist = period / 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_HEARTBEAT */
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_persistent_clock(struct timespec *ts)
|
|
||||||
{
|
|
||||||
struct rtc_time time;
|
|
||||||
ts->tv_sec = 0;
|
|
||||||
ts->tv_nsec = 0;
|
|
||||||
|
|
||||||
if (mach_hwclk) {
|
|
||||||
mach_hwclk(0, &time);
|
|
||||||
|
|
||||||
if ((time.tm_year += 1900) < 1970)
|
|
||||||
time.tm_year += 100;
|
|
||||||
ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
|
|
||||||
time.tm_hour, time.tm_min, time.tm_sec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init time_init(void)
|
|
||||||
{
|
|
||||||
mach_sched_init(timer_interrupt);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 arch_gettimeoffset(void)
|
|
||||||
{
|
|
||||||
return mach_gettimeoffset() * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init rtc_init(void)
|
|
||||||
{
|
|
||||||
struct platform_device *pdev;
|
|
||||||
|
|
||||||
if (!mach_hwclk)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
|
|
||||||
if (IS_ERR(pdev))
|
|
||||||
return PTR_ERR(pdev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(rtc_init);
|
|
@@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* linux/arch/m68knommu/kernel/time.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
|
|
||||||
*
|
|
||||||
* This file contains the m68k-specific time handling details.
|
|
||||||
* Most of the stuff is located in the machine specific files.
|
|
||||||
*
|
|
||||||
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
|
|
||||||
* "A Kernel Model for Precision Timekeeping" by Dave Mills
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/param.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/mm.h>
|
|
||||||
#include <linux/profile.h>
|
|
||||||
#include <linux/time.h>
|
|
||||||
#include <linux/timex.h>
|
|
||||||
|
|
||||||
#include <asm/machdep.h>
|
|
||||||
#include <asm/irq_regs.h>
|
|
||||||
|
|
||||||
#define TICK_SIZE (tick_nsec / 1000)
|
|
||||||
|
|
||||||
/* machine dependent timer functions */
|
|
||||||
void (*mach_gettod)(int*, int*, int*, int*, int*, int*);
|
|
||||||
|
|
||||||
static inline int set_rtc_mmss(unsigned long nowtime)
|
|
||||||
{
|
|
||||||
if (mach_set_clock_mmss)
|
|
||||||
return mach_set_clock_mmss (nowtime);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef CONFIG_GENERIC_CLOCKEVENTS
|
|
||||||
/*
|
|
||||||
* timer_interrupt() needs to keep up the real-time clock,
|
|
||||||
* as well as call the "xtime_update()" routine every clocktick
|
|
||||||
*/
|
|
||||||
irqreturn_t arch_timer_interrupt(int irq, void *dummy)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (current->pid)
|
|
||||||
profile_tick(CPU_PROFILING);
|
|
||||||
|
|
||||||
xtime_update(1);
|
|
||||||
|
|
||||||
update_process_times(user_mode(get_irq_regs()));
|
|
||||||
|
|
||||||
return(IRQ_HANDLED);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static unsigned long read_rtc_mmss(void)
|
|
||||||
{
|
|
||||||
unsigned int year, mon, day, hour, min, sec;
|
|
||||||
|
|
||||||
if (mach_gettod) {
|
|
||||||
mach_gettod(&year, &mon, &day, &hour, &min, &sec);
|
|
||||||
if ((year += 1900) < 1970)
|
|
||||||
year += 100;
|
|
||||||
} else {
|
|
||||||
year = 1970;
|
|
||||||
mon = day = 1;
|
|
||||||
hour = min = sec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return mktime(year, mon, day, hour, min, sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_persistent_clock(struct timespec *ts)
|
|
||||||
{
|
|
||||||
ts->tv_sec = read_rtc_mmss();
|
|
||||||
ts->tv_nsec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int update_persistent_clock(struct timespec now)
|
|
||||||
{
|
|
||||||
return set_rtc_mmss(now.tv_sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void time_init(void)
|
|
||||||
{
|
|
||||||
hw_timer_init();
|
|
||||||
}
|
|
@@ -1,195 +1,93 @@
|
|||||||
/*
|
/*
|
||||||
* vmlinux.lds.S -- master linker script for m68knommu arch
|
* vmlinux.lds.S -- master linker script for m68knommu arch
|
||||||
*
|
*
|
||||||
* (C) Copyright 2002-2006, Greg Ungerer <gerg@snapgear.com>
|
* (C) Copyright 2002-2012, Greg Ungerer <gerg@snapgear.com>
|
||||||
*
|
*
|
||||||
* This linker script is equipped to build either ROM loaded or RAM
|
* This linker script is equipped to build either ROM loaded or RAM
|
||||||
* run kernels.
|
* run kernels.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm-generic/vmlinux.lds.h>
|
#if defined(CONFIG_RAMKERNEL)
|
||||||
|
#define KTEXT_ADDR CONFIG_KERNELBASE
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_ROMKERNEL)
|
||||||
|
#define KTEXT_ADDR CONFIG_ROMSTART
|
||||||
|
#define KDATA_ADDR CONFIG_KERNELBASE
|
||||||
|
#define LOAD_OFFSET KDATA_ADDR + (ADDR(.text) + SIZEOF(.text))
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/thread_info.h>
|
#include <asm/thread_info.h>
|
||||||
|
#include <asm-generic/vmlinux.lds.h>
|
||||||
#if defined(CONFIG_RAMKERNEL)
|
|
||||||
#define RAM_START CONFIG_KERNELBASE
|
|
||||||
#define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE)
|
|
||||||
#define TEXT ram
|
|
||||||
#define DATA ram
|
|
||||||
#define INIT ram
|
|
||||||
#define BSSS ram
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)
|
|
||||||
#define RAM_START CONFIG_RAMBASE
|
|
||||||
#define RAM_LENGTH CONFIG_RAMSIZE
|
|
||||||
#define ROMVEC_START CONFIG_ROMVEC
|
|
||||||
#define ROMVEC_LENGTH CONFIG_ROMVECSIZE
|
|
||||||
#define ROM_START CONFIG_ROMSTART
|
|
||||||
#define ROM_LENGTH CONFIG_ROMSIZE
|
|
||||||
#define TEXT rom
|
|
||||||
#define DATA ram
|
|
||||||
#define INIT ram
|
|
||||||
#define BSSS ram
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef DATA_ADDR
|
|
||||||
#define DATA_ADDR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
OUTPUT_ARCH(m68k)
|
OUTPUT_ARCH(m68k)
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
MEMORY {
|
|
||||||
ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH
|
|
||||||
#ifdef ROM_START
|
|
||||||
romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH
|
|
||||||
rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jiffies = jiffies_64 + 4;
|
jiffies = jiffies_64 + 4;
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
|
|
||||||
#ifdef ROMVEC_START
|
#ifdef CONFIG_ROMVEC
|
||||||
. = ROMVEC_START ;
|
. = CONFIG_ROMVEC;
|
||||||
.romvec : {
|
.romvec : {
|
||||||
__rom_start = . ;
|
__rom_start = .;
|
||||||
_romvec = .;
|
_romvec = .;
|
||||||
|
*(.romvec)
|
||||||
*(.data..initvect)
|
*(.data..initvect)
|
||||||
} > romvec
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
. = KTEXT_ADDR;
|
||||||
|
|
||||||
|
_text = .;
|
||||||
|
_stext = .;
|
||||||
.text : {
|
.text : {
|
||||||
_text = .;
|
|
||||||
_stext = . ;
|
|
||||||
HEAD_TEXT
|
HEAD_TEXT
|
||||||
TEXT_TEXT
|
TEXT_TEXT
|
||||||
SCHED_TEXT
|
SCHED_TEXT
|
||||||
LOCK_TEXT
|
LOCK_TEXT
|
||||||
*(.text..lock)
|
|
||||||
*(.fixup)
|
*(.fixup)
|
||||||
|
. = ALIGN(16);
|
||||||
|
}
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
. = ALIGN(16); /* Exception table */
|
#ifdef KDATA_ADDR
|
||||||
__start___ex_table = .;
|
. = KDATA_ADDR;
|
||||||
*(__ex_table)
|
#endif
|
||||||
__stop___ex_table = .;
|
|
||||||
|
|
||||||
*(.rodata) *(.rodata.*)
|
_sdata = .;
|
||||||
*(__vermagic) /* Kernel version magic */
|
RO_DATA_SECTION(PAGE_SIZE)
|
||||||
*(.rodata1)
|
RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
|
||||||
*(.rodata.str1.1)
|
_edata = .;
|
||||||
|
|
||||||
/* Kernel symbol table: Normal symbols */
|
EXCEPTION_TABLE(16)
|
||||||
. = ALIGN(4);
|
NOTES
|
||||||
__start___ksymtab = .;
|
|
||||||
*(SORT(___ksymtab+*))
|
|
||||||
__stop___ksymtab = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: GPL-only symbols */
|
|
||||||
__start___ksymtab_gpl = .;
|
|
||||||
*(SORT(___ksymtab_gpl+*))
|
|
||||||
__stop___ksymtab_gpl = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: Normal unused symbols */
|
|
||||||
__start___ksymtab_unused = .;
|
|
||||||
*(SORT(___ksymtab_unused+*))
|
|
||||||
__stop___ksymtab_unused = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: GPL-only unused symbols */
|
|
||||||
__start___ksymtab_unused_gpl = .;
|
|
||||||
*(SORT(___ksymtab_unused_gpl+*))
|
|
||||||
__stop___ksymtab_unused_gpl = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: GPL-future symbols */
|
|
||||||
__start___ksymtab_gpl_future = .;
|
|
||||||
*(SORT(___ksymtab_gpl_future+*))
|
|
||||||
__stop___ksymtab_gpl_future = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: Normal symbols */
|
|
||||||
__start___kcrctab = .;
|
|
||||||
*(SORT(___kcrctab+*))
|
|
||||||
__stop___kcrctab = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: GPL-only symbols */
|
|
||||||
__start___kcrctab_gpl = .;
|
|
||||||
*(SORT(___kcrctab_gpl+*))
|
|
||||||
__stop___kcrctab_gpl = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: Normal unused symbols */
|
|
||||||
__start___kcrctab_unused = .;
|
|
||||||
*(SORT(___kcrctab_unused+*))
|
|
||||||
__stop___kcrctab_unused = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: GPL-only unused symbols */
|
|
||||||
__start___kcrctab_unused_gpl = .;
|
|
||||||
*(SORT(___kcrctab_unused_gpl+*))
|
|
||||||
__stop___kcrctab_unused_gpl = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: GPL-future symbols */
|
|
||||||
__start___kcrctab_gpl_future = .;
|
|
||||||
*(SORT(___kcrctab_gpl_future+*))
|
|
||||||
__stop___kcrctab_gpl_future = .;
|
|
||||||
|
|
||||||
/* Kernel symbol table: strings */
|
|
||||||
*(__ksymtab_strings)
|
|
||||||
|
|
||||||
/* Built-in module parameters */
|
|
||||||
. = ALIGN(4) ;
|
|
||||||
__start___param = .;
|
|
||||||
*(__param)
|
|
||||||
__stop___param = .;
|
|
||||||
|
|
||||||
/* Built-in module versions */
|
|
||||||
. = ALIGN(4) ;
|
|
||||||
__start___modver = .;
|
|
||||||
*(__modver)
|
|
||||||
__stop___modver = .;
|
|
||||||
|
|
||||||
. = ALIGN(4) ;
|
|
||||||
_etext = . ;
|
|
||||||
} > TEXT
|
|
||||||
|
|
||||||
.data DATA_ADDR : {
|
|
||||||
. = ALIGN(4);
|
|
||||||
_sdata = . ;
|
|
||||||
DATA_DATA
|
|
||||||
CACHELINE_ALIGNED_DATA(32)
|
|
||||||
PAGE_ALIGNED_DATA(PAGE_SIZE)
|
|
||||||
*(.data..shared_aligned)
|
|
||||||
INIT_TASK_DATA(THREAD_SIZE)
|
|
||||||
_edata = . ;
|
|
||||||
} > DATA
|
|
||||||
|
|
||||||
|
. = ALIGN(PAGE_SIZE);
|
||||||
|
__init_begin = .;
|
||||||
|
INIT_TEXT_SECTION(PAGE_SIZE)
|
||||||
|
INIT_DATA_SECTION(16)
|
||||||
|
PERCPU_SECTION(16)
|
||||||
.m68k_fixup : {
|
.m68k_fixup : {
|
||||||
__start_fixup = .;
|
__start_fixup = .;
|
||||||
*(.m68k_fixup)
|
*(.m68k_fixup)
|
||||||
__stop_fixup = .;
|
__stop_fixup = .;
|
||||||
} > DATA
|
}
|
||||||
NOTES > DATA
|
|
||||||
|
|
||||||
.init.text : {
|
|
||||||
. = ALIGN(PAGE_SIZE);
|
|
||||||
__init_begin = .;
|
|
||||||
} > INIT
|
|
||||||
INIT_TEXT_SECTION(PAGE_SIZE) > INIT
|
|
||||||
INIT_DATA_SECTION(16) > INIT
|
|
||||||
.init.data : {
|
.init.data : {
|
||||||
. = ALIGN(PAGE_SIZE);
|
. = ALIGN(PAGE_SIZE);
|
||||||
__init_end = .;
|
__init_end = .;
|
||||||
} > INIT
|
}
|
||||||
|
|
||||||
.bss : {
|
_sbss = .;
|
||||||
. = ALIGN(4);
|
BSS_SECTION(0, 0, 0)
|
||||||
_sbss = . ;
|
_ebss = .;
|
||||||
*(.bss)
|
|
||||||
*(COMMON)
|
|
||||||
. = ALIGN(4) ;
|
|
||||||
_ebss = . ;
|
|
||||||
_end = . ;
|
|
||||||
} > BSSS
|
|
||||||
|
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
STABS_DEBUG
|
||||||
|
.comment 0 : { *(.comment) }
|
||||||
|
|
||||||
|
/* Sections to be discarded */
|
||||||
DISCARDS
|
DISCARDS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,83 +16,6 @@
|
|||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/coldfire.h>
|
#include <asm/coldfire.h>
|
||||||
#include <asm/mcfsim.h>
|
#include <asm/mcfsim.h>
|
||||||
#include <asm/mcfuart.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static struct mcf_platform_uart m5206_uart_platform[] = {
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE1,
|
|
||||||
.irq = 73,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE2,
|
|
||||||
.irq = 74,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m5206_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m5206_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device *m5206_devices[] __initdata = {
|
|
||||||
&m5206_uart,
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void __init m5206_uart_init_line(int line, int irq)
|
|
||||||
{
|
|
||||||
if (line == 0) {
|
|
||||||
writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
|
|
||||||
writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
|
|
||||||
mcf_mapirq2imr(irq, MCFINTC_UART0);
|
|
||||||
} else if (line == 1) {
|
|
||||||
writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
|
|
||||||
writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
|
|
||||||
mcf_mapirq2imr(irq, MCFINTC_UART1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init m5206_uarts_init(void)
|
|
||||||
{
|
|
||||||
const int nrlines = ARRAY_SIZE(m5206_uart_platform);
|
|
||||||
int line;
|
|
||||||
|
|
||||||
for (line = 0; (line < nrlines); line++)
|
|
||||||
m5206_uart_init_line(line, m5206_uart_platform[line].irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void __init m5206_timers_init(void)
|
|
||||||
{
|
|
||||||
/* Timer1 is always used as system timer */
|
|
||||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
|
|
||||||
MCF_MBAR + MCFSIM_TIMER1ICR);
|
|
||||||
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
|
|
||||||
|
|
||||||
#ifdef CONFIG_HIGHPROFILE
|
|
||||||
/* Timer2 is to be used as a high speed profile timer */
|
|
||||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
|
|
||||||
MCF_MBAR + MCFSIM_TIMER2ICR);
|
|
||||||
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void m5206_cpu_reset(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
/* Set watchdog to soft reset, and enabled */
|
|
||||||
__raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
|
|
||||||
for (;;)
|
|
||||||
/* wait for watchdog to timeout */;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
@@ -104,9 +27,7 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
commandp[size-1] = 0;
|
commandp[size-1] = 0;
|
||||||
#endif /* CONFIG_NETtel */
|
#endif /* CONFIG_NETtel */
|
||||||
|
|
||||||
mach_reset = m5206_cpu_reset;
|
mach_sched_init = hw_timer_init;
|
||||||
m5206_timers_init();
|
|
||||||
m5206_uarts_init();
|
|
||||||
|
|
||||||
/* Only support the external interrupts on their primary level */
|
/* Only support the external interrupts on their primary level */
|
||||||
mcf_mapirq2imr(25, MCFINTC_EINT1);
|
mcf_mapirq2imr(25, MCFINTC_EINT1);
|
||||||
@@ -115,13 +36,3 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
|
||||||
{
|
|
||||||
platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(init_BSP);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
@@ -15,194 +15,14 @@
|
|||||||
#include <linux/param.h>
|
#include <linux/param.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/spi/spi.h>
|
|
||||||
#include <linux/gpio.h>
|
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/coldfire.h>
|
#include <asm/coldfire.h>
|
||||||
#include <asm/mcfsim.h>
|
#include <asm/mcfsim.h>
|
||||||
#include <asm/mcfuart.h>
|
#include <asm/mcfuart.h>
|
||||||
#include <asm/mcfqspi.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct mcf_platform_uart m520x_uart_platform[] = {
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE1,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE2,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE3,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART2,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m520x_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m520x_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource m520x_fec_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFFEC_BASE,
|
|
||||||
.end = MCFFEC_BASE + MCFFEC_SIZE - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 36,
|
|
||||||
.end = 64 + 36,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 40,
|
|
||||||
.end = 64 + 40,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 42,
|
|
||||||
.end = 64 + 42,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m520x_fec = {
|
|
||||||
.name = "fec",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m520x_fec_resources),
|
|
||||||
.resource = m520x_fec_resources,
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
static struct resource m520x_qspi_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFQSPI_IOBASE,
|
|
||||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MCFQSPI_CS0 46
|
|
||||||
#define MCFQSPI_CS1 47
|
|
||||||
#define MCFQSPI_CS2 27
|
|
||||||
|
|
||||||
static int m520x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail0;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail3:
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
fail2:
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
fail1:
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
fail0:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m520x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m520x_cs_select(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
switch (chip_select) {
|
|
||||||
case 0:
|
|
||||||
gpio_set_value(MCFQSPI_CS0, cs_high);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gpio_set_value(MCFQSPI_CS1, cs_high);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_set_value(MCFQSPI_CS2, cs_high);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m520x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
switch (chip_select) {
|
|
||||||
case 0:
|
|
||||||
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mcfqspi_cs_control m520x_cs_control = {
|
|
||||||
.setup = m520x_cs_setup,
|
|
||||||
.teardown = m520x_cs_teardown,
|
|
||||||
.select = m520x_cs_select,
|
|
||||||
.deselect = m520x_cs_deselect,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct mcfqspi_platform_data m520x_qspi_data = {
|
|
||||||
.bus_num = 0,
|
|
||||||
.num_chipselect = 3,
|
|
||||||
.cs_control = &m520x_cs_control,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m520x_qspi = {
|
|
||||||
.name = "mcfqspi",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m520x_qspi_resources),
|
|
||||||
.resource = m520x_qspi_resources,
|
|
||||||
.dev.platform_data = &m520x_qspi_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init m520x_qspi_init(void)
|
static void __init m520x_qspi_init(void)
|
||||||
{
|
{
|
||||||
@@ -214,54 +34,28 @@ static void __init m520x_qspi_init(void)
|
|||||||
par &= 0x00ff;
|
par &= 0x00ff;
|
||||||
writew(par, MCF_GPIO_PAR_UART);
|
writew(par, MCF_GPIO_PAR_UART);
|
||||||
}
|
}
|
||||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
|
||||||
|
|
||||||
|
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||||
static struct platform_device *m520x_devices[] __initdata = {
|
|
||||||
&m520x_uart,
|
|
||||||
&m520x_fec,
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
&m520x_qspi,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void __init m520x_uart_init_line(int line, int irq)
|
static void __init m520x_uarts_init(void)
|
||||||
{
|
{
|
||||||
u16 par;
|
u16 par;
|
||||||
u8 par2;
|
u8 par2;
|
||||||
|
|
||||||
switch (line) {
|
/* UART0 and UART1 GPIO pin setup */
|
||||||
case 0:
|
par = readw(MCF_GPIO_PAR_UART);
|
||||||
par = readw(MCF_GPIO_PAR_UART);
|
par |= MCF_GPIO_PAR_UART_PAR_UTXD0 | MCF_GPIO_PAR_UART_PAR_URXD0;
|
||||||
par |= MCF_GPIO_PAR_UART_PAR_UTXD0 |
|
par |= MCF_GPIO_PAR_UART_PAR_UTXD1 | MCF_GPIO_PAR_UART_PAR_URXD1;
|
||||||
MCF_GPIO_PAR_UART_PAR_URXD0;
|
writew(par, MCF_GPIO_PAR_UART);
|
||||||
writew(par, MCF_GPIO_PAR_UART);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
par = readw(MCF_GPIO_PAR_UART);
|
|
||||||
par |= MCF_GPIO_PAR_UART_PAR_UTXD1 |
|
|
||||||
MCF_GPIO_PAR_UART_PAR_URXD1;
|
|
||||||
writew(par, MCF_GPIO_PAR_UART);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
par2 = readb(MCF_GPIO_PAR_FECI2C);
|
|
||||||
par2 &= ~0x0F;
|
|
||||||
par2 |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 |
|
|
||||||
MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
|
|
||||||
writeb(par2, MCF_GPIO_PAR_FECI2C);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init m520x_uarts_init(void)
|
/* UART1 GPIO pin setup */
|
||||||
{
|
par2 = readb(MCF_GPIO_PAR_FECI2C);
|
||||||
const int nrlines = ARRAY_SIZE(m520x_uart_platform);
|
par2 &= ~0x0F;
|
||||||
int line;
|
par2 |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 |
|
||||||
|
MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
|
||||||
for (line = 0; (line < nrlines); line++)
|
writeb(par2, MCF_GPIO_PAR_FECI2C);
|
||||||
m520x_uart_init_line(line, m520x_uart_platform[line].irq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
@@ -280,32 +74,14 @@ static void __init m520x_fec_init(void)
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void m520x_cpu_reset(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
__raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void __init config_BSP(char *commandp, int size)
|
void __init config_BSP(char *commandp, int size)
|
||||||
{
|
{
|
||||||
mach_reset = m520x_cpu_reset;
|
mach_sched_init = hw_timer_init;
|
||||||
m520x_uarts_init();
|
m520x_uarts_init();
|
||||||
m520x_fec_init();
|
m520x_fec_init();
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
m520x_qspi_init();
|
m520x_qspi_init();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
|
||||||
{
|
|
||||||
platform_add_devices(m520x_devices, ARRAY_SIZE(m520x_devices));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(init_BSP);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
@@ -16,215 +16,13 @@
|
|||||||
#include <linux/param.h>
|
#include <linux/param.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/spi/spi.h>
|
|
||||||
#include <linux/gpio.h>
|
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/coldfire.h>
|
#include <asm/coldfire.h>
|
||||||
#include <asm/mcfsim.h>
|
#include <asm/mcfsim.h>
|
||||||
#include <asm/mcfuart.h>
|
|
||||||
#include <asm/mcfqspi.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct mcf_platform_uart m523x_uart_platform[] = {
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE1,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE2,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART0 + 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE3,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART0 + 2,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m523x_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m523x_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource m523x_fec_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFFEC_BASE,
|
|
||||||
.end = MCFFEC_BASE + MCFFEC_SIZE - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 23,
|
|
||||||
.end = 64 + 23,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 27,
|
|
||||||
.end = 64 + 27,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 29,
|
|
||||||
.end = 64 + 29,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m523x_fec = {
|
|
||||||
.name = "fec",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m523x_fec_resources),
|
|
||||||
.resource = m523x_fec_resources,
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
static struct resource m523x_qspi_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFQSPI_IOBASE,
|
|
||||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MCFQSPI_CS0 91
|
|
||||||
#define MCFQSPI_CS1 92
|
|
||||||
#define MCFQSPI_CS2 103
|
|
||||||
#define MCFQSPI_CS3 99
|
|
||||||
|
|
||||||
static int m523x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail0;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
|
||||||
goto fail4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail4:
|
|
||||||
gpio_free(MCFQSPI_CS3);
|
|
||||||
fail3:
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
fail2:
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
fail1:
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
fail0:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m523x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
gpio_free(MCFQSPI_CS3);
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m523x_cs_select(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
switch (chip_select) {
|
|
||||||
case 0:
|
|
||||||
gpio_set_value(MCFQSPI_CS0, cs_high);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gpio_set_value(MCFQSPI_CS1, cs_high);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_set_value(MCFQSPI_CS2, cs_high);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_set_value(MCFQSPI_CS3, cs_high);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m523x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
switch (chip_select) {
|
|
||||||
case 0:
|
|
||||||
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_set_value(MCFQSPI_CS3, !cs_high);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mcfqspi_cs_control m523x_cs_control = {
|
|
||||||
.setup = m523x_cs_setup,
|
|
||||||
.teardown = m523x_cs_teardown,
|
|
||||||
.select = m523x_cs_select,
|
|
||||||
.deselect = m523x_cs_deselect,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct mcfqspi_platform_data m523x_qspi_data = {
|
|
||||||
.bus_num = 0,
|
|
||||||
.num_chipselect = 4,
|
|
||||||
.cs_control = &m523x_cs_control,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m523x_qspi = {
|
|
||||||
.name = "mcfqspi",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m523x_qspi_resources),
|
|
||||||
.resource = m523x_qspi_resources,
|
|
||||||
.dev.platform_data = &m523x_qspi_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init m523x_qspi_init(void)
|
static void __init m523x_qspi_init(void)
|
||||||
{
|
{
|
||||||
@@ -237,15 +35,8 @@ static void __init m523x_qspi_init(void)
|
|||||||
par &= 0x3f3f;
|
par &= 0x3f3f;
|
||||||
writew(par, MCFGPIO_PAR_TIMER);
|
writew(par, MCFGPIO_PAR_TIMER);
|
||||||
}
|
}
|
||||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
|
||||||
|
|
||||||
static struct platform_device *m523x_devices[] __initdata = {
|
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||||
&m523x_uart,
|
|
||||||
&m523x_fec,
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
&m523x_qspi,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
@@ -263,31 +54,13 @@ static void __init m523x_fec_init(void)
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void m523x_cpu_reset(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
__raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void __init config_BSP(char *commandp, int size)
|
void __init config_BSP(char *commandp, int size)
|
||||||
{
|
{
|
||||||
mach_reset = m523x_cpu_reset;
|
mach_sched_init = hw_timer_init;
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
|
||||||
{
|
|
||||||
m523x_fec_init();
|
m523x_fec_init();
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
m523x_qspi_init();
|
m523x_qspi_init();
|
||||||
#endif
|
#endif
|
||||||
platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arch_initcall(init_BSP);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@@ -12,34 +12,13 @@
|
|||||||
#include <linux/param.h>
|
#include <linux/param.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/gpio.h>
|
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/coldfire.h>
|
#include <asm/coldfire.h>
|
||||||
#include <asm/mcfsim.h>
|
#include <asm/mcfsim.h>
|
||||||
#include <asm/mcfuart.h>
|
|
||||||
#include <asm/mcfqspi.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct mcf_platform_uart m5249_uart_platform[] = {
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE1,
|
|
||||||
.irq = 73,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE2,
|
|
||||||
.irq = 74,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m5249_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m5249_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_M5249C3
|
#ifdef CONFIG_M5249C3
|
||||||
|
|
||||||
static struct resource m5249_smc91x_resources[] = {
|
static struct resource m5249_smc91x_resources[] = {
|
||||||
@@ -64,153 +43,15 @@ static struct platform_device m5249_smc91x = {
|
|||||||
|
|
||||||
#endif /* CONFIG_M5249C3 */
|
#endif /* CONFIG_M5249C3 */
|
||||||
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
static struct platform_device *m5249_devices[] __initdata = {
|
||||||
static struct resource m5249_qspi_resources[] = {
|
#ifdef CONFIG_M5249C3
|
||||||
{
|
&m5249_smc91x,
|
||||||
.start = MCFQSPI_IOBASE,
|
#endif
|
||||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = MCF_IRQ_QSPI,
|
|
||||||
.end = MCF_IRQ_QSPI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MCFQSPI_CS0 29
|
/***************************************************************************/
|
||||||
#define MCFQSPI_CS1 24
|
|
||||||
#define MCFQSPI_CS2 21
|
|
||||||
#define MCFQSPI_CS3 22
|
|
||||||
|
|
||||||
static int m5249_cs_setup(struct mcfqspi_cs_control *cs_control)
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail0;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
|
||||||
goto fail4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail4:
|
|
||||||
gpio_free(MCFQSPI_CS3);
|
|
||||||
fail3:
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
fail2:
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
fail1:
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
fail0:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m5249_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
gpio_free(MCFQSPI_CS3);
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m5249_cs_select(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
switch (chip_select) {
|
|
||||||
case 0:
|
|
||||||
gpio_set_value(MCFQSPI_CS0, cs_high);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gpio_set_value(MCFQSPI_CS1, cs_high);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_set_value(MCFQSPI_CS2, cs_high);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_set_value(MCFQSPI_CS3, cs_high);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m5249_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
switch (chip_select) {
|
|
||||||
case 0:
|
|
||||||
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_set_value(MCFQSPI_CS3, !cs_high);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mcfqspi_cs_control m5249_cs_control = {
|
|
||||||
.setup = m5249_cs_setup,
|
|
||||||
.teardown = m5249_cs_teardown,
|
|
||||||
.select = m5249_cs_select,
|
|
||||||
.deselect = m5249_cs_deselect,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct mcfqspi_platform_data m5249_qspi_data = {
|
|
||||||
.bus_num = 0,
|
|
||||||
.num_chipselect = 4,
|
|
||||||
.cs_control = &m5249_cs_control,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m5249_qspi = {
|
|
||||||
.name = "mcfqspi",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m5249_qspi_resources),
|
|
||||||
.resource = m5249_qspi_resources,
|
|
||||||
.dev.platform_data = &m5249_qspi_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init m5249_qspi_init(void)
|
static void __init m5249_qspi_init(void)
|
||||||
{
|
{
|
||||||
@@ -219,42 +60,8 @@ static void __init m5249_qspi_init(void)
|
|||||||
MCF_MBAR + MCFSIM_QSPIICR);
|
MCF_MBAR + MCFSIM_QSPIICR);
|
||||||
mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
|
mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
|
||||||
}
|
}
|
||||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
|
||||||
|
|
||||||
|
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||||
static struct platform_device *m5249_devices[] __initdata = {
|
|
||||||
&m5249_uart,
|
|
||||||
#ifdef CONFIG_M5249C3
|
|
||||||
&m5249_smc91x,
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
&m5249_qspi,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void __init m5249_uart_init_line(int line, int irq)
|
|
||||||
{
|
|
||||||
if (line == 0) {
|
|
||||||
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
|
|
||||||
writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
|
|
||||||
mcf_mapirq2imr(irq, MCFINTC_UART0);
|
|
||||||
} else if (line == 1) {
|
|
||||||
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
|
|
||||||
writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
|
|
||||||
mcf_mapirq2imr(irq, MCFINTC_UART1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init m5249_uarts_init(void)
|
|
||||||
{
|
|
||||||
const int nrlines = ARRAY_SIZE(m5249_uart_platform);
|
|
||||||
int line;
|
|
||||||
|
|
||||||
for (line = 0; (line < nrlines); line++)
|
|
||||||
m5249_uart_init_line(line, m5249_uart_platform[line].irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
@@ -276,43 +83,14 @@ static void __init m5249_smc91x_init(void)
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void __init m5249_timers_init(void)
|
|
||||||
{
|
|
||||||
/* Timer1 is always used as system timer */
|
|
||||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
|
|
||||||
MCF_MBAR + MCFSIM_TIMER1ICR);
|
|
||||||
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
|
|
||||||
|
|
||||||
#ifdef CONFIG_HIGHPROFILE
|
|
||||||
/* Timer2 is to be used as a high speed profile timer */
|
|
||||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
|
|
||||||
MCF_MBAR + MCFSIM_TIMER2ICR);
|
|
||||||
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void m5249_cpu_reset(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
/* Set watchdog to soft reset, and enabled */
|
|
||||||
__raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
|
|
||||||
for (;;)
|
|
||||||
/* wait for watchdog to timeout */;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void __init config_BSP(char *commandp, int size)
|
void __init config_BSP(char *commandp, int size)
|
||||||
{
|
{
|
||||||
mach_reset = m5249_cpu_reset;
|
mach_sched_init = hw_timer_init;
|
||||||
m5249_timers_init();
|
|
||||||
m5249_uarts_init();
|
|
||||||
#ifdef CONFIG_M5249C3
|
#ifdef CONFIG_M5249C3
|
||||||
m5249_smc91x_init();
|
m5249_smc91x_init();
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
m5249_qspi_init();
|
m5249_qspi_init();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -30,84 +30,18 @@ unsigned char ledbank = 0xff;
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct mcf_platform_uart m5272_uart_platform[] = {
|
static void __init m5272_uarts_init(void)
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE1,
|
|
||||||
.irq = MCF_IRQ_UART1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE2,
|
|
||||||
.irq = MCF_IRQ_UART2,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m5272_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m5272_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource m5272_fec_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCF_MBAR + 0x840,
|
|
||||||
.end = MCF_MBAR + 0x840 + 0x1cf,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = MCF_IRQ_ERX,
|
|
||||||
.end = MCF_IRQ_ERX,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = MCF_IRQ_ETX,
|
|
||||||
.end = MCF_IRQ_ETX,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = MCF_IRQ_ENTC,
|
|
||||||
.end = MCF_IRQ_ENTC,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m5272_fec = {
|
|
||||||
.name = "fec",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m5272_fec_resources),
|
|
||||||
.resource = m5272_fec_resources,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device *m5272_devices[] __initdata = {
|
|
||||||
&m5272_uart,
|
|
||||||
&m5272_fec,
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void __init m5272_uart_init_line(int line, int irq)
|
|
||||||
{
|
{
|
||||||
u32 v;
|
u32 v;
|
||||||
|
|
||||||
if ((line >= 0) && (line < 2)) {
|
/* Enable the output lines for the serial ports */
|
||||||
/* Enable the output lines for the serial ports */
|
v = readl(MCF_MBAR + MCFSIM_PBCNT);
|
||||||
v = readl(MCF_MBAR + MCFSIM_PBCNT);
|
v = (v & ~0x000000ff) | 0x00000055;
|
||||||
v = (v & ~0x000000ff) | 0x00000055;
|
writel(v, MCF_MBAR + MCFSIM_PBCNT);
|
||||||
writel(v, MCF_MBAR + MCFSIM_PBCNT);
|
|
||||||
|
|
||||||
v = readl(MCF_MBAR + MCFSIM_PDCNT);
|
v = readl(MCF_MBAR + MCFSIM_PDCNT);
|
||||||
v = (v & ~0x000003fc) | 0x000002a8;
|
v = (v & ~0x000003fc) | 0x000002a8;
|
||||||
writel(v, MCF_MBAR + MCFSIM_PDCNT);
|
writel(v, MCF_MBAR + MCFSIM_PDCNT);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init m5272_uarts_init(void)
|
|
||||||
{
|
|
||||||
const int nrlines = ARRAY_SIZE(m5272_uart_platform);
|
|
||||||
int line;
|
|
||||||
|
|
||||||
for (line = 0; (line < nrlines); line++)
|
|
||||||
m5272_uart_init_line(line, m5272_uart_platform[line].irq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
@@ -146,6 +80,7 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
mach_reset = m5272_cpu_reset;
|
mach_reset = m5272_cpu_reset;
|
||||||
|
mach_sched_init = hw_timer_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
@@ -167,7 +102,6 @@ static int __init init_BSP(void)
|
|||||||
{
|
{
|
||||||
m5272_uarts_init();
|
m5272_uarts_init();
|
||||||
fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status);
|
fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status);
|
||||||
platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,253 +16,14 @@
|
|||||||
#include <linux/param.h>
|
#include <linux/param.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/spi/spi.h>
|
|
||||||
#include <linux/gpio.h>
|
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/coldfire.h>
|
#include <asm/coldfire.h>
|
||||||
#include <asm/mcfsim.h>
|
#include <asm/mcfsim.h>
|
||||||
#include <asm/mcfuart.h>
|
#include <asm/mcfuart.h>
|
||||||
#include <asm/mcfqspi.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct mcf_platform_uart m527x_uart_platform[] = {
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE1,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE2,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE3,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART2,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m527x_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m527x_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource m527x_fec0_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFFEC_BASE0,
|
|
||||||
.end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 23,
|
|
||||||
.end = 64 + 23,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 27,
|
|
||||||
.end = 64 + 27,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 29,
|
|
||||||
.end = 64 + 29,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource m527x_fec1_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFFEC_BASE1,
|
|
||||||
.end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 128 + 23,
|
|
||||||
.end = 128 + 23,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 128 + 27,
|
|
||||||
.end = 128 + 27,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 128 + 29,
|
|
||||||
.end = 128 + 29,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m527x_fec[] = {
|
|
||||||
{
|
|
||||||
.name = "fec",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m527x_fec0_resources),
|
|
||||||
.resource = m527x_fec0_resources,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "fec",
|
|
||||||
.id = 1,
|
|
||||||
.num_resources = ARRAY_SIZE(m527x_fec1_resources),
|
|
||||||
.resource = m527x_fec1_resources,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
static struct resource m527x_qspi_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFQSPI_IOBASE,
|
|
||||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(CONFIG_M5271)
|
|
||||||
#define MCFQSPI_CS0 91
|
|
||||||
#define MCFQSPI_CS1 92
|
|
||||||
#define MCFQSPI_CS2 99
|
|
||||||
#define MCFQSPI_CS3 103
|
|
||||||
#elif defined(CONFIG_M5275)
|
|
||||||
#define MCFQSPI_CS0 59
|
|
||||||
#define MCFQSPI_CS1 60
|
|
||||||
#define MCFQSPI_CS2 61
|
|
||||||
#define MCFQSPI_CS3 62
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int m527x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail0;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
|
||||||
goto fail4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail4:
|
|
||||||
gpio_free(MCFQSPI_CS3);
|
|
||||||
fail3:
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
fail2:
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
fail1:
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
fail0:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m527x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
gpio_free(MCFQSPI_CS3);
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m527x_cs_select(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
switch (chip_select) {
|
|
||||||
case 0:
|
|
||||||
gpio_set_value(MCFQSPI_CS0, cs_high);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gpio_set_value(MCFQSPI_CS1, cs_high);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_set_value(MCFQSPI_CS2, cs_high);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_set_value(MCFQSPI_CS3, cs_high);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m527x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
switch (chip_select) {
|
|
||||||
case 0:
|
|
||||||
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_set_value(MCFQSPI_CS3, !cs_high);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mcfqspi_cs_control m527x_cs_control = {
|
|
||||||
.setup = m527x_cs_setup,
|
|
||||||
.teardown = m527x_cs_teardown,
|
|
||||||
.select = m527x_cs_select,
|
|
||||||
.deselect = m527x_cs_deselect,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct mcfqspi_platform_data m527x_qspi_data = {
|
|
||||||
.bus_num = 0,
|
|
||||||
.num_chipselect = 4,
|
|
||||||
.cs_control = &m527x_cs_control,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m527x_qspi = {
|
|
||||||
.name = "mcfqspi",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m527x_qspi_resources),
|
|
||||||
.resource = m527x_qspi_resources,
|
|
||||||
.dev.platform_data = &m527x_qspi_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init m527x_qspi_init(void)
|
static void __init m527x_qspi_init(void)
|
||||||
{
|
{
|
||||||
@@ -280,50 +41,23 @@ static void __init m527x_qspi_init(void)
|
|||||||
writew(0x003e, MCFGPIO_PAR_QSPI);
|
writew(0x003e, MCFGPIO_PAR_QSPI);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
|
||||||
|
|
||||||
static struct platform_device *m527x_devices[] __initdata = {
|
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||||
&m527x_uart,
|
|
||||||
&m527x_fec[0],
|
|
||||||
#ifdef CONFIG_FEC2
|
|
||||||
&m527x_fec[1],
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
&m527x_qspi,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void __init m527x_uart_init_line(int line, int irq)
|
static void __init m527x_uarts_init(void)
|
||||||
{
|
{
|
||||||
u16 sepmask;
|
u16 sepmask;
|
||||||
|
|
||||||
if ((line < 0) || (line > 2))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External Pin Mask Setting & Enable External Pin for Interface
|
* External Pin Mask Setting & Enable External Pin for Interface
|
||||||
*/
|
*/
|
||||||
sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
|
sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
|
||||||
if (line == 0)
|
sepmask |= UART0_ENABLE_MASK | UART1_ENABLE_MASK | UART2_ENABLE_MASK;
|
||||||
sepmask |= UART0_ENABLE_MASK;
|
|
||||||
else if (line == 1)
|
|
||||||
sepmask |= UART1_ENABLE_MASK;
|
|
||||||
else if (line == 2)
|
|
||||||
sepmask |= UART2_ENABLE_MASK;
|
|
||||||
writew(sepmask, MCF_IPSBAR + MCF_GPIO_PAR_UART);
|
writew(sepmask, MCF_IPSBAR + MCF_GPIO_PAR_UART);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init m527x_uarts_init(void)
|
|
||||||
{
|
|
||||||
const int nrlines = ARRAY_SIZE(m527x_uart_platform);
|
|
||||||
int line;
|
|
||||||
|
|
||||||
for (line = 0; (line < nrlines); line++)
|
|
||||||
m527x_uart_init_line(line, m527x_uart_platform[line].irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void __init m527x_fec_init(void)
|
static void __init m527x_fec_init(void)
|
||||||
@@ -353,32 +87,14 @@ static void __init m527x_fec_init(void)
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void m527x_cpu_reset(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
__raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void __init config_BSP(char *commandp, int size)
|
void __init config_BSP(char *commandp, int size)
|
||||||
{
|
{
|
||||||
mach_reset = m527x_cpu_reset;
|
mach_sched_init = hw_timer_init;
|
||||||
m527x_uarts_init();
|
m527x_uarts_init();
|
||||||
m527x_fec_init();
|
m527x_fec_init();
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
m527x_qspi_init();
|
m527x_qspi_init();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
|
||||||
{
|
|
||||||
platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(init_BSP);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
@@ -17,229 +17,33 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/spi/spi.h>
|
|
||||||
#include <linux/gpio.h>
|
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/coldfire.h>
|
#include <asm/coldfire.h>
|
||||||
#include <asm/mcfsim.h>
|
#include <asm/mcfsim.h>
|
||||||
#include <asm/mcfuart.h>
|
#include <asm/mcfuart.h>
|
||||||
#include <asm/mcfqspi.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct mcf_platform_uart m528x_uart_platform[] = {
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE1,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE2,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART0 + 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE3,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART0 + 2,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m528x_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m528x_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource m528x_fec_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFFEC_BASE,
|
|
||||||
.end = MCFFEC_BASE + MCFFEC_SIZE - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 23,
|
|
||||||
.end = 64 + 23,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 27,
|
|
||||||
.end = 64 + 27,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 29,
|
|
||||||
.end = 64 + 29,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m528x_fec = {
|
|
||||||
.name = "fec",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m528x_fec_resources),
|
|
||||||
.resource = m528x_fec_resources,
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
static struct resource m528x_qspi_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFQSPI_IOBASE,
|
|
||||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MCFQSPI_CS0 147
|
|
||||||
#define MCFQSPI_CS1 148
|
|
||||||
#define MCFQSPI_CS2 149
|
|
||||||
#define MCFQSPI_CS3 150
|
|
||||||
|
|
||||||
static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail0;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
|
||||||
goto fail4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail4:
|
|
||||||
gpio_free(MCFQSPI_CS3);
|
|
||||||
fail3:
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
fail2:
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
fail1:
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
fail0:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
gpio_free(MCFQSPI_CS3);
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m528x_cs_select(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mcfqspi_cs_control m528x_cs_control = {
|
|
||||||
.setup = m528x_cs_setup,
|
|
||||||
.teardown = m528x_cs_teardown,
|
|
||||||
.select = m528x_cs_select,
|
|
||||||
.deselect = m528x_cs_deselect,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct mcfqspi_platform_data m528x_qspi_data = {
|
|
||||||
.bus_num = 0,
|
|
||||||
.num_chipselect = 4,
|
|
||||||
.cs_control = &m528x_cs_control,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m528x_qspi = {
|
|
||||||
.name = "mcfqspi",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m528x_qspi_resources),
|
|
||||||
.resource = m528x_qspi_resources,
|
|
||||||
.dev.platform_data = &m528x_qspi_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init m528x_qspi_init(void)
|
static void __init m528x_qspi_init(void)
|
||||||
{
|
{
|
||||||
/* setup Port QS for QSPI with gpio CS control */
|
/* setup Port QS for QSPI with gpio CS control */
|
||||||
__raw_writeb(0x07, MCFGPIO_PQSPAR);
|
__raw_writeb(0x07, MCFGPIO_PQSPAR);
|
||||||
}
|
}
|
||||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
|
||||||
|
|
||||||
static struct platform_device *m528x_devices[] __initdata = {
|
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||||
&m528x_uart,
|
|
||||||
&m528x_fec,
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
&m528x_qspi,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void __init m528x_uart_init_line(int line, int irq)
|
static void __init m528x_uarts_init(void)
|
||||||
{
|
{
|
||||||
u8 port;
|
u8 port;
|
||||||
|
|
||||||
if ((line < 0) || (line > 2))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* make sure PUAPAR is set for UART0 and UART1 */
|
/* make sure PUAPAR is set for UART0 and UART1 */
|
||||||
if (line < 2) {
|
port = readb(MCF5282_GPIO_PUAPAR);
|
||||||
port = readb(MCF5282_GPIO_PUAPAR);
|
port |= 0x03 | (0x03 << 2);
|
||||||
port |= (0x03 << (line * 2));
|
writeb(port, MCF5282_GPIO_PUAPAR);
|
||||||
writeb(port, MCF5282_GPIO_PUAPAR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init m528x_uarts_init(void)
|
|
||||||
{
|
|
||||||
const int nrlines = ARRAY_SIZE(m528x_uart_platform);
|
|
||||||
int line;
|
|
||||||
|
|
||||||
for (line = 0; (line < nrlines); line++)
|
|
||||||
m528x_uart_init_line(line, m528x_uart_platform[line].irq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
@@ -256,14 +60,6 @@ static void __init m528x_fec_init(void)
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void m528x_cpu_reset(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
__raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef CONFIG_WILDFIRE
|
#ifdef CONFIG_WILDFIRE
|
||||||
void wildfire_halt(void)
|
void wildfire_halt(void)
|
||||||
{
|
{
|
||||||
@@ -299,22 +95,12 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
#ifdef CONFIG_WILDFIREMOD
|
#ifdef CONFIG_WILDFIREMOD
|
||||||
mach_halt = wildfiremod_halt;
|
mach_halt = wildfiremod_halt;
|
||||||
#endif
|
#endif
|
||||||
}
|
mach_sched_init = hw_timer_init;
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
|
||||||
{
|
|
||||||
mach_reset = m528x_cpu_reset;
|
|
||||||
m528x_uarts_init();
|
m528x_uarts_init();
|
||||||
m528x_fec_init();
|
m528x_fec_init();
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
m528x_qspi_init();
|
m528x_qspi_init();
|
||||||
#endif
|
#endif
|
||||||
platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arch_initcall(init_BSP);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@@ -16,7 +16,6 @@
|
|||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/coldfire.h>
|
#include <asm/coldfire.h>
|
||||||
#include <asm/mcfsim.h>
|
#include <asm/mcfsim.h>
|
||||||
#include <asm/mcfuart.h>
|
|
||||||
#include <asm/mcfwdebug.h>
|
#include <asm/mcfwdebug.h>
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
@@ -29,82 +28,6 @@ unsigned char ledbank = 0xff;
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct mcf_platform_uart m5307_uart_platform[] = {
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE1,
|
|
||||||
.irq = 73,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE2,
|
|
||||||
.irq = 74,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m5307_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m5307_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device *m5307_devices[] __initdata = {
|
|
||||||
&m5307_uart,
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void __init m5307_uart_init_line(int line, int irq)
|
|
||||||
{
|
|
||||||
if (line == 0) {
|
|
||||||
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
|
|
||||||
writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
|
|
||||||
mcf_mapirq2imr(irq, MCFINTC_UART0);
|
|
||||||
} else if (line == 1) {
|
|
||||||
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
|
|
||||||
writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
|
|
||||||
mcf_mapirq2imr(irq, MCFINTC_UART1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init m5307_uarts_init(void)
|
|
||||||
{
|
|
||||||
const int nrlines = ARRAY_SIZE(m5307_uart_platform);
|
|
||||||
int line;
|
|
||||||
|
|
||||||
for (line = 0; (line < nrlines); line++)
|
|
||||||
m5307_uart_init_line(line, m5307_uart_platform[line].irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void __init m5307_timers_init(void)
|
|
||||||
{
|
|
||||||
/* Timer1 is always used as system timer */
|
|
||||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
|
|
||||||
MCF_MBAR + MCFSIM_TIMER1ICR);
|
|
||||||
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
|
|
||||||
|
|
||||||
#ifdef CONFIG_HIGHPROFILE
|
|
||||||
/* Timer2 is to be used as a high speed profile timer */
|
|
||||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
|
|
||||||
MCF_MBAR + MCFSIM_TIMER2ICR);
|
|
||||||
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void m5307_cpu_reset(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
/* Set watchdog to soft reset, and enabled */
|
|
||||||
__raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
|
|
||||||
for (;;)
|
|
||||||
/* wait for watchdog to timeout */;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void __init config_BSP(char *commandp, int size)
|
void __init config_BSP(char *commandp, int size)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_NETtel) || \
|
#if defined(CONFIG_NETtel) || \
|
||||||
@@ -114,9 +37,7 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
commandp[size-1] = 0;
|
commandp[size-1] = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mach_reset = m5307_cpu_reset;
|
mach_sched_init = hw_timer_init;
|
||||||
m5307_timers_init();
|
|
||||||
m5307_uarts_init();
|
|
||||||
|
|
||||||
/* Only support the external interrupts on their primary level */
|
/* Only support the external interrupts on their primary level */
|
||||||
mcf_mapirq2imr(25, MCFINTC_EINT1);
|
mcf_mapirq2imr(25, MCFINTC_EINT1);
|
||||||
@@ -135,13 +56,3 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
|
||||||
{
|
|
||||||
platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(init_BSP);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
@@ -21,214 +21,33 @@
|
|||||||
#include <linux/param.h>
|
#include <linux/param.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/spi/spi.h>
|
|
||||||
#include <linux/gpio.h>
|
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/coldfire.h>
|
#include <asm/coldfire.h>
|
||||||
#include <asm/mcfsim.h>
|
#include <asm/mcfsim.h>
|
||||||
#include <asm/mcfuart.h>
|
#include <asm/mcfuart.h>
|
||||||
#include <asm/mcfdma.h>
|
#include <asm/mcfdma.h>
|
||||||
#include <asm/mcfwdebug.h>
|
#include <asm/mcfwdebug.h>
|
||||||
#include <asm/mcfqspi.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct mcf_platform_uart m532x_uart_platform[] = {
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE1,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE2,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCFUART_BASE3,
|
|
||||||
.irq = MCFINT_VECBASE + MCFINT_UART2,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m532x_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m532x_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct resource m532x_fec_resources[] = {
|
|
||||||
{
|
|
||||||
.start = 0xfc030000,
|
|
||||||
.end = 0xfc0307ff,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 36,
|
|
||||||
.end = 64 + 36,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 40,
|
|
||||||
.end = 64 + 40,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = 64 + 42,
|
|
||||||
.end = 64 + 42,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m532x_fec = {
|
|
||||||
.name = "fec",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m532x_fec_resources),
|
|
||||||
.resource = m532x_fec_resources,
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
static struct resource m532x_qspi_resources[] = {
|
|
||||||
{
|
|
||||||
.start = MCFQSPI_IOBASE,
|
|
||||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
|
||||||
.flags = IORESOURCE_IRQ,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MCFQSPI_CS0 84
|
|
||||||
#define MCFQSPI_CS1 85
|
|
||||||
#define MCFQSPI_CS2 86
|
|
||||||
|
|
||||||
static int m532x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail0;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
|
||||||
if (status) {
|
|
||||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
|
||||||
goto fail3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fail3:
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
fail2:
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
fail1:
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
fail0:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m532x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
|
||||||
{
|
|
||||||
gpio_free(MCFQSPI_CS2);
|
|
||||||
gpio_free(MCFQSPI_CS1);
|
|
||||||
gpio_free(MCFQSPI_CS0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m532x_cs_select(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void m532x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
|
||||||
u8 chip_select, bool cs_high)
|
|
||||||
{
|
|
||||||
gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mcfqspi_cs_control m532x_cs_control = {
|
|
||||||
.setup = m532x_cs_setup,
|
|
||||||
.teardown = m532x_cs_teardown,
|
|
||||||
.select = m532x_cs_select,
|
|
||||||
.deselect = m532x_cs_deselect,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct mcfqspi_platform_data m532x_qspi_data = {
|
|
||||||
.bus_num = 0,
|
|
||||||
.num_chipselect = 3,
|
|
||||||
.cs_control = &m532x_cs_control,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m532x_qspi = {
|
|
||||||
.name = "mcfqspi",
|
|
||||||
.id = 0,
|
|
||||||
.num_resources = ARRAY_SIZE(m532x_qspi_resources),
|
|
||||||
.resource = m532x_qspi_resources,
|
|
||||||
.dev.platform_data = &m532x_qspi_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init m532x_qspi_init(void)
|
static void __init m532x_qspi_init(void)
|
||||||
{
|
{
|
||||||
/* setup QSPS pins for QSPI with gpio CS control */
|
/* setup QSPS pins for QSPI with gpio CS control */
|
||||||
writew(0x01f0, MCF_GPIO_PAR_QSPI);
|
writew(0x01f0, MCF_GPIO_PAR_QSPI);
|
||||||
}
|
}
|
||||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
|
||||||
|
|
||||||
|
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||||
static struct platform_device *m532x_devices[] __initdata = {
|
|
||||||
&m532x_uart,
|
|
||||||
&m532x_fec,
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
&m532x_qspi,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void __init m532x_uart_init_line(int line, int irq)
|
|
||||||
{
|
|
||||||
if (line == 0) {
|
|
||||||
/* GPIO initialization */
|
|
||||||
MCF_GPIO_PAR_UART |= 0x000F;
|
|
||||||
} else if (line == 1) {
|
|
||||||
/* GPIO initialization */
|
|
||||||
MCF_GPIO_PAR_UART |= 0x0FF0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init m532x_uarts_init(void)
|
static void __init m532x_uarts_init(void)
|
||||||
{
|
{
|
||||||
const int nrlines = ARRAY_SIZE(m532x_uart_platform);
|
/* UART GPIO initialization */
|
||||||
int line;
|
MCF_GPIO_PAR_UART |= 0x0FFF;
|
||||||
|
|
||||||
for (line = 0; (line < nrlines); line++)
|
|
||||||
m532x_uart_init_line(line, m532x_uart_platform[line].irq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void __init m532x_fec_init(void)
|
static void __init m532x_fec_init(void)
|
||||||
@@ -242,14 +61,6 @@ static void __init m532x_fec_init(void)
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static void m532x_cpu_reset(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
__raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void __init config_BSP(char *commandp, int size)
|
void __init config_BSP(char *commandp, int size)
|
||||||
{
|
{
|
||||||
#if !defined(CONFIG_BOOTPARAM)
|
#if !defined(CONFIG_BOOTPARAM)
|
||||||
@@ -263,6 +74,13 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mach_sched_init = hw_timer_init;
|
||||||
|
m532x_uarts_init();
|
||||||
|
m532x_fec_init();
|
||||||
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
|
m532x_qspi_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_BDM_DISABLE
|
#ifdef CONFIG_BDM_DISABLE
|
||||||
/*
|
/*
|
||||||
* Disable the BDM clocking. This also turns off most of the rest of
|
* Disable the BDM clocking. This also turns off most of the rest of
|
||||||
@@ -273,21 +91,6 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
|
||||||
{
|
|
||||||
m532x_uarts_init();
|
|
||||||
m532x_fec_init();
|
|
||||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
|
||||||
m532x_qspi_init();
|
|
||||||
#endif
|
|
||||||
platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(init_BSP);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/* Board initialization */
|
/* Board initialization */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@@ -16,91 +16,12 @@
|
|||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/coldfire.h>
|
#include <asm/coldfire.h>
|
||||||
#include <asm/mcfsim.h>
|
#include <asm/mcfsim.h>
|
||||||
#include <asm/mcfuart.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static struct mcf_platform_uart m5407_uart_platform[] = {
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE1,
|
|
||||||
.irq = 73,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE2,
|
|
||||||
.irq = 74,
|
|
||||||
},
|
|
||||||
{ },
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m5407_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m5407_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device *m5407_devices[] __initdata = {
|
|
||||||
&m5407_uart,
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void __init m5407_uart_init_line(int line, int irq)
|
|
||||||
{
|
|
||||||
if (line == 0) {
|
|
||||||
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
|
|
||||||
writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
|
|
||||||
mcf_mapirq2imr(irq, MCFINTC_UART0);
|
|
||||||
} else if (line == 1) {
|
|
||||||
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
|
|
||||||
writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
|
|
||||||
mcf_mapirq2imr(irq, MCFINTC_UART1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init m5407_uarts_init(void)
|
|
||||||
{
|
|
||||||
const int nrlines = ARRAY_SIZE(m5407_uart_platform);
|
|
||||||
int line;
|
|
||||||
|
|
||||||
for (line = 0; (line < nrlines); line++)
|
|
||||||
m5407_uart_init_line(line, m5407_uart_platform[line].irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void __init m5407_timers_init(void)
|
|
||||||
{
|
|
||||||
/* Timer1 is always used as system timer */
|
|
||||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
|
|
||||||
MCF_MBAR + MCFSIM_TIMER1ICR);
|
|
||||||
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
|
|
||||||
|
|
||||||
#ifdef CONFIG_HIGHPROFILE
|
|
||||||
/* Timer2 is to be used as a high speed profile timer */
|
|
||||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
|
|
||||||
MCF_MBAR + MCFSIM_TIMER2ICR);
|
|
||||||
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void m5407_cpu_reset(void)
|
|
||||||
{
|
|
||||||
local_irq_disable();
|
|
||||||
/* set watchdog to soft reset, and enabled */
|
|
||||||
__raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
|
|
||||||
for (;;)
|
|
||||||
/* wait for watchdog to timeout */;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
void __init config_BSP(char *commandp, int size)
|
void __init config_BSP(char *commandp, int size)
|
||||||
{
|
{
|
||||||
mach_reset = m5407_cpu_reset;
|
mach_sched_init = hw_timer_init;
|
||||||
m5407_timers_init();
|
|
||||||
m5407_uarts_init();
|
|
||||||
|
|
||||||
/* Only support the external interrupts on their primary level */
|
/* Only support the external interrupts on their primary level */
|
||||||
mcf_mapirq2imr(25, MCFINTC_EINT1);
|
mcf_mapirq2imr(25, MCFINTC_EINT1);
|
||||||
@@ -110,13 +31,3 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
|
||||||
{
|
|
||||||
platform_add_devices(m5407_devices, ARRAY_SIZE(m5407_devices));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(init_BSP);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
@@ -27,64 +27,17 @@
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static struct mcf_platform_uart m54xx_uart_platform[] = {
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE1,
|
|
||||||
.irq = 64 + 35,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE2,
|
|
||||||
.irq = 64 + 34,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE3,
|
|
||||||
.irq = 64 + 33,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mapbase = MCF_MBAR + MCFUART_BASE4,
|
|
||||||
.irq = 64 + 32,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device m54xx_uart = {
|
|
||||||
.name = "mcfuart",
|
|
||||||
.id = 0,
|
|
||||||
.dev.platform_data = m54xx_uart_platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device *m54xx_devices[] __initdata = {
|
|
||||||
&m54xx_uart,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void __init m54xx_uart_init_line(int line, int irq)
|
|
||||||
{
|
|
||||||
int rts_cts;
|
|
||||||
|
|
||||||
/* enable io pins */
|
|
||||||
switch (line) {
|
|
||||||
case 0:
|
|
||||||
rts_cts = 0; break;
|
|
||||||
case 1:
|
|
||||||
rts_cts = MCF_PAR_PSC_RTS_RTS; break;
|
|
||||||
case 2:
|
|
||||||
rts_cts = MCF_PAR_PSC_RTS_RTS | MCF_PAR_PSC_CTS_CTS; break;
|
|
||||||
case 3:
|
|
||||||
rts_cts = 0; break;
|
|
||||||
}
|
|
||||||
__raw_writeb(MCF_PAR_PSC_TXD | rts_cts | MCF_PAR_PSC_RXD,
|
|
||||||
MCF_MBAR + MCF_PAR_PSC(line));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init m54xx_uarts_init(void)
|
static void __init m54xx_uarts_init(void)
|
||||||
{
|
{
|
||||||
const int nrlines = ARRAY_SIZE(m54xx_uart_platform);
|
/* enable io pins */
|
||||||
int line;
|
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD,
|
||||||
|
MCF_MBAR + MCF_PAR_PSC(0));
|
||||||
for (line = 0; (line < nrlines); line++)
|
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD | MCF_PAR_PSC_RTS_RTS,
|
||||||
m54xx_uart_init_line(line, m54xx_uart_platform[line].irq);
|
MCF_MBAR + MCF_PAR_PSC(1));
|
||||||
|
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD | MCF_PAR_PSC_RTS_RTS |
|
||||||
|
MCF_PAR_PSC_CTS_CTS, MCF_MBAR + MCF_PAR_PSC(2));
|
||||||
|
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD,
|
||||||
|
MCF_MBAR + MCF_PAR_PSC(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
@@ -145,18 +98,8 @@ void __init config_BSP(char *commandp, int size)
|
|||||||
mmu_context_init();
|
mmu_context_init();
|
||||||
#endif
|
#endif
|
||||||
mach_reset = mcf54xx_reset;
|
mach_reset = mcf54xx_reset;
|
||||||
|
mach_sched_init = hw_timer_init;
|
||||||
m54xx_uarts_init();
|
m54xx_uarts_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
platform_add_devices(m54xx_devices, ARRAY_SIZE(m54xx_devices));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_initcall(init_BSP);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/MC68328.h>
|
#include <asm/MC68328.h>
|
||||||
@@ -26,7 +27,7 @@
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
|
int m68328_hwclk(int set, struct rtc_time *t);
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ void config_BSP(char *command, int len)
|
|||||||
printk(KERN_INFO "68328 support Kenneth Albanowski <kjahds@kjshds.com>\n");
|
printk(KERN_INFO "68328 support Kenneth Albanowski <kjahds@kjshds.com>\n");
|
||||||
printk(KERN_INFO "68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n");
|
printk(KERN_INFO "68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n");
|
||||||
|
|
||||||
mach_gettod = m68328_timer_gettod;
|
mach_hwclk = m68328_hwclk;
|
||||||
mach_reset = m68328_reset;
|
mach_reset = m68328_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -68,8 +68,6 @@ asmlinkage irqreturn_t inthandler5(void);
|
|||||||
asmlinkage irqreturn_t inthandler6(void);
|
asmlinkage irqreturn_t inthandler6(void);
|
||||||
asmlinkage irqreturn_t inthandler7(void);
|
asmlinkage irqreturn_t inthandler7(void);
|
||||||
|
|
||||||
extern e_vector *_ramvec;
|
|
||||||
|
|
||||||
/* The 68k family did not have a good way to determine the source
|
/* The 68k family did not have a good way to determine the source
|
||||||
* of interrupts until later in the family. The EC000 core does
|
* of interrupts until later in the family. The EC000 core does
|
||||||
* not provide the vector number on the stack, we vector everything
|
* not provide the vector number on the stack, we vector everything
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/clocksource.h>
|
#include <linux/clocksource.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
@@ -119,14 +120,17 @@ void hw_timer_init(void)
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec)
|
int m68328_hwclk(int set, struct rtc_time *t)
|
||||||
{
|
{
|
||||||
long now = RTCTIME;
|
if (!set) {
|
||||||
|
long now = RTCTIME;
|
||||||
|
t->tm_year = t->tm_mon = t->tm_mday = 1;
|
||||||
|
t->tm_hour = (now >> 24) % 24;
|
||||||
|
t->tm_min = (now >> 16) % 60;
|
||||||
|
t->tm_sec = now % 60;
|
||||||
|
}
|
||||||
|
|
||||||
*year = *mon = *day = 1;
|
return 0;
|
||||||
*hour = (now >> 24) % 24;
|
|
||||||
*min = (now >> 16) % 60;
|
|
||||||
*sec = now % 60;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@@ -103,11 +103,6 @@ void hw_timer_init(void)
|
|||||||
pquicc->timer_tgcr = tgcr_save;
|
pquicc->timer_tgcr = tgcr_save;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSP_gettod (int *yearp, int *monp, int *dayp,
|
|
||||||
int *hourp, int *minp, int *secp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int BSP_set_clock_mmss(unsigned long nowtime)
|
int BSP_set_clock_mmss(unsigned long nowtime)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
@@ -181,6 +176,5 @@ void config_BSP(char *command, int len)
|
|||||||
scc1_hwaddr = "\00\01\02\03\04\05";
|
scc1_hwaddr = "\00\01\02\03\04\05";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mach_gettod = BSP_gettod;
|
mach_reset = BSP_reset;
|
||||||
mach_reset = BSP_reset;
|
|
||||||
}
|
}
|
||||||
|
@@ -32,8 +32,6 @@ asmlinkage void trap(void);
|
|||||||
asmlinkage void bad_interrupt(void);
|
asmlinkage void bad_interrupt(void);
|
||||||
asmlinkage void inthandler(void);
|
asmlinkage void inthandler(void);
|
||||||
|
|
||||||
extern void *_ramvec[];
|
|
||||||
|
|
||||||
static void intc_irq_unmask(struct irq_data *d)
|
static void intc_irq_unmask(struct irq_data *d)
|
||||||
{
|
{
|
||||||
pquicc->intr_cimr |= (1 << d->irq);
|
pquicc->intr_cimr |= (1 << d->irq);
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
@@ -25,7 +26,7 @@
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
|
int m68328_hwclk(int set, struct rtc_time *t);
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ void config_BSP(char *command, int len)
|
|||||||
else command[0] = 0;
|
else command[0] = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mach_gettod = m68328_timer_gettod;
|
mach_hwclk = m68328_hwclk;
|
||||||
mach_reset = m68ez328_reset;
|
mach_reset = m68ez328_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
|
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec);
|
int m68328_hwclk(int set, struct rtc_time *t);
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/* Init Drangon Engine hardware */
|
/* Init Drangon Engine hardware */
|
||||||
@@ -181,7 +182,7 @@ void config_BSP(char *command, int size)
|
|||||||
|
|
||||||
init_hardware(command, size);
|
init_hardware(command, size);
|
||||||
|
|
||||||
mach_gettod = m68328_timer_gettod;
|
mach_hwclk = m68328_hwclk;
|
||||||
mach_reset = m68vz328_reset;
|
mach_reset = m68vz328_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,18 +14,18 @@
|
|||||||
|
|
||||||
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
|
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
|
||||||
|
|
||||||
obj-$(CONFIG_COLDFIRE) += cache.o clk.o dma.o entry.o vectors.o
|
obj-$(CONFIG_COLDFIRE) += cache.o clk.o device.o dma.o entry.o vectors.o
|
||||||
obj-$(CONFIG_M5206) += timers.o intc.o
|
obj-$(CONFIG_M5206) += timers.o intc.o reset.o
|
||||||
obj-$(CONFIG_M5206e) += timers.o intc.o
|
obj-$(CONFIG_M5206e) += timers.o intc.o reset.o
|
||||||
obj-$(CONFIG_M520x) += pit.o intc-simr.o
|
obj-$(CONFIG_M520x) += pit.o intc-simr.o reset.o
|
||||||
obj-$(CONFIG_M523x) += pit.o dma_timer.o intc-2.o
|
obj-$(CONFIG_M523x) += pit.o dma_timer.o intc-2.o reset.o
|
||||||
obj-$(CONFIG_M5249) += timers.o intc.o
|
obj-$(CONFIG_M5249) += timers.o intc.o reset.o
|
||||||
obj-$(CONFIG_M527x) += pit.o intc-2.o
|
obj-$(CONFIG_M527x) += pit.o intc-2.o reset.o
|
||||||
obj-$(CONFIG_M5272) += timers.o
|
obj-$(CONFIG_M5272) += timers.o
|
||||||
obj-$(CONFIG_M528x) += pit.o intc-2.o
|
obj-$(CONFIG_M528x) += pit.o intc-2.o reset.o
|
||||||
obj-$(CONFIG_M5307) += timers.o intc.o
|
obj-$(CONFIG_M5307) += timers.o intc.o reset.o
|
||||||
obj-$(CONFIG_M532x) += timers.o intc-simr.o
|
obj-$(CONFIG_M532x) += timers.o intc-simr.o reset.o
|
||||||
obj-$(CONFIG_M5407) += timers.o intc.o
|
obj-$(CONFIG_M5407) += timers.o intc.o reset.o
|
||||||
obj-$(CONFIG_M54xx) += sltimers.o intc-2.o
|
obj-$(CONFIG_M54xx) += sltimers.o intc-2.o
|
||||||
|
|
||||||
obj-y += pinmux.o gpio.o
|
obj-y += pinmux.o gpio.o
|
||||||
|
318
arch/m68k/platform/coldfire/device.c
Normal file
318
arch/m68k/platform/coldfire/device.c
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
/*
|
||||||
|
* device.c -- common ColdFire SoC device support
|
||||||
|
*
|
||||||
|
* (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
|
* License. See the file COPYING in the main directory of this archive
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/spi/spi.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <asm/traps.h>
|
||||||
|
#include <asm/coldfire.h>
|
||||||
|
#include <asm/mcfsim.h>
|
||||||
|
#include <asm/mcfuart.h>
|
||||||
|
#include <asm/mcfqspi.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All current ColdFire parts contain from 2, 3 or 4 UARTS.
|
||||||
|
*/
|
||||||
|
static struct mcf_platform_uart mcf_uart_platform_data[] = {
|
||||||
|
{
|
||||||
|
.mapbase = MCFUART_BASE0,
|
||||||
|
.irq = MCF_IRQ_UART0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mapbase = MCFUART_BASE1,
|
||||||
|
.irq = MCF_IRQ_UART1,
|
||||||
|
},
|
||||||
|
#ifdef MCFUART_BASE2
|
||||||
|
{
|
||||||
|
.mapbase = MCFUART_BASE2,
|
||||||
|
.irq = MCF_IRQ_UART2,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef MCFUART_BASE3
|
||||||
|
{
|
||||||
|
.mapbase = MCFUART_BASE3,
|
||||||
|
.irq = MCF_IRQ_UART3,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device mcf_uart = {
|
||||||
|
.name = "mcfuart",
|
||||||
|
.id = 0,
|
||||||
|
.dev.platform_data = mcf_uart_platform_data,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_FEC
|
||||||
|
/*
|
||||||
|
* Some ColdFire cores contain the Fast Ethernet Controller (FEC)
|
||||||
|
* block. It is Freescale's own hardware block. Some ColdFires
|
||||||
|
* have 2 of these.
|
||||||
|
*/
|
||||||
|
static struct resource mcf_fec0_resources[] = {
|
||||||
|
{
|
||||||
|
.start = MCFFEC_BASE0,
|
||||||
|
.end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = MCF_IRQ_FECRX0,
|
||||||
|
.end = MCF_IRQ_FECRX0,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = MCF_IRQ_FECTX0,
|
||||||
|
.end = MCF_IRQ_FECTX0,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = MCF_IRQ_FECENTC0,
|
||||||
|
.end = MCF_IRQ_FECENTC0,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device mcf_fec0 = {
|
||||||
|
.name = "fec",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(mcf_fec0_resources),
|
||||||
|
.resource = mcf_fec0_resources,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef MCFFEC_BASE1
|
||||||
|
static struct resource mcf_fec1_resources[] = {
|
||||||
|
{
|
||||||
|
.start = MCFFEC_BASE1,
|
||||||
|
.end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = MCF_IRQ_FECRX1,
|
||||||
|
.end = MCF_IRQ_FECRX1,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = MCF_IRQ_FECTX1,
|
||||||
|
.end = MCF_IRQ_FECTX1,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = MCF_IRQ_FECENTC1,
|
||||||
|
.end = MCF_IRQ_FECENTC1,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device mcf_fec1 = {
|
||||||
|
.name = "fec",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(mcf_fec1_resources),
|
||||||
|
.resource = mcf_fec1_resources,
|
||||||
|
};
|
||||||
|
#endif /* MCFFEC_BASE1 */
|
||||||
|
#endif /* CONFIG_FEC */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
|
/*
|
||||||
|
* The ColdFire QSPI module is an SPI protocol hardware block used
|
||||||
|
* on a number of different ColdFire CPUs.
|
||||||
|
*/
|
||||||
|
static struct resource mcf_qspi_resources[] = {
|
||||||
|
{
|
||||||
|
.start = MCFQSPI_BASE,
|
||||||
|
.end = MCFQSPI_BASE + MCFQSPI_SIZE - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = MCF_IRQ_QSPI,
|
||||||
|
.end = MCF_IRQ_QSPI,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
||||||
|
if (status) {
|
||||||
|
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
||||||
|
goto fail0;
|
||||||
|
}
|
||||||
|
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
||||||
|
if (status) {
|
||||||
|
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
||||||
|
if (status) {
|
||||||
|
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
||||||
|
if (status) {
|
||||||
|
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
||||||
|
if (status) {
|
||||||
|
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
||||||
|
if (status) {
|
||||||
|
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
||||||
|
goto fail3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MCFQSPI_CS3
|
||||||
|
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
||||||
|
if (status) {
|
||||||
|
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
||||||
|
goto fail3;
|
||||||
|
}
|
||||||
|
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
||||||
|
if (status) {
|
||||||
|
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
||||||
|
gpio_free(MCFQSPI_CS3);
|
||||||
|
goto fail3;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail3:
|
||||||
|
gpio_free(MCFQSPI_CS2);
|
||||||
|
fail2:
|
||||||
|
gpio_free(MCFQSPI_CS1);
|
||||||
|
fail1:
|
||||||
|
gpio_free(MCFQSPI_CS0);
|
||||||
|
fail0:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
||||||
|
{
|
||||||
|
#ifdef MCFQSPI_CS3
|
||||||
|
gpio_free(MCFQSPI_CS3);
|
||||||
|
#endif
|
||||||
|
gpio_free(MCFQSPI_CS2);
|
||||||
|
gpio_free(MCFQSPI_CS1);
|
||||||
|
gpio_free(MCFQSPI_CS0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
|
||||||
|
u8 chip_select, bool cs_high)
|
||||||
|
{
|
||||||
|
switch (chip_select) {
|
||||||
|
case 0:
|
||||||
|
gpio_set_value(MCFQSPI_CS0, cs_high);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
gpio_set_value(MCFQSPI_CS1, cs_high);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
gpio_set_value(MCFQSPI_CS2, cs_high);
|
||||||
|
break;
|
||||||
|
#ifdef MCFQSPI_CS3
|
||||||
|
case 3:
|
||||||
|
gpio_set_value(MCFQSPI_CS3, cs_high);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
||||||
|
u8 chip_select, bool cs_high)
|
||||||
|
{
|
||||||
|
switch (chip_select) {
|
||||||
|
case 0:
|
||||||
|
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
||||||
|
break;
|
||||||
|
#ifdef MCFQSPI_CS3
|
||||||
|
case 3:
|
||||||
|
gpio_set_value(MCFQSPI_CS3, !cs_high);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mcfqspi_cs_control mcf_cs_control = {
|
||||||
|
.setup = mcf_cs_setup,
|
||||||
|
.teardown = mcf_cs_teardown,
|
||||||
|
.select = mcf_cs_select,
|
||||||
|
.deselect = mcf_cs_deselect,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mcfqspi_platform_data mcf_qspi_data = {
|
||||||
|
.bus_num = 0,
|
||||||
|
.num_chipselect = 4,
|
||||||
|
.cs_control = &mcf_cs_control,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device mcf_qspi = {
|
||||||
|
.name = "mcfqspi",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(mcf_qspi_resources),
|
||||||
|
.resource = mcf_qspi_resources,
|
||||||
|
.dev.platform_data = &mcf_qspi_data,
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||||
|
|
||||||
|
static struct platform_device *mcf_devices[] __initdata = {
|
||||||
|
&mcf_uart,
|
||||||
|
#ifdef CONFIG_FEC
|
||||||
|
&mcf_fec0,
|
||||||
|
#ifdef MCFFEC_BASE1
|
||||||
|
&mcf_fec1,
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||||
|
&mcf_qspi,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some ColdFire UARTs let you set the IRQ line to use.
|
||||||
|
*/
|
||||||
|
static void __init mcf_uart_set_irq(void)
|
||||||
|
{
|
||||||
|
#ifdef MCFUART_UIVR
|
||||||
|
/* UART0 interrupt setup */
|
||||||
|
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
|
||||||
|
writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
|
||||||
|
mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
|
||||||
|
|
||||||
|
/* UART1 interrupt setup */
|
||||||
|
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
|
||||||
|
writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
|
||||||
|
mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init mcf_init_devices(void)
|
||||||
|
{
|
||||||
|
mcf_uart_set_irq();
|
||||||
|
platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_initcall(mcf_init_devices);
|
||||||
|
|
@@ -158,6 +158,10 @@ _start:
|
|||||||
#if defined(CONFIG_UBOOT)
|
#if defined(CONFIG_UBOOT)
|
||||||
movel %sp,_init_sp /* save initial stack pointer */
|
movel %sp,_init_sp /* save initial stack pointer */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_MBAR
|
||||||
|
movel #CONFIG_MBAR+1,%d0 /* configured MBAR address */
|
||||||
|
movec %d0,%MBAR /* set it */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do any platform or board specific setup now. Most boards
|
* Do any platform or board specific setup now. Most boards
|
||||||
|
@@ -149,7 +149,7 @@ static struct clocksource pit_clk = {
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
void hw_timer_init(void)
|
void hw_timer_init(irq_handler_t handler)
|
||||||
{
|
{
|
||||||
cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id());
|
cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id());
|
||||||
cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
|
cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
|
||||||
|
50
arch/m68k/platform/coldfire/reset.c
Normal file
50
arch/m68k/platform/coldfire/reset.c
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* reset.c -- common ColdFire SoC reset support
|
||||||
|
*
|
||||||
|
* (C) Copyright 2012, Greg Ungerer <gerg@uclinux.org>
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
|
* License. See the file COPYING in the main directory of this archive
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <asm/machdep.h>
|
||||||
|
#include <asm/coldfire.h>
|
||||||
|
#include <asm/mcfsim.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are 2 common methods amongst the ColdFure parts for reseting
|
||||||
|
* the CPU. But there are couple of exceptions, the 5272 and the 547x
|
||||||
|
* have something completely special to them, and we let their specific
|
||||||
|
* subarch code handle them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef MCFSIM_SYPCR
|
||||||
|
static void mcf_cpu_reset(void)
|
||||||
|
{
|
||||||
|
local_irq_disable();
|
||||||
|
/* Set watchdog to soft reset, and enabled */
|
||||||
|
__raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
|
||||||
|
for (;;)
|
||||||
|
/* wait for watchdog to timeout */;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MCF_RCR
|
||||||
|
static void mcf_cpu_reset(void)
|
||||||
|
{
|
||||||
|
local_irq_disable();
|
||||||
|
__raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int __init mcf_setup_reset(void)
|
||||||
|
{
|
||||||
|
mach_reset = mcf_cpu_reset;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_initcall(mcf_setup_reset);
|
@@ -81,12 +81,14 @@ void mcfslt_profile_init(void)
|
|||||||
static u32 mcfslt_cycles_per_jiffy;
|
static u32 mcfslt_cycles_per_jiffy;
|
||||||
static u32 mcfslt_cnt;
|
static u32 mcfslt_cnt;
|
||||||
|
|
||||||
|
static irq_handler_t timer_interrupt;
|
||||||
|
|
||||||
static irqreturn_t mcfslt_tick(int irq, void *dummy)
|
static irqreturn_t mcfslt_tick(int irq, void *dummy)
|
||||||
{
|
{
|
||||||
/* Reset Slice Timer 0 */
|
/* Reset Slice Timer 0 */
|
||||||
__raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, TA(MCFSLT_SSR));
|
__raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, TA(MCFSLT_SSR));
|
||||||
mcfslt_cnt += mcfslt_cycles_per_jiffy;
|
mcfslt_cnt += mcfslt_cycles_per_jiffy;
|
||||||
return arch_timer_interrupt(irq, dummy);
|
return timer_interrupt(irq, dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irqaction mcfslt_timer_irq = {
|
static struct irqaction mcfslt_timer_irq = {
|
||||||
@@ -121,7 +123,7 @@ static struct clocksource mcfslt_clk = {
|
|||||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||||
};
|
};
|
||||||
|
|
||||||
void hw_timer_init(void)
|
void hw_timer_init(irq_handler_t handler)
|
||||||
{
|
{
|
||||||
mcfslt_cycles_per_jiffy = MCF_BUSCLK / HZ;
|
mcfslt_cycles_per_jiffy = MCF_BUSCLK / HZ;
|
||||||
/*
|
/*
|
||||||
@@ -136,6 +138,7 @@ void hw_timer_init(void)
|
|||||||
/* initialize mcfslt_cnt knowing that slice timers count down */
|
/* initialize mcfslt_cnt knowing that slice timers count down */
|
||||||
mcfslt_cnt = mcfslt_cycles_per_jiffy;
|
mcfslt_cnt = mcfslt_cycles_per_jiffy;
|
||||||
|
|
||||||
|
timer_interrupt = handler;
|
||||||
setup_irq(MCF_IRQ_TIMER, &mcfslt_timer_irq);
|
setup_irq(MCF_IRQ_TIMER, &mcfslt_timer_irq);
|
||||||
|
|
||||||
clocksource_register_hz(&mcfslt_clk, MCF_BUSCLK);
|
clocksource_register_hz(&mcfslt_clk, MCF_BUSCLK);
|
||||||
|
@@ -47,6 +47,27 @@ void coldfire_profile_init(void);
|
|||||||
static u32 mcftmr_cycles_per_jiffy;
|
static u32 mcftmr_cycles_per_jiffy;
|
||||||
static u32 mcftmr_cnt;
|
static u32 mcftmr_cnt;
|
||||||
|
|
||||||
|
static irq_handler_t timer_interrupt;
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
static void init_timer_irq(void)
|
||||||
|
{
|
||||||
|
#ifdef MCFSIM_ICR_AUTOVEC
|
||||||
|
/* Timer1 is always used as system timer */
|
||||||
|
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
|
||||||
|
MCF_MBAR + MCFSIM_TIMER1ICR);
|
||||||
|
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
|
||||||
|
|
||||||
|
#ifdef CONFIG_HIGHPROFILE
|
||||||
|
/* Timer2 is to be used as a high speed profile timer */
|
||||||
|
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
|
||||||
|
MCF_MBAR + MCFSIM_TIMER2ICR);
|
||||||
|
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
|
||||||
|
#endif
|
||||||
|
#endif /* MCFSIM_ICR_AUTOVEC */
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static irqreturn_t mcftmr_tick(int irq, void *dummy)
|
static irqreturn_t mcftmr_tick(int irq, void *dummy)
|
||||||
@@ -55,7 +76,7 @@ static irqreturn_t mcftmr_tick(int irq, void *dummy)
|
|||||||
__raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
|
__raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
|
||||||
|
|
||||||
mcftmr_cnt += mcftmr_cycles_per_jiffy;
|
mcftmr_cnt += mcftmr_cycles_per_jiffy;
|
||||||
return arch_timer_interrupt(irq, dummy);
|
return timer_interrupt(irq, dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
@@ -94,7 +115,7 @@ static struct clocksource mcftmr_clk = {
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
void hw_timer_init(void)
|
void hw_timer_init(irq_handler_t handler)
|
||||||
{
|
{
|
||||||
__raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
|
__raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
|
||||||
mcftmr_cycles_per_jiffy = FREQ / HZ;
|
mcftmr_cycles_per_jiffy = FREQ / HZ;
|
||||||
@@ -110,6 +131,8 @@ void hw_timer_init(void)
|
|||||||
|
|
||||||
clocksource_register_hz(&mcftmr_clk, FREQ);
|
clocksource_register_hz(&mcftmr_clk, FREQ);
|
||||||
|
|
||||||
|
timer_interrupt = handler;
|
||||||
|
init_timer_irq();
|
||||||
setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq);
|
setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq);
|
||||||
|
|
||||||
#ifdef CONFIG_HIGHPROFILE
|
#ifdef CONFIG_HIGHPROFILE
|
||||||
|
@@ -33,8 +33,6 @@ asmlinkage void dbginterrupt_c(struct frame *fp)
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
extern e_vector *_ramvec;
|
|
||||||
|
|
||||||
/* Assembler routines */
|
/* Assembler routines */
|
||||||
asmlinkage void buserr(void);
|
asmlinkage void buserr(void);
|
||||||
asmlinkage void trap(void);
|
asmlinkage void trap(void);
|
||||||
|
Reference in New Issue
Block a user