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:
commit
b57cb7231b
|
@ -7,6 +7,7 @@ config M68K
|
|||
select GENERIC_IRQ_SHOW
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
|
||||
select GENERIC_CPU_DEVICES
|
||||
select FPU if MMU
|
||||
|
||||
config RWSEM_GENERIC_SPINLOCK
|
||||
bool
|
||||
|
@ -24,9 +25,6 @@ config ARCH_HAS_ILOG2_U64
|
|||
config GENERIC_CLOCKEVENTS
|
||||
bool
|
||||
|
||||
config GENERIC_CMOS_UPDATE
|
||||
def_bool !MMU
|
||||
|
||||
config GENERIC_GPIO
|
||||
bool
|
||||
|
||||
|
@ -67,6 +65,9 @@ config CPU_HAS_NO_MULDIV64
|
|||
config CPU_HAS_ADDRESS_SPACES
|
||||
bool
|
||||
|
||||
config FPU
|
||||
bool
|
||||
|
||||
config HZ
|
||||
int
|
||||
default 1000 if CLEOPATRA
|
||||
|
|
|
@ -100,11 +100,11 @@
|
|||
#define MCFDMA_BASE1 (MCF_MBAR + 0x240) /* Base address DMA 1 */
|
||||
|
||||
#if defined(CONFIG_NETtel)
|
||||
#define MCFUART_BASE1 0x180 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0x140 /* Base address of UART2 */
|
||||
#define MCFUART_BASE0 (MCF_MBAR + 0x180) /* Base address UART0 */
|
||||
#define MCFUART_BASE1 (MCF_MBAR + 0x140) /* Base address UART1 */
|
||||
#else
|
||||
#define MCFUART_BASE1 0x140 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0x180 /* Base address of UART2 */
|
||||
#define MCFUART_BASE0 (MCF_MBAR + 0x140) /* Base address UART0 */
|
||||
#define MCFUART_BASE1 (MCF_MBAR + 0x180) /* Base address UART1 */
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -112,6 +112,8 @@
|
|||
*/
|
||||
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
||||
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
||||
#define MCF_IRQ_UART0 73 /* UART0 */
|
||||
#define MCF_IRQ_UART1 74 /* UART1 */
|
||||
|
||||
/*
|
||||
* Generic GPIO
|
||||
|
|
|
@ -48,8 +48,21 @@
|
|||
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
|
||||
#define MCFINT_UART2 28 /* Interrupt number for UART2 */
|
||||
#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 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.
|
||||
*/
|
||||
|
@ -144,15 +157,25 @@
|
|||
/*
|
||||
* UART module.
|
||||
*/
|
||||
#define MCFUART_BASE1 0xFC060000 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0xFC064000 /* Base address of UART2 */
|
||||
#define MCFUART_BASE3 0xFC068000 /* Base address of UART2 */
|
||||
#define MCFUART_BASE0 0xFC060000 /* Base address of UART0 */
|
||||
#define MCFUART_BASE1 0xFC064000 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0xFC068000 /* Base address of UART2 */
|
||||
|
||||
/*
|
||||
* FEC module.
|
||||
*/
|
||||
#define MCFFEC_BASE 0xFC030000 /* Base of FEC ethernet */
|
||||
#define MCFFEC_SIZE 0x800 /* Register set size */
|
||||
#define MCFFEC_BASE0 0xFC030000 /* Base of FEC ethernet */
|
||||
#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.
|
||||
|
|
|
@ -35,8 +35,23 @@
|
|||
|
||||
#define MCFINT_VECBASE 64 /* Vector base number */
|
||||
#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_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.
|
||||
|
@ -50,8 +65,8 @@
|
|||
/*
|
||||
* Reset Control Unit (relative to IPSBAR).
|
||||
*/
|
||||
#define MCF_RCR 0x110000
|
||||
#define MCF_RSR 0x110001
|
||||
#define MCF_RCR (MCF_IPSBAR + 0x110000)
|
||||
#define MCF_RSR (MCF_IPSBAR + 0x110001)
|
||||
|
||||
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
|
||||
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
|
||||
|
@ -59,15 +74,26 @@
|
|||
/*
|
||||
* UART module.
|
||||
*/
|
||||
#define MCFUART_BASE1 (MCF_IPSBAR + 0x200)
|
||||
#define MCFUART_BASE2 (MCF_IPSBAR + 0x240)
|
||||
#define MCFUART_BASE3 (MCF_IPSBAR + 0x280)
|
||||
#define MCFUART_BASE0 (MCF_IPSBAR + 0x200)
|
||||
#define MCFUART_BASE1 (MCF_IPSBAR + 0x240)
|
||||
#define MCFUART_BASE2 (MCF_IPSBAR + 0x280)
|
||||
|
||||
/*
|
||||
* FEC ethernet module.
|
||||
*/
|
||||
#define MCFFEC_BASE (MCF_IPSBAR + 0x1000)
|
||||
#define MCFFEC_SIZE 0x800
|
||||
#define MCFFEC_BASE0 (MCF_IPSBAR + 0x1000)
|
||||
#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.
|
||||
|
|
|
@ -76,8 +76,19 @@
|
|||
/*
|
||||
* UART module.
|
||||
*/
|
||||
#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0x200 /* Base address of UART2 */
|
||||
#define MCFUART_BASE0 (MCF_MBAR + 0x1c0) /* Base address UART0 */
|
||||
#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.
|
||||
|
@ -108,6 +119,9 @@
|
|||
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
||||
#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).
|
||||
*/
|
||||
|
|
|
@ -68,8 +68,8 @@
|
|||
#define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */
|
||||
#define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */
|
||||
|
||||
#define MCFUART_BASE1 0x100 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0x140 /* Base address of UART2 */
|
||||
#define MCFUART_BASE0 (MCF_MBAR + 0x100) /* Base address UART0 */
|
||||
#define MCFUART_BASE1 (MCF_MBAR + 0x140) /* Base address UART1 */
|
||||
|
||||
#define MCFSIM_PACNT (MCF_MBAR + 0x80) /* Port A Control (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_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.
|
||||
*/
|
||||
|
@ -101,8 +104,8 @@
|
|||
#define MCF_IRQ_TIMER2 70 /* Timer 2 */
|
||||
#define MCF_IRQ_TIMER3 71 /* Timer 3 */
|
||||
#define MCF_IRQ_TIMER4 72 /* Timer 4 */
|
||||
#define MCF_IRQ_UART1 73 /* UART 1 */
|
||||
#define MCF_IRQ_UART2 74 /* UART 2 */
|
||||
#define MCF_IRQ_UART0 73 /* UART 0 */
|
||||
#define MCF_IRQ_UART1 74 /* UART 1 */
|
||||
#define MCF_IRQ_PLIP 75 /* PLIC 2Khz Periodic */
|
||||
#define MCF_IRQ_PLIA 76 /* PLIC Asynchronous */
|
||||
#define MCF_IRQ_USB0 77 /* USB Endpoint 0 */
|
||||
|
@ -114,9 +117,9 @@
|
|||
#define MCF_IRQ_USB6 83 /* USB Endpoint 6 */
|
||||
#define MCF_IRQ_USB7 84 /* USB Endpoint 7 */
|
||||
#define MCF_IRQ_DMA 85 /* DMA Controller */
|
||||
#define MCF_IRQ_ERX 86 /* Ethernet Receiver */
|
||||
#define MCF_IRQ_ETX 87 /* Ethernet Transmitter */
|
||||
#define MCF_IRQ_ENTC 88 /* Ethernet Non-Time Critical */
|
||||
#define MCF_IRQ_FECRX0 86 /* Ethernet Receiver */
|
||||
#define MCF_IRQ_FECTX0 87 /* Ethernet Transmitter */
|
||||
#define MCF_IRQ_FECENTC0 88 /* Ethernet Non-Time Critical */
|
||||
#define MCF_IRQ_QSPI 89 /* Queued Serial Interface */
|
||||
#define MCF_IRQ_EINT5 90 /* External Interrupt 5 */
|
||||
#define MCF_IRQ_EINT6 91 /* External Interrupt 6 */
|
||||
|
|
|
@ -38,8 +38,29 @@
|
|||
#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_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 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.
|
||||
*/
|
||||
|
@ -72,9 +93,9 @@
|
|||
/*
|
||||
* UART module.
|
||||
*/
|
||||
#define MCFUART_BASE1 (MCF_IPSBAR + 0x200)
|
||||
#define MCFUART_BASE2 (MCF_IPSBAR + 0x240)
|
||||
#define MCFUART_BASE3 (MCF_IPSBAR + 0x280)
|
||||
#define MCFUART_BASE0 (MCF_IPSBAR + 0x200)
|
||||
#define MCFUART_BASE1 (MCF_IPSBAR + 0x240)
|
||||
#define MCFUART_BASE2 (MCF_IPSBAR + 0x280)
|
||||
|
||||
/*
|
||||
* FEC ethernet module.
|
||||
|
@ -84,6 +105,28 @@
|
|||
#define MCFFEC_BASE1 (MCF_IPSBAR + 0x1800)
|
||||
#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
|
||||
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000)
|
||||
#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001)
|
||||
|
@ -285,8 +328,8 @@
|
|||
/*
|
||||
* Reset Control Unit (relative to IPSBAR).
|
||||
*/
|
||||
#define MCF_RCR 0x110000
|
||||
#define MCF_RSR 0x110001
|
||||
#define MCF_RCR (MCF_IPSBAR + 0x110000)
|
||||
#define MCF_RSR (MCF_IPSBAR + 0x110001)
|
||||
|
||||
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
|
||||
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
|
||||
|
|
|
@ -35,9 +35,24 @@
|
|||
|
||||
#define MCFINT_VECBASE 64 /* Vector base number */
|
||||
#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_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 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.
|
||||
*/
|
||||
|
@ -58,15 +73,26 @@
|
|||
/*
|
||||
* UART module.
|
||||
*/
|
||||
#define MCFUART_BASE1 (MCF_IPSBAR + 0x00000200)
|
||||
#define MCFUART_BASE2 (MCF_IPSBAR + 0x00000240)
|
||||
#define MCFUART_BASE3 (MCF_IPSBAR + 0x00000280)
|
||||
#define MCFUART_BASE0 (MCF_IPSBAR + 0x00000200)
|
||||
#define MCFUART_BASE1 (MCF_IPSBAR + 0x00000240)
|
||||
#define MCFUART_BASE2 (MCF_IPSBAR + 0x00000280)
|
||||
|
||||
/*
|
||||
* FEC ethernet module.
|
||||
*/
|
||||
#define MCFFEC_BASE (MCF_IPSBAR + 0x00001000)
|
||||
#define MCFFEC_SIZE 0x800
|
||||
#define MCFFEC_BASE0 (MCF_IPSBAR + 0x00001000)
|
||||
#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
|
||||
|
@ -246,8 +272,8 @@
|
|||
/*
|
||||
* Reset Control Unit (relative to IPSBAR).
|
||||
*/
|
||||
#define MCF_RCR 0x110000
|
||||
#define MCF_RSR 0x110001
|
||||
#define MCF_RCR (MCF_IPSBAR + 0x110000)
|
||||
#define MCF_RSR (MCF_IPSBAR + 0x110001)
|
||||
|
||||
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
|
||||
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
|
||||
|
|
|
@ -117,11 +117,11 @@
|
|||
* UART module.
|
||||
*/
|
||||
#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
|
||||
#define MCFUART_BASE1 0x200 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */
|
||||
#define MCFUART_BASE0 (MCF_MBAR + 0x200) /* Base address UART0 */
|
||||
#define MCFUART_BASE1 (MCF_MBAR + 0x1c0) /* Base address UART1 */
|
||||
#else
|
||||
#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0x200 /* Base address of UART2 */
|
||||
#define MCFUART_BASE0 (MCF_MBAR + 0x1c0) /* Base address UART0 */
|
||||
#define MCFUART_BASE1 (MCF_MBAR + 0x200) /* Base address UART1 */
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -176,6 +176,8 @@
|
|||
*/
|
||||
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
||||
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
||||
#define MCF_IRQ_UART0 73 /* UART0 */
|
||||
#define MCF_IRQ_UART1 74 /* UART1 */
|
||||
|
||||
/****************************************************************************/
|
||||
#endif /* m5307sim_h */
|
||||
|
|
|
@ -24,6 +24,19 @@
|
|||
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
|
||||
#define MCFINT_UART2 28 /* Interrupt number for UART2 */
|
||||
#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)
|
||||
|
||||
|
@ -82,9 +95,25 @@
|
|||
/*
|
||||
* UART module.
|
||||
*/
|
||||
#define MCFUART_BASE1 0xFC060000 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0xFC064000 /* Base address of UART2 */
|
||||
#define MCFUART_BASE3 0xFC068000 /* Base address of UART3 */
|
||||
#define MCFUART_BASE0 0xFC060000 /* Base address of UART1 */
|
||||
#define MCFUART_BASE1 0xFC064000 /* Base address of UART2 */
|
||||
#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.
|
||||
|
|
|
@ -85,8 +85,8 @@
|
|||
#define MCFTIMER_BASE1 (MCF_MBAR + 0x140) /* Base of TIMER1 */
|
||||
#define MCFTIMER_BASE2 (MCF_MBAR + 0x180) /* Base of TIMER2 */
|
||||
|
||||
#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0x200 /* Base address of UART2 */
|
||||
#define MCFUART_BASE0 (MCF_MBAR + 0x1c0) /* Base address UART0 */
|
||||
#define MCFUART_BASE1 (MCF_MBAR + 0x200) /* Base address UART1 */
|
||||
|
||||
#define MCFSIM_PADDR (MCF_MBAR + 0x244)
|
||||
#define MCFSIM_PADAT (MCF_MBAR + 0x248)
|
||||
|
@ -139,6 +139,8 @@
|
|||
*/
|
||||
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
||||
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
||||
#define MCF_IRQ_UART0 73 /* UART0 */
|
||||
#define MCF_IRQ_UART1 74 /* UART1 */
|
||||
|
||||
/****************************************************************************/
|
||||
#endif /* m5407sim_h */
|
||||
|
|
|
@ -31,16 +31,20 @@
|
|||
/*
|
||||
* UART module.
|
||||
*/
|
||||
#define MCFUART_BASE1 0x8600 /* Base address of UART1 */
|
||||
#define MCFUART_BASE2 0x8700 /* Base address of UART2 */
|
||||
#define MCFUART_BASE3 0x8800 /* Base address of UART3 */
|
||||
#define MCFUART_BASE4 0x8900 /* Base address of UART4 */
|
||||
#define MCFUART_BASE0 (MCF_MBAR + 0x8600) /* Base address UART0 */
|
||||
#define MCFUART_BASE1 (MCF_MBAR + 0x8700) /* Base address UART1 */
|
||||
#define MCFUART_BASE2 (MCF_MBAR + 0x8800) /* Base address UART2 */
|
||||
#define MCFUART_BASE3 (MCF_MBAR + 0x8900) /* Base address UART3 */
|
||||
|
||||
/*
|
||||
* Define system peripheral IRQ usage.
|
||||
*/
|
||||
#define MCF_IRQ_TIMER (64 + 54) /* Slice Timer 0 */
|
||||
#define MCF_IRQ_PROFILER (64 + 53) /* Slice Timer 1 */
|
||||
#define MCF_IRQ_TIMER (MCFINT_VECBASE + 54) /* Slice Timer 0 */
|
||||
#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
|
||||
|
|
|
@ -22,8 +22,6 @@ extern unsigned int (*mach_get_ss)(void);
|
|||
extern int (*mach_get_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 void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
|
||||
int *min, int *sec);
|
||||
extern void (*mach_reset)( void );
|
||||
extern void (*mach_halt)( 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);
|
||||
|
||||
/* 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 irqreturn_t arch_timer_interrupt(int irq, void *dummy);
|
||||
|
||||
extern void config_BSP(char *command, int len);
|
||||
|
||||
|
|
|
@ -21,17 +21,6 @@
|
|||
#ifndef 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
|
||||
* @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_URF 0x2c /* Receiver FIFO (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) */
|
||||
#endif
|
||||
#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
|
||||
#include "process_no.c"
|
||||
__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 */
|
||||
#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
|
||||
#include "ptrace_mm.c"
|
||||
#else
|
||||
#include "ptrace_no.c"
|
||||
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);
|
||||
}
|
||||
#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/initrd.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/irq.h>
|
||||
|
@ -47,7 +48,9 @@ EXPORT_SYMBOL(memory_end);
|
|||
char __initdata command_line[COMMAND_LINE_SIZE];
|
||||
|
||||
/* machine dependent timer functions */
|
||||
void (*mach_sched_init)(irq_handler_t handler) __initdata = NULL;
|
||||
int (*mach_set_clock_mmss)(unsigned long);
|
||||
int (*mach_hwclk) (int, struct rtc_time*);
|
||||
|
||||
/* machine dependent reboot functions */
|
||||
void (*mach_reset)(void);
|
||||
|
|
|
@ -1,5 +1,111 @@
|
|||
#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
|
||||
#include "time_mm.c"
|
||||
#else
|
||||
#include "time_no.c"
|
||||
#endif
|
||||
/*
|
||||
* 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>
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* (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
|
||||
* 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/thread_info.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
|
||||
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
|
||||
OUTPUT_ARCH(m68k)
|
||||
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;
|
||||
|
||||
SECTIONS {
|
||||
|
||||
#ifdef ROMVEC_START
|
||||
. = ROMVEC_START ;
|
||||
#ifdef CONFIG_ROMVEC
|
||||
. = CONFIG_ROMVEC;
|
||||
.romvec : {
|
||||
__rom_start = . ;
|
||||
__rom_start = .;
|
||||
_romvec = .;
|
||||
*(.romvec)
|
||||
*(.data..initvect)
|
||||
} > romvec
|
||||
}
|
||||
#endif
|
||||
|
||||
. = KTEXT_ADDR;
|
||||
|
||||
_text = .;
|
||||
_stext = .;
|
||||
.text : {
|
||||
_text = .;
|
||||
_stext = . ;
|
||||
HEAD_TEXT
|
||||
TEXT_TEXT
|
||||
SCHED_TEXT
|
||||
LOCK_TEXT
|
||||
*(.text..lock)
|
||||
*(.fixup)
|
||||
. = ALIGN(16);
|
||||
}
|
||||
_etext = .;
|
||||
|
||||
. = ALIGN(16); /* Exception table */
|
||||
__start___ex_table = .;
|
||||
*(__ex_table)
|
||||
__stop___ex_table = .;
|
||||
#ifdef KDATA_ADDR
|
||||
. = KDATA_ADDR;
|
||||
#endif
|
||||
|
||||
*(.rodata) *(.rodata.*)
|
||||
*(__vermagic) /* Kernel version magic */
|
||||
*(.rodata1)
|
||||
*(.rodata.str1.1)
|
||||
_sdata = .;
|
||||
RO_DATA_SECTION(PAGE_SIZE)
|
||||
RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
|
||||
_edata = .;
|
||||
|
||||
/* Kernel symbol table: Normal symbols */
|
||||
. = ALIGN(4);
|
||||
__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
|
||||
EXCEPTION_TABLE(16)
|
||||
NOTES
|
||||
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_begin = .;
|
||||
INIT_TEXT_SECTION(PAGE_SIZE)
|
||||
INIT_DATA_SECTION(16)
|
||||
PERCPU_SECTION(16)
|
||||
.m68k_fixup : {
|
||||
__start_fixup = .;
|
||||
*(.m68k_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 : {
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
} > INIT
|
||||
}
|
||||
|
||||
.bss : {
|
||||
. = ALIGN(4);
|
||||
_sbss = . ;
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
. = ALIGN(4) ;
|
||||
_ebss = . ;
|
||||
_end = . ;
|
||||
} > BSSS
|
||||
_sbss = .;
|
||||
BSS_SECTION(0, 0, 0)
|
||||
_ebss = .;
|
||||
|
||||
_end = .;
|
||||
|
||||
STABS_DEBUG
|
||||
.comment 0 : { *(.comment) }
|
||||
|
||||
/* Sections to be discarded */
|
||||
DISCARDS
|
||||
}
|
||||
|
||||
|
|
|
@ -16,83 +16,6 @@
|
|||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.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;
|
||||
#endif /* CONFIG_NETtel */
|
||||
|
||||
mach_reset = m5206_cpu_reset;
|
||||
m5206_timers_init();
|
||||
m5206_uarts_init();
|
||||
mach_sched_init = hw_timer_init;
|
||||
|
||||
/* Only support the external interrupts on their primary level */
|
||||
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/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct mcf_platform_uart m520x_uart_platform[] = {
|
||||
{
|
||||
.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,
|
||||
};
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
|
||||
static void __init m520x_qspi_init(void)
|
||||
{
|
||||
|
@ -214,54 +34,28 @@ static void __init m520x_qspi_init(void)
|
|||
par &= 0x00ff;
|
||||
writew(par, MCF_GPIO_PAR_UART);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m520x_uart_init_line(int line, int irq)
|
||||
static void __init m520x_uarts_init(void)
|
||||
{
|
||||
u16 par;
|
||||
u8 par2;
|
||||
|
||||
switch (line) {
|
||||
case 0:
|
||||
par = readw(MCF_GPIO_PAR_UART);
|
||||
par |= MCF_GPIO_PAR_UART_PAR_UTXD0 |
|
||||
MCF_GPIO_PAR_UART_PAR_URXD0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
/* UART0 and UART1 GPIO pin setup */
|
||||
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_UTXD1 | MCF_GPIO_PAR_UART_PAR_URXD1;
|
||||
writew(par, MCF_GPIO_PAR_UART);
|
||||
|
||||
static void __init m520x_uarts_init(void)
|
||||
{
|
||||
const int nrlines = ARRAY_SIZE(m520x_uart_platform);
|
||||
int line;
|
||||
|
||||
for (line = 0; (line < nrlines); line++)
|
||||
m520x_uart_init_line(line, m520x_uart_platform[line].irq);
|
||||
/* UART1 GPIO pin setup */
|
||||
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);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -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)
|
||||
{
|
||||
mach_reset = m520x_cpu_reset;
|
||||
mach_sched_init = hw_timer_init;
|
||||
m520x_uarts_init();
|
||||
m520x_fec_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
m520x_qspi_init();
|
||||
#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/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct mcf_platform_uart m523x_uart_platform[] = {
|
||||
{
|
||||
.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,
|
||||
};
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
|
||||
static void __init m523x_qspi_init(void)
|
||||
{
|
||||
|
@ -237,15 +35,8 @@ static void __init m523x_qspi_init(void)
|
|||
par &= 0x3f3f;
|
||||
writew(par, MCFGPIO_PAR_TIMER);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
static struct platform_device *m523x_devices[] __initdata = {
|
||||
&m523x_uart,
|
||||
&m523x_fec,
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
&m523x_qspi,
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
mach_reset = m523x_cpu_reset;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static int __init init_BSP(void)
|
||||
{
|
||||
mach_sched_init = hw_timer_init;
|
||||
m523x_fec_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
m523x_qspi_init();
|
||||
#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/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.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
|
||||
|
||||
static struct resource m5249_smc91x_resources[] = {
|
||||
|
@ -64,153 +43,15 @@ static struct platform_device m5249_smc91x = {
|
|||
|
||||
#endif /* CONFIG_M5249C3 */
|
||||
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
static struct resource m5249_qspi_resources[] = {
|
||||
{
|
||||
.start = MCFQSPI_IOBASE,
|
||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_QSPI,
|
||||
.end = MCF_IRQ_QSPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static struct platform_device *m5249_devices[] __initdata = {
|
||||
#ifdef CONFIG_M5249C3
|
||||
&m5249_smc91x,
|
||||
#endif
|
||||
};
|
||||
|
||||
#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)
|
||||
{
|
||||
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,
|
||||
};
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
|
||||
static void __init m5249_qspi_init(void)
|
||||
{
|
||||
|
@ -219,42 +60,8 @@ static void __init m5249_qspi_init(void)
|
|||
MCF_MBAR + MCFSIM_QSPIICR);
|
||||
mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
mach_reset = m5249_cpu_reset;
|
||||
m5249_timers_init();
|
||||
m5249_uarts_init();
|
||||
mach_sched_init = hw_timer_init;
|
||||
|
||||
#ifdef CONFIG_M5249C3
|
||||
m5249_smc91x_init();
|
||||
#endif
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
m5249_qspi_init();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -30,84 +30,18 @@ unsigned char ledbank = 0xff;
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct mcf_platform_uart m5272_uart_platform[] = {
|
||||
{
|
||||
.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)
|
||||
static void __init m5272_uarts_init(void)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
if ((line >= 0) && (line < 2)) {
|
||||
/* Enable the output lines for the serial ports */
|
||||
v = readl(MCF_MBAR + MCFSIM_PBCNT);
|
||||
v = (v & ~0x000000ff) | 0x00000055;
|
||||
writel(v, MCF_MBAR + MCFSIM_PBCNT);
|
||||
/* Enable the output lines for the serial ports */
|
||||
v = readl(MCF_MBAR + MCFSIM_PBCNT);
|
||||
v = (v & ~0x000000ff) | 0x00000055;
|
||||
writel(v, MCF_MBAR + MCFSIM_PBCNT);
|
||||
|
||||
v = readl(MCF_MBAR + MCFSIM_PDCNT);
|
||||
v = (v & ~0x000003fc) | 0x000002a8;
|
||||
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);
|
||||
v = readl(MCF_MBAR + MCFSIM_PDCNT);
|
||||
v = (v & ~0x000003fc) | 0x000002a8;
|
||||
writel(v, MCF_MBAR + MCFSIM_PDCNT);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -146,6 +80,7 @@ void __init config_BSP(char *commandp, int size)
|
|||
#endif
|
||||
|
||||
mach_reset = m5272_cpu_reset;
|
||||
mach_sched_init = hw_timer_init;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -167,7 +102,6 @@ static int __init init_BSP(void)
|
|||
{
|
||||
m5272_uarts_init();
|
||||
fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status);
|
||||
platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,253 +16,14 @@
|
|||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct mcf_platform_uart m527x_uart_platform[] = {
|
||||
{
|
||||
.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,
|
||||
};
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
|
||||
static void __init m527x_qspi_init(void)
|
||||
{
|
||||
|
@ -280,50 +41,23 @@ static void __init m527x_qspi_init(void)
|
|||
writew(0x003e, MCFGPIO_PAR_QSPI);
|
||||
#endif
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
static struct platform_device *m527x_devices[] __initdata = {
|
||||
&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
|
||||
};
|
||||
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m527x_uart_init_line(int line, int irq)
|
||||
static void __init m527x_uarts_init(void)
|
||||
{
|
||||
u16 sepmask;
|
||||
|
||||
if ((line < 0) || (line > 2))
|
||||
return;
|
||||
|
||||
/*
|
||||
* External Pin Mask Setting & Enable External Pin for Interface
|
||||
*/
|
||||
sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
|
||||
if (line == 0)
|
||||
sepmask |= UART0_ENABLE_MASK;
|
||||
else if (line == 1)
|
||||
sepmask |= UART1_ENABLE_MASK;
|
||||
else if (line == 2)
|
||||
sepmask |= UART2_ENABLE_MASK;
|
||||
sepmask |= UART0_ENABLE_MASK | UART1_ENABLE_MASK | UART2_ENABLE_MASK;
|
||||
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)
|
||||
|
@ -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)
|
||||
{
|
||||
mach_reset = m527x_cpu_reset;
|
||||
mach_sched_init = hw_timer_init;
|
||||
m527x_uarts_init();
|
||||
m527x_fec_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
m527x_qspi_init();
|
||||
#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/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct mcf_platform_uart m528x_uart_platform[] = {
|
||||
{
|
||||
.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,
|
||||
};
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
|
||||
static void __init m528x_qspi_init(void)
|
||||
{
|
||||
/* setup Port QS for QSPI with gpio CS control */
|
||||
__raw_writeb(0x07, MCFGPIO_PQSPAR);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
static struct platform_device *m528x_devices[] __initdata = {
|
||||
&m528x_uart,
|
||||
&m528x_fec,
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
&m528x_qspi,
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void __init m528x_uart_init_line(int line, int irq)
|
||||
static void __init m528x_uarts_init(void)
|
||||
{
|
||||
u8 port;
|
||||
|
||||
if ((line < 0) || (line > 2))
|
||||
return;
|
||||
|
||||
/* make sure PUAPAR is set for UART0 and UART1 */
|
||||
if (line < 2) {
|
||||
port = readb(MCF5282_GPIO_PUAPAR);
|
||||
port |= (0x03 << (line * 2));
|
||||
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);
|
||||
port = readb(MCF5282_GPIO_PUAPAR);
|
||||
port |= 0x03 | (0x03 << 2);
|
||||
writeb(port, MCF5282_GPIO_PUAPAR);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -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
|
||||
void wildfire_halt(void)
|
||||
{
|
||||
|
@ -299,22 +95,12 @@ void __init config_BSP(char *commandp, int size)
|
|||
#ifdef CONFIG_WILDFIREMOD
|
||||
mach_halt = wildfiremod_halt;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static int __init init_BSP(void)
|
||||
{
|
||||
mach_reset = m528x_cpu_reset;
|
||||
mach_sched_init = hw_timer_init;
|
||||
m528x_uarts_init();
|
||||
m528x_fec_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
m528x_qspi_init();
|
||||
#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/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.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)
|
||||
{
|
||||
#if defined(CONFIG_NETtel) || \
|
||||
|
@ -114,9 +37,7 @@ void __init config_BSP(char *commandp, int size)
|
|||
commandp[size-1] = 0;
|
||||
#endif
|
||||
|
||||
mach_reset = m5307_cpu_reset;
|
||||
m5307_timers_init();
|
||||
m5307_uarts_init();
|
||||
mach_sched_init = hw_timer_init;
|
||||
|
||||
/* Only support the external interrupts on their primary level */
|
||||
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/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfdma.h>
|
||||
#include <asm/mcfwdebug.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static struct mcf_platform_uart m532x_uart_platform[] = {
|
||||
{
|
||||
.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,
|
||||
};
|
||||
#ifdef CONFIG_SPI_COLDFIRE_QSPI
|
||||
|
||||
static void __init m532x_qspi_init(void)
|
||||
{
|
||||
/* setup QSPS pins for QSPI with gpio CS control */
|
||||
writew(0x01f0, MCF_GPIO_PAR_QSPI);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
#endif /* CONFIG_SPI_COLDFIRE_QSPI */
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
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)
|
||||
{
|
||||
const int nrlines = ARRAY_SIZE(m532x_uart_platform);
|
||||
int line;
|
||||
|
||||
for (line = 0; (line < nrlines); line++)
|
||||
m532x_uart_init_line(line, m532x_uart_platform[line].irq);
|
||||
/* UART GPIO initialization */
|
||||
MCF_GPIO_PAR_UART |= 0x0FFF;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
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)
|
||||
{
|
||||
#if !defined(CONFIG_BOOTPARAM)
|
||||
|
@ -263,6 +74,13 @@ void __init config_BSP(char *commandp, int size)
|
|||
}
|
||||
#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
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
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 */
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -16,91 +16,12 @@
|
|||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.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)
|
||||
{
|
||||
mach_reset = m5407_cpu_reset;
|
||||
m5407_timers_init();
|
||||
m5407_uarts_init();
|
||||
mach_sched_init = hw_timer_init;
|
||||
|
||||
/* Only support the external interrupts on their primary level */
|
||||
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)
|
||||
{
|
||||
const int nrlines = ARRAY_SIZE(m54xx_uart_platform);
|
||||
int line;
|
||||
|
||||
for (line = 0; (line < nrlines); line++)
|
||||
m54xx_uart_init_line(line, m54xx_uart_platform[line].irq);
|
||||
/* enable io pins */
|
||||
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD,
|
||||
MCF_MBAR + MCF_PAR_PSC(0));
|
||||
__raw_writeb(MCF_PAR_PSC_TXD | MCF_PAR_PSC_RXD | MCF_PAR_PSC_RTS_RTS,
|
||||
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();
|
||||
#endif
|
||||
mach_reset = mcf54xx_reset;
|
||||
mach_sched_init = hw_timer_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/kernel.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/machdep.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/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;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,8 +68,6 @@ asmlinkage irqreturn_t inthandler5(void);
|
|||
asmlinkage irqreturn_t inthandler6(void);
|
||||
asmlinkage irqreturn_t inthandler7(void);
|
||||
|
||||
extern e_vector *_ramvec;
|
||||
|
||||
/* The 68k family did not have a good way to determine the source
|
||||
* of interrupts until later in the family. The EC000 core does
|
||||
* not provide the vector number on the stack, we vector everything
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/system.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;
|
||||
*hour = (now >> 24) % 24;
|
||||
*min = (now >> 16) % 60;
|
||||
*sec = now % 60;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -103,11 +103,6 @@ void hw_timer_init(void)
|
|||
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)
|
||||
{
|
||||
#if 0
|
||||
|
@ -181,6 +176,5 @@ void config_BSP(char *command, int len)
|
|||
scc1_hwaddr = "\00\01\02\03\04\05";
|
||||
#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 inthandler(void);
|
||||
|
||||
extern void *_ramvec[];
|
||||
|
||||
static void intc_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
pquicc->intr_cimr |= (1 << d->irq);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/pgtable.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;
|
||||
#endif
|
||||
|
||||
mach_gettod = m68328_timer_gettod;
|
||||
mach_hwclk = m68328_hwclk;
|
||||
mach_reset = m68ez328_reset;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/netdevice.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
#include <asm/system.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 */
|
||||
|
@ -181,7 +182,7 @@ void config_BSP(char *command, int size)
|
|||
|
||||
init_hardware(command, size);
|
||||
|
||||
mach_gettod = m68328_timer_gettod;
|
||||
mach_hwclk = m68328_hwclk;
|
||||
mach_reset = m68vz328_reset;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,18 +14,18 @@
|
|||
|
||||
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
|
||||
|
||||
obj-$(CONFIG_COLDFIRE) += cache.o clk.o dma.o entry.o vectors.o
|
||||
obj-$(CONFIG_M5206) += timers.o intc.o
|
||||
obj-$(CONFIG_M5206e) += timers.o intc.o
|
||||
obj-$(CONFIG_M520x) += pit.o intc-simr.o
|
||||
obj-$(CONFIG_M523x) += pit.o dma_timer.o intc-2.o
|
||||
obj-$(CONFIG_M5249) += timers.o intc.o
|
||||
obj-$(CONFIG_M527x) += pit.o intc-2.o
|
||||
obj-$(CONFIG_COLDFIRE) += cache.o clk.o device.o dma.o entry.o vectors.o
|
||||
obj-$(CONFIG_M5206) += timers.o intc.o reset.o
|
||||
obj-$(CONFIG_M5206e) += timers.o intc.o reset.o
|
||||
obj-$(CONFIG_M520x) += pit.o intc-simr.o reset.o
|
||||
obj-$(CONFIG_M523x) += pit.o dma_timer.o intc-2.o reset.o
|
||||
obj-$(CONFIG_M5249) += timers.o intc.o reset.o
|
||||
obj-$(CONFIG_M527x) += pit.o intc-2.o reset.o
|
||||
obj-$(CONFIG_M5272) += timers.o
|
||||
obj-$(CONFIG_M528x) += pit.o intc-2.o
|
||||
obj-$(CONFIG_M5307) += timers.o intc.o
|
||||
obj-$(CONFIG_M532x) += timers.o intc-simr.o
|
||||
obj-$(CONFIG_M5407) += timers.o intc.o
|
||||
obj-$(CONFIG_M528x) += pit.o intc-2.o reset.o
|
||||
obj-$(CONFIG_M5307) += timers.o intc.o reset.o
|
||||
obj-$(CONFIG_M532x) += timers.o intc-simr.o reset.o
|
||||
obj-$(CONFIG_M5407) += timers.o intc.o reset.o
|
||||
obj-$(CONFIG_M54xx) += sltimers.o intc-2.o
|
||||
|
||||
obj-y += pinmux.o gpio.o
|
||||
|
|
|
@ -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)
|
||||
movel %sp,_init_sp /* save initial stack pointer */
|
||||
#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
|
||||
|
|
|
@ -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.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
|
||||
|
|
|
@ -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_cnt;
|
||||
|
||||
static irq_handler_t timer_interrupt;
|
||||
|
||||
static irqreturn_t mcfslt_tick(int irq, void *dummy)
|
||||
{
|
||||
/* Reset Slice Timer 0 */
|
||||
__raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, TA(MCFSLT_SSR));
|
||||
mcfslt_cnt += mcfslt_cycles_per_jiffy;
|
||||
return arch_timer_interrupt(irq, dummy);
|
||||
return timer_interrupt(irq, dummy);
|
||||
}
|
||||
|
||||
static struct irqaction mcfslt_timer_irq = {
|
||||
|
@ -121,7 +123,7 @@ static struct clocksource mcfslt_clk = {
|
|||
.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;
|
||||
/*
|
||||
|
@ -136,6 +138,7 @@ void hw_timer_init(void)
|
|||
/* initialize mcfslt_cnt knowing that slice timers count down */
|
||||
mcfslt_cnt = mcfslt_cycles_per_jiffy;
|
||||
|
||||
timer_interrupt = handler;
|
||||
setup_irq(MCF_IRQ_TIMER, &mcfslt_timer_irq);
|
||||
|
||||
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_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)
|
||||
|
@ -55,7 +76,7 @@ static irqreturn_t mcftmr_tick(int irq, void *dummy)
|
|||
__raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
|
||||
|
||||
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));
|
||||
mcftmr_cycles_per_jiffy = FREQ / HZ;
|
||||
|
@ -110,6 +131,8 @@ void hw_timer_init(void)
|
|||
|
||||
clocksource_register_hz(&mcftmr_clk, FREQ);
|
||||
|
||||
timer_interrupt = handler;
|
||||
init_timer_irq();
|
||||
setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq);
|
||||
|
||||
#ifdef CONFIG_HIGHPROFILE
|
||||
|
|
|
@ -33,8 +33,6 @@ asmlinkage void dbginterrupt_c(struct frame *fp)
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
extern e_vector *_ramvec;
|
||||
|
||||
/* Assembler routines */
|
||||
asmlinkage void buserr(void);
|
||||
asmlinkage void trap(void);
|
||||
|
|
Loading…
Reference in New Issue