diff options
Diffstat (limited to 'arch/sparc')
115 files changed, 1572 insertions, 4483 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index a214002114e..e594559c8db 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -20,6 +20,11 @@ config GENERIC_ISA_DMA  	bool  	default y +config GENERIC_GPIO +	bool +	help +	  Generic GPIO API support +  config ARCH_NO_VIRT_TO_BUS  	def_bool y @@ -32,6 +37,8 @@ config HZ  source "init/Kconfig" +source "kernel/Kconfig.freezer" +  menu "General machine setup"  config SMP @@ -69,6 +76,9 @@ config SPARC  	select HAVE_OPROFILE  	select HAVE_ARCH_KGDB if !SMP  	select HAVE_ARCH_TRACEHOOK +	select ARCH_WANT_OPTIONAL_GPIOLIB +	select RTC_CLASS +	select RTC_DRV_M48T59  # Identify this as a Sparc32 build  config SPARC32 @@ -204,17 +214,6 @@ config SUN_PM  	  Enable power management and CPU standby features on supported  	  SPARC platforms. -config SUN4 -	bool "Support for SUN4 machines (disables SUN4[CDM] support)" -	depends on !SMP -	default n -	help -	  Say Y here if, and only if, your machine is a sun4. Note that -	  a kernel compiled with this option will run only on sun4. -	  (And the current version will probably work only on sun4/330.) - -if !SUN4 -  config PCI  	bool "Support for PCI and PS/2 keyboard/mouse"  	help @@ -227,11 +226,6 @@ config PCI_SYSCALL  source "drivers/pci/Kconfig" -endif - -config NO_DMA -	def_bool !PCI -  config SUN_OPENPROMFS  	tristate "Openprom tree appears in /proc/openprom"  	help @@ -263,9 +257,7 @@ source "net/Kconfig"  source "drivers/Kconfig" -if !SUN4  source "drivers/sbus/char/Kconfig" -endif  # This one must be before the filesystem configs. -DaveM diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index a5f0ce734ff..2d2769d766e 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -15,14 +15,11 @@ header-y += signal_32.h  header-y += signal_64.h  header-y += stat_32.h  header-y += stat_64.h -header-y += statfs_32.h -header-y += statfs_64.h  header-y += unistd_32.h  header-y += unistd_64.h  header-y += apc.h  header-y += asi.h -header-y += bpp.h  header-y += display7seg.h  header-y += envctrl.h  header-y += fbio.h @@ -41,5 +38,4 @@ header-y += reg_64.h  header-y += traps.h  header-y += uctx.h  header-y += utrap.h -header-y += vfc_ioctls.h  header-y += watchdog.h diff --git a/arch/sparc/include/asm/asmmacro.h b/arch/sparc/include/asm/asmmacro.h index a619a4d97aa..a995bf8aba3 100644 --- a/arch/sparc/include/asm/asmmacro.h +++ b/arch/sparc/include/asm/asmmacro.h @@ -34,12 +34,7 @@  /* sun4 probably wants half word accesses to ASI_SEGMAP, while sun4c+     likes byte accesses. These are to avoid ifdef mania. */ -#ifdef CONFIG_SUN4 -#define lduXa	lduha -#define stXa	stha -#else  #define lduXa	lduba  #define stXa	stba -#endif  #endif /* !(_SPARC_ASMMACRO_H) */ diff --git a/arch/sparc/include/asm/bpp.h b/arch/sparc/include/asm/bpp.h deleted file mode 100644 index 31f515e499a..00000000000 --- a/arch/sparc/include/asm/bpp.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _SPARC_BPP_H -#define _SPARC_BPP_H - -/* - * Copyright (c) 1995 Picture Elements - *	Stephen Williams - *	Gus Baldauf - * - * Linux/SPARC port by Peter Zaitcev. - * Integration into SPARC tree by Tom Dyas. - */ - -#include  <linux/ioctl.h> - -/* - * This is a driver that supports IEEE Std 1284-1994 communications - * with compliant or compatible devices. It will use whatever features - * the device supports, prefering those that are typically faster. - * - * When the device is opened, it is left in COMPATIBILITY mode, and - * writes work like any printer device. The driver only attempt to - * negotiate 1284 modes when needed so that plugs can be pulled, - * switch boxes switched, etc., without disrupting things. It will - * also leave the device in compatibility mode when closed. - */ - - - -/* - * This driver also supplies ioctls to manually manipulate the - * pins. This is great for testing devices, or writing code to deal - * with bizzarro-mode of the ACME Special TurboThingy Plus. - * - * NOTE: These ioctl currently do not interact well with - * read/write. Caveat emptor. - * - * PUT_PINS allows us to assign the sense of all the pins, including - * the data pins if being driven by the host. The GET_PINS returns the - * pins that the peripheral drives, including data if appropriate. - */ - -# define BPP_PUT_PINS _IOW('B', 1, int) -# define BPP_GET_PINS _IOR('B', 2, char) /* that's bogus - should've been _IO */ -# define BPP_PUT_DATA _IOW('B', 3, int) -# define BPP_GET_DATA _IOR('B', 4, char) /* ditto */ - -/* - * Set the data bus to input mode. Disengage the data bin driver and - * be prepared to read values from the peripheral. If the arg is 0, - * then revert the bus to output mode. - */ -# define BPP_SET_INPUT _IOW('B', 5, int) - -/* - * These bits apply to the PUT operation... - */ -# define BPP_PP_nStrobe   0x0001 -# define BPP_PP_nAutoFd   0x0002 -# define BPP_PP_nInit     0x0004 -# define BPP_PP_nSelectIn 0x0008 - -/* - * These apply to the GET operation, which also reads the current value - * of the previously put values. A bit mask of these will be returned - * as a bit mask in the return code of the ioctl(). - */ -# define BPP_GP_nAck   0x0100 -# define BPP_GP_Busy   0x0200 -# define BPP_GP_PError 0x0400 -# define BPP_GP_Select 0x0800 -# define BPP_GP_nFault 0x1000 - -#endif diff --git a/arch/sparc/include/asm/bugs.h b/arch/sparc/include/asm/bugs.h index e179bc12f64..61d86bbbe2b 100644 --- a/arch/sparc/include/asm/bugs.h +++ b/arch/sparc/include/asm/bugs.h @@ -7,10 +7,6 @@  #include <asm/cpudata.h>  #endif -#ifdef CONFIG_SPARC64 -#include <asm/sstate.h> -#endif -  extern unsigned long loops_per_jiffy;  static void __init check_bugs(void) @@ -18,7 +14,4 @@ static void __init check_bugs(void)  #if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP)  	cpu_data(0).udelay_val = loops_per_jiffy;  #endif -#ifdef CONFIG_SPARC64 -	sstate_running(); -#endif  } diff --git a/arch/sparc/include/asm/byteorder.h b/arch/sparc/include/asm/byteorder.h index bcd83aa351c..5a70f137f1f 100644 --- a/arch/sparc/include/asm/byteorder.h +++ b/arch/sparc/include/asm/byteorder.h @@ -4,15 +4,14 @@  #include <asm/types.h>  #include <asm/asi.h> -#ifdef __GNUC__ +#define __BIG_ENDIAN  #ifdef CONFIG_SPARC32  #define __SWAB_64_THRU_32__  #endif  #ifdef CONFIG_SPARC64 - -static inline __u16 ___arch__swab16p(const __u16 *addr) +static inline __u16 __arch_swab16p(const __u16 *addr)  {  	__u16 ret; @@ -21,8 +20,9 @@ static inline __u16 ___arch__swab16p(const __u16 *addr)  			      : "r" (addr), "i" (ASI_PL));  	return ret;  } +#define __arch_swab16p __arch_swab16p -static inline __u32 ___arch__swab32p(const __u32 *addr) +static inline __u32 __arch_swab32p(const __u32 *addr)  {  	__u32 ret; @@ -31,8 +31,9 @@ static inline __u32 ___arch__swab32p(const __u32 *addr)  			      : "r" (addr), "i" (ASI_PL));  	return ret;  } +#define __arch_swab32p __arch_swab32p -static inline __u64 ___arch__swab64p(const __u64 *addr) +static inline __u64 __arch_swab64p(const __u64 *addr)  {  	__u64 ret; @@ -41,17 +42,10 @@ static inline __u64 ___arch__swab64p(const __u64 *addr)  			      : "r" (addr), "i" (ASI_PL));  	return ret;  } - -#define __arch__swab16p(x) ___arch__swab16p(x) -#define __arch__swab32p(x) ___arch__swab32p(x) -#define __arch__swab64p(x) ___arch__swab64p(x) +#define __arch_swab64p __arch_swab64p  #endif /* CONFIG_SPARC64 */ -#define __BYTEORDER_HAS_U64__ - -#endif - -#include <linux/byteorder/big_endian.h> +#include <linux/byteorder.h>  #endif /* _SPARC_BYTEORDER_H */ diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h index 532975ecfe1..7da7c13d23c 100644 --- a/arch/sparc/include/asm/cpudata_64.h +++ b/arch/sparc/include/asm/cpudata_64.h @@ -86,7 +86,6 @@ extern struct trap_per_cpu trap_block[NR_CPUS];  extern void init_cur_cpu_trap(struct thread_info *);  extern void setup_tba(void);  extern int ncpus_probed; -extern void __init cpu_probe(void);  extern const struct seq_operations cpuinfo_op;  extern unsigned long real_hard_smp_processor_id(void); diff --git a/arch/sparc/include/asm/dma-mapping_32.h b/arch/sparc/include/asm/dma-mapping_32.h index f3a641e6b2c..8a57ea0573e 100644 --- a/arch/sparc/include/asm/dma-mapping_32.h +++ b/arch/sparc/include/asm/dma-mapping_32.h @@ -1,11 +1,60 @@  #ifndef _ASM_SPARC_DMA_MAPPING_H  #define _ASM_SPARC_DMA_MAPPING_H +#include <linux/types.h> -#ifdef CONFIG_PCI -#include <asm-generic/dma-mapping.h> -#else -#include <asm-generic/dma-mapping-broken.h> -#endif /* PCI */ +struct device; +struct scatterlist; +struct page; + +#define DMA_ERROR_CODE	(~(dma_addr_t)0x0) + +extern int dma_supported(struct device *dev, u64 mask); +extern int dma_set_mask(struct device *dev, u64 dma_mask); +extern void *dma_alloc_coherent(struct device *dev, size_t size, +				dma_addr_t *dma_handle, gfp_t flag); +extern void dma_free_coherent(struct device *dev, size_t size, +			      void *cpu_addr, dma_addr_t dma_handle); +extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, +				 size_t size, +				 enum dma_data_direction direction); +extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, +			     size_t size, +			     enum dma_data_direction direction); +extern dma_addr_t dma_map_page(struct device *dev, struct page *page, +			       unsigned long offset, size_t size, +			       enum dma_data_direction direction); +extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address, +			   size_t size, enum dma_data_direction direction); +extern int dma_map_sg(struct device *dev, struct scatterlist *sg, +		      int nents, enum dma_data_direction direction); +extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg, +			 int nents, enum dma_data_direction direction); +extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, +				    size_t size, +				    enum dma_data_direction direction); +extern void dma_sync_single_for_device(struct device *dev, +				       dma_addr_t dma_handle, +				       size_t size, +				       enum dma_data_direction direction); +extern void dma_sync_single_range_for_cpu(struct device *dev, +					  dma_addr_t dma_handle, +					  unsigned long offset, +					  size_t size, +					  enum dma_data_direction direction); +extern void dma_sync_single_range_for_device(struct device *dev, +					     dma_addr_t dma_handle, +					     unsigned long offset, size_t size, +					     enum dma_data_direction direction); +extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, +				int nelems, enum dma_data_direction direction); +extern void dma_sync_sg_for_device(struct device *dev, +				   struct scatterlist *sg, int nelems, +				   enum dma_data_direction direction); +extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr); +extern int dma_get_cache_alignment(void); + +#define dma_alloc_noncoherent	dma_alloc_coherent +#define dma_free_noncoherent	dma_free_coherent  #endif /* _ASM_SPARC_DMA_MAPPING_H */ diff --git a/arch/sparc/include/asm/dma.h b/arch/sparc/include/asm/dma.h index aa1d90ac04c..b554927bbaf 100644 --- a/arch/sparc/include/asm/dma.h +++ b/arch/sparc/include/asm/dma.h @@ -1,8 +1,139 @@ -#ifndef ___ASM_SPARC_DMA_H -#define ___ASM_SPARC_DMA_H -#if defined(__sparc__) && defined(__arch64__) -#include <asm/dma_64.h> +#ifndef _ASM_SPARC_DMA_H +#define _ASM_SPARC_DMA_H + +/* These are irrelevant for Sparc DMA, but we leave it in so that + * things can compile. + */ +#define MAX_DMA_CHANNELS 8 +#define DMA_MODE_READ    1 +#define DMA_MODE_WRITE   2 +#define MAX_DMA_ADDRESS  (~0UL) + +/* Useful constants */ +#define SIZE_16MB      (16*1024*1024) +#define SIZE_64K       (64*1024) + +/* SBUS DMA controller reg offsets */ +#define DMA_CSR		0x00UL		/* rw  DMA control/status register    0x00   */ +#define DMA_ADDR	0x04UL		/* rw  DMA transfer address register  0x04   */ +#define DMA_COUNT	0x08UL		/* rw  DMA transfer count register    0x08   */ +#define DMA_TEST	0x0cUL		/* rw  DMA test/debug register        0x0c   */ + +/* Fields in the cond_reg register */ +/* First, the version identification bits */ +#define DMA_DEVICE_ID    0xf0000000        /* Device identification bits */ +#define DMA_VERS0        0x00000000        /* Sunray DMA version */ +#define DMA_ESCV1        0x40000000        /* DMA ESC Version 1 */ +#define DMA_VERS1        0x80000000        /* DMA rev 1 */ +#define DMA_VERS2        0xa0000000        /* DMA rev 2 */ +#define DMA_VERHME       0xb0000000        /* DMA hme gate array */ +#define DMA_VERSPLUS     0x90000000        /* DMA rev 1 PLUS */ + +#define DMA_HNDL_INTR    0x00000001        /* An IRQ needs to be handled */ +#define DMA_HNDL_ERROR   0x00000002        /* We need to take an error */ +#define DMA_FIFO_ISDRAIN 0x0000000c        /* The DMA FIFO is draining */ +#define DMA_INT_ENAB     0x00000010        /* Turn on interrupts */ +#define DMA_FIFO_INV     0x00000020        /* Invalidate the FIFO */ +#define DMA_ACC_SZ_ERR   0x00000040        /* The access size was bad */ +#define DMA_FIFO_STDRAIN 0x00000040        /* DMA_VERS1 Drain the FIFO */ +#define DMA_RST_SCSI     0x00000080        /* Reset the SCSI controller */ +#define DMA_RST_ENET     DMA_RST_SCSI      /* Reset the ENET controller */ +#define DMA_ST_WRITE     0x00000100        /* write from device to memory */ +#define DMA_ENABLE       0x00000200        /* Fire up DMA, handle requests */ +#define DMA_PEND_READ    0x00000400        /* DMA_VERS1/0/PLUS Pending Read */ +#define DMA_ESC_BURST    0x00000800        /* 1=16byte 0=32byte */ +#define DMA_READ_AHEAD   0x00001800        /* DMA read ahead partial longword */ +#define DMA_DSBL_RD_DRN  0x00001000        /* No EC drain on slave reads */ +#define DMA_BCNT_ENAB    0x00002000        /* If on, use the byte counter */ +#define DMA_TERM_CNTR    0x00004000        /* Terminal counter */ +#define DMA_SCSI_SBUS64  0x00008000        /* HME: Enable 64-bit SBUS mode. */ +#define DMA_CSR_DISAB    0x00010000        /* No FIFO drains during csr */ +#define DMA_SCSI_DISAB   0x00020000        /* No FIFO drains during reg */ +#define DMA_DSBL_WR_INV  0x00020000        /* No EC inval. on slave writes */ +#define DMA_ADD_ENABLE   0x00040000        /* Special ESC DVMA optimization */ +#define DMA_E_BURSTS	 0x000c0000	   /* ENET: SBUS r/w burst mask */ +#define DMA_E_BURST32	 0x00040000	   /* ENET: SBUS 32 byte r/w burst */ +#define DMA_E_BURST16	 0x00000000	   /* ENET: SBUS 16 byte r/w burst */ +#define DMA_BRST_SZ      0x000c0000        /* SCSI: SBUS r/w burst size */ +#define DMA_BRST64       0x000c0000        /* SCSI: 64byte bursts (HME on UltraSparc only) */ +#define DMA_BRST32       0x00040000        /* SCSI: 32byte bursts */ +#define DMA_BRST16       0x00000000        /* SCSI: 16byte bursts */ +#define DMA_BRST0        0x00080000        /* SCSI: no bursts (non-HME gate arrays) */ +#define DMA_ADDR_DISAB   0x00100000        /* No FIFO drains during addr */ +#define DMA_2CLKS        0x00200000        /* Each transfer = 2 clock ticks */ +#define DMA_3CLKS        0x00400000        /* Each transfer = 3 clock ticks */ +#define DMA_EN_ENETAUI   DMA_3CLKS         /* Put lance into AUI-cable mode */ +#define DMA_CNTR_DISAB   0x00800000        /* No IRQ when DMA_TERM_CNTR set */ +#define DMA_AUTO_NADDR   0x01000000        /* Use "auto nxt addr" feature */ +#define DMA_SCSI_ON      0x02000000        /* Enable SCSI dma */ +#define DMA_PARITY_OFF   0x02000000        /* HME: disable parity checking */ +#define DMA_LOADED_ADDR  0x04000000        /* Address has been loaded */ +#define DMA_LOADED_NADDR 0x08000000        /* Next address has been loaded */ +#define DMA_RESET_FAS366 0x08000000        /* HME: Assert RESET to FAS366 */ + +/* Values describing the burst-size property from the PROM */ +#define DMA_BURST1       0x01 +#define DMA_BURST2       0x02 +#define DMA_BURST4       0x04 +#define DMA_BURST8       0x08 +#define DMA_BURST16      0x10 +#define DMA_BURST32      0x20 +#define DMA_BURST64      0x40 +#define DMA_BURSTBITS    0x7f + +/* From PCI */ + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy;  #else -#include <asm/dma_32.h> +#define isa_dma_bridge_buggy 	(0)  #endif + +#ifdef CONFIG_SPARC32 + +/* Routines for data transfer buffers. */ +BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long) +BTFIXUPDEF_CALL(void,   mmu_unlockarea, char *, unsigned long) + +#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len) +#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len) + +struct page; +struct device; +struct scatterlist; + +/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */ +BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, struct device *, char *, unsigned long) +BTFIXUPDEF_CALL(void,  mmu_get_scsi_sgl, struct device *, struct scatterlist *, int) +BTFIXUPDEF_CALL(void,  mmu_release_scsi_one, struct device *, __u32, unsigned long) +BTFIXUPDEF_CALL(void,  mmu_release_scsi_sgl, struct device *, struct scatterlist *, int) + +#define mmu_get_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_get_scsi_one)(dev,vaddr,len) +#define mmu_get_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_get_scsi_sgl)(dev,sg,sz) +#define mmu_release_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_release_scsi_one)(dev,vaddr,len) +#define mmu_release_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_release_scsi_sgl)(dev,sg,sz) + +/* + * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep. + * + * The mmu_map_dma_area establishes two mappings in one go. + * These mappings point to pages normally mapped at 'va' (linear address). + * First mapping is for CPU visible address at 'a', uncached. + * This is an alias, but it works because it is an uncached mapping. + * Second mapping is for device visible address, or "bus" address. + * The bus address is returned at '*pba'. + * + * These functions seem distinct, but are hard to split. On sun4c, + * at least for now, 'a' is equal to bus address, and retured in *pba. + * On sun4m, page attributes depend on the CPU type, so we have to + * know if we are mapping RAM or I/O, so it has to be an additional argument + * to a separate mapping function for CPU visible mappings. + */ +BTFIXUPDEF_CALL(int, mmu_map_dma_area, struct device *, dma_addr_t *, unsigned long, unsigned long, int len) +BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, struct device *, unsigned long busa, int len) + +#define mmu_map_dma_area(dev,pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(dev,pba,va,a,len) +#define mmu_unmap_dma_area(dev,ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(dev,ba,len)  #endif + +#endif /* !(_ASM_SPARC_DMA_H) */ diff --git a/arch/sparc/include/asm/dma_32.h b/arch/sparc/include/asm/dma_32.h deleted file mode 100644 index cf7189c0079..00000000000 --- a/arch/sparc/include/asm/dma_32.h +++ /dev/null @@ -1,288 +0,0 @@ -/* include/asm/dma.h - * - * Copyright 1995 (C) David S. Miller (davem@davemloft.net) - */ - -#ifndef _ASM_SPARC_DMA_H -#define _ASM_SPARC_DMA_H - -#include <linux/kernel.h> -#include <linux/types.h> - -#include <asm/vac-ops.h>  /* for invalidate's, etc. */ -#include <asm/sbus.h> -#include <asm/delay.h> -#include <asm/oplib.h> -#include <asm/system.h> -#include <asm/io.h> -#include <linux/spinlock.h> - -struct page; -extern spinlock_t  dma_spin_lock; - -static inline unsigned long claim_dma_lock(void) -{ -	unsigned long flags; -	spin_lock_irqsave(&dma_spin_lock, flags); -	return flags; -} - -static inline void release_dma_lock(unsigned long flags) -{ -	spin_unlock_irqrestore(&dma_spin_lock, flags); -} - -/* These are irrelevant for Sparc DMA, but we leave it in so that - * things can compile. - */ -#define MAX_DMA_CHANNELS 8 -#define MAX_DMA_ADDRESS  (~0UL) -#define DMA_MODE_READ    1 -#define DMA_MODE_WRITE   2 - -/* Useful constants */ -#define SIZE_16MB      (16*1024*1024) -#define SIZE_64K       (64*1024) - -/* SBUS DMA controller reg offsets */ -#define DMA_CSR		0x00UL		/* rw  DMA control/status register    0x00   */ -#define DMA_ADDR	0x04UL		/* rw  DMA transfer address register  0x04   */ -#define DMA_COUNT	0x08UL		/* rw  DMA transfer count register    0x08   */ -#define DMA_TEST	0x0cUL		/* rw  DMA test/debug register        0x0c   */ - -/* DVMA chip revisions */ -enum dvma_rev { -	dvmarev0, -	dvmaesc1, -	dvmarev1, -	dvmarev2, -	dvmarev3, -	dvmarevplus, -	dvmahme -}; - -#define DMA_HASCOUNT(rev)  ((rev)==dvmaesc1) - -/* Linux DMA information structure, filled during probe. */ -struct sbus_dma { -	struct sbus_dma *next; -	struct sbus_dev *sdev; -	void __iomem *regs; - -	/* Status, misc info */ -	int node;                /* Prom node for this DMA device */ -	int running;             /* Are we doing DMA now? */ -	int allocated;           /* Are we "owned" by anyone yet? */ - -	/* Transfer information. */ -	unsigned long addr;      /* Start address of current transfer */ -	int nbytes;              /* Size of current transfer */ -	int realbytes;           /* For splitting up large transfers, etc. */ - -	/* DMA revision */ -	enum dvma_rev revision; -}; - -extern struct sbus_dma *dma_chain; - -/* Broken hardware... */ -#ifdef CONFIG_SUN4 -/* Have to sort this out. Does rev0 work fine on sun4[cmd] without isbroken? - * Or is rev0 present only on sun4 boxes? -jj */ -#define DMA_ISBROKEN(dma)    ((dma)->revision == dvmarev0 || (dma)->revision == dvmarev1) -#else -#define DMA_ISBROKEN(dma)    ((dma)->revision == dvmarev1) -#endif -#define DMA_ISESC1(dma)      ((dma)->revision == dvmaesc1) - -/* Main routines in dma.c */ -extern void dvma_init(struct sbus_bus *); - -/* Fields in the cond_reg register */ -/* First, the version identification bits */ -#define DMA_DEVICE_ID    0xf0000000        /* Device identification bits */ -#define DMA_VERS0        0x00000000        /* Sunray DMA version */ -#define DMA_ESCV1        0x40000000        /* DMA ESC Version 1 */ -#define DMA_VERS1        0x80000000        /* DMA rev 1 */ -#define DMA_VERS2        0xa0000000        /* DMA rev 2 */ -#define DMA_VERHME       0xb0000000        /* DMA hme gate array */ -#define DMA_VERSPLUS     0x90000000        /* DMA rev 1 PLUS */ - -#define DMA_HNDL_INTR    0x00000001        /* An IRQ needs to be handled */ -#define DMA_HNDL_ERROR   0x00000002        /* We need to take an error */ -#define DMA_FIFO_ISDRAIN 0x0000000c        /* The DMA FIFO is draining */ -#define DMA_INT_ENAB     0x00000010        /* Turn on interrupts */ -#define DMA_FIFO_INV     0x00000020        /* Invalidate the FIFO */ -#define DMA_ACC_SZ_ERR   0x00000040        /* The access size was bad */ -#define DMA_FIFO_STDRAIN 0x00000040        /* DMA_VERS1 Drain the FIFO */ -#define DMA_RST_SCSI     0x00000080        /* Reset the SCSI controller */ -#define DMA_RST_ENET     DMA_RST_SCSI      /* Reset the ENET controller */ -#define DMA_RST_BPP      DMA_RST_SCSI      /* Reset the BPP controller */ -#define DMA_ST_WRITE     0x00000100        /* write from device to memory */ -#define DMA_ENABLE       0x00000200        /* Fire up DMA, handle requests */ -#define DMA_PEND_READ    0x00000400        /* DMA_VERS1/0/PLUS Pending Read */ -#define DMA_ESC_BURST    0x00000800        /* 1=16byte 0=32byte */ -#define DMA_READ_AHEAD   0x00001800        /* DMA read ahead partial longword */ -#define DMA_DSBL_RD_DRN  0x00001000        /* No EC drain on slave reads */ -#define DMA_BCNT_ENAB    0x00002000        /* If on, use the byte counter */ -#define DMA_TERM_CNTR    0x00004000        /* Terminal counter */ -#define DMA_SCSI_SBUS64  0x00008000        /* HME: Enable 64-bit SBUS mode. */ -#define DMA_CSR_DISAB    0x00010000        /* No FIFO drains during csr */ -#define DMA_SCSI_DISAB   0x00020000        /* No FIFO drains during reg */ -#define DMA_DSBL_WR_INV  0x00020000        /* No EC inval. on slave writes */ -#define DMA_ADD_ENABLE   0x00040000        /* Special ESC DVMA optimization */ -#define DMA_E_BURSTS	 0x000c0000	   /* ENET: SBUS r/w burst mask */ -#define DMA_E_BURST32	 0x00040000	   /* ENET: SBUS 32 byte r/w burst */ -#define DMA_E_BURST16	 0x00000000	   /* ENET: SBUS 16 byte r/w burst */ -#define DMA_BRST_SZ      0x000c0000        /* SCSI: SBUS r/w burst size */ -#define DMA_BRST64       0x00080000        /* SCSI: 64byte bursts (HME on UltraSparc only) */ -#define DMA_BRST32       0x00040000        /* SCSI/BPP: 32byte bursts */ -#define DMA_BRST16       0x00000000        /* SCSI/BPP: 16byte bursts */ -#define DMA_BRST0        0x00080000        /* SCSI: no bursts (non-HME gate arrays) */ -#define DMA_ADDR_DISAB   0x00100000        /* No FIFO drains during addr */ -#define DMA_2CLKS        0x00200000        /* Each transfer = 2 clock ticks */ -#define DMA_3CLKS        0x00400000        /* Each transfer = 3 clock ticks */ -#define DMA_EN_ENETAUI   DMA_3CLKS         /* Put lance into AUI-cable mode */ -#define DMA_CNTR_DISAB   0x00800000        /* No IRQ when DMA_TERM_CNTR set */ -#define DMA_AUTO_NADDR   0x01000000        /* Use "auto nxt addr" feature */ -#define DMA_SCSI_ON      0x02000000        /* Enable SCSI dma */ -#define DMA_BPP_ON       DMA_SCSI_ON       /* Enable BPP dma */ -#define DMA_PARITY_OFF   0x02000000        /* HME: disable parity checking */ -#define DMA_LOADED_ADDR  0x04000000        /* Address has been loaded */ -#define DMA_LOADED_NADDR 0x08000000        /* Next address has been loaded */ -#define DMA_RESET_FAS366 0x08000000        /* HME: Assert RESET to FAS366 */ - -/* Values describing the burst-size property from the PROM */ -#define DMA_BURST1       0x01 -#define DMA_BURST2       0x02 -#define DMA_BURST4       0x04 -#define DMA_BURST8       0x08 -#define DMA_BURST16      0x10 -#define DMA_BURST32      0x20 -#define DMA_BURST64      0x40 -#define DMA_BURSTBITS    0x7f - -/* Determine highest possible final transfer address given a base */ -#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL)) - -/* Yes, I hack a lot of elisp in my spare time... */ -#define DMA_ERROR_P(regs)  ((((regs)->cond_reg) & DMA_HNDL_ERROR)) -#define DMA_IRQ_P(regs)    ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))) -#define DMA_WRITE_P(regs)  ((((regs)->cond_reg) & DMA_ST_WRITE)) -#define DMA_OFF(regs)      ((((regs)->cond_reg) &= (~DMA_ENABLE))) -#define DMA_INTSOFF(regs)  ((((regs)->cond_reg) &= (~DMA_INT_ENAB))) -#define DMA_INTSON(regs)   ((((regs)->cond_reg) |= (DMA_INT_ENAB))) -#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV)) -#define DMA_SETSTART(regs, addr)  ((((regs)->st_addr) = (char *) addr)) -#define DMA_BEGINDMA_W(regs) \ -        ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB)))) -#define DMA_BEGINDMA_R(regs) \ -        ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE))))) - -/* For certain DMA chips, we need to disable ints upon irq entry - * and turn them back on when we are done.  So in any ESP interrupt - * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT - * when leaving the handler.  You have been warned... - */ -#define DMA_IRQ_ENTRY(dma, dregs) do { \ -        if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \ -   } while (0) - -#define DMA_IRQ_EXIT(dma, dregs) do { \ -	if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \ -   } while(0) - -#if 0	/* P3 this stuff is inline in ledma.c:init_restart_ledma() */ -/* Pause until counter runs out or BIT isn't set in the DMA condition - * register. - */ -static inline void sparc_dma_pause(struct sparc_dma_registers *regs, -				       unsigned long bit) -{ -	int ctr = 50000;   /* Let's find some bugs ;) */ - -	/* Busy wait until the bit is not set any more */ -	while((regs->cond_reg&bit) && (ctr>0)) { -		ctr--; -		__delay(5); -	} - -	/* Check for bogus outcome. */ -	if(!ctr) -		panic("DMA timeout"); -} - -/* Reset the friggin' thing... */ -#define DMA_RESET(dma) do { \ -	struct sparc_dma_registers *regs = dma->regs;                      \ -	/* Let the current FIFO drain itself */                            \ -	sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN));                         \ -	/* Reset the logic */                                              \ -	regs->cond_reg |= (DMA_RST_SCSI);     /* assert */                 \ -	__delay(400);                         /* let the bits set ;) */    \ -	regs->cond_reg &= ~(DMA_RST_SCSI);    /* de-assert */              \ -	sparc_dma_enable_interrupts(regs);    /* Re-enable interrupts */   \ -	/* Enable FAST transfers if available */                           \ -	if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS;            \ -	dma->running = 0;                                                  \ -} while(0) -#endif - -#define for_each_dvma(dma) \ -        for((dma) = dma_chain; (dma); (dma) = (dma)->next) - -extern int get_dma_list(char *); -extern int request_dma(unsigned int, __const__ char *); -extern void free_dma(unsigned int); - -/* From PCI */ - -#ifdef CONFIG_PCI -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy	(0) -#endif - -/* Routines for data transfer buffers. */ -BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long) -BTFIXUPDEF_CALL(void,   mmu_unlockarea, char *, unsigned long) - -#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len) -#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len) - -/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */ -BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, char *, unsigned long, struct sbus_bus *sbus) -BTFIXUPDEF_CALL(void,  mmu_get_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus) -BTFIXUPDEF_CALL(void,  mmu_release_scsi_one, __u32, unsigned long, struct sbus_bus *sbus) -BTFIXUPDEF_CALL(void,  mmu_release_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus) - -#define mmu_get_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_get_scsi_one)(vaddr,len,sbus) -#define mmu_get_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_get_scsi_sgl)(sg,sz,sbus) -#define mmu_release_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_release_scsi_one)(vaddr,len,sbus) -#define mmu_release_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_release_scsi_sgl)(sg,sz,sbus) - -/* - * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep. - * - * The mmu_map_dma_area establishes two mappings in one go. - * These mappings point to pages normally mapped at 'va' (linear address). - * First mapping is for CPU visible address at 'a', uncached. - * This is an alias, but it works because it is an uncached mapping. - * Second mapping is for device visible address, or "bus" address. - * The bus address is returned at '*pba'. - * - * These functions seem distinct, but are hard to split. On sun4c, - * at least for now, 'a' is equal to bus address, and retured in *pba. - * On sun4m, page attributes depend on the CPU type, so we have to - * know if we are mapping RAM or I/O, so it has to be an additional argument - * to a separate mapping function for CPU visible mappings. - */ -BTFIXUPDEF_CALL(int,  mmu_map_dma_area, dma_addr_t *, unsigned long, unsigned long, int len) -BTFIXUPDEF_CALL(struct page *, mmu_translate_dvma, unsigned long busa) -BTFIXUPDEF_CALL(void,  mmu_unmap_dma_area, unsigned long busa, int len) - -#define mmu_map_dma_area(pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(pba,va,a,len) -#define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len) -#define mmu_translate_dvma(ba)     BTFIXUP_CALL(mmu_translate_dvma)(ba) - -#endif /* !(_ASM_SPARC_DMA_H) */ diff --git a/arch/sparc/include/asm/dma_64.h b/arch/sparc/include/asm/dma_64.h deleted file mode 100644 index 46a8aecffc0..00000000000 --- a/arch/sparc/include/asm/dma_64.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * include/asm/dma.h - * - * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef _ASM_SPARC64_DMA_H -#define _ASM_SPARC64_DMA_H - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/spinlock.h> - -#include <asm/sbus.h> -#include <asm/delay.h> -#include <asm/oplib.h> - -/* These are irrelevant for Sparc DMA, but we leave it in so that - * things can compile. - */ -#define MAX_DMA_CHANNELS 8 -#define DMA_MODE_READ    1 -#define DMA_MODE_WRITE   2 -#define MAX_DMA_ADDRESS  (~0UL) - -/* Useful constants */ -#define SIZE_16MB      (16*1024*1024) -#define SIZE_64K       (64*1024) - -/* SBUS DMA controller reg offsets */ -#define DMA_CSR		0x00UL		/* rw  DMA control/status register    0x00   */ -#define DMA_ADDR	0x04UL		/* rw  DMA transfer address register  0x04   */ -#define DMA_COUNT	0x08UL		/* rw  DMA transfer count register    0x08   */ -#define DMA_TEST	0x0cUL		/* rw  DMA test/debug register        0x0c   */ - -/* DVMA chip revisions */ -enum dvma_rev { -	dvmarev0, -	dvmaesc1, -	dvmarev1, -	dvmarev2, -	dvmarev3, -	dvmarevplus, -	dvmahme -}; - -#define DMA_HASCOUNT(rev)  ((rev)==dvmaesc1) - -/* Linux DMA information structure, filled during probe. */ -struct sbus_dma { -	struct sbus_dma *next; -	struct sbus_dev *sdev; -	void __iomem *regs; - -	/* Status, misc info */ -	int node;                /* Prom node for this DMA device */ -	int running;             /* Are we doing DMA now? */ -	int allocated;           /* Are we "owned" by anyone yet? */ - -	/* Transfer information. */ -	u32 addr;                /* Start address of current transfer */ -	int nbytes;              /* Size of current transfer */ -	int realbytes;           /* For splitting up large transfers, etc. */ - -	/* DMA revision */ -	enum dvma_rev revision; -}; - -extern struct sbus_dma *dma_chain; - -/* Broken hardware... */ -#define DMA_ISBROKEN(dma)    ((dma)->revision == dvmarev1) -#define DMA_ISESC1(dma)      ((dma)->revision == dvmaesc1) - -/* Main routines in dma.c */ -extern void dvma_init(struct sbus_bus *); - -/* Fields in the cond_reg register */ -/* First, the version identification bits */ -#define DMA_DEVICE_ID    0xf0000000        /* Device identification bits */ -#define DMA_VERS0        0x00000000        /* Sunray DMA version */ -#define DMA_ESCV1        0x40000000        /* DMA ESC Version 1 */ -#define DMA_VERS1        0x80000000        /* DMA rev 1 */ -#define DMA_VERS2        0xa0000000        /* DMA rev 2 */ -#define DMA_VERHME       0xb0000000        /* DMA hme gate array */ -#define DMA_VERSPLUS     0x90000000        /* DMA rev 1 PLUS */ - -#define DMA_HNDL_INTR    0x00000001        /* An IRQ needs to be handled */ -#define DMA_HNDL_ERROR   0x00000002        /* We need to take an error */ -#define DMA_FIFO_ISDRAIN 0x0000000c        /* The DMA FIFO is draining */ -#define DMA_INT_ENAB     0x00000010        /* Turn on interrupts */ -#define DMA_FIFO_INV     0x00000020        /* Invalidate the FIFO */ -#define DMA_ACC_SZ_ERR   0x00000040        /* The access size was bad */ -#define DMA_FIFO_STDRAIN 0x00000040        /* DMA_VERS1 Drain the FIFO */ -#define DMA_RST_SCSI     0x00000080        /* Reset the SCSI controller */ -#define DMA_RST_ENET     DMA_RST_SCSI      /* Reset the ENET controller */ -#define DMA_ST_WRITE     0x00000100        /* write from device to memory */ -#define DMA_ENABLE       0x00000200        /* Fire up DMA, handle requests */ -#define DMA_PEND_READ    0x00000400        /* DMA_VERS1/0/PLUS Pending Read */ -#define DMA_ESC_BURST    0x00000800        /* 1=16byte 0=32byte */ -#define DMA_READ_AHEAD   0x00001800        /* DMA read ahead partial longword */ -#define DMA_DSBL_RD_DRN  0x00001000        /* No EC drain on slave reads */ -#define DMA_BCNT_ENAB    0x00002000        /* If on, use the byte counter */ -#define DMA_TERM_CNTR    0x00004000        /* Terminal counter */ -#define DMA_SCSI_SBUS64  0x00008000        /* HME: Enable 64-bit SBUS mode. */ -#define DMA_CSR_DISAB    0x00010000        /* No FIFO drains during csr */ -#define DMA_SCSI_DISAB   0x00020000        /* No FIFO drains during reg */ -#define DMA_DSBL_WR_INV  0x00020000        /* No EC inval. on slave writes */ -#define DMA_ADD_ENABLE   0x00040000        /* Special ESC DVMA optimization */ -#define DMA_E_BURSTS	 0x000c0000	   /* ENET: SBUS r/w burst mask */ -#define DMA_E_BURST32	 0x00040000	   /* ENET: SBUS 32 byte r/w burst */ -#define DMA_E_BURST16	 0x00000000	   /* ENET: SBUS 16 byte r/w burst */ -#define DMA_BRST_SZ      0x000c0000        /* SCSI: SBUS r/w burst size */ -#define DMA_BRST64       0x000c0000        /* SCSI: 64byte bursts (HME on UltraSparc only) */ -#define DMA_BRST32       0x00040000        /* SCSI: 32byte bursts */ -#define DMA_BRST16       0x00000000        /* SCSI: 16byte bursts */ -#define DMA_BRST0        0x00080000        /* SCSI: no bursts (non-HME gate arrays) */ -#define DMA_ADDR_DISAB   0x00100000        /* No FIFO drains during addr */ -#define DMA_2CLKS        0x00200000        /* Each transfer = 2 clock ticks */ -#define DMA_3CLKS        0x00400000        /* Each transfer = 3 clock ticks */ -#define DMA_EN_ENETAUI   DMA_3CLKS         /* Put lance into AUI-cable mode */ -#define DMA_CNTR_DISAB   0x00800000        /* No IRQ when DMA_TERM_CNTR set */ -#define DMA_AUTO_NADDR   0x01000000        /* Use "auto nxt addr" feature */ -#define DMA_SCSI_ON      0x02000000        /* Enable SCSI dma */ -#define DMA_PARITY_OFF   0x02000000        /* HME: disable parity checking */ -#define DMA_LOADED_ADDR  0x04000000        /* Address has been loaded */ -#define DMA_LOADED_NADDR 0x08000000        /* Next address has been loaded */ -#define DMA_RESET_FAS366 0x08000000        /* HME: Assert RESET to FAS366 */ - -/* Values describing the burst-size property from the PROM */ -#define DMA_BURST1       0x01 -#define DMA_BURST2       0x02 -#define DMA_BURST4       0x04 -#define DMA_BURST8       0x08 -#define DMA_BURST16      0x10 -#define DMA_BURST32      0x20 -#define DMA_BURST64      0x40 -#define DMA_BURSTBITS    0x7f - -/* Determine highest possible final transfer address given a base */ -#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL)) - -/* Yes, I hack a lot of elisp in my spare time... */ -#define DMA_ERROR_P(regs)  ((sbus_readl((regs) + DMA_CSR) & DMA_HNDL_ERROR)) -#define DMA_IRQ_P(regs)    ((sbus_readl((regs) + DMA_CSR)) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)) -#define DMA_WRITE_P(regs)  ((sbus_readl((regs) + DMA_CSR) & DMA_ST_WRITE)) -#define DMA_OFF(__regs)		\ -do {	u32 tmp = sbus_readl((__regs) + DMA_CSR); \ -	tmp &= ~DMA_ENABLE; \ -	sbus_writel(tmp, (__regs) + DMA_CSR); \ -} while(0) -#define DMA_INTSOFF(__regs)	\ -do {	u32 tmp = sbus_readl((__regs) + DMA_CSR); \ -	tmp &= ~DMA_INT_ENAB; \ -	sbus_writel(tmp, (__regs) + DMA_CSR); \ -} while(0) -#define DMA_INTSON(__regs)	\ -do {	u32 tmp = sbus_readl((__regs) + DMA_CSR); \ -	tmp |= DMA_INT_ENAB; \ -	sbus_writel(tmp, (__regs) + DMA_CSR); \ -} while(0) -#define DMA_PUNTFIFO(__regs)	\ -do {	u32 tmp = sbus_readl((__regs) + DMA_CSR); \ -	tmp |= DMA_FIFO_INV; \ -	sbus_writel(tmp, (__regs) + DMA_CSR); \ -} while(0) -#define DMA_SETSTART(__regs, __addr)	\ -	sbus_writel((u32)(__addr), (__regs) + DMA_ADDR); -#define DMA_BEGINDMA_W(__regs)	\ -do {	u32 tmp = sbus_readl((__regs) + DMA_CSR); \ -	tmp |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB); \ -	sbus_writel(tmp, (__regs) + DMA_CSR); \ -} while(0) -#define DMA_BEGINDMA_R(__regs)	\ -do {	u32 tmp = sbus_readl((__regs) + DMA_CSR); \ -	tmp |= (DMA_ENABLE|DMA_INT_ENAB); \ -	tmp &= ~DMA_ST_WRITE; \ -	sbus_writel(tmp, (__regs) + DMA_CSR); \ -} while(0) - -/* For certain DMA chips, we need to disable ints upon irq entry - * and turn them back on when we are done.  So in any ESP interrupt - * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT - * when leaving the handler.  You have been warned... - */ -#define DMA_IRQ_ENTRY(dma, dregs) do { \ -        if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \ -   } while (0) - -#define DMA_IRQ_EXIT(dma, dregs) do { \ -	if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \ -   } while(0) - -#define for_each_dvma(dma) \ -        for((dma) = dma_chain; (dma); (dma) = (dma)->next) - -/* From PCI */ - -#ifdef CONFIG_PCI -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy 	(0) -#endif - -#endif /* !(_ASM_SPARC64_DMA_H) */ diff --git a/arch/sparc/include/asm/ebus.h b/arch/sparc/include/asm/ebus.h deleted file mode 100644 index 83a6d16c22e..00000000000 --- a/arch/sparc/include/asm/ebus.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef ___ASM_SPARC_EBUS_H -#define ___ASM_SPARC_EBUS_H -#if defined(__sparc__) && defined(__arch64__) -#include <asm/ebus_64.h> -#else -#include <asm/ebus_32.h> -#endif -#endif diff --git a/arch/sparc/include/asm/ebus_32.h b/arch/sparc/include/asm/ebus_32.h deleted file mode 100644 index f91f0b267ce..00000000000 --- a/arch/sparc/include/asm/ebus_32.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * ebus.h: PCI to Ebus pseudo driver software state. - * - * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) - * - * Adopted for sparc by V. Roganov and G. Raiko. - */ - -#ifndef __SPARC_EBUS_H -#define __SPARC_EBUS_H - -#ifndef _LINUX_IOPORT_H -#include <linux/ioport.h> -#endif -#include <linux/of_device.h> -#include <asm/oplib.h> -#include <asm/prom.h> - -struct linux_ebus_child { -	struct linux_ebus_child		*next; -	struct linux_ebus_device	*parent; -	struct linux_ebus		*bus; -	struct device_node		*prom_node; -	struct resource			 resource[PROMREG_MAX]; -	int				 num_addrs; -	unsigned int			 irqs[PROMINTR_MAX]; -	int				 num_irqs; -}; - -struct linux_ebus_device { -	struct of_device		ofdev; -	struct linux_ebus_device	*next; -	struct linux_ebus_child		*children; -	struct linux_ebus		*bus; -	struct device_node		*prom_node; -	struct resource			 resource[PROMREG_MAX]; -	int				 num_addrs; -	unsigned int			 irqs[PROMINTR_MAX]; -	int				 num_irqs; -}; -#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev) - -struct linux_ebus { -	struct of_device		ofdev; -	struct linux_ebus		*next; -	struct linux_ebus_device	*devices; -	struct linux_pbm_info		*parent; -	struct pci_dev			*self; -	struct device_node		*prom_node; -}; -#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev) - -struct linux_ebus_dma { -	unsigned int dcsr; -	unsigned int dacr; -	unsigned int dbcr; -}; - -#define EBUS_DCSR_INT_PEND	0x00000001 -#define EBUS_DCSR_ERR_PEND	0x00000002 -#define EBUS_DCSR_DRAIN		0x00000004 -#define EBUS_DCSR_INT_EN	0x00000010 -#define EBUS_DCSR_RESET		0x00000080 -#define EBUS_DCSR_WRITE		0x00000100 -#define EBUS_DCSR_EN_DMA	0x00000200 -#define EBUS_DCSR_CYC_PEND	0x00000400 -#define EBUS_DCSR_DIAG_RD_DONE	0x00000800 -#define EBUS_DCSR_DIAG_WR_DONE	0x00001000 -#define EBUS_DCSR_EN_CNT	0x00002000 -#define EBUS_DCSR_TC		0x00004000 -#define EBUS_DCSR_DIS_CSR_DRN	0x00010000 -#define EBUS_DCSR_BURST_SZ_MASK	0x000c0000 -#define EBUS_DCSR_BURST_SZ_1	0x00080000 -#define EBUS_DCSR_BURST_SZ_4	0x00000000 -#define EBUS_DCSR_BURST_SZ_8	0x00040000 -#define EBUS_DCSR_BURST_SZ_16	0x000c0000 -#define EBUS_DCSR_DIAG_EN	0x00100000 -#define EBUS_DCSR_DIS_ERR_PEND	0x00400000 -#define EBUS_DCSR_TCI_DIS	0x00800000 -#define EBUS_DCSR_EN_NEXT	0x01000000 -#define EBUS_DCSR_DMA_ON	0x02000000 -#define EBUS_DCSR_A_LOADED	0x04000000 -#define EBUS_DCSR_NA_LOADED	0x08000000 -#define EBUS_DCSR_DEV_ID_MASK	0xf0000000 - -extern struct linux_ebus		*ebus_chain; - -extern void ebus_init(void); - -#define for_each_ebus(bus)						\ -        for((bus) = ebus_chain; (bus); (bus) = (bus)->next) - -#define for_each_ebusdev(dev, bus)					\ -        for((dev) = (bus)->devices; (dev); (dev) = (dev)->next) - -#define for_each_edevchild(dev, child)					\ -        for((child) = (dev)->children; (child); (child) = (child)->next) - -#endif /* !(__SPARC_EBUS_H) */ diff --git a/arch/sparc/include/asm/ebus_64.h b/arch/sparc/include/asm/ebus_64.h deleted file mode 100644 index 14c6a111f60..00000000000 --- a/arch/sparc/include/asm/ebus_64.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * ebus.h: PCI to Ebus pseudo driver software state. - * - * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) - * Copyright (C) 1999 David S. Miller (davem@redhat.com) - */ - -#ifndef __SPARC64_EBUS_H -#define __SPARC64_EBUS_H - -#include <linux/of_device.h> - -#include <asm/oplib.h> -#include <asm/prom.h> - -struct linux_ebus_child { -	struct linux_ebus_child		*next; -	struct linux_ebus_device	*parent; -	struct linux_ebus		*bus; -	struct device_node		*prom_node; -	struct resource			 resource[PROMREG_MAX]; -	int				 num_addrs; -	unsigned int			 irqs[PROMINTR_MAX]; -	int				 num_irqs; -}; - -struct linux_ebus_device { -	struct of_device		ofdev; -	struct linux_ebus_device	*next; -	struct linux_ebus_child		*children; -	struct linux_ebus		*bus; -	struct device_node		*prom_node; -	struct resource			 resource[PROMREG_MAX]; -	int				 num_addrs; -	unsigned int			 irqs[PROMINTR_MAX]; -	int				 num_irqs; -}; -#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev) - -struct linux_ebus { -	struct of_device		ofdev; -	struct linux_ebus		*next; -	struct linux_ebus_device	*devices; -	struct pci_dev			*self; -	int				 index; -	int				 is_rio; -	struct device_node		*prom_node; -}; -#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev) - -struct ebus_dma_info { -	spinlock_t	lock; -	void __iomem	*regs; - -	unsigned int	flags; -#define EBUS_DMA_FLAG_USE_EBDMA_HANDLER		0x00000001 -#define EBUS_DMA_FLAG_TCI_DISABLE		0x00000002 - -	/* These are only valid is EBUS_DMA_FLAG_USE_EBDMA_HANDLER is -	 * set. -	 */ -	void (*callback)(struct ebus_dma_info *p, int event, void *cookie); -	void *client_cookie; -	unsigned int	irq; -#define EBUS_DMA_EVENT_ERROR	1 -#define EBUS_DMA_EVENT_DMA	2 -#define EBUS_DMA_EVENT_DEVICE	4 - -	unsigned char	name[64]; -}; - -extern int ebus_dma_register(struct ebus_dma_info *p); -extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on); -extern void ebus_dma_unregister(struct ebus_dma_info *p); -extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr, -			    size_t len); -extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); -extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); -extern unsigned int ebus_dma_addr(struct ebus_dma_info *p); -extern void ebus_dma_enable(struct ebus_dma_info *p, int on); - -extern struct linux_ebus		*ebus_chain; - -extern void ebus_init(void); - -#define for_each_ebus(bus)						\ -        for((bus) = ebus_chain; (bus); (bus) = (bus)->next) - -#define for_each_ebusdev(dev, bus)					\ -        for((dev) = (bus)->devices; (dev); (dev) = (dev)->next) - -#define for_each_edevchild(dev, child)					\ -        for((child) = (dev)->children; (child); (child) = (child)->next) - -#endif /* !(__SPARC64_EBUS_H) */ diff --git a/arch/sparc/include/asm/ebus_dma.h b/arch/sparc/include/asm/ebus_dma.h new file mode 100644 index 00000000000..f07a5b541c9 --- /dev/null +++ b/arch/sparc/include/asm/ebus_dma.h @@ -0,0 +1,35 @@ +#ifndef __ASM_SPARC_EBUS_DMA_H +#define __ASM_SPARC_EBUS_DMA_H + +struct ebus_dma_info { +	spinlock_t	lock; +	void __iomem	*regs; + +	unsigned int	flags; +#define EBUS_DMA_FLAG_USE_EBDMA_HANDLER		0x00000001 +#define EBUS_DMA_FLAG_TCI_DISABLE		0x00000002 + +	/* These are only valid is EBUS_DMA_FLAG_USE_EBDMA_HANDLER is +	 * set. +	 */ +	void (*callback)(struct ebus_dma_info *p, int event, void *cookie); +	void *client_cookie; +	unsigned int	irq; +#define EBUS_DMA_EVENT_ERROR	1 +#define EBUS_DMA_EVENT_DMA	2 +#define EBUS_DMA_EVENT_DEVICE	4 + +	unsigned char	name[64]; +}; + +extern int ebus_dma_register(struct ebus_dma_info *p); +extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on); +extern void ebus_dma_unregister(struct ebus_dma_info *p); +extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr, +			    size_t len); +extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); +extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); +extern unsigned int ebus_dma_addr(struct ebus_dma_info *p); +extern void ebus_dma_enable(struct ebus_dma_info *p, int on); + +#endif /* __ASM_SPARC_EBUS_DMA_H */ diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h index d043f80bc2f..381a1b5256d 100644 --- a/arch/sparc/include/asm/elf_32.h +++ b/arch/sparc/include/asm/elf_32.h @@ -105,11 +105,8 @@ typedef struct {  #define ELF_DATA	ELFDATA2MSB  #define USE_ELF_CORE_DUMP -#ifndef CONFIG_SUN4 +  #define ELF_EXEC_PAGESIZE	4096 -#else -#define ELF_EXEC_PAGESIZE	8192 -#endif  /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical @@ -126,7 +123,7 @@ typedef struct {  /* Sun4c has none of the capabilities, most sun4m's have them all.   * XXX This is gross, set some global variable at boot time. -DaveM   */ -#define ELF_HWCAP	((ARCH_SUN4C_SUN4) ? 0 : \ +#define ELF_HWCAP	((ARCH_SUN4C) ? 0 : \  			 (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \  			  HWCAP_SPARC_SWAP | \  			  ((srmmu_modtype != Cypress && \ @@ -140,6 +137,6 @@ typedef struct {  #define ELF_PLATFORM	(NULL) -#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) +#define SET_PERSONALITY(ex) set_personality(PER_LINUX)  #endif /* !(__ASMSPARC_ELF_H) */ diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h index 0818a1308f4..425c2f9be6d 100644 --- a/arch/sparc/include/asm/elf_64.h +++ b/arch/sparc/include/asm/elf_64.h @@ -195,7 +195,7 @@ static inline unsigned int sparc64_elf_hwcap(void)  #define ELF_PLATFORM	(NULL) -#define SET_PERSONALITY(ex, ibcs2)			\ +#define SET_PERSONALITY(ex)				\  do {	unsigned long new_flags = current_thread_info()->flags; \  	new_flags &= _TIF_32BIT;			\  	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)	\ @@ -208,9 +208,7 @@ do {	unsigned long new_flags = current_thread_info()->flags; \  	else						\  		clear_thread_flag(TIF_ABI_PENDING);	\  	/* flush_thread will update pgd cache */	\ -	if (ibcs2)					\ -		set_personality(PER_SVR4);		\ -	else if (current->personality != PER_LINUX32)	\ +	if (current->personality != PER_LINUX32)	\  		set_personality(PER_LINUX);		\  } while (0) diff --git a/arch/sparc/include/asm/fhc.h b/arch/sparc/include/asm/fhc.h index 788cbc46a11..57f1b303ad5 100644 --- a/arch/sparc/include/asm/fhc.h +++ b/arch/sparc/include/asm/fhc.h @@ -1,5 +1,4 @@ -/* - * fhc.h: Structures for central/fhc pseudo driver on Sunfire/Starfire/Wildfire. +/* fhc.h: FHC and Clock board register definitions.   *   * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)   */ @@ -7,14 +6,6 @@  #ifndef _SPARC64_FHC_H  #define _SPARC64_FHC_H -#include <linux/timer.h> - -#include <asm/oplib.h> -#include <asm/prom.h> -#include <asm/upa.h> - -struct linux_fhc; -  /* Clock board register offsets. */  #define CLOCK_CTRL	0x00UL	/* Main control */  #define CLOCK_STAT1	0x10UL	/* Status one */ @@ -29,21 +20,7 @@ struct linux_fhc;  #define CLOCK_CTRL_MLED		0x02	/* Mid LED, 1 == on */  #define CLOCK_CTRL_RLED		0x01	/* RIght LED, 1 == on */ -struct linux_central { -	struct linux_fhc		*child; -	unsigned long			cfreg; -	unsigned long			clkregs; -	unsigned long			clkver; -	int				slots; -	struct device_node		*prom_node; - -	struct linux_prom_ranges	central_ranges[PROMREG_MAX]; -	int				num_central_ranges; -}; -  /* Firehose controller register offsets */ -struct fhc_regs { -	unsigned long			pregs;	/* FHC internal regs */  #define FHC_PREGS_ID	0x00UL	/* FHC ID */  #define  FHC_ID_VERS		0xf0000000 /* Version of this FHC		*/  #define  FHC_ID_PARTID		0x0ffff000 /* Part ID code (0x0f9f == FHC)	*/ @@ -90,32 +67,14 @@ struct fhc_regs {  #define  FHC_JTAG_CTRL_MENAB	0x80000000 /* Indicates this is JTAG Master	 */  #define  FHC_JTAG_CTRL_MNONE	0x40000000 /* Indicates no JTAG Master present	 */  #define FHC_PREGS_JCMD	0x100UL	/* FHC JTAG Command Register */ -	unsigned long			ireg;	/* FHC IGN reg */  #define FHC_IREG_IGN	0x00UL	/* This FHC's IGN */ -	unsigned long			ffregs;	/* FHC fanfail regs */  #define FHC_FFREGS_IMAP	0x00UL	/* FHC Fanfail IMAP */  #define FHC_FFREGS_ICLR	0x10UL	/* FHC Fanfail ICLR */ -	unsigned long			sregs;	/* FHC system regs */  #define FHC_SREGS_IMAP	0x00UL	/* FHC System IMAP */  #define FHC_SREGS_ICLR	0x10UL	/* FHC System ICLR */ -	unsigned long			uregs;	/* FHC uart regs */  #define FHC_UREGS_IMAP	0x00UL	/* FHC Uart IMAP */  #define FHC_UREGS_ICLR	0x10UL	/* FHC Uart ICLR */ -	unsigned long			tregs;	/* FHC TOD regs */  #define FHC_TREGS_IMAP	0x00UL	/* FHC TOD IMAP */  #define FHC_TREGS_ICLR	0x10UL	/* FHC TOD ICLR */ -}; - -struct linux_fhc { -	struct linux_fhc		*next; -	struct linux_central		*parent;	/* NULL if not central FHC */ -	struct fhc_regs			fhc_regs; -	int				board; -	int				jtag_master; -	struct device_node		*prom_node; - -	struct linux_prom_ranges	fhc_ranges[PROMREG_MAX]; -	int				num_fhc_ranges; -};  #endif /* !(_SPARC64_FHC_H) */ diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h index ae3f00bf22f..c792830636d 100644 --- a/arch/sparc/include/asm/floppy_32.h +++ b/arch/sparc/include/asm/floppy_32.h @@ -6,6 +6,9 @@  #ifndef __ASM_SPARC_FLOPPY_H  #define __ASM_SPARC_FLOPPY_H +#include <linux/of.h> +#include <linux/of_device.h> +  #include <asm/page.h>  #include <asm/pgtable.h>  #include <asm/system.h> @@ -343,7 +346,7 @@ static int sun_floppy_init(void)  	r.flags = fd_regs[0].which_io;  	r.start = fd_regs[0].phys_addr;  	sun_fdc = (struct sun_flpy_controller *) -	    sbus_ioremap(&r, 0, fd_regs[0].reg_size, "floppy"); +	    of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");  	/* Last minute sanity check... */  	if(sun_fdc->status_82072 == 0xff) { @@ -385,4 +388,15 @@ static int sparc_eject(void)  #define EXTRA_FLOPPY_PARAMS +static DEFINE_SPINLOCK(dma_spin_lock); + +#define claim_dma_lock() \ +({	unsigned long flags; \ +	spin_lock_irqsave(&dma_spin_lock, flags); \ +	flags; \ +}) + +#define release_dma_lock(__flags) \ +	spin_unlock_irqrestore(&dma_spin_lock, __flags); +  #endif /* !(__ASM_SPARC_FLOPPY_H) */ diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index c39db1060bc..36439d67ad7 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -1,6 +1,6 @@  /* floppy.h: Sparc specific parts of the Floppy driver.   * - * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net)   * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)   *   * Ultra/PCI support added: Sep 1997  Eddie C. Dost  (ecd@skynet.be) @@ -9,18 +9,11 @@  #ifndef __ASM_SPARC64_FLOPPY_H  #define __ASM_SPARC64_FLOPPY_H -#include <linux/init.h> -#include <linux/pci.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/dma-mapping.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/idprom.h> -#include <asm/oplib.h>  #include <asm/auxio.h> -#include <asm/sbus.h> -#include <asm/irq.h> -  /*   * Define this to enable exchanging drive 0 and 1 if only drive 1 is @@ -50,7 +43,7 @@ struct sun_flpy_controller {  /* You'll only ever find one controller on an Ultra anyways. */  static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;  unsigned long fdc_status; -static struct sbus_dev *floppy_sdev = NULL; +static struct of_device *floppy_op = NULL;  struct sun_floppy_ops {  	unsigned char	(*fd_inb) (unsigned long port); @@ -291,12 +284,11 @@ static int sun_fd_eject(int drive)  	return 0;  } -#ifdef CONFIG_PCI -#include <asm/ebus.h> +#include <asm/ebus_dma.h>  #include <asm/ns87303.h>  static struct ebus_dma_info sun_pci_fd_ebus_dma; -static struct pci_dev *sun_pci_ebus_dev; +static struct device *sun_floppy_dev;  static int sun_pci_broken_drive = -1;  struct sun_pci_dma_op { @@ -377,7 +369,7 @@ static void sun_pci_fd_enable_dma(void)  	sun_pci_dma_pending.addr = -1U;  	sun_pci_dma_current.addr = -		pci_map_single(sun_pci_ebus_dev, +		dma_map_single(sun_floppy_dev,  			       sun_pci_dma_current.buf,  			       sun_pci_dma_current.len,  			       sun_pci_dma_current.direction); @@ -394,7 +386,7 @@ static void sun_pci_fd_disable_dma(void)  {  	ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);  	if (sun_pci_dma_current.addr != -1U) -		pci_unmap_single(sun_pci_ebus_dev, +		dma_unmap_single(sun_floppy_dev,  				 sun_pci_dma_current.addr,  				 sun_pci_dma_current.len,  				 sun_pci_dma_current.direction); @@ -404,9 +396,9 @@ static void sun_pci_fd_disable_dma(void)  static void sun_pci_fd_set_dma_mode(int mode)  {  	if (mode == DMA_MODE_WRITE) -		sun_pci_dma_pending.direction = PCI_DMA_TODEVICE; +		sun_pci_dma_pending.direction = DMA_TO_DEVICE;  	else -		sun_pci_dma_pending.direction = PCI_DMA_FROMDEVICE; +		sun_pci_dma_pending.direction = DMA_FROM_DEVICE;  	ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);  } @@ -538,80 +530,84 @@ static int sun_pci_fd_test_drive(unsigned long port, int drive)  #undef MSR  #undef DOR -#endif /* CONFIG_PCI */ - -#ifdef CONFIG_PCI -static int __init ebus_fdthree_p(struct linux_ebus_device *edev) +static int __init ebus_fdthree_p(struct device_node *dp)  { -	if (!strcmp(edev->prom_node->name, "fdthree")) +	if (!strcmp(dp->name, "fdthree"))  		return 1; -	if (!strcmp(edev->prom_node->name, "floppy")) { +	if (!strcmp(dp->name, "floppy")) {  		const char *compat; -		compat = of_get_property(edev->prom_node, -					 "compatible", NULL); +		compat = of_get_property(dp, "compatible", NULL);  		if (compat && !strcmp(compat, "fdthree"))  			return 1;  	}  	return 0;  } -#endif  static unsigned long __init sun_floppy_init(void)  { -	char state[128]; -	struct sbus_bus *bus; -	struct sbus_dev *sdev = NULL;  	static int initialized = 0; +	struct device_node *dp; +	struct of_device *op; +	const char *prop; +	char state[128];  	if (initialized)  		return sun_floppy_types[0];  	initialized = 1; -	for_all_sbusdev (sdev, bus) { -		if (!strcmp(sdev->prom_name, "SUNW,fdtwo")) +	op = NULL; + +	for_each_node_by_name(dp, "SUNW,fdtwo") { +		if (strcmp(dp->parent->name, "sbus")) +			continue; +		op = of_find_device_by_node(dp); +		if (op)  			break;  	} -	if(sdev) { -		floppy_sdev = sdev; -		FLOPPY_IRQ = sdev->irqs[0]; +	if (op) { +		floppy_op = op; +		FLOPPY_IRQ = op->irqs[0];  	} else { -#ifdef CONFIG_PCI -		struct linux_ebus *ebus; -		struct linux_ebus_device *edev = NULL; -		unsigned long config = 0; +		struct device_node *ebus_dp;  		void __iomem *auxio_reg;  		const char *state_prop; +		unsigned long config; -		for_each_ebus(ebus) { -			for_each_ebusdev(edev, ebus) { -				if (ebus_fdthree_p(edev)) -					goto ebus_done; +		dp = NULL; +		for_each_node_by_name(ebus_dp, "ebus") { +			for (dp = ebus_dp->child; dp; dp = dp->sibling) { +				if (ebus_fdthree_p(dp)) +					goto found_fdthree;  			}  		} -	ebus_done: -		if (!edev) +	found_fdthree: +		if (!dp) +			return 0; + +		op = of_find_device_by_node(dp); +		if (!op)  			return 0; -		state_prop = of_get_property(edev->prom_node, "status", NULL); +		state_prop = of_get_property(op->node, "status", NULL);  		if (state_prop && !strncmp(state_prop, "disabled", 8))  			return 0; -		FLOPPY_IRQ = edev->irqs[0]; +		FLOPPY_IRQ = op->irqs[0];  		/* Make sure the high density bit is set, some systems  		 * (most notably Ultra5/Ultra10) come up with it clear.  		 */ -		auxio_reg = (void __iomem *) edev->resource[2].start; +		auxio_reg = (void __iomem *) op->resource[2].start;  		writel(readl(auxio_reg)|0x2, auxio_reg); -		sun_pci_ebus_dev = ebus->self; +		sun_floppy_dev = &op->dev;  		spin_lock_init(&sun_pci_fd_ebus_dma.lock);  		/* XXX ioremap */  		sun_pci_fd_ebus_dma.regs = (void __iomem *) -			edev->resource[1].start; +			op->resource[1].start;  		if (!sun_pci_fd_ebus_dma.regs)  			return 0; @@ -625,7 +621,7 @@ static unsigned long __init sun_floppy_init(void)  			return 0;  		/* XXX ioremap */ -		sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start; +		sun_fdc = (struct sun_flpy_controller *) op->resource[0].start;  		sun_fdops.fd_inb = sun_pci_fd_inb;  		sun_fdops.fd_outb = sun_pci_fd_outb; @@ -662,12 +658,15 @@ static unsigned long __init sun_floppy_init(void)  		/*  		 * Find NS87303 SuperIO config registers (through ecpp).  		 */ -		for_each_ebus(ebus) { -			for_each_ebusdev(edev, ebus) { -				if (!strcmp(edev->prom_node->name, "ecpp")) { -					config = edev->resource[1].start; -					goto config_done; -				} +		config = 0; +		for (dp = ebus_dp->child; dp; dp = dp->sibling) { +			if (!strcmp(dp->name, "ecpp")) { +				struct of_device *ecpp_op; + +				ecpp_op = of_find_device_by_node(dp); +				if (ecpp_op) +					config = ecpp_op->resource[1].start; +				goto config_done;  			}  		}  	config_done: @@ -716,26 +715,23 @@ static unsigned long __init sun_floppy_init(void)  #endif /* PCI_FDC_SWAP_DRIVES */  		return sun_floppy_types[0]; -#else -		return 0; -#endif  	} -	prom_getproperty(sdev->prom_node, "status", state, sizeof(state)); -	if(!strncmp(state, "disabled", 8)) +	prop = of_get_property(op->node, "status", NULL); +	if (prop && !strncmp(state, "disabled", 8))  		return 0;  	/* -	 * We cannot do sbus_ioremap here: it does request_region, +	 * We cannot do of_ioremap here: it does request_region,  	 * which the generic floppy driver tries to do once again.  	 * But we must use the sdev resource values as they have  	 * had parent ranges applied.  	 */  	sun_fdc = (struct sun_flpy_controller *) -		(sdev->resource[0].start + -		 ((sdev->resource[0].flags & 0x1ffUL) << 32UL)); +		(op->resource[0].start + +		 ((op->resource[0].flags & 0x1ffUL) << 32UL));  	/* Last minute sanity check... */ -	if(sbus_readb(&sun_fdc->status1_82077) == 0xff) { +	if (sbus_readb(&sun_fdc->status1_82077) == 0xff) {  		sun_fdc = (struct sun_flpy_controller *)-1;  		return 0;  	} diff --git a/arch/sparc/include/asm/gpio.h b/arch/sparc/include/asm/gpio.h new file mode 100644 index 00000000000..a0e3ac0af59 --- /dev/null +++ b/arch/sparc/include/asm/gpio.h @@ -0,0 +1,36 @@ +#ifndef __ASM_SPARC_GPIO_H +#define __ASM_SPARC_GPIO_H + +#include <linux/errno.h> +#include <asm-generic/gpio.h> + +#ifdef CONFIG_GPIOLIB + +static inline int gpio_get_value(unsigned int gpio) +{ +	return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ +	__gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ +	return __gpio_cansleep(gpio); +} + +static inline int gpio_to_irq(unsigned int gpio) +{ +	return -ENOSYS; +} + +static inline int irq_to_gpio(unsigned int irq) +{ +	return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* __ASM_SPARC_GPIO_H */ diff --git a/arch/sparc/include/asm/io-unit.h b/arch/sparc/include/asm/io-unit.h index 96823b47fd4..01ab2f613e9 100644 --- a/arch/sparc/include/asm/io-unit.h +++ b/arch/sparc/include/asm/io-unit.h @@ -55,8 +55,4 @@ struct iounit_struct {  #define IOUNIT_BMAPM_START	IOUNIT_BMAP2_END  #define IOUNIT_BMAPM_END	((IOUNIT_DMA_SIZE - IOUNIT_DVMA_SIZE) >> PAGE_SHIFT) -extern __u32 iounit_map_dma_init(struct sbus_bus *, int); -#define iounit_map_dma_finish(sbus, addr, len) mmu_release_scsi_one(addr, len, sbus) -extern __u32 iounit_map_dma_page(__u32, void *, struct sbus_bus *); -  #endif /* !(_SPARC_IO_UNIT_H) */ diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h index 10d7da45007..93fe21e02c8 100644 --- a/arch/sparc/include/asm/io_32.h +++ b/arch/sparc/include/asm/io_32.h @@ -293,14 +293,6 @@ extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);  extern void pci_iounmap(struct pci_dev *dev, void __iomem *);  /* - * Bus number may be in res->flags... somewhere. - */ -extern void __iomem *sbus_ioremap(struct resource *res, unsigned long offset, -    unsigned long size, char *name); -extern void sbus_iounmap(volatile void __iomem *vaddr, unsigned long size); - - -/*   * At the moment, we do not use CMOS_READ anywhere outside of rtc.c,   * so rtc_port is static in it. This should not change unless a new   * hardware pops up. @@ -308,6 +300,17 @@ extern void sbus_iounmap(volatile void __iomem *vaddr, unsigned long size);  #define RTC_PORT(x)   (rtc_port + (x))  #define RTC_ALWAYS_BCD  0 +static inline int sbus_can_dma_64bit(void) +{ +	return 0; /* actually, sparc_cpu_model==sun4d */ +} +static inline int sbus_can_burst64(void) +{ +	return 0; /* actually, sparc_cpu_model==sun4d */ +} +struct device; +extern void sbus_set_sbus64(struct device *, int); +  #endif  #define __ARCH_HAS_NO_PAGE_ZERO_MAPPED		1 diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h index 0bff078ffdd..4aee21dc9c6 100644 --- a/arch/sparc/include/asm/io_64.h +++ b/arch/sparc/include/asm/io_64.h @@ -482,18 +482,16 @@ struct pci_dev;  extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);  extern void pci_iounmap(struct pci_dev *dev, void __iomem *); -/* Similarly for SBUS. */ -#define sbus_ioremap(__res, __offset, __size, __name) \ -({	unsigned long __ret; \ -	__ret  = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \ -	__ret += (unsigned long) (__offset); \ -	if (! request_region((__ret), (__size), (__name))) \ -		__ret = 0UL; \ -	(void __iomem *) __ret; \ -}) - -#define sbus_iounmap(__addr, __size)	\ -	release_region((unsigned long)(__addr), (__size)) +static inline int sbus_can_dma_64bit(void) +{ +	return 1; +} +static inline int sbus_can_burst64(void) +{ +	return 1; +} +struct device; +extern void sbus_set_sbus64(struct device *, int);  /*   * Convert a physical pointer to a virtual kernel pointer for /dev/mem diff --git a/arch/sparc/include/asm/iommu_64.h b/arch/sparc/include/asm/iommu_64.h index d7b9afcba08..caf798b5619 100644 --- a/arch/sparc/include/asm/iommu_64.h +++ b/arch/sparc/include/asm/iommu_64.h @@ -48,6 +48,9 @@ struct strbuf {  	unsigned long		strbuf_control;  	unsigned long		strbuf_pflush;  	unsigned long		strbuf_fsync; +	unsigned long		strbuf_err_stat; +	unsigned long		strbuf_tag_diag; +	unsigned long		strbuf_line_diag;  	unsigned long		strbuf_ctxflush;  	unsigned long		strbuf_ctxmatch_base;  	unsigned long		strbuf_flushflag_pa; diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h index e3dd9303643..71673eca366 100644 --- a/arch/sparc/include/asm/irq_64.h +++ b/arch/sparc/include/asm/irq_64.h @@ -56,7 +56,6 @@ extern unsigned int sun4u_build_msi(u32 portid, unsigned int *virt_irq_p,  				    unsigned long imap_base,  				    unsigned long iclr_base);  extern void sun4u_destroy_msi(unsigned int virt_irq); -extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);  extern unsigned char virt_irq_alloc(unsigned int dev_handle,  				    unsigned int dev_ino); diff --git a/arch/sparc/include/asm/kdebug_32.h b/arch/sparc/include/asm/kdebug_32.h index f69fe7d84b3..1d0b240222e 100644 --- a/arch/sparc/include/asm/kdebug_32.h +++ b/arch/sparc/include/asm/kdebug_32.h @@ -60,6 +60,7 @@ static inline void sp_enter_debugger(void)  enum die_val {  	DIE_UNUSED, +	DIE_OOPS,  };  #endif /* !(__ASSEMBLY__) */ diff --git a/arch/sparc/include/asm/mc146818rtc_64.h b/arch/sparc/include/asm/mc146818rtc_64.h index e9c0fcc25c6..7238d174e0e 100644 --- a/arch/sparc/include/asm/mc146818rtc_64.h +++ b/arch/sparc/include/asm/mc146818rtc_64.h @@ -7,12 +7,8 @@  #include <asm/io.h>  #ifndef RTC_PORT -#ifdef CONFIG_PCI -extern unsigned long ds1287_regs; -#else -#define ds1287_regs (0UL) -#endif -#define RTC_PORT(x)	(ds1287_regs + (x)) +extern unsigned long cmos_regs; +#define RTC_PORT(x)	(cmos_regs + (x))  #define RTC_ALWAYS_BCD	0  #endif @@ -29,6 +25,4 @@ outb_p((addr),RTC_PORT(0)); \  outb_p((val),RTC_PORT(1)); \  }) -#define RTC_IRQ 8 -  #endif /* __ASM_SPARC64_MC146818RTC_H */ diff --git a/arch/sparc/include/asm/memctrl.h b/arch/sparc/include/asm/memctrl.h new file mode 100644 index 00000000000..4065c56af7b --- /dev/null +++ b/arch/sparc/include/asm/memctrl.h @@ -0,0 +1,9 @@ +#ifndef _SPARC_MEMCTRL_H +#define _SPARC_MEMCTRL_H + +typedef int (*dimm_printer_t)(int synd_code, unsigned long paddr, char *buf, int buflen); + +int register_dimm_printer(dimm_printer_t func); +void unregister_dimm_printer(dimm_printer_t func); + +#endif /* _SPARC_MEMCTRL_H */ diff --git a/arch/sparc/include/asm/mostek.h b/arch/sparc/include/asm/mostek.h deleted file mode 100644 index 433be3e0a69..00000000000 --- a/arch/sparc/include/asm/mostek.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef ___ASM_SPARC_MOSTEK_H -#define ___ASM_SPARC_MOSTEK_H -#if defined(__sparc__) && defined(__arch64__) -#include <asm/mostek_64.h> -#else -#include <asm/mostek_32.h> -#endif -#endif diff --git a/arch/sparc/include/asm/mostek_32.h b/arch/sparc/include/asm/mostek_32.h deleted file mode 100644 index a99590c4c50..00000000000 --- a/arch/sparc/include/asm/mostek_32.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * mostek.h:  Describes the various Mostek time of day clock registers. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) - * Added intersil code 05/25/98 Chris Davis (cdavis@cois.on.ca) - */ - -#ifndef _SPARC_MOSTEK_H -#define _SPARC_MOSTEK_H - -#include <asm/idprom.h> -#include <asm/io.h> - -/*       M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ) - * - *                             Data - * Address                                                 Function - *        Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0 - *   7ff  -     -     -     -    -     -     -     -       Year 00-99 - *   7fe  0     0     0     -    -     -     -     -      Month 01-12 - *   7fd  0     0     -     -    -     -     -     -       Date 01-31 - *   7fc  0     FT    0     0    0     -     -     -        Day 01-07 - *   7fb  KS    0     -     -    -     -     -     -      Hours 00-23 - *   7fa  0     -     -     -    -     -     -     -    Minutes 00-59 - *   7f9  ST    -     -     -    -     -     -     -    Seconds 00-59 - *   7f8  W     R     S     -    -     -     -     -    Control - * - *   * ST is STOP BIT - *   * W is WRITE BIT - *   * R is READ BIT - *   * S is SIGN BIT - *   * FT is FREQ TEST BIT - *   * KS is KICK START BIT - */ - -/* The Mostek 48t02 real time clock and NVRAM chip. The registers - * other than the control register are in binary coded decimal. Some - * control bits also live outside the control register. - */ -#define mostek_read(_addr)		readb(_addr) -#define mostek_write(_addr,_val)	writeb(_val, _addr) -#define MOSTEK_EEPROM		0x0000UL -#define MOSTEK_IDPROM		0x07d8UL -#define MOSTEK_CREG		0x07f8UL -#define MOSTEK_SEC		0x07f9UL -#define MOSTEK_MIN		0x07faUL -#define MOSTEK_HOUR		0x07fbUL -#define MOSTEK_DOW		0x07fcUL -#define MOSTEK_DOM		0x07fdUL -#define MOSTEK_MONTH		0x07feUL -#define MOSTEK_YEAR		0x07ffUL - -struct mostek48t02 { -	volatile char eeprom[2008];	/* This is the eeprom, don't touch! */ -	struct idprom idprom;		/* The idprom lives here. */ -	volatile unsigned char creg;	/* Control register */ -	volatile unsigned char sec;	/* Seconds (0-59) */ -	volatile unsigned char min;	/* Minutes (0-59) */ -	volatile unsigned char hour;	/* Hour (0-23) */ -	volatile unsigned char dow;	/* Day of the week (1-7) */ -	volatile unsigned char dom;	/* Day of the month (1-31) */ -	volatile unsigned char month;	/* Month of year (1-12) */ -	volatile unsigned char year;	/* Year (0-99) */ -}; - -extern spinlock_t mostek_lock; -extern void __iomem *mstk48t02_regs; - -/* Control register values. */ -#define	MSTK_CREG_WRITE	0x80	/* Must set this before placing values. */ -#define	MSTK_CREG_READ	0x40	/* Stop updates to allow a clean read. */ -#define	MSTK_CREG_SIGN	0x20	/* Slow/speed clock in calibration mode. */ - -/* Control bits that live in the other registers. */ -#define	MSTK_STOP	0x80	/* Stop the clock oscillator. (sec) */ -#define	MSTK_KICK_START	0x80	/* Kick start the clock chip. (hour) */ -#define MSTK_FREQ_TEST	0x40	/* Frequency test mode. (day) */ - -#define MSTK_YEAR_ZERO       1968   /* If year reg has zero, it is 1968. */ -#define MSTK_CVT_YEAR(yr)  ((yr) + MSTK_YEAR_ZERO) - -/* Masks that define how much space each value takes up. */ -#define	MSTK_SEC_MASK	0x7f -#define	MSTK_MIN_MASK	0x7f -#define	MSTK_HOUR_MASK	0x3f -#define	MSTK_DOW_MASK	0x07 -#define	MSTK_DOM_MASK	0x3f -#define	MSTK_MONTH_MASK	0x1f -#define	MSTK_YEAR_MASK	0xffU - -/* Binary coded decimal conversion macros. */ -#define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04)) -#define MSTK_DECIMAL_TO_REGVAL(x)  ((((x) / 0x0A) << 0x04) + ((x) % 0x0A)) - -/* Generic register set and get macros for internal use. */ -#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(((struct mostek48t02 *)regs)->var & MSTK_ ## mask ## _MASK)) -#define MSTK_SET(regs,var,value,mask) do { ((struct mostek48t02 *)regs)->var &= ~(MSTK_ ## mask ## _MASK); ((struct mostek48t02 *)regs)->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0) - -/* Macros to make register access easier on our fingers. These give you - * the decimal value of the register requested if applicable. You pass - * the a pointer to a 'struct mostek48t02'. - */ -#define	MSTK_REG_CREG(regs)	(((struct mostek48t02 *)regs)->creg) -#define	MSTK_REG_SEC(regs)	MSTK_GET(regs,sec,SEC) -#define	MSTK_REG_MIN(regs)	MSTK_GET(regs,min,MIN) -#define	MSTK_REG_HOUR(regs)	MSTK_GET(regs,hour,HOUR) -#define	MSTK_REG_DOW(regs)	MSTK_GET(regs,dow,DOW) -#define	MSTK_REG_DOM(regs)	MSTK_GET(regs,dom,DOM) -#define	MSTK_REG_MONTH(regs)	MSTK_GET(regs,month,MONTH) -#define	MSTK_REG_YEAR(regs)	MSTK_GET(regs,year,YEAR) - -#define	MSTK_SET_REG_SEC(regs,value)	MSTK_SET(regs,sec,value,SEC) -#define	MSTK_SET_REG_MIN(regs,value)	MSTK_SET(regs,min,value,MIN) -#define	MSTK_SET_REG_HOUR(regs,value)	MSTK_SET(regs,hour,value,HOUR) -#define	MSTK_SET_REG_DOW(regs,value)	MSTK_SET(regs,dow,value,DOW) -#define	MSTK_SET_REG_DOM(regs,value)	MSTK_SET(regs,dom,value,DOM) -#define	MSTK_SET_REG_MONTH(regs,value)	MSTK_SET(regs,month,value,MONTH) -#define	MSTK_SET_REG_YEAR(regs,value)	MSTK_SET(regs,year,value,YEAR) - - -/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the - * same (basically) layout of the 48t02 chip except for the extra - * NVRAM on board (8 KB against the 48t02's 2 KB). - */ -struct mostek48t08 { -	char offset[6*1024];         /* Magic things may be here, who knows? */ -	struct mostek48t02 regs;     /* Here is what we are interested in.   */ -}; - -#ifdef CONFIG_SUN4 -enum sparc_clock_type {	MSTK48T02, MSTK48T08, \ -INTERSIL, MSTK_INVALID }; -#else -enum sparc_clock_type {	MSTK48T02, MSTK48T08, \ -MSTK_INVALID }; -#endif - -#ifdef CONFIG_SUN4 -/* intersil on a sun 4/260 code  data from harris doc */ -struct intersil_dt { -        volatile unsigned char int_csec; -        volatile unsigned char int_hour; -        volatile unsigned char int_min; -        volatile unsigned char int_sec; -        volatile unsigned char int_month; -        volatile unsigned char int_day; -        volatile unsigned char int_year; -        volatile unsigned char int_dow; -}; - -struct intersil { -	struct intersil_dt clk; -	struct intersil_dt cmp; -	volatile unsigned char int_intr_reg; -	volatile unsigned char int_cmd_reg; -}; - -#define INTERSIL_STOP        0x0 -#define INTERSIL_START       0x8 -#define INTERSIL_INTR_DISABLE   0x0 -#define INTERSIL_INTR_ENABLE   0x10 -#define INTERSIL_32K		0x0 -#define INTERSIL_NORMAL		0x0 -#define INTERSIL_24H		0x4 -#define INTERSIL_INT_100HZ	0x2 - -/* end of intersil info */ -#endif - -#endif /* !(_SPARC_MOSTEK_H) */ diff --git a/arch/sparc/include/asm/mostek_64.h b/arch/sparc/include/asm/mostek_64.h deleted file mode 100644 index c5652de2ace..00000000000 --- a/arch/sparc/include/asm/mostek_64.h +++ /dev/null @@ -1,143 +0,0 @@ -/* mostek.h:  Describes the various Mostek time of day clock registers. - * - * Copyright (C) 1995 David S. Miller (davem@davemloft.net) - * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) - */ - -#ifndef _SPARC64_MOSTEK_H -#define _SPARC64_MOSTEK_H - -#include <asm/idprom.h> - -/*       M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ) - * - *                             Data - * Address                                                 Function - *        Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0 - *   7ff  -     -     -     -    -     -     -     -       Year 00-99 - *   7fe  0     0     0     -    -     -     -     -      Month 01-12 - *   7fd  0     0     -     -    -     -     -     -       Date 01-31 - *   7fc  0     FT    0     0    0     -     -     -        Day 01-07 - *   7fb  KS    0     -     -    -     -     -     -      Hours 00-23 - *   7fa  0     -     -     -    -     -     -     -    Minutes 00-59 - *   7f9  ST    -     -     -    -     -     -     -    Seconds 00-59 - *   7f8  W     R     S     -    -     -     -     -    Control - * - *   * ST is STOP BIT - *   * W is WRITE BIT - *   * R is READ BIT - *   * S is SIGN BIT - *   * FT is FREQ TEST BIT - *   * KS is KICK START BIT - */ - -/* The Mostek 48t02 real time clock and NVRAM chip. The registers - * other than the control register are in binary coded decimal. Some - * control bits also live outside the control register. - * - * We now deal with physical addresses for I/O to the chip. -DaveM - */ -static inline u8 mostek_read(void __iomem *addr) -{ -	u8 ret; - -	__asm__ __volatile__("lduba	[%1] %2, %0" -			     : "=r" (ret) -			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); -	return ret; -} - -static inline void mostek_write(void __iomem *addr, u8 val) -{ -	__asm__ __volatile__("stba	%0, [%1] %2" -			     : /* no outputs */ -			     : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); -} - -#define MOSTEK_EEPROM		0x0000UL -#define MOSTEK_IDPROM		0x07d8UL -#define MOSTEK_CREG		0x07f8UL -#define MOSTEK_SEC		0x07f9UL -#define MOSTEK_MIN		0x07faUL -#define MOSTEK_HOUR		0x07fbUL -#define MOSTEK_DOW		0x07fcUL -#define MOSTEK_DOM		0x07fdUL -#define MOSTEK_MONTH		0x07feUL -#define MOSTEK_YEAR		0x07ffUL - -extern spinlock_t mostek_lock; -extern void __iomem *mstk48t02_regs; - -/* Control register values. */ -#define	MSTK_CREG_WRITE	0x80	/* Must set this before placing values. */ -#define	MSTK_CREG_READ	0x40	/* Stop updates to allow a clean read. */ -#define	MSTK_CREG_SIGN	0x20	/* Slow/speed clock in calibration mode. */ - -/* Control bits that live in the other registers. */ -#define	MSTK_STOP	0x80	/* Stop the clock oscillator. (sec) */ -#define	MSTK_KICK_START	0x80	/* Kick start the clock chip. (hour) */ -#define MSTK_FREQ_TEST	0x40	/* Frequency test mode. (day) */ - -#define MSTK_YEAR_ZERO       1968   /* If year reg has zero, it is 1968. */ -#define MSTK_CVT_YEAR(yr)  ((yr) + MSTK_YEAR_ZERO) - -/* Masks that define how much space each value takes up. */ -#define	MSTK_SEC_MASK	0x7f -#define	MSTK_MIN_MASK	0x7f -#define	MSTK_HOUR_MASK	0x3f -#define	MSTK_DOW_MASK	0x07 -#define	MSTK_DOM_MASK	0x3f -#define	MSTK_MONTH_MASK	0x1f -#define	MSTK_YEAR_MASK	0xffU - -/* Binary coded decimal conversion macros. */ -#define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04)) -#define MSTK_DECIMAL_TO_REGVAL(x)  ((((x) / 0x0A) << 0x04) + ((x) % 0x0A)) - -/* Generic register set and get macros for internal use. */ -#define MSTK_GET(regs,name)	\ -	(MSTK_REGVAL_TO_DECIMAL(mostek_read(regs + MOSTEK_ ## name) & MSTK_ ## name ## _MASK)) -#define MSTK_SET(regs,name,value) \ -do {	u8 __val = mostek_read(regs + MOSTEK_ ## name); \ -	__val &= ~(MSTK_ ## name ## _MASK); \ -	__val |= (MSTK_DECIMAL_TO_REGVAL(value) & \ -		  (MSTK_ ## name ## _MASK)); \ -	mostek_write(regs + MOSTEK_ ## name, __val); \ -} while(0) - -/* Macros to make register access easier on our fingers. These give you - * the decimal value of the register requested if applicable. You pass - * the a pointer to a 'struct mostek48t02'. - */ -#define	MSTK_REG_CREG(regs)	(mostek_read((regs) + MOSTEK_CREG)) -#define	MSTK_REG_SEC(regs)	MSTK_GET(regs,SEC) -#define	MSTK_REG_MIN(regs)	MSTK_GET(regs,MIN) -#define	MSTK_REG_HOUR(regs)	MSTK_GET(regs,HOUR) -#define	MSTK_REG_DOW(regs)	MSTK_GET(regs,DOW) -#define	MSTK_REG_DOM(regs)	MSTK_GET(regs,DOM) -#define	MSTK_REG_MONTH(regs)	MSTK_GET(regs,MONTH) -#define	MSTK_REG_YEAR(regs)	MSTK_GET(regs,YEAR) - -#define	MSTK_SET_REG_SEC(regs,value)	MSTK_SET(regs,SEC,value) -#define	MSTK_SET_REG_MIN(regs,value)	MSTK_SET(regs,MIN,value) -#define	MSTK_SET_REG_HOUR(regs,value)	MSTK_SET(regs,HOUR,value) -#define	MSTK_SET_REG_DOW(regs,value)	MSTK_SET(regs,DOW,value) -#define	MSTK_SET_REG_DOM(regs,value)	MSTK_SET(regs,DOM,value) -#define	MSTK_SET_REG_MONTH(regs,value)	MSTK_SET(regs,MONTH,value) -#define	MSTK_SET_REG_YEAR(regs,value)	MSTK_SET(regs,YEAR,value) - - -/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the - * same (basically) layout of the 48t02 chip except for the extra - * NVRAM on board (8 KB against the 48t02's 2 KB). - */ -#define MOSTEK_48T08_OFFSET	0x0000UL	/* Lower NVRAM portions */ -#define MOSTEK_48T08_48T02	0x1800UL	/* Offset to 48T02 chip */ - -/* SUN5 systems usually have 48t59 model clock chipsets.  But we keep the older - * clock chip definitions around just in case. - */ -#define MOSTEK_48T59_OFFSET	0x0000UL	/* Lower NVRAM portions */ -#define MOSTEK_48T59_48T02	0x1800UL	/* Offset to 48T02 chip */ - -#endif /* !(_SPARC64_MOSTEK_H) */ diff --git a/arch/sparc/include/asm/obio.h b/arch/sparc/include/asm/obio.h index 1a7544ceb57..4ade0c8a2c7 100644 --- a/arch/sparc/include/asm/obio.h +++ b/arch/sparc/include/asm/obio.h @@ -155,17 +155,6 @@ static inline void bw_set_ctrl(int cpu, unsigned ctrl)  			      "i" (ASI_M_CTL));  } -extern unsigned char cpu_leds[32]; - -static inline void show_leds(int cpuid) -{ -	cpuid &= 0x1e; -	__asm__ __volatile__ ("stba %0, [%1] %2" : : -			      "r" ((cpu_leds[cpuid] << 4) | cpu_leds[cpuid+1]), -			      "r" (ECSR_BASE(cpuid) | BB_LEDS), -			      "i" (ASI_M_CTL)); -} -  static inline unsigned cc_get_ipen(void)  {  	unsigned pending; diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h index bba777a416d..a5d9811f969 100644 --- a/arch/sparc/include/asm/of_device.h +++ b/arch/sparc/include/asm/of_device.h @@ -30,6 +30,8 @@ struct of_device  extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);  extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); +extern void of_propagate_archdata(struct of_device *bus); +  /* This is just here during the transition */  #include <linux/of_platform.h> diff --git a/arch/sparc/include/asm/of_platform.h b/arch/sparc/include/asm/of_platform.h index 2348ab90a57..90da99059f8 100644 --- a/arch/sparc/include/asm/of_platform.h +++ b/arch/sparc/include/asm/of_platform.h @@ -13,9 +13,6 @@   *   */ -extern struct bus_type ebus_bus_type; -extern struct bus_type sbus_bus_type; -  #define of_bus_type	of_platform_bus_type	/* for compatibility */  #endif diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index b2631da259e..699da05235c 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -21,7 +21,6 @@ enum prom_major_version {  	PROM_V2,      /* sun4c and early sun4m V2 prom */  	PROM_V3,      /* sun4m and later, up to sun4d/sun4e machines V3 */  	PROM_P1275,   /* IEEE compliant ISA based Sun PROM, only sun4u */ -	PROM_SUN4,    /* Old sun4 proms are totally different, but we'll shoehorn it to make it fit */  };  extern enum prom_major_version prom_vers; diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h index cf5fb70ca1c..d1806edc095 100644 --- a/arch/sparc/include/asm/page_32.h +++ b/arch/sparc/include/asm/page_32.h @@ -8,11 +8,8 @@  #ifndef _SPARC_PAGE_H  #define _SPARC_PAGE_H -#ifdef CONFIG_SUN4 -#define PAGE_SHIFT   13 -#else  #define PAGE_SHIFT   12 -#endif +  #ifndef __ASSEMBLY__  /* I have my suspicions... -DaveM */  #define PAGE_SIZE    (1UL << PAGE_SHIFT) diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h index b579b910ef5..4274ed13ddb 100644 --- a/arch/sparc/include/asm/page_64.h +++ b/arch/sparc/include/asm/page_64.h @@ -38,6 +38,8 @@  #ifndef __ASSEMBLY__ +#define WANT_PAGE_VIRTUAL +  extern void _clear_page(void *page);  #define clear_page(X)	_clear_page((void *)(X))  struct page; diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index d9830621c90..dff3f0253aa 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -8,7 +8,7 @@  #include <linux/of_device.h> -#include <asm/ebus.h> +#include <asm/ebus_dma.h>  #include <asm/ns87303.h>  #include <asm/prom.h> @@ -215,7 +215,7 @@ static int __devexit ecpp_remove(struct of_device *op)  	return 0;  } -static struct of_device_id ecpp_match[] = { +static const struct of_device_id ecpp_match[] = {  	{  		.name = "ecpp",  	}, diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h index 0ee949d220c..b41c4c19815 100644 --- a/arch/sparc/include/asm/pci_32.h +++ b/arch/sparc/include/asm/pci_32.h @@ -3,6 +3,8 @@  #ifdef __KERNEL__ +#include <linux/dma-mapping.h> +  /* Can be used to override the logic in pci_scan_bus for skipping   * already-configured bus numbers - to be used for buggy BIOSes   * or architectures with incomplete PCI setup by the loader. diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h index 08237fda887..e0cabe790ec 100644 --- a/arch/sparc/include/asm/pgtable_32.h +++ b/arch/sparc/include/asm/pgtable_32.h @@ -14,11 +14,7 @@  #include <linux/spinlock.h>  #include <linux/swap.h>  #include <asm/types.h> -#ifdef CONFIG_SUN4 -#include <asm/pgtsun4.h> -#else  #include <asm/pgtsun4c.h> -#endif  #include <asm/pgtsrmmu.h>  #include <asm/vac-ops.h>  #include <asm/oplib.h> diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index bb9ec2cce35..b049abf9902 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -770,6 +770,8 @@ extern void sun4v_patch_tlb_handlers(void);  extern unsigned long cmdline_memory_size; +extern asmlinkage void do_sparc64_fault(struct pt_regs *regs); +  #endif /* !(__ASSEMBLY__) */  #endif /* !(_SPARC64_PGTABLE_H) */ diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 137a6bd72fc..59fcebb8f44 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h @@ -36,10 +36,10 @@  #define VPTE_SIZE	(1 << (VA_BITS - PAGE_SHIFT + 3))  #endif -#define TASK_SIZE	((unsigned long)-VPTE_SIZE)  #define TASK_SIZE_OF(tsk) \  	(test_tsk_thread_flag(tsk,TIF_32BIT) ? \ -	 (1UL << 32UL) : TASK_SIZE) +	 (1UL << 32UL) : ((unsigned long)-VPTE_SIZE)) +#define TASK_SIZE	TASK_SIZE_OF(current)  #ifdef __KERNEL__  #define STACK_TOP32	((1UL << 32UL) - PAGE_SIZE) diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index fd55522481c..900d44714f8 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -18,6 +18,7 @@   */  #include <linux/types.h>  #include <linux/proc_fs.h> +#include <linux/mutex.h>  #include <asm/atomic.h>  #define OF_ROOT_NODE_ADDR_CELLS_DEFAULT	2 @@ -73,6 +74,7 @@ struct of_irq_controller {  extern struct device_node *of_find_node_by_cpuid(int cpuid);  extern int of_set_property(struct device_node *node, const char *name, void *val, int len); +extern struct mutex of_set_property_mutex;  extern int of_getintprop_default(struct device_node *np,  				 const char *name,  				 int def); @@ -94,6 +96,16 @@ static inline void of_node_put(struct device_node *node)  {  } +/* These routines are here to provide compatibility with how powerpc + * handles IRQ mapping for OF device nodes.  We precompute and permanently + * register them in the of_device objects, whereas powerpc computes them + * on request. + */ +extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); +static inline void irq_dispose_mapping(unsigned int virq) +{ +} +  /*   * NB:  This is here while we transition from using asm/prom.h   * to linux/of.h diff --git a/arch/sparc/include/asm/ptrace_64.h b/arch/sparc/include/asm/ptrace_64.h index 06e4914c13f..3d3e9c161d8 100644 --- a/arch/sparc/include/asm/ptrace_64.h +++ b/arch/sparc/include/asm/ptrace_64.h @@ -113,6 +113,8 @@ struct sparc_trapf {  #ifdef __KERNEL__ +#include <linux/threads.h> +  static inline int pt_regs_trap_type(struct pt_regs *regs)  {  	return regs->magic & 0x1ff; @@ -138,6 +140,7 @@ struct global_reg_snapshot {  	struct thread_info	*thread;  	unsigned long		pad1;  }; +extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS];  #define __ARCH_WANT_COMPAT_SYS_PTRACE diff --git a/arch/sparc/include/asm/reboot.h b/arch/sparc/include/asm/reboot.h deleted file mode 100644 index 3f3f43f5be5..00000000000 --- a/arch/sparc/include/asm/reboot.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _SPARC64_REBOOT_H -#define _SPARC64_REBOOT_H - -extern void machine_alt_power_off(void); - -#endif /* _SPARC64_REBOOT_H */ diff --git a/arch/sparc/include/asm/rtc.h b/arch/sparc/include/asm/rtc.h deleted file mode 100644 index f9ecb1fe2ec..00000000000 --- a/arch/sparc/include/asm/rtc.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * rtc.h: Definitions for access to the Mostek real time clock - * - * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) - */ - -#ifndef _RTC_H -#define _RTC_H - -#include <linux/ioctl.h> - -struct rtc_time -{ -	int	sec;	/* Seconds (0-59) */ -	int	min;	/* Minutes (0-59) */ -	int	hour;	/* Hour (0-23) */ -	int	dow;	/* Day of the week (1-7) */ -	int	dom;	/* Day of the month (1-31) */ -	int	month;	/* Month of year (1-12) */ -	int	year;	/* Year (0-99) */ -}; - -#define RTCGET _IOR('p', 20, struct rtc_time) -#define RTCSET _IOW('p', 21, struct rtc_time) - -#endif diff --git a/arch/sparc/include/asm/sbus.h b/arch/sparc/include/asm/sbus.h deleted file mode 100644 index f82481ab44d..00000000000 --- a/arch/sparc/include/asm/sbus.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef ___ASM_SPARC_SBUS_H -#define ___ASM_SPARC_SBUS_H -#if defined(__sparc__) && defined(__arch64__) -#include <asm/sbus_64.h> -#else -#include <asm/sbus_32.h> -#endif -#endif diff --git a/arch/sparc/include/asm/sbus_32.h b/arch/sparc/include/asm/sbus_32.h deleted file mode 100644 index a7b4fa21931..00000000000 --- a/arch/sparc/include/asm/sbus_32.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * sbus.h:  Defines for the Sun SBus. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef _SPARC_SBUS_H -#define _SPARC_SBUS_H - -#include <linux/dma-mapping.h> -#include <linux/ioport.h> -#include <linux/of_device.h> - -#include <asm/oplib.h> -#include <asm/prom.h> -#include <asm/scatterlist.h> - -/* We scan which devices are on the SBus using the PROM node device - * tree.  SBus devices are described in two different ways.  You can - * either get an absolute address at which to access the device, or - * you can get a SBus 'slot' number and an offset within that slot. - */ - -/* The base address at which to calculate device OBIO addresses. */ -#define SUN_SBUS_BVADDR        0xf8000000 -#define SBUS_OFF_MASK          0x01ffffff - -/* These routines are used to calculate device address from slot - * numbers + offsets, and vice versa. - */ - -static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset) -{ -  return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset)); -} - -static inline int sbus_dev_slot(unsigned long dev_addr) -{ -  return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25); -} - -struct sbus_bus; - -/* Linux SBUS device tables */ -struct sbus_dev { -	struct of_device	ofdev; -	struct sbus_bus		*bus; -	struct sbus_dev		*next; -	struct sbus_dev		*child; -	struct sbus_dev		*parent; -	int prom_node; -	char prom_name[64]; -	int slot; - -	struct resource resource[PROMREG_MAX]; - -	struct linux_prom_registers reg_addrs[PROMREG_MAX]; -	int num_registers; - -	struct linux_prom_ranges device_ranges[PROMREG_MAX]; -	int num_device_ranges; - -	unsigned int irqs[4]; -	int num_irqs; -}; -#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev) - -/* This struct describes the SBus(s) found on this machine. */ -struct sbus_bus { -	struct of_device	ofdev; -	struct sbus_dev		*devices;	/* Link to devices on this SBus */ -	struct sbus_bus		*next;		/* next SBus, if more than one SBus */ -	int			prom_node;	/* PROM device tree node for this SBus */ -	char			prom_name[64];  /* Usually "sbus" or "sbi" */ -	int			clock_freq; - -	struct linux_prom_ranges sbus_ranges[PROMREG_MAX]; -	int num_sbus_ranges; - -	int devid; -	int board; -}; -#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev) - -extern struct sbus_bus *sbus_root; - -static inline int -sbus_is_slave(struct sbus_dev *dev) -{ -	/* XXX Have to write this for sun4c's */ -	return 0; -} - -/* Device probing routines could find these handy */ -#define for_each_sbus(bus) \ -        for((bus) = sbus_root; (bus); (bus)=(bus)->next) - -#define for_each_sbusdev(device, bus) \ -        for((device) = (bus)->devices; (device); (device)=(device)->next) - -#define for_all_sbusdev(device, bus) \ -	for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \ -		for ((device) = (bus)->devices; (device); (device) = (device)->next) - -/* Driver DVMA interfaces. */ -#define sbus_can_dma_64bit(sdev)	(0) /* actually, sparc_cpu_model==sun4d */ -#define sbus_can_burst64(sdev)		(0) /* actually, sparc_cpu_model==sun4d */ -extern void sbus_set_sbus64(struct sbus_dev *, int); -extern void sbus_fill_device_irq(struct sbus_dev *); - -/* These yield IOMMU mappings in consistent mode. */ -extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp); -extern void sbus_free_consistent(struct sbus_dev *, long, void *, u32); -void prom_adjust_ranges(struct linux_prom_ranges *, int, -			struct linux_prom_ranges *, int); - -#define SBUS_DMA_BIDIRECTIONAL	DMA_BIDIRECTIONAL -#define SBUS_DMA_TODEVICE	DMA_TO_DEVICE -#define SBUS_DMA_FROMDEVICE	DMA_FROM_DEVICE -#define	SBUS_DMA_NONE		DMA_NONE - -/* All the rest use streaming mode mappings. */ -extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t, int); -extern void sbus_unmap_single(struct sbus_dev *, dma_addr_t, size_t, int); -extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int, int); -extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int, int); - -/* Finally, allow explicit synchronization of streamable mappings. */ -extern void sbus_dma_sync_single_for_cpu(struct sbus_dev *, dma_addr_t, size_t, int); -#define sbus_dma_sync_single sbus_dma_sync_single_for_cpu -extern void sbus_dma_sync_single_for_device(struct sbus_dev *, dma_addr_t, size_t, int); -extern void sbus_dma_sync_sg_for_cpu(struct sbus_dev *, struct scatterlist *, int, int); -#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu -extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *, int, int); - -/* Eric Brower (ebrower@usa.net) - * Translate SBus interrupt levels to ino values-- - * this is used when converting sbus "interrupts" OBP - * node values to "intr" node values, and is platform - * dependent.  If only we could call OBP with - * "sbus-intr>cpu (sbint -- ino)" from kernel... - * See .../drivers/sbus/sbus.c for details. - */ -BTFIXUPDEF_CALL(unsigned int, sbint_to_irq, struct sbus_dev *sdev, unsigned int) -#define sbint_to_irq(sdev, sbint) BTFIXUP_CALL(sbint_to_irq)(sdev, sbint) - -extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *); -extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *); -extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *); -extern int sbus_arch_preinit(void); -extern void sbus_arch_postinit(void); - -#endif /* !(_SPARC_SBUS_H) */ diff --git a/arch/sparc/include/asm/sbus_64.h b/arch/sparc/include/asm/sbus_64.h deleted file mode 100644 index b606c14343f..00000000000 --- a/arch/sparc/include/asm/sbus_64.h +++ /dev/null @@ -1,190 +0,0 @@ -/* sbus.h: Defines for the Sun SBus. - * - * Copyright (C) 1996, 1999, 2007 David S. Miller (davem@davemloft.net) - */ - -#ifndef _SPARC64_SBUS_H -#define _SPARC64_SBUS_H - -#include <linux/dma-mapping.h> -#include <linux/ioport.h> -#include <linux/of_device.h> - -#include <asm/oplib.h> -#include <asm/prom.h> -#include <asm/iommu.h> -#include <asm/scatterlist.h> - -/* We scan which devices are on the SBus using the PROM node device - * tree.  SBus devices are described in two different ways.  You can - * either get an absolute address at which to access the device, or - * you can get a SBus 'slot' number and an offset within that slot. - */ - -/* The base address at which to calculate device OBIO addresses. */ -#define SUN_SBUS_BVADDR        0x00000000 -#define SBUS_OFF_MASK          0x0fffffff - -/* These routines are used to calculate device address from slot - * numbers + offsets, and vice versa. - */ - -static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset) -{ -  return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<28)+(offset)); -} - -static inline int sbus_dev_slot(unsigned long dev_addr) -{ -  return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>28); -} - -struct sbus_bus; - -/* Linux SBUS device tables */ -struct sbus_dev { -	struct of_device	ofdev; -	struct sbus_bus		*bus; -	struct sbus_dev		*next; -	struct sbus_dev		*child; -	struct sbus_dev		*parent; -	int prom_node; -	char prom_name[64]; -	int slot; - -	struct resource resource[PROMREG_MAX]; - -	struct linux_prom_registers reg_addrs[PROMREG_MAX]; -	int num_registers; - -	struct linux_prom_ranges device_ranges[PROMREG_MAX]; -	int num_device_ranges; - -	unsigned int irqs[4]; -	int num_irqs; -}; -#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev) - -/* This struct describes the SBus(s) found on this machine. */ -struct sbus_bus { -	struct of_device	ofdev; -	struct sbus_dev		*devices;	/* Tree of SBUS devices	*/ -	struct sbus_bus		*next;		/* Next SBUS in system	*/ -	int			prom_node;      /* OBP node of SBUS	*/ -	char			prom_name[64];	/* Usually "sbus" or "sbi" */ -	int			clock_freq; - -	struct linux_prom_ranges sbus_ranges[PROMREG_MAX]; -	int num_sbus_ranges; - -	int portid; -}; -#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev) - -extern struct sbus_bus *sbus_root; - -/* Device probing routines could find these handy */ -#define for_each_sbus(bus) \ -        for((bus) = sbus_root; (bus); (bus)=(bus)->next) - -#define for_each_sbusdev(device, bus) \ -        for((device) = (bus)->devices; (device); (device)=(device)->next) - -#define for_all_sbusdev(device, bus) \ -	for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \ -		for ((device) = (bus)->devices; (device); (device) = (device)->next) - -/* Driver DVMA interfaces. */ -#define sbus_can_dma_64bit(sdev)	(1) -#define sbus_can_burst64(sdev)		(1) -extern void sbus_set_sbus64(struct sbus_dev *, int); -extern void sbus_fill_device_irq(struct sbus_dev *); - -static inline void *sbus_alloc_consistent(struct sbus_dev *sdev , size_t size, -					  dma_addr_t *dma_handle) -{ -	return dma_alloc_coherent(&sdev->ofdev.dev, size, -				  dma_handle, GFP_ATOMIC); -} - -static inline void sbus_free_consistent(struct sbus_dev *sdev, size_t size, -					void *vaddr, dma_addr_t dma_handle) -{ -	return dma_free_coherent(&sdev->ofdev.dev, size, vaddr, dma_handle); -} - -#define SBUS_DMA_BIDIRECTIONAL	DMA_BIDIRECTIONAL -#define SBUS_DMA_TODEVICE	DMA_TO_DEVICE -#define SBUS_DMA_FROMDEVICE	DMA_FROM_DEVICE -#define	SBUS_DMA_NONE		DMA_NONE - -/* All the rest use streaming mode mappings. */ -static inline dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, -					 size_t size, int direction) -{ -	return dma_map_single(&sdev->ofdev.dev, ptr, size, -			      (enum dma_data_direction) direction); -} - -static inline void sbus_unmap_single(struct sbus_dev *sdev, -				     dma_addr_t dma_addr, size_t size, -				     int direction) -{ -	dma_unmap_single(&sdev->ofdev.dev, dma_addr, size, -			 (enum dma_data_direction) direction); -} - -static inline int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, -			      int nents, int direction) -{ -	return dma_map_sg(&sdev->ofdev.dev, sg, nents, -			  (enum dma_data_direction) direction); -} - -static inline void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, -				 int nents, int direction) -{ -	dma_unmap_sg(&sdev->ofdev.dev, sg, nents, -		     (enum dma_data_direction) direction); -} - -/* Finally, allow explicit synchronization of streamable mappings. */ -static inline void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, -						dma_addr_t dma_handle, -						size_t size, int direction) -{ -	dma_sync_single_for_cpu(&sdev->ofdev.dev, dma_handle, size, -				(enum dma_data_direction) direction); -} -#define sbus_dma_sync_single sbus_dma_sync_single_for_cpu - -static inline void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, -						   dma_addr_t dma_handle, -						   size_t size, int direction) -{ -	/* No flushing needed to sync cpu writes to the device.  */ -} - -static inline void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, -					    struct scatterlist *sg, -					    int nents, int direction) -{ -	dma_sync_sg_for_cpu(&sdev->ofdev.dev, sg, nents, -			    (enum dma_data_direction) direction); -} -#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu - -static inline void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, -					       struct scatterlist *sg, -					       int nents, int direction) -{ -	/* No flushing needed to sync cpu writes to the device.  */ -} - -extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *); -extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *); -extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *); -extern int sbus_arch_preinit(void); -extern void sbus_arch_postinit(void); - -#endif /* !(_SPARC64_SBUS_H) */ diff --git a/arch/sparc/include/asm/serial.h b/arch/sparc/include/asm/serial.h new file mode 100644 index 00000000000..f90d61c2805 --- /dev/null +++ b/arch/sparc/include/asm/serial.h @@ -0,0 +1,6 @@ +#ifndef __SPARC_SERIAL_H +#define __SPARC_SERIAL_H + +#define BASE_BAUD ( 1843200 / 16 ) + +#endif /* __SPARC_SERIAL_H */ diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index de2249b267c..bf2d532593e 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h @@ -6,8 +6,6 @@  #ifndef __SPARC_SPINLOCK_H  #define __SPARC_SPINLOCK_H -#include <linux/threads.h>	/* For NR_CPUS */ -  #ifndef __ASSEMBLY__  #include <asm/psr.h> diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index 0006fe9f8c7..120cfe4577c 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h @@ -6,8 +6,6 @@  #ifndef __SPARC64_SPINLOCK_H  #define __SPARC64_SPINLOCK_H -#include <linux/threads.h>	/* For NR_CPUS */ -  #ifndef __ASSEMBLY__  /* To get debugging spinlocks which detect and catch diff --git a/arch/sparc/include/asm/sstate.h b/arch/sparc/include/asm/sstate.h deleted file mode 100644 index a7c35dbcb28..00000000000 --- a/arch/sparc/include/asm/sstate.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _SPARC64_SSTATE_H -#define _SPARC64_SSTATE_H - -extern void sstate_booting(void); -extern void sstate_running(void); -extern void sstate_halt(void); -extern void sstate_poweroff(void); -extern void sstate_panic(void); -extern void sstate_reboot(void); - -extern void sun4v_sstate_init(void); - -#endif /* _SPARC64_SSTATE_H */ diff --git a/arch/sparc/include/asm/starfire.h b/arch/sparc/include/asm/starfire.h index 07bafd31e33..d56ce60a599 100644 --- a/arch/sparc/include/asm/starfire.h +++ b/arch/sparc/include/asm/starfire.h @@ -12,7 +12,6 @@  extern int this_is_starfire;  extern void check_if_starfire(void); -extern void starfire_cpu_setup(void);  extern int starfire_hard_smp_processor_id(void);  extern void starfire_hookup(int);  extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid); diff --git a/arch/sparc/include/asm/statfs.h b/arch/sparc/include/asm/statfs.h index 5e937a73743..55e607ad461 100644 --- a/arch/sparc/include/asm/statfs.h +++ b/arch/sparc/include/asm/statfs.h @@ -1,8 +1,6 @@  #ifndef ___ASM_SPARC_STATFS_H  #define ___ASM_SPARC_STATFS_H -#if defined(__sparc__) && defined(__arch64__) -#include <asm/statfs_64.h> -#else -#include <asm/statfs_32.h> -#endif + +#include <asm-generic/statfs.h> +  #endif diff --git a/arch/sparc/include/asm/statfs_32.h b/arch/sparc/include/asm/statfs_32.h deleted file mode 100644 index 304520fa886..00000000000 --- a/arch/sparc/include/asm/statfs_32.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _SPARC_STATFS_H -#define _SPARC_STATFS_H - -#include <asm-generic/statfs.h> - -#endif diff --git a/arch/sparc/include/asm/statfs_64.h b/arch/sparc/include/asm/statfs_64.h deleted file mode 100644 index 79b3c890a5f..00000000000 --- a/arch/sparc/include/asm/statfs_64.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef _SPARC64_STATFS_H -#define _SPARC64_STATFS_H - -#ifndef __KERNEL_STRICT_NAMES - -#include <linux/types.h> - -typedef __kernel_fsid_t	fsid_t; - -#endif - -struct statfs { -	long f_type; -	long f_bsize; -	long f_blocks; -	long f_bfree; -	long f_bavail; -	long f_files; -	long f_ffree; -	__kernel_fsid_t f_fsid; -	long f_namelen; -	long f_frsize; -	long f_spare[5]; -}; - -struct statfs64 { -	long f_type; -	long f_bsize; -	long f_blocks; -	long f_bfree; -	long f_bavail; -	long f_files; -	long f_ffree; -	__kernel_fsid_t f_fsid; -	long f_namelen; -	long f_frsize; -	long f_spare[5]; -}; - -struct compat_statfs64 { -	__u32 f_type; -	__u32 f_bsize; -	__u64 f_blocks; -	__u64 f_bfree; -	__u64 f_bavail; -	__u64 f_files; -	__u64 f_ffree; -	__kernel_fsid_t f_fsid; -	__u32 f_namelen; -	__u32 f_frsize; -	__u32 f_spare[5]; -}; - -#endif diff --git a/arch/sparc/include/asm/sun4paddr.h b/arch/sparc/include/asm/sun4paddr.h deleted file mode 100644 index d52985f19f4..00000000000 --- a/arch/sparc/include/asm/sun4paddr.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * sun4paddr.h:  Various physical addresses on sun4 machines - * - * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au) - * Copyright (C) 1998 Chris Davis (cdavis@cois.on.ca) - *  - * Now supports more sun4's - */ - -#ifndef _SPARC_SUN4PADDR_H -#define _SPARC_SUN4PADDR_H - -#define SUN4_IE_PHYSADDR		0xf5000000 -#define SUN4_UNUSED_PHYSADDR		0 - -/* these work for me */ -#define SUN4_200_MEMREG_PHYSADDR	0xf4000000 -#define SUN4_200_CLOCK_PHYSADDR		0xf3000000 -#define SUN4_200_BWTWO_PHYSADDR		0xfd000000 -#define SUN4_200_ETH_PHYSADDR		0xf6000000 -#define SUN4_200_SI_PHYSADDR		0xff200000 - -/* these were here before */ -#define SUN4_300_MEMREG_PHYSADDR	0xf4000000 -#define SUN4_300_CLOCK_PHYSADDR		0xf2000000 -#define SUN4_300_TIMER_PHYSADDR		0xef000000 -#define SUN4_300_ETH_PHYSADDR		0xf9000000 -#define SUN4_300_BWTWO_PHYSADDR		0xfb400000 -#define SUN4_300_DMA_PHYSADDR		0xfa001000 -#define SUN4_300_ESP_PHYSADDR		0xfa000000 - -/* Are these right? */ -#define SUN4_400_MEMREG_PHYSADDR	0xf4000000 -#define SUN4_400_CLOCK_PHYSADDR		0xf2000000 -#define SUN4_400_TIMER_PHYSADDR		0xef000000 -#define SUN4_400_ETH_PHYSADDR		0xf9000000 -#define SUN4_400_BWTWO_PHYSADDR		0xfb400000 -#define SUN4_400_DMA_PHYSADDR		0xfa001000 -#define SUN4_400_ESP_PHYSADDR		0xfa000000 - -/*  -	these are the actual values set and used in the code. Unused items set  -	to SUN_UNUSED_PHYSADDR  - */ - -extern int sun4_memreg_physaddr; /* memory register (ecc?) */ -extern int sun4_clock_physaddr;  /* system clock */ -extern int sun4_timer_physaddr;  /* timer, where applicable */ -extern int sun4_eth_physaddr;    /* onboard ethernet (ie/le) */ -extern int sun4_si_physaddr;     /* sun3 scsi adapter */ -extern int sun4_bwtwo_physaddr;  /* onboard bw2 */ -extern int sun4_dma_physaddr;    /* scsi dma */ -extern int sun4_esp_physaddr;    /* esp scsi */ -extern int sun4_ie_physaddr;     /* interrupt enable */ - -#endif /* !(_SPARC_SUN4PADDR_H) */ diff --git a/arch/sparc/include/asm/sun4prom.h b/arch/sparc/include/asm/sun4prom.h deleted file mode 100644 index 9c8b4cbf629..00000000000 --- a/arch/sparc/include/asm/sun4prom.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * sun4prom.h -- interface to sun4 PROM monitor.  We don't use most of this, - *               so most of these are just placeholders. - */ - -#ifndef _SUN4PROM_H_ -#define _SUN4PROM_H_ - -/* - * Although this looks similar to an romvec for a OpenProm machine, it is  - * actually closer to what was used in the Sun2 and Sun3. - * - * V2 entries exist only in version 2 PROMs and later, V3 in version 3 and later. - *  - * Many of the function prototypes are guesses.  Some are certainly wrong. - * Use with care. - */ - -typedef struct { -	char		*initSP;		/* Initial system stack ptr */ -	void		(*startmon)(void);	/* Initial PC for hardware */ -	int		*diagberr;		/* Bus err handler for diags */ -	struct linux_arguments_v0 **bootParam; /* Info for bootstrapped pgm */ - 	unsigned int	*memorysize;		/* Usable memory in bytes */ -	unsigned char	(*getchar)(void);	/* Get char from input device */  -	void		(*putchar)(char);	/* Put char to output device */ -	int		(*mayget)(void);	/* Maybe get char, or -1 */ -	int		(*mayput)(int);		/* Maybe put char, or -1 */ -	unsigned char	*echo;			/* Should getchar echo? */ -	unsigned char	*insource;		/* Input source selector */ -	unsigned char	*outsink;		/* Output sink selector */ -	int		(*getkey)(void);	/* Get next key if one exists */ -	void		(*initgetkey)(void);	/* Initialize get key */ -	unsigned int	*translation;		/* Kbd translation selector */ -	unsigned char	*keybid;		/* Keyboard ID byte */ -	int		*screen_x;		/* V2: Screen x pos (r/o) */ -	int		*screen_y;		/* V2: Screen y pos (r/o) */ -	struct keybuf	*keybuf;		/* Up/down keycode buffer */ -	char		*monid;			/* Monitor version ID */ -	void		(*fbwritechar)(char);	/* Write a character to FB */ -	int		*fbAddr;		/* Address of frame buffer */ -	char		**font;			/* Font table for FB */ -	void		(*fbwritestr)(char *);	/* Write string to FB */ -	void		(*reboot)(char *);	/* e.g. reboot("sd()vmlinux") */ -	unsigned char	*linebuf;		/* The line input buffer */ -	unsigned char	**lineptr;		/* Cur pointer into linebuf */ -	int		*linesize;		/* length of line in linebuf */ -	void		(*getline)(char *);	/* Get line from user */ -	unsigned char	(*getnextchar)(void);	/* Get next char from linebuf */ -	unsigned char	(*peeknextchar)(void);	/* Peek at next char */ -	int		*fbthere;		/* =1 if frame buffer there */ -	int		(*getnum)(void);	/* Grab hex num from line */ -	int		(*printf)(char *, ...);	/* See prom_printf() instead */  -	void		(*printhex)(int);	/* Format N digits in hex */ -	unsigned char	*leds;			/* RAM copy of LED register */ -	void		(*setLEDs)(unsigned char *);	/* Sets LED's and RAM copy */ -	void		(*NMIaddr)(void *);	/* Addr for level 7 vector */ -	void		(*abortentry)(void);	/* Entry for keyboard abort */ -	int		*nmiclock;		/* Counts up in msec */ -	int		*FBtype;		/* Frame buffer type */ - 	unsigned int	romvecversion;		/* Version number for this romvec */ -	struct globram  *globram;		/* monitor global variables ??? */ -	void *		kbdaddr;		/* Addr of keyboard in use */ -	int		*keyrinit;		/* ms before kbd repeat */ -	unsigned char	*keyrtick; 		/* ms between repetitions */ -	unsigned int	*memoryavail;		/* V1: Main mem usable size */ -	long		*resetaddr;		/* where to jump on a reset */ -	long		*resetmap;		/* pgmap entry for resetaddr */ -	void		(*exittomon)(void);	/* Exit from user program */ -	unsigned char	**memorybitmap;		/* V1: &{0 or &bits} */ -	void		(*setcxsegmap)(int ctxt, char *va, int pmeg);	/* Set seg in any context */ -	void		(**vector_cmd)(void *);	/* V2: Handler for 'v' cmd */ -	unsigned long	*expectedtrapsig;	/* V3: Location of the expected trap signal */ -	unsigned long	*trapvectorbasetable;	/* V3: Address of the trap vector table */ -	int		unused1; -	int		unused2; -	int		unused3; -	int		unused4; -} linux_sun4_romvec; - -extern linux_sun4_romvec *sun4_romvec; - -#endif /* _SUN4PROM_H_ */ diff --git a/arch/sparc/include/asm/system_32.h b/arch/sparc/include/asm/system_32.h index b4b024445fc..8623fc48fe2 100644 --- a/arch/sparc/include/asm/system_32.h +++ b/arch/sparc/include/asm/system_32.h @@ -34,13 +34,7 @@ enum sparc_cpu {  extern enum sparc_cpu sparc_cpu_model; -#ifndef CONFIG_SUN4 -#define ARCH_SUN4C_SUN4 (sparc_cpu_model==sun4c) -#define ARCH_SUN4 0 -#else -#define ARCH_SUN4C_SUN4 1 -#define ARCH_SUN4 1 -#endif +#define ARCH_SUN4C (sparc_cpu_model==sun4c)  #define SUN4M_NCPUS            4              /* Architectural limit of sun4m. */ @@ -55,6 +49,7 @@ extern unsigned long empty_zero_page;  extern void sun_do_break(void);  extern int serial_console;  extern int stop_a_enabled; +extern int scons_pwroff;  static inline int con_is_present(void)  { diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h index db9e742a406..8759f2a1b83 100644 --- a/arch/sparc/include/asm/system_64.h +++ b/arch/sparc/include/asm/system_64.h @@ -26,9 +26,8 @@ enum sparc_cpu {  #define sparc_cpu_model sun4u -/* This cannot ever be a sun4c nor sun4 :) That's just history. */ -#define ARCH_SUN4C_SUN4 0 -#define ARCH_SUN4 0 +/* This cannot ever be a sun4c :) That's just history. */ +#define ARCH_SUN4C 0  extern char reboot_command[]; @@ -118,6 +117,7 @@ do {	__asm__ __volatile__("ba,pt	%%xcc, 1f\n\t" \  extern void sun_do_break(void);  extern int stop_a_enabled; +extern int scons_pwroff;  extern void fault_in_user_windows(void);  extern void synchronize_user_stack(void); diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h index cbb892d0dff..80fe547c3f4 100644 --- a/arch/sparc/include/asm/thread_info_32.h +++ b/arch/sparc/include/asm/thread_info_32.h @@ -80,11 +80,7 @@ register struct thread_info *current_thread_info_reg asm("g6");  /*   * thread information allocation   */ -#if PAGE_SHIFT == 13 -#define THREAD_INFO_ORDER  0 -#else /* PAGE_SHIFT */  #define THREAD_INFO_ORDER  1 -#endif  #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR @@ -139,6 +135,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)  #define TIF_POLLING_NRFLAG	9	/* true if poll_idle() is polling  					 * TIF_NEED_RESCHED */  #define TIF_MEMDIE		10 +#define TIF_FREEZE		11	/* is freezing for suspend */  /* as above, but as bit values */  #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE) @@ -152,6 +149,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)  #define _TIF_DO_NOTIFY_RESUME_MASK	(_TIF_NOTIFY_RESUME | \  					 _TIF_SIGPENDING | \  					 _TIF_RESTORE_SIGMASK) +#define _TIF_FREEZE		(1<<TIF_FREEZE)  #endif /* __KERNEL__ */ diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index c0a737d7292..639ac805448 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h @@ -237,6 +237,7 @@ register struct thread_info *current_thread_info_reg asm("g6");  #define TIF_ABI_PENDING		12  #define TIF_MEMDIE		13  #define TIF_POLLING_NRFLAG	14 +#define TIF_FREEZE		15	/* is freezing for suspend */  #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)  #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME) @@ -249,6 +250,7 @@ register struct thread_info *current_thread_info_reg asm("g6");  #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)  #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)  #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG) +#define _TIF_FREEZE		(1<<TIF_FREEZE)  #define _TIF_USER_WORK_MASK	((0xff << TI_FLAG_WSAVED_SHIFT) | \  				 _TIF_DO_NOTIFY_RESUME_MASK | \ diff --git a/arch/sparc/include/asm/timer_32.h b/arch/sparc/include/asm/timer_32.h index 361e53898dd..2ec030ef381 100644 --- a/arch/sparc/include/asm/timer_32.h +++ b/arch/sparc/include/asm/timer_32.h @@ -9,96 +9,9 @@  #define _SPARC_TIMER_H  #include <asm/system.h>  /* For SUN4M_NCPUS */ -#include <asm/sun4paddr.h>  #include <asm/btfixup.h> -/* Timer structures. The interrupt timer has two properties which - * are the counter (which is handled in do_timer in sched.c) and the limit. - * This limit is where the timer's counter 'wraps' around. Oddly enough, - * the sun4c timer when it hits the limit wraps back to 1 and not zero - * thus when calculating the value at which it will fire a microsecond you - * must adjust by one.  Thanks SUN for designing such great hardware ;( - */ - -/* Note that I am only going to use the timer that interrupts at - * Sparc IRQ 10.  There is another one available that can fire at - * IRQ 14. Currently it is left untouched, we keep the PROM's limit - * register value and let the prom take these interrupts.  This allows - * L1-A to work. - */ - -struct sun4c_timer_info { -  __volatile__ unsigned int cur_count10; -  __volatile__ unsigned int timer_limit10; -  __volatile__ unsigned int cur_count14; -  __volatile__ unsigned int timer_limit14; -}; - -#define SUN4C_TIMER_PHYSADDR   0xf3000000 -#ifdef CONFIG_SUN4 -#define SUN_TIMER_PHYSADDR SUN4_300_TIMER_PHYSADDR -#else -#define SUN_TIMER_PHYSADDR SUN4C_TIMER_PHYSADDR -#endif - -/* A sun4m has two blocks of registers which are probably of the same - * structure. LSI Logic's L64851 is told to _decrement_ from the limit - * value. Aurora behaves similarly but its limit value is compacted in - * other fashion (it's wider). Documented fields are defined here. - */ - -/* As with the interrupt register, we have two classes of timer registers - * which are per-cpu and master.  Per-cpu timers only hit that cpu and are - * only level 14 ticks, master timer hits all cpus and is level 10. - */ - -#define SUN4M_PRM_CNT_L       0x80000000 -#define SUN4M_PRM_CNT_LVALUE  0x7FFFFC00 - -struct sun4m_timer_percpu_info { -  __volatile__ unsigned int l14_timer_limit;    /* Initial value is 0x009c4000 */ -  __volatile__ unsigned int l14_cur_count; - -  /* This register appears to be write only and/or inaccessible -   * on Uni-Processor sun4m machines. -   */ -  __volatile__ unsigned int l14_limit_noclear;  /* Data access error is here */ - -  __volatile__ unsigned int cntrl;            /* =1 after POST on Aurora */ -  __volatile__ unsigned char space[PAGE_SIZE - 16]; -}; - -struct sun4m_timer_regs { -	struct sun4m_timer_percpu_info cpu_timers[SUN4M_NCPUS]; -	volatile unsigned int l10_timer_limit; -	volatile unsigned int l10_cur_count; - -	/* Again, this appears to be write only and/or inaccessible -	 * on uni-processor sun4m machines. -	 */ -	volatile unsigned int l10_limit_noclear; - -	/* This register too, it must be magic. */ -	volatile unsigned int foobar; - -	volatile unsigned int cfg;     /* equals zero at boot time... */ -}; - -#define SUN4D_PRM_CNT_L       0x80000000 -#define SUN4D_PRM_CNT_LVALUE  0x7FFFFC00 - -struct sun4d_timer_regs { -	volatile unsigned int l10_timer_limit; -	volatile unsigned int l10_cur_countx; -	volatile unsigned int l10_limit_noclear; -	volatile unsigned int ctrl; -	volatile unsigned int l10_cur_count; -}; - -extern struct sun4d_timer_regs *sun4d_timers; -  extern __volatile__ unsigned int *master_l10_counter; -extern __volatile__ unsigned int *master_l10_limit;  /* FIXME: Make do_[gs]ettimeofday btfixup calls */  BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv) diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index 296ef30e05c..c64e767a3e4 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h @@ -265,8 +265,8 @@ extern long __strnlen_user(const char __user *, long len);  #define strlen_user __strlen_user  #define strnlen_user __strnlen_user -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +#define __copy_to_user_inatomic ___copy_to_user +#define __copy_from_user_inatomic ___copy_from_user  #endif  /* __ASSEMBLY__ */ diff --git a/arch/sparc/include/asm/vac-ops.h b/arch/sparc/include/asm/vac-ops.h index d10527611f1..a63e88ef042 100644 --- a/arch/sparc/include/asm/vac-ops.h +++ b/arch/sparc/include/asm/vac-ops.h @@ -76,11 +76,7 @@   * cacheable bit in the pte's of all such pages.   */ -#ifdef CONFIG_SUN4 -#define S4CVAC_BADBITS     0x0001e000 -#else  #define S4CVAC_BADBITS    0x0000f000 -#endif  /* The following is true if vaddr1 and vaddr2 would cause   * a 'bad alias'. @@ -94,10 +90,7 @@   */  struct sun4c_vac_props {  	unsigned int num_bytes;     /* Size of the cache */ -	unsigned int num_lines;     /* Number of cache lines */  	unsigned int do_hwflushes;  /* Hardware flushing available? */ -	enum { VAC_NONE, VAC_WRITE_THROUGH, -	    VAC_WRITE_BACK } type;  /* What type of VAC? */  	unsigned int linesize;      /* Size of each line in bytes */  	unsigned int log2lsize;     /* log2(linesize) */  	unsigned int on;            /* VAC is enabled */ diff --git a/arch/sparc/include/asm/vfc_ioctls.h b/arch/sparc/include/asm/vfc_ioctls.h deleted file mode 100644 index af8b69007b2..00000000000 --- a/arch/sparc/include/asm/vfc_ioctls.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 1996 by Manish Vachharajani */ - -#ifndef _LINUX_VFC_IOCTLS_H_ -#define	_LINUX_VFC_IOCTLS_H_ - -	/* IOCTLs */ -#define VFC_IOCTL(a)          (('j' << 8) | a) -#define VFCGCTRL	(VFC_IOCTL (0))	        /* get vfc attributes */ -#define VFCSCTRL	(VFC_IOCTL (1))  	/* set vfc attributes */ -#define VFCGVID		(VFC_IOCTL (2)) 	/* get video decoder attributes */ -#define VFCSVID		(VFC_IOCTL (3))	        /* set video decoder attributes */ -#define VFCHUE		(VFC_IOCTL (4))   	/* set hue */ -#define VFCPORTCHG	(VFC_IOCTL (5))  	/* change port */ -#define VFCRDINFO	(VFC_IOCTL (6))  	/* read info */ - -	/* Options for setting the vfc attributes and status */ -#define MEMPRST		0x1	/* reset FIFO ptr. */ -#define CAPTRCMD	0x2	/* start capture and wait */ -#define DIAGMODE	0x3	/* diag mode */ -#define NORMMODE	0x4	/* normal mode */ -#define CAPTRSTR	0x5	/* start capture */ -#define CAPTRWAIT	0x6	/* wait for capture to finish */ - - -	/* Options for the decoder */ -#define STD_NTSC	0x1	/* NTSC mode */ -#define STD_PAL		0x2	/* PAL mode */ -#define COLOR_ON	0x3	/* force color ON */ -#define MONO		0x4	/* force color OFF */ - -	/* Values returned by ioctl 2 */ - -#define NO_LOCK	        1 -#define NTSC_COLOR	2 -#define NTSC_NOCOLOR    3 -#define PAL_COLOR	4 -#define PAL_NOCOLOR	5 - -/* Not too sure what this does yet */ -	/* Options for setting Field number */ -#define ODD_FIELD	0x1 -#define EVEN_FIELD	0x0 -#define ACTIVE_ONLY     0x2 -#define NON_ACTIVE	0x0 - -/* Debug options */ -#define VFC_I2C_SEND 0 -#define VFC_I2C_RECV 1 - -struct vfc_debug_inout -{ -	unsigned long addr; -	unsigned long ret; -	unsigned long len; -	unsigned char __user *buffer; -}; - -#endif /* _LINUX_VFC_IOCTLS_H_ */ diff --git a/arch/sparc/include/asm/visasm.h b/arch/sparc/include/asm/visasm.h index de797b9bf55..39ca301920d 100644 --- a/arch/sparc/include/asm/visasm.h +++ b/arch/sparc/include/asm/visasm.h @@ -57,6 +57,7 @@ static inline void save_and_clear_fpu(void) {  "		" : : "i" (FPRS_FEF|FPRS_DU) :  		"o5", "g1", "g2", "g3", "g7", "cc");  } +extern int vis_emul(struct pt_regs *, unsigned int);  #endif  #endif /* _SPARC64_ASI_H */ diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 6e03a2a7863..2d658209509 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -13,15 +13,13 @@ obj-y    := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \  	    time.o windows.o cpu.o devices.o \  	    tadpole.o tick14.o ptrace.o \  	    unaligned.o una_asm.o muldiv.o \ -	    prom.o of_device.o devres.o +	    prom.o of_device.o devres.o dma.o  devres-y = ../../../kernel/irq/devres.o  obj-$(CONFIG_PCI) += pcic.o -obj-$(CONFIG_SUN4) += sun4setup.o  obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o  obj-$(CONFIG_SUN_AUXIO) += auxio.o -obj-$(CONFIG_PCI) += ebus.o  obj-$(CONFIG_SUN_PM) += apc.o pmc.o  obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o  obj-$(CONFIG_SPARC_LED) += led.o diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 5267d48fb2c..9c115823c4b 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -12,9 +12,10 @@  #include <linux/miscdevice.h>  #include <linux/smp_lock.h>  #include <linux/pm.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include <asm/io.h> -#include <asm/sbus.h>  #include <asm/oplib.h>  #include <asm/uaccess.h>  #include <asm/auxio.h> @@ -29,11 +30,10 @@  #define APC_OBPNAME	"power-management"  #define APC_DEVNAME "apc" -volatile static u8 __iomem *regs;  -static int apc_regsize; -static int apc_no_idle __initdata = 0; +static u8 __iomem *regs; +static int apc_no_idle __devinitdata = 0; -#define apc_readb(offs)			(sbus_readb(regs+offs)) +#define apc_readb(offs)		(sbus_readb(regs+offs))  #define apc_writeb(val, offs) 	(sbus_writeb(val, regs+offs))  /* Specify "apc=noidle" on the kernel command line to  @@ -69,9 +69,9 @@ static void apc_swift_idle(void)  #endif  }  -static inline void apc_free(void) +static inline void apc_free(struct of_device *op)  { -	sbus_iounmap(regs, apc_regsize); +	of_iounmap(&op->resource[0], regs, resource_size(&op->resource[0]));  }  static int apc_open(struct inode *inode, struct file *f) @@ -153,52 +153,56 @@ static const struct file_operations apc_fops = {  static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops }; -static int __init apc_probe(void) +static int __devinit apc_probe(struct of_device *op, +			       const struct of_device_id *match)  { -	struct sbus_bus *sbus = NULL; -	struct sbus_dev *sdev = NULL; -	int iTmp = 0; - -	for_each_sbus(sbus) { -		for_each_sbusdev(sdev, sbus) { -			if (!strcmp(sdev->prom_name, APC_OBPNAME)) { -				goto sbus_done; -			} -		} -	} +	int err; -sbus_done: -	if (!sdev) { -		return -ENODEV; -	} - -	apc_regsize = sdev->reg_addrs[0].reg_size; -	regs = sbus_ioremap(&sdev->resource[0], 0,  -				   apc_regsize, APC_OBPNAME); -	if(!regs) { +	regs = of_ioremap(&op->resource[0], 0, +			  resource_size(&op->resource[0]), APC_OBPNAME); +	if (!regs) {  		printk(KERN_ERR "%s: unable to map registers\n", APC_DEVNAME);  		return -ENODEV;  	} -	iTmp = misc_register(&apc_miscdev); -	if (iTmp != 0) { +	err = misc_register(&apc_miscdev); +	if (err) {  		printk(KERN_ERR "%s: unable to register device\n", APC_DEVNAME); -		apc_free(); +		apc_free(op);  		return -ENODEV;  	}  	/* Assign power management IDLE handler */ -	if(!apc_no_idle) +	if (!apc_no_idle)  		pm_idle = apc_swift_idle;	  	printk(KERN_INFO "%s: power management initialized%s\n",  -		APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : ""); +	       APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : ""); +  	return 0;  } +static struct of_device_id __initdata apc_match[] = { +	{ +		.name = APC_OBPNAME, +	}, +	{}, +}; +MODULE_DEVICE_TABLE(of, apc_match); + +static struct of_platform_driver apc_driver = { +	.name		= "apc", +	.match_table	= apc_match, +	.probe		= apc_probe, +}; + +static int __init apc_init(void) +{ +	return of_register_driver(&apc_driver, &of_bus_type); +} +  /* This driver is not critical to the boot process   * and is easiest to ioremap when SBus is already   * initialized, so we install ourselves thusly:   */ -__initcall(apc_probe); - +__initcall(apc_init); diff --git a/arch/sparc/kernel/auxio.c b/arch/sparc/kernel/auxio.c index baf4ed3fb0f..09c857215a5 100644 --- a/arch/sparc/kernel/auxio.c +++ b/arch/sparc/kernel/auxio.c @@ -6,6 +6,8 @@  #include <linux/stddef.h>  #include <linux/init.h>  #include <linux/spinlock.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include <asm/oplib.h>  #include <asm/io.h>  #include <asm/auxio.h> @@ -59,7 +61,7 @@ void __init auxio_probe(void)  	r.flags = auxregs[0].which_io & 0xF;  	r.start = auxregs[0].phys_addr;  	r.end = auxregs[0].phys_addr + auxregs[0].reg_size - 1; -	auxio_register = sbus_ioremap(&r, 0, auxregs[0].reg_size, "auxio"); +	auxio_register = of_ioremap(&r, 0, auxregs[0].reg_size, "auxio");  	/* Fix the address on sun4m and sun4c. */  	if((((unsigned long) auxregs[0].phys_addr) & 3) == 3 ||  	   sparc_cpu_model == sun4c) @@ -128,7 +130,7 @@ void __init auxio_power_probe(void)  	r.flags = regs.which_io & 0xF;  	r.start = regs.phys_addr;  	r.end = regs.phys_addr + regs.reg_size - 1; -	auxio_power_register = (unsigned char *) sbus_ioremap(&r, 0, +	auxio_power_register = (unsigned char *) of_ioremap(&r, 0,  	    regs.reg_size, "auxpower");  	/* Display a quick message on the console. */ diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index b240b8863fd..ad656b044b8 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c @@ -143,7 +143,7 @@ void __init device_scan(void)  #endif  	clock_stop_probe(); -	if (ARCH_SUN4C_SUN4) +	if (ARCH_SUN4C)  		sun4c_probe_memerr_reg();  	return; diff --git a/arch/sparc/kernel/dma.c b/arch/sparc/kernel/dma.c new file mode 100644 index 00000000000..ebc8403b035 --- /dev/null +++ b/arch/sparc/kernel/dma.c @@ -0,0 +1,227 @@ +/* dma.c: PCI and SBUS DMA accessors for 32-bit sparc. + * + * Copyright (C) 2008 David S. Miller <davem@davemloft.net> + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/dma-mapping.h> +#include <linux/scatterlist.h> +#include <linux/mm.h> + +#ifdef CONFIG_PCI +#include <linux/pci.h> +#endif + +#include "dma.h" + +int dma_supported(struct device *dev, u64 mask) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) +		return pci_dma_supported(to_pci_dev(dev), mask); +#endif +	return 0; +} +EXPORT_SYMBOL(dma_supported); + +int dma_set_mask(struct device *dev, u64 dma_mask) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) +		return pci_set_dma_mask(to_pci_dev(dev), dma_mask); +#endif +	return -EOPNOTSUPP; +} +EXPORT_SYMBOL(dma_set_mask); + +void *dma_alloc_coherent(struct device *dev, size_t size, +			 dma_addr_t *dma_handle, gfp_t flag) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) +		return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle); +#endif +	return sbus_alloc_consistent(dev, size, dma_handle); +} +EXPORT_SYMBOL(dma_alloc_coherent); + +void dma_free_coherent(struct device *dev, size_t size, +		       void *cpu_addr, dma_addr_t dma_handle) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) { +		pci_free_consistent(to_pci_dev(dev), size, +				    cpu_addr, dma_handle); +		return; +	} +#endif +	sbus_free_consistent(dev, size, cpu_addr, dma_handle); +} +EXPORT_SYMBOL(dma_free_coherent); + +dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, +			  size_t size, enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) +		return pci_map_single(to_pci_dev(dev), cpu_addr, +				      size, (int)direction); +#endif +	return sbus_map_single(dev, cpu_addr, size, (int)direction); +} +EXPORT_SYMBOL(dma_map_single); + +void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, +		      size_t size, +		      enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) { +		pci_unmap_single(to_pci_dev(dev), dma_addr, +				 size, (int)direction); +		return; +	} +#endif +	sbus_unmap_single(dev, dma_addr, size, (int)direction); +} +EXPORT_SYMBOL(dma_unmap_single); + +dma_addr_t dma_map_page(struct device *dev, struct page *page, +			unsigned long offset, size_t size, +			enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) +		return pci_map_page(to_pci_dev(dev), page, offset, +				    size, (int)direction); +#endif +	return sbus_map_single(dev, page_address(page) + offset, +			       size, (int)direction); +} +EXPORT_SYMBOL(dma_map_page); + +void dma_unmap_page(struct device *dev, dma_addr_t dma_address, +		    size_t size, enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) { +		pci_unmap_page(to_pci_dev(dev), dma_address, +			       size, (int)direction); +		return; +	} +#endif +	sbus_unmap_single(dev, dma_address, size, (int)direction); +} +EXPORT_SYMBOL(dma_unmap_page); + +int dma_map_sg(struct device *dev, struct scatterlist *sg, +			     int nents, enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) +		return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction); +#endif +	return sbus_map_sg(dev, sg, nents, direction); +} +EXPORT_SYMBOL(dma_map_sg); + +void dma_unmap_sg(struct device *dev, struct scatterlist *sg, +		  int nents, enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) { +		pci_unmap_sg(to_pci_dev(dev), sg, nents, (int)direction); +		return; +	} +#endif +	sbus_unmap_sg(dev, sg, nents, (int)direction); +} +EXPORT_SYMBOL(dma_unmap_sg); + +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, +			     size_t size, enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) { +		pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle, +					    size, (int)direction); +		return; +	} +#endif +	sbus_dma_sync_single_for_cpu(dev, dma_handle, size, (int) direction); +} +EXPORT_SYMBOL(dma_sync_single_for_cpu); + +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, +				size_t size, enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) { +		pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle, +					       size, (int)direction); +		return; +	} +#endif +	sbus_dma_sync_single_for_device(dev, dma_handle, size, (int) direction); +} +EXPORT_SYMBOL(dma_sync_single_for_device); + +void dma_sync_single_range_for_cpu(struct device *dev, +				   dma_addr_t dma_handle, +				   unsigned long offset, +				   size_t size, +				   enum dma_data_direction direction) +{ +	dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction); +} +EXPORT_SYMBOL(dma_sync_single_range_for_cpu); + +void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, +				      unsigned long offset, size_t size, +				      enum dma_data_direction direction) +{ +	dma_sync_single_for_device(dev, dma_handle+offset, size, direction); +} +EXPORT_SYMBOL(dma_sync_single_range_for_device); + +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, +			 int nelems, enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) { +		pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg, +					nelems, (int)direction); +		return; +	} +#endif +	BUG(); +} +EXPORT_SYMBOL(dma_sync_sg_for_cpu); + +void dma_sync_sg_for_device(struct device *dev, +			    struct scatterlist *sg, int nelems, +			    enum dma_data_direction direction) +{ +#ifdef CONFIG_PCI +	if (dev->bus == &pci_bus_type) { +		pci_dma_sync_sg_for_device(to_pci_dev(dev), sg, +					   nelems, (int)direction); +		return; +	} +#endif +	BUG(); +} +EXPORT_SYMBOL(dma_sync_sg_for_device); + +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ +	return (dma_addr == DMA_ERROR_CODE); +} +EXPORT_SYMBOL(dma_mapping_error); + +int dma_get_cache_alignment(void) +{ +	return 32; +} +EXPORT_SYMBOL(dma_get_cache_alignment); diff --git a/arch/sparc/kernel/dma.h b/arch/sparc/kernel/dma.h new file mode 100644 index 00000000000..f8d8951adb5 --- /dev/null +++ b/arch/sparc/kernel/dma.h @@ -0,0 +1,14 @@ +void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp); +void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba); +dma_addr_t sbus_map_single(struct device *dev, void *va, +			   size_t len, int direction); +void sbus_unmap_single(struct device *dev, dma_addr_t ba, +		       size_t n, int direction); +int sbus_map_sg(struct device *dev, struct scatterlist *sg, +		int n, int direction); +void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, +		   int n, int direction); +void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba, +				  size_t size, int direction); +void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, +				     size_t size, int direction); diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c deleted file mode 100644 index 97294232259..00000000000 --- a/arch/sparc/kernel/ebus.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * ebus.c: PCI to EBus bridge device. - * - * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be) - * - * Adopted for sparc by V. Roganov and G. Raiko. - * Fixes for different platforms by Pete Zaitcev. - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/string.h> - -#include <asm/system.h> -#include <asm/page.h> -#include <asm/pbm.h> -#include <asm/ebus.h> -#include <asm/io.h> -#include <asm/oplib.h> -#include <asm/prom.h> -#include <asm/bpp.h> - -struct linux_ebus *ebus_chain = NULL; - -/* We are together with pcic.c under CONFIG_PCI. */ -extern unsigned int pcic_pin_to_irq(unsigned int, const char *name); - -/* - * IRQ Blacklist - * Here we list PROMs and systems that are known to supply crap as IRQ numbers. - */ -struct ebus_device_irq { -	char *name; -	unsigned int pin; -}; - -struct ebus_system_entry { -	char *esname; -	struct ebus_device_irq *ipt; -}; - -static struct ebus_device_irq je1_1[] = { -	{ "8042",		 3 }, -	{ "SUNW,CS4231",	 0 }, -	{ "parallel",		 0 }, -	{ "se",			 2 }, -	{ NULL, 0 } -}; - -/* - * Gleb's JE1 supplied reasonable pin numbers, but mine did not (OBP 2.32). - * Blacklist the sucker... Note that Gleb's system will work. - */ -static struct ebus_system_entry ebus_blacklist[] = { -	{ "SUNW,JavaEngine1", je1_1 }, -	{ NULL, NULL } -}; - -static struct ebus_device_irq *ebus_blackp = NULL; - -/* - */ -static inline unsigned long ebus_alloc(size_t size) -{ -	return (unsigned long)kmalloc(size, GFP_ATOMIC); -} - -/* - */ -static int __init ebus_blacklist_irq(const char *name) -{ -	struct ebus_device_irq *dp; - -	if ((dp = ebus_blackp) != NULL) { -		for (; dp->name != NULL; dp++) { -			if (strcmp(name, dp->name) == 0) { -				return pcic_pin_to_irq(dp->pin, name); -			} -		} -	} -	return 0; -} - -static void __init fill_ebus_child(struct device_node *dp, -				   struct linux_ebus_child *dev) -{ -	const int *regs; -	const int *irqs; -	int i, len; - -	dev->prom_node = dp; -	regs = of_get_property(dp, "reg", &len); -	if (!regs) -		len = 0; -	dev->num_addrs = len / sizeof(regs[0]); - -	for (i = 0; i < dev->num_addrs; i++) { -		if (regs[i] >= dev->parent->num_addrs) { -			prom_printf("UGH: property for %s was %d, need < %d\n", -				    dev->prom_node->name, len, -				    dev->parent->num_addrs); -			panic(__func__); -		} - -		/* XXX resource */ -		dev->resource[i].start = -			dev->parent->resource[regs[i]].start; -	} - -	for (i = 0; i < PROMINTR_MAX; i++) -		dev->irqs[i] = PCI_IRQ_NONE; - -	if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) { -		dev->num_irqs = 1; -	} else { -		irqs = of_get_property(dp, "interrupts", &len); -		if (!irqs) { -			dev->num_irqs = 0; -			dev->irqs[0] = 0; -			if (dev->parent->num_irqs != 0) { -				dev->num_irqs = 1; -				dev->irqs[0] = dev->parent->irqs[0]; -			} -		} else { -			dev->num_irqs = len / sizeof(irqs[0]); -			if (irqs[0] == 0 || irqs[0] >= 8) { -				/* -				 * XXX Zero is a valid pin number... -				 * This works as long as Ebus is not wired -				 * to INTA#. -				 */ -				printk("EBUS: %s got bad irq %d from PROM\n", -				       dev->prom_node->name, irqs[0]); -				dev->num_irqs = 0; -				dev->irqs[0] = 0; -			} else { -				dev->irqs[0] = -					pcic_pin_to_irq(irqs[0], -							dev->prom_node->name); -			} -		} -	} -} - -static void __init fill_ebus_device(struct device_node *dp, -				    struct linux_ebus_device *dev) -{ -	const struct linux_prom_registers *regs; -	struct linux_ebus_child *child; -	struct dev_archdata *sd; -	const int *irqs; -	int i, n, len; -	unsigned long baseaddr; - -	dev->prom_node = dp; - -	regs = of_get_property(dp, "reg", &len); -	if (!regs) -		len = 0; -	if (len % sizeof(struct linux_prom_registers)) { -		prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", -			    dev->prom_node->name, len, -			    (int)sizeof(struct linux_prom_registers)); -		panic(__func__); -	} -	dev->num_addrs = len / sizeof(struct linux_prom_registers); - -	for (i = 0; i < dev->num_addrs; i++) { -		/* -		 * XXX Collect JE-1 PROM -		 *  -		 * Example - JS-E with 3.11: -		 *  /ebus -		 *      regs  -		 *        0x00000000, 0x0, 0x00000000, 0x0, 0x00000000, -		 *        0x82000010, 0x0, 0xf0000000, 0x0, 0x01000000, -		 *        0x82000014, 0x0, 0x38800000, 0x0, 0x00800000, -		 *      ranges -		 *        0x00, 0x00000000, 0x02000010, 0x0, 0x0, 0x01000000, -		 *        0x01, 0x01000000, 0x02000014, 0x0, 0x0, 0x00800000, -		 *  /ebus/8042 -		 *      regs -		 *        0x00000001, 0x00300060, 0x00000008, -		 *        0x00000001, 0x00300060, 0x00000008, -		 */ -		n = regs[i].which_io; -		if (n >= 4) { -			/* XXX This is copied from old JE-1 by Gleb. */ -			n = (regs[i].which_io - 0x10) >> 2; -		} else { -			; -		} - -/* - * XXX Now as we have regions, why don't we make an on-demand allocation... - */ -		dev->resource[i].start = 0; -		if ((baseaddr = dev->bus->self->resource[n].start + -		    regs[i].phys_addr) != 0) { -			/* dev->resource[i].name = dev->prom_name; */ -			if ((baseaddr = (unsigned long) ioremap(baseaddr, -			    regs[i].reg_size)) == 0) { -				panic("ebus: unable to remap dev %s", -				      dev->prom_node->name); -			} -		} -		dev->resource[i].start = baseaddr;	/* XXX Unaligned */ -	} - -	for (i = 0; i < PROMINTR_MAX; i++) -		dev->irqs[i] = PCI_IRQ_NONE; - -	if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) { -		dev->num_irqs = 1; -	} else { -		irqs = of_get_property(dp, "interrupts", &len); -		if (!irqs) { -			dev->num_irqs = 0; -			if ((dev->irqs[0] = dev->bus->self->irq) != 0) { -				dev->num_irqs = 1; -/* P3 */ /* printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */ -			} -		} else { -			dev->num_irqs = 1;  /* dev->num_irqs = len / sizeof(irqs[0]); */ -			if (irqs[0] == 0 || irqs[0] >= 8) { -				/* See above for the parent. XXX */ -				printk("EBUS: %s got bad irq %d from PROM\n", -				       dev->prom_node->name, irqs[0]); -				dev->num_irqs = 0; -				dev->irqs[0] = 0; -			} else { -				dev->irqs[0] = -					pcic_pin_to_irq(irqs[0], -							dev->prom_node->name); -			} -		} -	} - -	sd = &dev->ofdev.dev.archdata; -	sd->prom_node = dp; -	sd->op = &dev->ofdev; -	sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu; - -	dev->ofdev.node = dp; -	dev->ofdev.dev.parent = &dev->bus->ofdev.dev; -	dev->ofdev.dev.bus = &ebus_bus_type; -	sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node); - -	/* Register with core */ -	if (of_device_register(&dev->ofdev) != 0) -		printk(KERN_DEBUG "ebus: device registration error for %s!\n", -		       dp->path_component_name); - -	if ((dp = dp->child) != NULL) { -		dev->children = (struct linux_ebus_child *) -			ebus_alloc(sizeof(struct linux_ebus_child)); - -		child = dev->children; -		child->next = NULL; -		child->parent = dev; -		child->bus = dev->bus; -		fill_ebus_child(dp, child); - -		while ((dp = dp->sibling) != NULL) { -			child->next = (struct linux_ebus_child *) -				ebus_alloc(sizeof(struct linux_ebus_child)); - -			child = child->next; -			child->next = NULL; -			child->parent = dev; -			child->bus = dev->bus; -			fill_ebus_child(dp, child); -		} -	} -} - -void __init ebus_init(void) -{ -	const struct linux_prom_pci_registers *regs; -	struct linux_pbm_info *pbm; -	struct linux_ebus_device *dev; -	struct linux_ebus *ebus; -	struct ebus_system_entry *sp; -	struct pci_dev *pdev; -	struct pcidev_cookie *cookie; -	struct device_node *dp; -	struct resource *p; -	unsigned short pci_command; -	int len, reg, nreg; -	int num_ebus = 0; - -	dp = of_find_node_by_path("/"); -	for (sp = ebus_blacklist; sp->esname != NULL; sp++) { -		if (strcmp(dp->name, sp->esname) == 0) { -			ebus_blackp = sp->ipt; -			break; -		} -	} - -	pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL); -	if (!pdev) -		return; - -	cookie = pdev->sysdata; -	dp = cookie->prom_node; - -	ebus_chain = ebus = (struct linux_ebus *) -			ebus_alloc(sizeof(struct linux_ebus)); -	ebus->next = NULL; - -	while (dp) { -		struct device_node *nd; - -		ebus->prom_node = dp; -		ebus->self = pdev; -		ebus->parent = pbm = cookie->pbm; - -		/* Enable BUS Master. */ -		pci_read_config_word(pdev, PCI_COMMAND, &pci_command); -		pci_command |= PCI_COMMAND_MASTER; -		pci_write_config_word(pdev, PCI_COMMAND, pci_command); - -		regs = of_get_property(dp, "reg", &len); -		if (!regs) { -			prom_printf("%s: can't find reg property\n", -				    __func__); -			prom_halt(); -		} -		nreg = len / sizeof(struct linux_prom_pci_registers); - -		p = &ebus->self->resource[0]; -		for (reg = 0; reg < nreg; reg++) { -			if (!(regs[reg].which_io & 0x03000000)) -				continue; - -			(p++)->start = regs[reg].phys_lo; -		} - -		ebus->ofdev.node = dp; -		ebus->ofdev.dev.parent = &pdev->dev; -		ebus->ofdev.dev.bus = &ebus_bus_type; -		sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus); - -		/* Register with core */ -		if (of_device_register(&ebus->ofdev) != 0) -			printk(KERN_DEBUG "ebus: device registration error for %s!\n", -			       dp->path_component_name); - - -		nd = dp->child; -		if (!nd) -			goto next_ebus; - -		ebus->devices = (struct linux_ebus_device *) -				ebus_alloc(sizeof(struct linux_ebus_device)); - -		dev = ebus->devices; -		dev->next = NULL; -		dev->children = NULL; -		dev->bus = ebus; -		fill_ebus_device(nd, dev); - -		while ((nd = nd->sibling) != NULL) { -			dev->next = (struct linux_ebus_device *) -				ebus_alloc(sizeof(struct linux_ebus_device)); - -			dev = dev->next; -			dev->next = NULL; -			dev->children = NULL; -			dev->bus = ebus; -			fill_ebus_device(nd, dev); -		} - -	next_ebus: -		pdev = pci_get_device(PCI_VENDOR_ID_SUN, -				       PCI_DEVICE_ID_SUN_EBUS, pdev); -		if (!pdev) -			break; - -		cookie = pdev->sysdata; -		dp = cookie->prom_node; - -		ebus->next = (struct linux_ebus *) -			ebus_alloc(sizeof(struct linux_ebus)); -		ebus = ebus->next; -		ebus->next = NULL; -		++num_ebus; -	} -	if (pdev) -		pci_dev_put(pdev); -} diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index e8cdf715a54..faf9ccd9ef5 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -20,11 +20,7 @@  #include <asm/memreg.h>  #include <asm/page.h>  #include <asm/pgtable.h> -#ifdef CONFIG_SUN4 -#include <asm/pgtsun4.h> -#else  #include <asm/pgtsun4c.h> -#endif  #include <asm/winmacro.h>  #include <asm/signal.h>  #include <asm/obio.h> @@ -276,17 +272,18 @@ smp4m_ticker:  	 */  maybe_smp4m_msg:  	GET_PROCESSOR4M_ID(o3) -	set	sun4m_interrupts, %l5 -	ld	[%l5], %o5 +	sethi	%hi(sun4m_irq_percpu), %l5 +	sll	%o3, 2, %o3 +	or	%l5, %lo(sun4m_irq_percpu), %o5  	sethi	%hi(0x40000000), %o2 -	sll	%o3, 12, %o3  	ld	[%o5 + %o3], %o1 -	andcc	%o1, %o2, %g0 +	ld	[%o1 + 0x00], %o3	! sun4m_irq_percpu[cpu]->pending +	andcc	%o3, %o2, %g0  	be,a	smp4m_ticker  	 cmp	%l7, 14 -	st	%o2, [%o5 + 0x4] +	st	%o2, [%o1 + 0x04]	! sun4m_irq_percpu[cpu]->clear=0x40000000  	WRITE_PAUSE -	ld	[%o5], %g0 +	ld	[%o1 + 0x00], %g0	! sun4m_irq_percpu[cpu]->pending  	WRITE_PAUSE  	or	%l0, PSR_PIL, %l4  	wr	%l4, 0x0, %psr @@ -304,16 +301,16 @@ linux_trap_ipi15_sun4m:  	SAVE_ALL  	sethi	%hi(0x80000000), %o2  	GET_PROCESSOR4M_ID(o0) -	set	sun4m_interrupts, %l5 -	ld	[%l5], %o5 -	sll	%o0, 12, %o0 -	add	%o5, %o0, %o5 -	ld	[%o5], %o3 +	sethi	%hi(sun4m_irq_percpu), %l5 +	or	%l5, %lo(sun4m_irq_percpu), %o5 +	sll	%o0, 2, %o0 +	ld	[%o5 + %o0], %o5 +	ld	[%o5 + 0x00], %o3	! sun4m_irq_percpu[cpu]->pending  	andcc	%o3, %o2, %g0  	be	1f			! Must be an NMI async memory error -	 st	%o2, [%o5 + 4] +	 st	%o2, [%o5 + 0x04]	! sun4m_irq_percpu[cpu]->clear=0x80000000  	WRITE_PAUSE -	ld	[%o5], %g0 +	ld	[%o5 + 0x00], %g0	! sun4m_irq_percpu[cpu]->pending  	WRITE_PAUSE  	or	%l0, PSR_PIL, %l4  	wr	%l4, 0x0, %psr @@ -327,12 +324,11 @@ linux_trap_ipi15_sun4m:  1:  	/* NMI async memory error handling. */  	sethi	%hi(0x80000000), %l4 -	sethi	%hi(0x4000), %o3 -	sub	%o5, %o0, %o5 -	add	%o5, %o3, %l5 -	st	%l4, [%l5 + 0xc] +	sethi	%hi(sun4m_irq_global), %o5 +	ld	[%o5 + %lo(sun4m_irq_global)], %l5 +	st	%l4, [%l5 + 0x0c]	! sun4m_irq_global->mask_set=0x80000000  	WRITE_PAUSE -	ld	[%l5], %g0 +	ld	[%l5 + 0x00], %g0	! sun4m_irq_global->pending  	WRITE_PAUSE  	or	%l0, PSR_PIL, %l4  	wr	%l4, 0x0, %psr @@ -341,9 +337,9 @@ linux_trap_ipi15_sun4m:  	WRITE_PAUSE  	call	sun4m_nmi  	 nop -	st	%l4, [%l5 + 0x8] +	st	%l4, [%l5 + 0x08]	! sun4m_irq_global->mask_clear=0x80000000  	WRITE_PAUSE -	ld	[%l5], %g0 +	ld	[%l5 + 0x00], %g0	! sun4m_irq_global->pending  	WRITE_PAUSE  	RESTORE_ALL @@ -775,11 +771,7 @@ vac_linesize_patch_32:		subcc	%l7, 32, %l7   * Ugly, but we cant use hardware flushing on the sun4 and we'd require   * two instructions (Anton)   */ -#ifdef CONFIG_SUN4 -vac_hwflush_patch1_on:		nop -#else  vac_hwflush_patch1_on:		addcc	%l7, -PAGE_SIZE, %l7 -#endif  vac_hwflush_patch2_on:		sta	%g0, [%l3 + %l7] ASI_HWFLUSHSEG @@ -798,42 +790,10 @@ vac_hwflush_patch2_on:		sta	%g0, [%l3 + %l7] ASI_HWFLUSHSEG  ! %l7 = 1 for textfault  ! We want error in %l5, vaddr in %l6  sun4c_fault: -#ifdef CONFIG_SUN4 -	sethi	%hi(sun4c_memerr_reg), %l4 -	ld	[%l4+%lo(sun4c_memerr_reg)], %l4  ! memerr ctrl reg addr -	ld	[%l4], %l6		! memerr ctrl reg -	ld	[%l4 + 4], %l5		! memerr vaddr reg -	andcc	%l6, 0x80, %g0		! check for error type -	st	%g0, [%l4 + 4]		! clear the error -	be	0f			! normal error -	 sethi	%hi(AC_BUS_ERROR), %l4	! bus err reg addr - -	call	prom_halt	! something weird happened -					! what exactly did happen? -					! what should we do here? - -0:	or	%l4, %lo(AC_BUS_ERROR), %l4	! bus err reg addr -	lduba	[%l4] ASI_CONTROL, %l6	! bus err reg - -	cmp    %l7, 1			! text fault? -	be	1f			! yes -	 nop - -	ld     [%l1], %l4		! load instruction that caused fault -	srl	%l4, 21, %l4 -	andcc	%l4, 1, %g0		! store instruction? - -	be	1f			! no -	 sethi	%hi(SUN4C_SYNC_BADWRITE), %l4 ! yep -					! %lo(SUN4C_SYNC_BADWRITE) = 0 -	or	%l4, %l6, %l6		! set write bit to emulate sun4c -1: -#else  	sethi	%hi(AC_SYNC_ERR), %l4  	add	%l4, 0x4, %l6			! AC_SYNC_VA in %l6  	lda	[%l6] ASI_CONTROL, %l5		! Address  	lda	[%l4] ASI_CONTROL, %l6		! Error, retained for a bit -#endif  	andn	%l5, 0xfff, %l5			! Encode all info into l7  	srl	%l6, 14, %l4 @@ -880,12 +840,7 @@ sun4c_fault:  	or      %l4, %lo(swapper_pg_dir), %l4  	sll     %l6, 2, %l6  	ld      [%l4 + %l6], %l4 -#ifdef CONFIG_SUN4 -	sethi	%hi(PAGE_MASK), %l6 -	andcc	%l4, %l6, %g0 -#else  	andcc   %l4, PAGE_MASK, %g0 -#endif  	be      sun4c_fault_fromuser  	 lduXa  [%l5] ASI_SEGMAP, %l4 @@ -937,11 +892,7 @@ invalid_segment_patch1:  	ld	[%l6 + 0x08], %l3	! tmp = entry->vaddr  	! Flush segment from the cache. -#ifdef CONFIG_SUN4 -	sethi	%hi((128 * 1024)), %l7 -#else  	sethi	%hi((64 * 1024)), %l7 -#endif  9:  vac_hwflush_patch1:  vac_linesize_patch: @@ -1029,12 +980,7 @@ invalid_segment_patch2:  	or	%l4, %lo(swapper_pg_dir), %l4  	sll	%l3, 2, %l3  	ld	[%l4 + %l3], %l4 -#ifndef CONFIG_SUN4  	and	%l4, PAGE_MASK, %l4 -#else -	sethi	%hi(PAGE_MASK), %l6 -	and	%l4, %l6, %l4 -#endif  	srl	%l5, (PAGE_SHIFT - 2), %l6  	and	%l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6 diff --git a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S index 50d9a16af79..2d325fd8457 100644 --- a/arch/sparc/kernel/head.S +++ b/arch/sparc/kernel/head.S @@ -63,15 +63,9 @@ cputypvar_sun4m:  	.align 4 -#ifndef CONFIG_SUN4  sun4_notsup: -	.asciz	"Sparc-Linux sun4 needs a specially compiled kernel, turn CONFIG_SUN4 on.\n\n" +	.asciz	"Sparc-Linux sun4 support does no longer exist.\n\n"  	.align 4 -#else -sun4cdm_notsup: -	.asciz	"Kernel compiled with CONFIG_SUN4 cannot run on SUN4C/SUN4M/SUN4D\nTurn CONFIG_SUN4 off.\n\n" -	.align 4 -#endif  sun4e_notsup:          .asciz  "Sparc-Linux sun4e support does not exist\n\n" @@ -780,15 +774,6 @@ execute_in_high_mem:  		 nop  found_version: -#ifdef CONFIG_SUN4 -/* For people who try sun4 kernels, even if Configure.help advises them. */ -		ld	[%g7 + 0x68], %o1 -		set	sun4cdm_notsup, %o0 -		call	%o1 -		 nop -		b	halt_me -		 nop -#endif  /* Get the machine type via the mysterious romvec node operations. */  		add	%g7, 0x1c, %l1		 @@ -1150,15 +1135,6 @@ sun4c_continue_boot:  		 nop  sun4_init: -#ifdef CONFIG_SUN4 -/* There, happy now Adrian? */ -		set	cputypval, %o2		! Let everyone know we -		set	' ', %o0			! are a "sun4 " architecture -		stb	%o0, [%o2 + 0x4]		 - -		b got_prop  -		 nop -#else  		sethi   %hi(SUN4_PROM_VECTOR+0x84), %o1  		ld      [%o1 + %lo(SUN4_PROM_VECTOR+0x84)], %o1  		set     sun4_notsup, %o0 @@ -1170,7 +1146,7 @@ sun4_init:  		 nop  1:		ba      1b                      ! Cannot exit into KMON  		 nop -#endif +  no_sun4e_here:  		ld	[%g7 + 0x68], %o1  		set	sun4e_notsup, %o0 diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c index fc511f3c4c1..223a6582e1e 100644 --- a/arch/sparc/kernel/idprom.c +++ b/arch/sparc/kernel/idprom.c @@ -12,10 +12,6 @@  #include <asm/oplib.h>  #include <asm/idprom.h>  #include <asm/machines.h>  /* Fun with Sun released architectures. */ -#ifdef CONFIG_SUN4 -#include <asm/sun4paddr.h> -extern void sun4setup(void); -#endif  struct idprom *idprom;  static struct idprom idprom_buffer; @@ -101,7 +97,4 @@ void __init idprom_init(void)  		    idprom->id_ethaddr[0], idprom->id_ethaddr[1],  		    idprom->id_ethaddr[2], idprom->id_ethaddr[3],  		    idprom->id_ethaddr[4], idprom->id_ethaddr[5]); -#ifdef CONFIG_SUN4 -	sun4setup(); -#endif  } diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 2a8a847764d..4f025b36934 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -42,10 +42,13 @@  #include <asm/vaddrs.h>  #include <asm/oplib.h>  #include <asm/prom.h> -#include <asm/sbus.h>  #include <asm/page.h>  #include <asm/pgalloc.h>  #include <asm/dma.h> +#include <asm/iommu.h> +#include <asm/io-unit.h> + +#include "dma.h"  #define mmu_inval_dma_area(p, l)	/* Anton pulled it out for 2.4.0-xx */ @@ -139,15 +142,6 @@ void iounmap(volatile void __iomem *virtual)  	}  } -/* - */ -void __iomem *sbus_ioremap(struct resource *phyres, unsigned long offset, -    unsigned long size, char *name) -{ -	return _sparc_alloc_io(phyres->flags & 0xF, -	    phyres->start + offset, size, name); -} -  void __iomem *of_ioremap(struct resource *res, unsigned long offset,  			 unsigned long size, char *name)  { @@ -164,13 +158,6 @@ void of_iounmap(struct resource *res, void __iomem *base, unsigned long size)  EXPORT_SYMBOL(of_iounmap);  /* - */ -void sbus_iounmap(volatile void __iomem *addr, unsigned long size) -{ -	iounmap(addr); -} - -/*   * Meat of mapping   */  static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, @@ -246,63 +233,19 @@ static void _sparc_free_io(struct resource *res)  #ifdef CONFIG_SBUS -void sbus_set_sbus64(struct sbus_dev *sdev, int x) +void sbus_set_sbus64(struct device *dev, int x)  {  	printk("sbus_set_sbus64: unsupported\n");  } -extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq); -void __init sbus_fill_device_irq(struct sbus_dev *sdev) -{ -	struct linux_prom_irqs irqs[PROMINTR_MAX]; -	int len; - -	len = prom_getproperty(sdev->prom_node, "intr", -			       (char *)irqs, sizeof(irqs)); -	if (len != -1) { -		sdev->num_irqs = len / 8; -		if (sdev->num_irqs == 0) { -			sdev->irqs[0] = 0; -		} else if (sparc_cpu_model == sun4d) { -			for (len = 0; len < sdev->num_irqs; len++) -				sdev->irqs[len] = -					sun4d_build_irq(sdev, irqs[len].pri); -		} else { -			for (len = 0; len < sdev->num_irqs; len++) -				sdev->irqs[len] = irqs[len].pri; -		} -	} else { -		int interrupts[PROMINTR_MAX]; - -		/* No "intr" node found-- check for "interrupts" node. -		 * This node contains SBus interrupt levels, not IPLs -		 * as in "intr", and no vector values.  We convert -		 * SBus interrupt levels to PILs (platform specific). -		 */ -		len = prom_getproperty(sdev->prom_node, "interrupts", -				       (char *)interrupts, sizeof(interrupts)); -		if (len == -1) { -			sdev->irqs[0] = 0; -			sdev->num_irqs = 0; -		} else { -			sdev->num_irqs = len / sizeof(int); -			for (len = 0; len < sdev->num_irqs; len++) { -				sdev->irqs[len] = -					sbint_to_irq(sdev, interrupts[len]); -			} -		} -	}  -} -  /*   * Allocate a chunk of memory suitable for DMA.   * Typically devices use them for control blocks.   * CPU may access them without any explicit flushing. - * - * XXX Some clever people know that sdev is not used and supply NULL. Watch.   */ -void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) +void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp)  { +	struct of_device *op = to_of_device(dev);  	unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;  	unsigned long va;  	struct resource *res; @@ -336,13 +279,10 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp)  	 * XXX That's where sdev would be used. Currently we load  	 * all iommu tables with the same translations.  	 */ -	if (mmu_map_dma_area(dma_addrp, va, res->start, len_total) != 0) +	if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0)  		goto err_noiommu; -	/* Set the resource name, if known. */ -	if (sdev) { -		res->name = sdev->prom_name; -	} +	res->name = op->node->name;  	return (void *)(unsigned long)res->start; @@ -356,7 +296,7 @@ err_nopages:  	return NULL;  } -void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba) +void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba)  {  	struct resource *res;  	struct page *pgv; @@ -383,8 +323,8 @@ void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba)  	kfree(res);  	/* mmu_inval_dma_area(va, n); */ /* it's consistent, isn't it */ -	pgv = mmu_translate_dvma(ba); -	mmu_unmap_dma_area(ba, n); +	pgv = virt_to_page(p); +	mmu_unmap_dma_area(dev, ba, n);  	__free_pages(pgv, get_order(n));  } @@ -394,7 +334,7 @@ void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba)   * CPU view of this memory may be inconsistent with   * a device view and explicit flushing is necessary.   */ -dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *va, size_t len, int direction) +dma_addr_t sbus_map_single(struct device *dev, void *va, size_t len, int direction)  {  	/* XXX why are some lengths signed, others unsigned? */  	if (len <= 0) { @@ -404,17 +344,17 @@ dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *va, size_t len, int dire  	if (len > 256*1024) {			/* __get_free_pages() limit */  		return 0;  	} -	return mmu_get_scsi_one(va, len, sdev->bus); +	return mmu_get_scsi_one(dev, va, len);  } -void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t ba, size_t n, int direction) +void sbus_unmap_single(struct device *dev, dma_addr_t ba, size_t n, int direction)  { -	mmu_release_scsi_one(ba, n, sdev->bus); +	mmu_release_scsi_one(dev, ba, n);  } -int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) +int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n, int direction)  { -	mmu_get_scsi_sgl(sg, n, sdev->bus); +	mmu_get_scsi_sgl(dev, sg, n);  	/*  	 * XXX sparc64 can return a partial length here. sun4c should do this @@ -423,145 +363,28 @@ int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direct  	return n;  } -void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) -{ -	mmu_release_scsi_sgl(sg, n, sdev->bus); -} - -/* - */ -void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction) -{ -#if 0 -	unsigned long va; -	struct resource *res; - -	/* We do not need the resource, just print a message if invalid. */ -	res = _sparc_find_resource(&_sparc_dvma, ba); -	if (res == NULL) -		panic("sbus_dma_sync_single: 0x%x\n", ba); - -	va = page_address(mmu_translate_dvma(ba)); /* XXX higmem */ -	/* -	 * XXX This bogosity will be fixed with the iommu rewrite coming soon -	 * to a kernel near you. - Anton -	 */ -	/* mmu_inval_dma_area(va, (size + PAGE_SIZE-1) & PAGE_MASK); */ -#endif -} - -void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction) +void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, int n, int direction)  { -#if 0 -	unsigned long va; -	struct resource *res; - -	/* We do not need the resource, just print a message if invalid. */ -	res = _sparc_find_resource(&_sparc_dvma, ba); -	if (res == NULL) -		panic("sbus_dma_sync_single: 0x%x\n", ba); - -	va = page_address(mmu_translate_dvma(ba)); /* XXX higmem */ -	/* -	 * XXX This bogosity will be fixed with the iommu rewrite coming soon -	 * to a kernel near you. - Anton -	 */ -	/* mmu_inval_dma_area(va, (size + PAGE_SIZE-1) & PAGE_MASK); */ -#endif +	mmu_release_scsi_sgl(dev, sg, n);  } -void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) +void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba, size_t size, int direction)  { -	printk("sbus_dma_sync_sg_for_cpu: not implemented yet\n");  } -void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) +void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, size_t size, int direction)  { -	printk("sbus_dma_sync_sg_for_device: not implemented yet\n"); -} - -/* Support code for sbus_init().  */ -/* - * XXX This functions appears to be a distorted version of - * prom_sbus_ranges_init(), with all sun4d stuff cut away. - * Ask DaveM what is going on here, how is sun4d supposed to work... XXX - */ -/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */ -void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *sbus) -{ -	int parent_node = pn->node; - -	if (sparc_cpu_model == sun4d) { -		struct linux_prom_ranges iounit_ranges[PROMREG_MAX]; -		int num_iounit_ranges, len; - -		len = prom_getproperty(parent_node, "ranges", -				       (char *) iounit_ranges, -				       sizeof (iounit_ranges)); -		if (len != -1) { -			num_iounit_ranges = -				(len / sizeof(struct linux_prom_ranges)); -			prom_adjust_ranges(sbus->sbus_ranges, -					   sbus->num_sbus_ranges, -					   iounit_ranges, num_iounit_ranges); -		} -	}  } -void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) -{ -#ifndef CONFIG_SUN4 -	struct device_node *parent = dp->parent; - -	if (sparc_cpu_model != sun4d && -	    parent != NULL && -	    !strcmp(parent->name, "iommu")) { -		extern void iommu_init(int iommu_node, struct sbus_bus *sbus); - -		iommu_init(parent->node, sbus); -	} - -	if (sparc_cpu_model == sun4d) { -		extern void iounit_init(int sbi_node, int iounit_node, -					struct sbus_bus *sbus); - -		iounit_init(dp->node, parent->node, sbus); -	} -#endif -} - -void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp) -{ -	if (sparc_cpu_model == sun4d) { -		struct device_node *parent = dp->parent; - -		sbus->devid = of_getintprop_default(parent, "device-id", 0); -		sbus->board = of_getintprop_default(parent, "board#", 0); -	} -} - -int __init sbus_arch_preinit(void) +static int __init sparc_register_ioport(void)  {  	register_proc_sparc_ioport(); -#ifdef CONFIG_SUN4 -	{ -		extern void sun4_dvma_init(void); -		sun4_dvma_init(); -	} -	return 1; -#else  	return 0; -#endif  } -void __init sbus_arch_postinit(void) -{ -	if (sparc_cpu_model == sun4d) { -		extern void sun4d_init_sbi_irq(void); -		sun4d_init_sbi_irq(); -	} -} +arch_initcall(sparc_register_ioport); +  #endif /* CONFIG_SBUS */  #ifdef CONFIG_PCI diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index 32ef3ebd0a8..db751388153 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h @@ -13,7 +13,6 @@ BTFIXUPDEF_CALL(void, enable_irq, unsigned int)  BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int)  BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int)  BTFIXUPDEF_CALL(void, clear_clock_irq, void) -BTFIXUPDEF_CALL(void, clear_profile_irq, int)  BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int)  static inline void __disable_irq(unsigned int irq) @@ -41,11 +40,6 @@ static inline void clear_clock_irq(void)  	BTFIXUP_CALL(clear_clock_irq)();  } -static inline void clear_profile_irq(int irq) -{ -	BTFIXUP_CALL(clear_profile_irq)(irq); -} -  static inline void load_profile_irq(int cpu, int limit)  {  	BTFIXUP_CALL(load_profile_irq)(cpu, limit); diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index f58c537446a..0837bd52e28 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -29,15 +29,38 @@ struct of_device *of_find_device_by_node(struct device_node *dp)  }  EXPORT_SYMBOL(of_find_device_by_node); -#ifdef CONFIG_PCI -struct bus_type ebus_bus_type; -EXPORT_SYMBOL(ebus_bus_type); -#endif +unsigned int irq_of_parse_and_map(struct device_node *node, int index) +{ +	struct of_device *op = of_find_device_by_node(node); + +	if (!op || index >= op->num_irqs) +		return 0; + +	return op->irqs[index]; +} +EXPORT_SYMBOL(irq_of_parse_and_map); + +/* Take the archdata values for IOMMU, STC, and HOSTDATA found in + * BUS and propagate to all child of_device objects. + */ +void of_propagate_archdata(struct of_device *bus) +{ +	struct dev_archdata *bus_sd = &bus->dev.archdata; +	struct device_node *bus_dp = bus->node; +	struct device_node *dp; + +	for (dp = bus_dp->child; dp; dp = dp->sibling) { +		struct of_device *op = of_find_device_by_node(dp); -#ifdef CONFIG_SBUS -struct bus_type sbus_bus_type; -EXPORT_SYMBOL(sbus_bus_type); -#endif +		op->dev.archdata.iommu = bus_sd->iommu; +		op->dev.archdata.stc = bus_sd->stc; +		op->dev.archdata.host_controller = bus_sd->host_controller; +		op->dev.archdata.numa_node = bus_sd->numa_node; + +		if (dp->child) +			of_propagate_archdata(op); +	} +}  struct bus_type of_platform_bus_type;  EXPORT_SYMBOL(of_platform_bus_type); @@ -327,6 +350,27 @@ static int __init build_one_resource(struct device_node *parent,  	return 1;  } +static int __init use_1to1_mapping(struct device_node *pp) +{ +	/* If we have a ranges property in the parent, use it.  */ +	if (of_find_property(pp, "ranges", NULL) != NULL) +		return 0; + +	/* Some SBUS devices use intermediate nodes to express +	 * hierarchy within the device itself.  These aren't +	 * real bus nodes, and don't have a 'ranges' property. +	 * But, we should still pass the translation work up +	 * to the SBUS itself. +	 */ +	if (!strcmp(pp->name, "dma") || +	    !strcmp(pp->name, "espdma") || +	    !strcmp(pp->name, "ledma") || +	    !strcmp(pp->name, "lebuffer")) +		return 0; + +	return 1; +} +  static int of_resource_verbose;  static void __init build_device_resources(struct of_device *op, @@ -373,10 +417,7 @@ static void __init build_device_resources(struct of_device *op,  		flags = bus->get_flags(reg, 0); -		/* If the immediate parent has no ranges property to apply, -		 * just use a 1<->1 mapping. -		 */ -		if (of_find_property(pp, "ranges", NULL) == NULL) { +		if (use_1to1_mapping(pp)) {  			result = of_read_addr(addr, na);  			goto build_res;  		} @@ -565,15 +606,6 @@ static int __init of_bus_driver_init(void)  	int err;  	err = of_bus_type_init(&of_platform_bus_type, "of"); -#ifdef CONFIG_PCI -	if (!err) -		err = of_bus_type_init(&ebus_bus_type, "ebus"); -#endif -#ifdef CONFIG_SBUS -	if (!err) -		err = of_bus_type_init(&sbus_bus_type, "sbus"); -#endif -  	if (!err)  		scan_of_devices(); diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index a6a6f982337..462584e55fb 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -17,8 +17,6 @@  #include <linux/slab.h>  #include <linux/jiffies.h> -#include <asm/ebus.h> -#include <asm/sbus.h> /* for sanity check... */  #include <asm/swift.h> /* for cache flushing. */  #include <asm/io.h> @@ -430,7 +428,6 @@ static int __init pcic_init(void)  	pcic_pbm_scan_bus(pcic); -	ebus_init();  	return 0;  } @@ -493,10 +490,6 @@ static void pcic_map_pci_device(struct linux_pcic *pcic,  				 * do ioremap() before accessing PC-style I/O,  				 * we supply virtual, ready to access address.  				 * -				 * Ebus devices do not come here even if -				 * CheerIO makes a similar conversion. -				 * See ebus.c for details. -				 *  				 * Note that request_region()  				 * works for these devices.  				 * @@ -677,7 +670,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)  }  /* - * pcic_pin_to_irq() is exported to ebus.c. + * pcic_pin_to_irq() is exported to bus probing code   */  unsigned int  pcic_pin_to_irq(unsigned int pin, const char *name) @@ -904,11 +897,6 @@ static void pcic_enable_irq(unsigned int irq_nr)  	local_irq_restore(flags);  } -static void pcic_clear_profile_irq(int cpu) -{ -	printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__); -} -  static void pcic_load_profile_irq(int cpu, unsigned int limit)  {  	printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__); @@ -934,7 +922,6 @@ void __init sun4m_pci_init_IRQ(void)  	BTFIXUPSET_CALL(enable_pil_irq, pcic_enable_pil_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(disable_pil_irq, pcic_disable_pil_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM); -	BTFIXUPSET_CALL(clear_profile_irq, pcic_clear_profile_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM);  } diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index 7eca8871ff4..2afcfab4f11 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -8,11 +8,11 @@  #include <linux/fs.h>  #include <linux/errno.h>  #include <linux/init.h> -#include <linux/miscdevice.h>  #include <linux/pm.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include <asm/io.h> -#include <asm/sbus.h>  #include <asm/oplib.h>  #include <asm/uaccess.h>  #include <asm/auxio.h> @@ -23,17 +23,15 @@   * #define PMC_NO_IDLE   */ -#define PMC_MINOR	MISC_DYNAMIC_MINOR  #define PMC_OBPNAME	"SUNW,pmc"  #define PMC_DEVNAME "pmc"  #define PMC_IDLE_REG	0x00  #define PMC_IDLE_ON		0x01 -volatile static u8 __iomem *regs;  -static int pmc_regsize; +static u8 __iomem *regs; -#define pmc_readb(offs)			(sbus_readb(regs+offs)) +#define pmc_readb(offs)		(sbus_readb(regs+offs))  #define pmc_writeb(val, offs) 	(sbus_writeb(val, regs+offs))  /*  @@ -53,31 +51,11 @@ void pmc_swift_idle(void)  #endif  }  -static inline void pmc_free(void) +static int __devinit pmc_probe(struct of_device *op, +			       const struct of_device_id *match)  { -	sbus_iounmap(regs, pmc_regsize); -} - -static int __init pmc_probe(void) -{ -	struct sbus_bus *sbus = NULL; -	struct sbus_dev *sdev = NULL; -	for_each_sbus(sbus) { -		for_each_sbusdev(sdev, sbus) { -			if (!strcmp(sdev->prom_name, PMC_OBPNAME)) { -				goto sbus_done; -			} -		} -	} - -sbus_done: -	if (!sdev) { -		return -ENODEV; -	} - -	pmc_regsize = sdev->reg_addrs[0].reg_size; -	regs = sbus_ioremap(&sdev->resource[0], 0,  -				   pmc_regsize, PMC_OBPNAME); +	regs = of_ioremap(&op->resource[0], 0, +			  resource_size(&op->resource[0]), PMC_OBPNAME);  	if (!regs) {  		printk(KERN_ERR "%s: unable to map registers\n", PMC_DEVNAME);  		return -ENODEV; @@ -92,8 +70,27 @@ sbus_done:  	return 0;  } +static struct of_device_id __initdata pmc_match[] = { +	{ +		.name = PMC_OBPNAME, +	}, +	{}, +}; +MODULE_DEVICE_TABLE(of, pmc_match); + +static struct of_platform_driver pmc_driver = { +	.name		= "pmc", +	.match_table	= pmc_match, +	.probe		= pmc_probe, +}; + +static int __init pmc_init(void) +{ +	return of_register_driver(&pmc_driver, &of_bus_type); +} +  /* This driver is not critical to the boot process   * and is easiest to ioremap when SBus is already   * initialized, so we install ourselves thusly:   */ -__initcall(pmc_probe); +__initcall(pmc_init); diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 4bb430940a6..e8c43ffe317 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -75,7 +75,7 @@ void cpu_idle(void)  {  	/* endless idle loop with no priority at all */  	for (;;) { -		if (ARCH_SUN4C_SUN4) { +		if (ARCH_SUN4C) {  			static int count = HZ;  			static unsigned long last_jiffies;  			static unsigned long last_faults; diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index cd4fb79aa3a..eee5efcfe50 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -54,6 +54,9 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)  }  EXPORT_SYMBOL(of_getintprop_default); +DEFINE_MUTEX(of_set_property_mutex); +EXPORT_SYMBOL(of_set_property_mutex); +  int of_set_property(struct device_node *dp, const char *name, void *val, int len)  {  	struct property **prevp; @@ -77,7 +80,10 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len  			void *old_val = prop->value;  			int ret; +			mutex_lock(&of_set_property_mutex);  			ret = prom_setprop(dp->node, (char *) name, val, len); +			mutex_unlock(&of_set_property_mutex); +  			err = -EINVAL;  			if (ret >= 0) {  				prop->value = new_val; @@ -436,7 +442,6 @@ static void __init of_console_init(void)  	switch (prom_vers) {  	case PROM_V0: -	case PROM_SUN4:  		skip = 0;  		switch (*romvec->pv_stdout) {  		case PROMDEV_SCREEN: diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index 9e451b21202..24fe3078bd4 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -213,23 +213,25 @@ void __init setup_arch(char **cmdline_p)  	/* Initialize PROM console and command line. */  	*cmdline_p = prom_getbootargs();  	strcpy(boot_command_line, *cmdline_p); +	parse_early_param();  	/* Set sparc_cpu_model */  	sparc_cpu_model = sun_unknown; -	if(!strcmp(&cputypval,"sun4 ")) { sparc_cpu_model=sun4; } -	if(!strcmp(&cputypval,"sun4c")) { sparc_cpu_model=sun4c; } -	if(!strcmp(&cputypval,"sun4m")) { sparc_cpu_model=sun4m; } -	if(!strcmp(&cputypval,"sun4s")) { sparc_cpu_model=sun4m; }  /* CP-1200 with PROM 2.30 -E */ -	if(!strcmp(&cputypval,"sun4d")) { sparc_cpu_model=sun4d; } -	if(!strcmp(&cputypval,"sun4e")) { sparc_cpu_model=sun4e; } -	if(!strcmp(&cputypval,"sun4u")) { sparc_cpu_model=sun4u; } - -#ifdef CONFIG_SUN4 -	if (sparc_cpu_model != sun4) { -		prom_printf("This kernel is for Sun4 architecture only.\n"); -		prom_halt(); -	} -#endif +	if (!strcmp(&cputypval,"sun4 ")) +		sparc_cpu_model = sun4; +	if (!strcmp(&cputypval,"sun4c")) +		sparc_cpu_model = sun4c; +	if (!strcmp(&cputypval,"sun4m")) +		sparc_cpu_model = sun4m; +	if (!strcmp(&cputypval,"sun4s")) +		sparc_cpu_model = sun4m; /* CP-1200 with PROM 2.30 -E */ +	if (!strcmp(&cputypval,"sun4d")) +		sparc_cpu_model = sun4d; +	if (!strcmp(&cputypval,"sun4e")) +		sparc_cpu_model = sun4e; +	if (!strcmp(&cputypval,"sun4u")) +		sparc_cpu_model = sun4u; +  	printk("ARCH: ");  	switch(sparc_cpu_model) {  	case sun4: @@ -263,7 +265,7 @@ void __init setup_arch(char **cmdline_p)  	boot_flags_init(*cmdline_p);  	idprom_init(); -	if (ARCH_SUN4C_SUN4) +	if (ARCH_SUN4C)  		sun4c_probe_vac();  	load_mmu(); diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index b23cea5ca5d..b0dfff84865 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -38,17 +38,12 @@  #include <asm/idprom.h>  #include <asm/head.h>  #include <asm/smp.h> -#include <asm/mostek.h>  #include <asm/ptrace.h>  #include <asm/uaccess.h>  #include <asm/checksum.h>  #ifdef CONFIG_SBUS -#include <asm/sbus.h>  #include <asm/dma.h>  #endif -#ifdef CONFIG_PCI -#include <asm/ebus.h> -#endif  #include <asm/io-unit.h>  #include <asm/bug.h> @@ -127,16 +122,11 @@ EXPORT_SYMBOL(phys_cpu_present_map);  EXPORT_SYMBOL(__udelay);  EXPORT_SYMBOL(__ndelay);  EXPORT_SYMBOL(rtc_lock); -EXPORT_SYMBOL(mostek_lock); -EXPORT_SYMBOL(mstk48t02_regs);  #ifdef CONFIG_SUN_AUXIO  EXPORT_SYMBOL(set_auxio);  EXPORT_SYMBOL(get_auxio);  #endif  EXPORT_SYMBOL(io_remap_pfn_range); -  /* P3: iounit_xxx may be needed, sun4d users */ -/* EXPORT_SYMBOL(iounit_map_dma_init); */ -/* EXPORT_SYMBOL(iounit_map_dma_page); */  #ifndef CONFIG_SMP  EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32)); @@ -153,24 +143,9 @@ EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_one));  EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached));  #ifdef CONFIG_SBUS -EXPORT_SYMBOL(sbus_root); -EXPORT_SYMBOL(dma_chain);  EXPORT_SYMBOL(sbus_set_sbus64); -EXPORT_SYMBOL(sbus_alloc_consistent); -EXPORT_SYMBOL(sbus_free_consistent); -EXPORT_SYMBOL(sbus_map_single); -EXPORT_SYMBOL(sbus_unmap_single); -EXPORT_SYMBOL(sbus_map_sg); -EXPORT_SYMBOL(sbus_unmap_sg); -EXPORT_SYMBOL(sbus_dma_sync_single_for_cpu); -EXPORT_SYMBOL(sbus_dma_sync_single_for_device); -EXPORT_SYMBOL(sbus_dma_sync_sg_for_cpu); -EXPORT_SYMBOL(sbus_dma_sync_sg_for_device); -EXPORT_SYMBOL(sbus_iounmap); -EXPORT_SYMBOL(sbus_ioremap);  #endif  #ifdef CONFIG_PCI -EXPORT_SYMBOL(ebus_chain);  EXPORT_SYMBOL(insb);  EXPORT_SYMBOL(outsb);  EXPORT_SYMBOL(insw); diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c index 340fc395fe2..5dc8a576948 100644 --- a/arch/sparc/kernel/sun4c_irq.c +++ b/arch/sparc/kernel/sun4c_irq.c @@ -18,6 +18,8 @@  #include <linux/interrupt.h>  #include <linux/slab.h>  #include <linux/init.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include "irq.h"  #include <asm/ptrace.h> @@ -31,15 +33,8 @@  #include <asm/traps.h>  #include <asm/irq.h>  #include <asm/io.h> -#include <asm/sun4paddr.h>  #include <asm/idprom.h>  #include <asm/machines.h> -#include <asm/sbus.h> - -#if 0 -static struct resource sun4c_timer_eb = { "sun4c_timer" }; -static struct resource sun4c_intr_eb = { "sun4c_intr" }; -#endif  /*   * Bit field defines for the interrupt registers on various @@ -64,19 +59,7 @@ static struct resource sun4c_intr_eb = { "sun4c_intr" };   *   * so don't go making it static, like I tried. sigh.   */ -unsigned char *interrupt_enable = NULL; - -static int sun4c_pil_map[] = { 0, 1, 2, 3, 5, 7, 8, 9 }; - -static unsigned int sun4c_sbint_to_irq(struct sbus_dev *sdev, -				       unsigned int sbint) -{ -	if (sbint >= sizeof(sun4c_pil_map)) { -		printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint); -		BUG(); -	} -	return sun4c_pil_map[sbint]; -} +unsigned char __iomem *interrupt_enable = NULL;  static void sun4c_disable_irq(unsigned int irq_nr)  { @@ -85,7 +68,7 @@ static void sun4c_disable_irq(unsigned int irq_nr)  	local_irq_save(flags);  	irq_nr &= (NR_IRQS - 1); -	current_mask = *interrupt_enable; +	current_mask = sbus_readb(interrupt_enable);  	switch(irq_nr) {  	case 1:  		new_mask = ((current_mask) & (~(SUN4C_INT_E1))); @@ -103,7 +86,7 @@ static void sun4c_disable_irq(unsigned int irq_nr)  		local_irq_restore(flags);  		return;  	} -	*interrupt_enable = new_mask; +	sbus_writeb(new_mask, interrupt_enable);  	local_irq_restore(flags);  } @@ -114,7 +97,7 @@ static void sun4c_enable_irq(unsigned int irq_nr)  	local_irq_save(flags);  	irq_nr &= (NR_IRQS - 1); -	current_mask = *interrupt_enable; +	current_mask = sbus_readb(interrupt_enable);  	switch(irq_nr) {  	case 1:  		new_mask = ((current_mask) | SUN4C_INT_E1); @@ -132,37 +115,22 @@ static void sun4c_enable_irq(unsigned int irq_nr)  		local_irq_restore(flags);  		return;  	} -	*interrupt_enable = new_mask; +	sbus_writeb(new_mask, interrupt_enable);  	local_irq_restore(flags);  } -#define TIMER_IRQ  	10    /* Also at level 14, but we ignore that one. */ -#define PROFILE_IRQ	14    /* Level14 ticker.. used by OBP for polling */ - -volatile struct sun4c_timer_info *sun4c_timers; +struct sun4c_timer_info { +	u32		l10_count; +	u32		l10_limit; +	u32		l14_count; +	u32		l14_limit; +}; -#ifdef CONFIG_SUN4 -/* This is an ugly hack to work around the -   current timer code, and make it work with  -   the sun4/260 intersil  -   */ -volatile struct sun4c_timer_info sun4_timer; -#endif +static struct sun4c_timer_info __iomem *sun4c_timers;  static void sun4c_clear_clock_irq(void)  { -	volatile unsigned int clear_intr; -#ifdef CONFIG_SUN4 -	if (idprom->id_machtype == (SM_SUN4 | SM_4_260))  -	  clear_intr = sun4_timer.timer_limit10; -	else -#endif -	clear_intr = sun4c_timers->timer_limit10; -} - -static void sun4c_clear_profile_irq(int cpu) -{ -	/* Errm.. not sure how to do this.. */ +	sbus_readl(&sun4c_timers->l10_limit);  }  static void sun4c_load_profile_irq(int cpu, unsigned int limit) @@ -172,41 +140,48 @@ static void sun4c_load_profile_irq(int cpu, unsigned int limit)  static void __init sun4c_init_timers(irq_handler_t counter_fn)  { -	int irq; +	const struct linux_prom_irqs *irq; +	struct device_node *dp; +	const u32 *addr; +	int err; + +	dp = of_find_node_by_name(NULL, "counter-timer"); +	if (!dp) { +		prom_printf("sun4c_init_timers: Unable to find counter-timer\n"); +		prom_halt(); +	} -	/* Map the Timer chip, this is implemented in hardware inside -	 * the cache chip on the sun4c. -	 */ -#ifdef CONFIG_SUN4 -	if (idprom->id_machtype == (SM_SUN4 | SM_4_260)) -		sun4c_timers = &sun4_timer; -	else -#endif -	sun4c_timers = ioremap(SUN_TIMER_PHYSADDR, -	    sizeof(struct sun4c_timer_info)); +	addr = of_get_property(dp, "address", NULL); +	if (!addr) { +		prom_printf("sun4c_init_timers: No address property\n"); +		prom_halt(); +	} + +	sun4c_timers = (void __iomem *) (unsigned long) addr[0]; + +	irq = of_get_property(dp, "intr", NULL); +	if (!irq) { +		prom_printf("sun4c_init_timers: No intr property\n"); +		prom_halt(); +	}  	/* Have the level 10 timer tick at 100HZ.  We don't touch the  	 * level 14 timer limit since we are letting the prom handle  	 * them until we have a real console driver so L1-A works.  	 */ -	sun4c_timers->timer_limit10 = (((1000000/HZ) + 1) << 10); -	master_l10_counter = &sun4c_timers->cur_count10; -	master_l10_limit = &sun4c_timers->timer_limit10; +	sbus_writel((((1000000/HZ) + 1) << 10), &sun4c_timers->l10_limit); -	irq = request_irq(TIMER_IRQ, -			  counter_fn, +	master_l10_counter = &sun4c_timers->l10_count; + +	err = request_irq(irq[0].pri, counter_fn,  			  (IRQF_DISABLED | SA_STATIC_ALLOC),  			  "timer", NULL); -	if (irq) { -		prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ); +	if (err) { +		prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err);  		prom_halt();  	} -#if 0 -	/* This does not work on 4/330 */ -	sun4c_enable_irq(10); -#endif -	claim_ticker14(NULL, PROFILE_IRQ, 0); +	sun4c_disable_irq(irq[1].pri);  }  #ifdef CONFIG_SMP @@ -215,41 +190,28 @@ static void sun4c_nop(void) {}  void __init sun4c_init_IRQ(void)  { -	struct linux_prom_registers int_regs[2]; -	int ie_node; +	struct device_node *dp; +	const u32 *addr; -	if (ARCH_SUN4) { -		interrupt_enable = (char *) -		    ioremap(sun4_ie_physaddr, PAGE_SIZE); -	} else { -		struct resource phyres; - -		ie_node = prom_searchsiblings (prom_getchild(prom_root_node), -				       	"interrupt-enable"); -		if(ie_node == 0) -			panic("Cannot find /interrupt-enable node"); +	dp = of_find_node_by_name(NULL, "interrupt-enable"); +	if (!dp) { +		prom_printf("sun4c_init_IRQ: Unable to find interrupt-enable\n"); +		prom_halt(); +	} -		/* Depending on the "address" property is bad news... */ -		interrupt_enable = NULL; -		if (prom_getproperty(ie_node, "reg", (char *) int_regs, -				     sizeof(int_regs)) != -1) { -			memset(&phyres, 0, sizeof(struct resource)); -			phyres.flags = int_regs[0].which_io; -			phyres.start = int_regs[0].phys_addr; -			interrupt_enable = (char *) sbus_ioremap(&phyres, 0, -			    int_regs[0].reg_size, "sun4c_intr"); -		} +	addr = of_get_property(dp, "address", NULL); +	if (!addr) { +		prom_printf("sun4c_init_IRQ: No address property\n"); +		prom_halt();  	} -	if (!interrupt_enable) -		panic("Cannot map interrupt_enable"); -	BTFIXUPSET_CALL(sbint_to_irq, sun4c_sbint_to_irq, BTFIXUPCALL_NORM); +	interrupt_enable = (void __iomem *) (unsigned long) addr[0]; +  	BTFIXUPSET_CALL(enable_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(disable_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(enable_pil_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(disable_pil_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM); -	BTFIXUPSET_CALL(clear_profile_irq, sun4c_clear_profile_irq, BTFIXUPCALL_NOP);  	BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP);  	sparc_init_timers = sun4c_init_timers;  #ifdef CONFIG_SMP @@ -257,6 +219,6 @@ void __init sun4c_init_IRQ(void)  	BTFIXUPSET_CALL(clear_cpu_int, sun4c_nop, BTFIXUPCALL_NOP);  	BTFIXUPSET_CALL(set_irq_udt, sun4c_nop, BTFIXUPCALL_NOP);  #endif -	*interrupt_enable = (SUN4C_INT_ENABLE); +	sbus_writeb(SUN4C_INT_ENABLE, interrupt_enable);  	/* Cannot enable interrupts until OBP ticker is disabled. */  } diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 1290b5998f8..d3cb76ce418 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -19,6 +19,8 @@  #include <linux/smp.h>  #include <linux/spinlock.h>  #include <linux/seq_file.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include <asm/ptrace.h>  #include <asm/processor.h> @@ -34,7 +36,6 @@  #include <asm/io.h>  #include <asm/pgalloc.h>  #include <asm/pgtable.h> -#include <asm/sbus.h>  #include <asm/sbi.h>  #include <asm/cacheflush.h>  #include <asm/irq_regs.h> @@ -44,16 +45,22 @@  /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */  /* #define DISTRIBUTE_IRQS */ -struct sun4d_timer_regs *sun4d_timers; +struct sun4d_timer_regs { +	u32	l10_timer_limit; +	u32	l10_cur_countx; +	u32	l10_limit_noclear; +	u32	ctrl; +	u32	l10_cur_count; +}; + +static struct sun4d_timer_regs __iomem *sun4d_timers; +  #define TIMER_IRQ	10  #define MAX_STATIC_ALLOC	4  extern struct irqaction static_irqaction[MAX_STATIC_ALLOC];  extern int static_irq_count; -unsigned char cpu_leds[32]; -#ifdef CONFIG_SMP  static unsigned char sbus_tid[32]; -#endif  static struct irqaction *irq_action[NR_IRQS];  extern spinlock_t irq_action_lock; @@ -72,9 +79,9 @@ static int sbus_to_pil[] = {  };  static int nsbi; -#ifdef CONFIG_SMP + +/* Exported for sun4d_smp.c */  DEFINE_SPINLOCK(sun4d_imsk_lock); -#endif  int show_sun4d_interrupts(struct seq_file *p, void *v)  { @@ -257,26 +264,6 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)  	set_irq_regs(old_regs);  } -unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq) -{ -	int sbusl = pil_to_sbus[irq]; - -	if (sbusl) -		return ((sdev->bus->board + 1) << 5) + (sbusl << 2) + sdev->slot; -	else -		return irq; -} - -static unsigned int sun4d_sbint_to_irq(struct sbus_dev *sdev, -				       unsigned int sbint) -{ -	if (sbint >= sizeof(sbus_to_pil)) { -		printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint); -		BUG(); -	} -	return sun4d_build_irq(sdev, sbus_to_pil[sbint]); -} -  int sun4d_request_irq(unsigned int irq,  		irq_handler_t handler,  		unsigned long irqflags, const char * devname, void *dev_id) @@ -360,36 +347,28 @@ out:  static void sun4d_disable_irq(unsigned int irq)  { -#ifdef CONFIG_SMP  	int tid = sbus_tid[(irq >> 5) - 1];  	unsigned long flags; -#endif	 -	if (irq < NR_IRQS) return; -#ifdef CONFIG_SMP +	if (irq < NR_IRQS) +		return; +  	spin_lock_irqsave(&sun4d_imsk_lock, flags);  	cc_set_imsk_other(tid, cc_get_imsk_other(tid) | (1 << sbus_to_pil[(irq >> 2) & 7]));  	spin_unlock_irqrestore(&sun4d_imsk_lock, flags); -#else		 -	cc_set_imsk(cc_get_imsk() | (1 << sbus_to_pil[(irq >> 2) & 7])); -#endif  }  static void sun4d_enable_irq(unsigned int irq)  { -#ifdef CONFIG_SMP  	int tid = sbus_tid[(irq >> 5) - 1];  	unsigned long flags; -#endif	 -	if (irq < NR_IRQS) return; -#ifdef CONFIG_SMP +	if (irq < NR_IRQS) +		return; +  	spin_lock_irqsave(&sun4d_imsk_lock, flags);  	cc_set_imsk_other(tid, cc_get_imsk_other(tid) & ~(1 << sbus_to_pil[(irq >> 2) & 7]));  	spin_unlock_irqrestore(&sun4d_imsk_lock, flags); -#else		 -	cc_set_imsk(cc_get_imsk() & ~(1 << sbus_to_pil[(irq >> 2) & 7])); -#endif  }  #ifdef CONFIG_SMP @@ -409,47 +388,55 @@ static void sun4d_set_udt(int cpu)  /* Setup IRQ distribution scheme. */  void __init sun4d_distribute_irqs(void)  { +	struct device_node *dp; +  #ifdef DISTRIBUTE_IRQS -	struct sbus_bus *sbus; -	unsigned long sbus_serving_map; +	cpumask_t sbus_serving_map;  	sbus_serving_map = cpu_present_map; -	for_each_sbus(sbus) { -		if ((sbus->board * 2) == boot_cpu_id && (cpu_present_map & (1 << (sbus->board * 2 + 1)))) -			sbus_tid[sbus->board] = (sbus->board * 2 + 1); -		else if (cpu_present_map & (1 << (sbus->board * 2))) -			sbus_tid[sbus->board] = (sbus->board * 2); -		else if (cpu_present_map & (1 << (sbus->board * 2 + 1))) -			sbus_tid[sbus->board] = (sbus->board * 2 + 1); +	for_each_node_by_name(dp, "sbi") { +		int board = of_getintprop_default(dp, "board#", 0); + +		if ((board * 2) == boot_cpu_id && cpu_isset(board * 2 + 1, cpu_present_map)) +			sbus_tid[board] = (board * 2 + 1); +		else if (cpu_isset(board * 2, cpu_present_map)) +			sbus_tid[board] = (board * 2); +		else if (cpu_isset(board * 2 + 1, cpu_present_map)) +			sbus_tid[board] = (board * 2 + 1);  		else -			sbus_tid[sbus->board] = 0xff; -		if (sbus_tid[sbus->board] != 0xff) -			sbus_serving_map &= ~(1 << sbus_tid[sbus->board]); +			sbus_tid[board] = 0xff; +		if (sbus_tid[board] != 0xff) +			cpu_clear(sbus_tid[board], sbus_serving_map);  	} -	for_each_sbus(sbus) -		if (sbus_tid[sbus->board] == 0xff) { +	for_each_node_by_name(dp, "sbi") { +		int board = of_getintprop_default(dp, "board#", 0); +		if (sbus_tid[board] == 0xff) {  			int i = 31; -			if (!sbus_serving_map) +			if (cpus_empty(sbus_serving_map))  				sbus_serving_map = cpu_present_map; -			while (!(sbus_serving_map & (1 << i))) +			while (cpu_isset(i, sbus_serving_map))  				i--; -			sbus_tid[sbus->board] = i; -			sbus_serving_map &= ~(1 << i); +			sbus_tid[board] = i; +			cpu_clear(i, sbus_serving_map);  		} -	for_each_sbus(sbus) { -		printk("sbus%d IRQs directed to CPU%d\n", sbus->board, sbus_tid[sbus->board]); -		set_sbi_tid(sbus->devid, sbus_tid[sbus->board] << 3); +	} +	for_each_node_by_name(dp, "sbi") { +		int devid = of_getintprop_default(dp, "device-id", 0); +		int board = of_getintprop_default(dp, "board#", 0); +		printk("sbus%d IRQs directed to CPU%d\n", board, sbus_tid[board]); +		set_sbi_tid(devid, sbus_tid[board] << 3);  	}  #else -	struct sbus_bus *sbus;  	int cpuid = cpu_logical_map(1);  	if (cpuid == -1)  		cpuid = cpu_logical_map(0); -	for_each_sbus(sbus) { -		sbus_tid[sbus->board] = cpuid; -		set_sbi_tid(sbus->devid, cpuid << 3); +	for_each_node_by_name(dp, "sbi") { +		int devid = of_getintprop_default(dp, "device-id", 0); +		int board = of_getintprop_default(dp, "board#", 0); +		sbus_tid[board] = cpuid; +		set_sbi_tid(devid, cpuid << 3);  	}  	printk("All sbus IRQs directed to CPU%d\n", cpuid);  #endif @@ -458,13 +445,7 @@ void __init sun4d_distribute_irqs(void)  static void sun4d_clear_clock_irq(void)  { -	volatile unsigned int clear_intr; -	clear_intr = sun4d_timers->l10_timer_limit; -} - -static void sun4d_clear_profile_irq(int cpu) -{ -	bw_get_prof_limit(cpu); +	sbus_readl(&sun4d_timers->l10_timer_limit);  }  static void sun4d_load_profile_irq(int cpu, unsigned int limit) @@ -472,98 +453,121 @@ static void sun4d_load_profile_irq(int cpu, unsigned int limit)  	bw_set_prof_limit(cpu, limit);  } -static void __init sun4d_init_timers(irq_handler_t counter_fn) +static void __init sun4d_load_profile_irqs(void)  { -	int irq; -	int cpu; -	struct resource r; -	int mid; +	int cpu = 0, mid; -	/* Map the User Timer registers. */ -	memset(&r, 0, sizeof(r)); +	while (!cpu_find_by_instance(cpu, NULL, &mid)) { +		sun4d_load_profile_irq(mid >> 3, 0); +		cpu++; +	} +} + +static void __init sun4d_fixup_trap_table(void) +{  #ifdef CONFIG_SMP -	r.start = CSR_BASE(boot_cpu_id)+BW_TIMER_LIMIT; -#else -	r.start = CSR_BASE(0)+BW_TIMER_LIMIT; +	unsigned long flags; +	extern unsigned long lvl14_save[4]; +	struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; +	extern unsigned int real_irq_entry[], smp4d_ticker[]; +	extern unsigned int patchme_maybe_smp_msg[]; + +	/* Adjust so that we jump directly to smp4d_ticker */ +	lvl14_save[2] += smp4d_ticker - real_irq_entry; + +	/* For SMP we use the level 14 ticker, however the bootup code +	 * has copied the firmware's level 14 vector into the boot cpu's +	 * trap table, we must fix this now or we get squashed. +	 */ +	local_irq_save(flags); +	patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */ +	trap_table->inst_one = lvl14_save[0]; +	trap_table->inst_two = lvl14_save[1]; +	trap_table->inst_three = lvl14_save[2]; +	trap_table->inst_four = lvl14_save[3]; +	local_flush_cache_all(); +	local_irq_restore(flags);  #endif -	r.flags = 0xf; -	sun4d_timers = (struct sun4d_timer_regs *) sbus_ioremap(&r, 0, -	    PAGE_SIZE, "user timer"); +} -	sun4d_timers->l10_timer_limit =  (((1000000/HZ) + 1) << 10); -	master_l10_counter = &sun4d_timers->l10_cur_count; -	master_l10_limit = &sun4d_timers->l10_timer_limit; +static void __init sun4d_init_timers(irq_handler_t counter_fn) +{ +	struct device_node *dp; +	struct resource res; +	const u32 *reg; +	int err; + +	dp = of_find_node_by_name(NULL, "cpu-unit"); +	if (!dp) { +		prom_printf("sun4d_init_timers: Unable to find cpu-unit\n"); +		prom_halt(); +	} -	irq = request_irq(TIMER_IRQ, -			  counter_fn, -			  (IRQF_DISABLED | SA_STATIC_ALLOC), -			  "timer", NULL); -	if (irq) { -		prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ); +	/* Which cpu-unit we use is arbitrary, we can view the bootbus timer +	 * registers via any cpu's mapping.  The first 'reg' property is the +	 * bootbus. +	 */ +	reg = of_get_property(dp, "reg", NULL); +	if (!reg) { +		prom_printf("sun4d_init_timers: No reg property\n");  		prom_halt();  	} -	 -	/* Enable user timer free run for CPU 0 in BW */ -	/* bw_set_ctrl(0, bw_get_ctrl(0) | BW_CTRL_USER_TIMER); */ -	cpu = 0; -	while (!cpu_find_by_instance(cpu, NULL, &mid)) { -		sun4d_load_profile_irq(mid >> 3, 0); -		cpu++; +	res.start = reg[1]; +	res.end = reg[2] - 1; +	res.flags = reg[0] & 0xff; +	sun4d_timers = of_ioremap(&res, BW_TIMER_LIMIT, +				  sizeof(struct sun4d_timer_regs), "user timer"); +	if (!sun4d_timers) { +		prom_printf("sun4d_init_timers: Can't map timer regs\n"); +		prom_halt();  	} -		 -#ifdef CONFIG_SMP -	{ -		unsigned long flags; -		extern unsigned long lvl14_save[4]; -		struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; -		extern unsigned int real_irq_entry[], smp4d_ticker[]; -		extern unsigned int patchme_maybe_smp_msg[]; - -		/* Adjust so that we jump directly to smp4d_ticker */ -		lvl14_save[2] += smp4d_ticker - real_irq_entry; - -		/* For SMP we use the level 14 ticker, however the bootup code -		 * has copied the firmware's level 14 vector into the boot cpu's -		 * trap table, we must fix this now or we get squashed. -		 */ -		local_irq_save(flags); -		patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */ -		trap_table->inst_one = lvl14_save[0]; -		trap_table->inst_two = lvl14_save[1]; -		trap_table->inst_three = lvl14_save[2]; -		trap_table->inst_four = lvl14_save[3]; -		local_flush_cache_all(); -		local_irq_restore(flags); + +	sbus_writel((((1000000/HZ) + 1) << 10), &sun4d_timers->l10_timer_limit); + +	master_l10_counter = &sun4d_timers->l10_cur_count; + +	err = request_irq(TIMER_IRQ, counter_fn, +			  (IRQF_DISABLED | SA_STATIC_ALLOC), +			  "timer", NULL); +	if (err) { +		prom_printf("sun4d_init_timers: request_irq() failed with %d\n", err); +		prom_halt();  	} -#endif +	sun4d_load_profile_irqs(); +	sun4d_fixup_trap_table();  }  void __init sun4d_init_sbi_irq(void)  { -	struct sbus_bus *sbus; -	unsigned mask; +	struct device_node *dp; +	int target_cpu = 0; + +#ifdef CONFIG_SMP +	target_cpu = boot_cpu_id; +#endif  	nsbi = 0; -	for_each_sbus(sbus) +	for_each_node_by_name(dp, "sbi")  		nsbi++;  	sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC);  	if (!sbus_actions) {  		prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n");  		prom_halt();  	} -	for_each_sbus(sbus) { -#ifdef CONFIG_SMP	 -		extern unsigned char boot_cpu_id; -		 -		set_sbi_tid(sbus->devid, boot_cpu_id << 3); -		sbus_tid[sbus->board] = boot_cpu_id; -#endif +	for_each_node_by_name(dp, "sbi") { +		int devid = of_getintprop_default(dp, "device-id", 0); +		int board = of_getintprop_default(dp, "board#", 0); +		unsigned int mask; + +		set_sbi_tid(devid, target_cpu << 3); +		sbus_tid[board] = target_cpu; +  		/* Get rid of pending irqs from PROM */ -		mask = acquire_sbi(sbus->devid, 0xffffffff); +		mask = acquire_sbi(devid, 0xffffffff);  		if (mask) { -			printk ("Clearing pending IRQs %08x on SBI %d\n", mask, sbus->board); -			release_sbi(sbus->devid, mask); +			printk ("Clearing pending IRQs %08x on SBI %d\n", mask, board); +			release_sbi(devid, mask);  		}  	}  } @@ -572,11 +576,9 @@ void __init sun4d_init_IRQ(void)  {  	local_irq_disable(); -	BTFIXUPSET_CALL(sbint_to_irq, sun4d_sbint_to_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(enable_irq, sun4d_enable_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM); -	BTFIXUPSET_CALL(clear_profile_irq, sun4d_clear_profile_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM);  	sparc_init_timers = sun4d_init_timers;  #ifdef CONFIG_SMP diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 69596402a50..7a6a5e79592 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -20,6 +20,7 @@  #include <linux/swap.h>  #include <linux/profile.h>  #include <linux/delay.h> +#include <linux/cpu.h>  #include <asm/ptrace.h>  #include <asm/atomic.h> @@ -30,7 +31,6 @@  #include <asm/pgalloc.h>  #include <asm/pgtable.h>  #include <asm/oplib.h> -#include <asm/sbus.h>  #include <asm/sbi.h>  #include <asm/tlbflush.h>  #include <asm/cacheflush.h> @@ -72,6 +72,17 @@ static void smp_setup_percpu_timer(void);  extern void cpu_probe(void);  extern void sun4d_distribute_irqs(void); +static unsigned char cpu_leds[32]; + +static inline void show_leds(int cpuid) +{ +	cpuid &= 0x1e; +	__asm__ __volatile__ ("stba %0, [%1] %2" : : +			      "r" ((cpu_leds[cpuid] << 4) | cpu_leds[cpuid+1]), +			      "r" (ECSR_BASE(cpuid) | BB_LEDS), +			      "i" (ASI_M_CTL)); +} +  void __init smp4d_callin(void)  {  	int cpuid = hard_smp4d_processor_id(); @@ -88,6 +99,7 @@ void __init smp4d_callin(void)  	local_flush_cache_all();  	local_flush_tlb_all(); +	notify_cpu_starting(cpuid);  	/*  	 * Unblock the master CPU _only_ when the scheduler state  	 * of all secondary CPUs will be up-to-date, so after diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 94e02de960e..f10317179ee 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c @@ -20,6 +20,8 @@  #include <linux/slab.h>  #include <linux/init.h>  #include <linux/ioport.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include <asm/ptrace.h>  #include <asm/processor.h> @@ -35,59 +37,27 @@  #include <asm/smp.h>  #include <asm/irq.h>  #include <asm/io.h> -#include <asm/sbus.h>  #include <asm/cacheflush.h>  #include "irq.h" -/* On the sun4m, just like the timers, we have both per-cpu and master - * interrupt registers. - */ - -/* These registers are used for sending/receiving irqs from/to - * different cpu's. - */ -struct sun4m_intreg_percpu { -	unsigned int tbt;        /* Interrupts still pending for this cpu. */ - -	/* These next two registers are WRITE-ONLY and are only -	 * "on bit" sensitive, "off bits" written have NO affect. -	 */ -	unsigned int clear;  /* Clear this cpus irqs here. */ -	unsigned int set;    /* Set this cpus irqs here. */ -	unsigned char space[PAGE_SIZE - 12]; +struct sun4m_irq_percpu { +	u32		pending; +	u32		clear; +	u32		set;  }; -/* - * djhr - * Actually the clear and set fields in this struct are misleading.. - * according to the SLAVIO manual (and the same applies for the SEC) - * the clear field clears bits in the mask which will ENABLE that IRQ - * the set field sets bits in the mask to DISABLE the IRQ. - * - * Also the undirected_xx address in the SLAVIO is defined as - * RESERVED and write only.. - * - * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor - *             sun4m machines, for MP the layout makes more sense. - */ -struct sun4m_intregs { -	struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS]; -	unsigned int tbt;                /* IRQ's that are still pending. */ -	unsigned int irqs;               /* Master IRQ bits. */ - -	/* Again, like the above, two these registers are WRITE-ONLY. */ -	unsigned int clear;              /* Clear master IRQ's by setting bits here. */ -	unsigned int set;                /* Set master IRQ's by setting bits here. */ - -	/* This register is both READ and WRITE. */ -	unsigned int undirected_target;  /* Which cpu gets undirected irqs. */ +struct sun4m_irq_global { +	u32		pending; +	u32		mask; +	u32		mask_clear; +	u32		mask_set; +	u32		interrupt_target;  }; -static unsigned long dummy; - -struct sun4m_intregs *sun4m_interrupts; -unsigned long *irq_rcvreg = &dummy; +/* Code in entry.S needs to get at these register mappings.  */ +struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS]; +struct sun4m_irq_global __iomem *sun4m_irq_global;  /* Dave Redman (djhr@tadpole.co.uk)   * The sun4m interrupt registers. @@ -101,8 +71,9 @@ unsigned long *irq_rcvreg = &dummy;  #define	SUN4M_INT_MASKALL	0x80000000	  /* mask all interrupts */  #define	SUN4M_INT_MODULE_ERR	0x40000000	  /* module error */ -#define	SUN4M_INT_M2S_WRITE	0x20000000	  /* write buffer error */ -#define	SUN4M_INT_ECC		0x10000000	  /* ecc memory error */ +#define	SUN4M_INT_M2S_WRITE_ERR	0x20000000	  /* write buffer error */ +#define	SUN4M_INT_ECC_ERR	0x10000000	  /* ecc memory error */ +#define	SUN4M_INT_VME_ERR	0x08000000	  /* vme async error */  #define	SUN4M_INT_FLOPPY	0x00400000	  /* floppy disk */  #define	SUN4M_INT_MODULE	0x00200000	  /* module interrupt */  #define	SUN4M_INT_VIDEO		0x00100000	  /* onboard video */ @@ -113,75 +84,126 @@ unsigned long *irq_rcvreg = &dummy;  #define	SUN4M_INT_SERIAL	0x00008000	  /* serial ports */  #define	SUN4M_INT_KBDMS		0x00004000	  /* keyboard/mouse */  #define	SUN4M_INT_SBUSBITS	0x00003F80	  /* sbus int bits */ +#define	SUN4M_INT_VMEBITS	0x0000007F	  /* vme int bits */ + +#define	SUN4M_INT_ERROR		(SUN4M_INT_MODULE_ERR |    \ +				 SUN4M_INT_M2S_WRITE_ERR | \ +				 SUN4M_INT_ECC_ERR |       \ +				 SUN4M_INT_VME_ERR)  #define SUN4M_INT_SBUS(x)	(1 << (x+7))  #define SUN4M_INT_VME(x)	(1 << (x)) -/* These tables only apply for interrupts greater than 15.. - *  - * any intr value below 0x10 is considered to be a soft-int - * this may be useful or it may not.. but that's how I've done it. - * and it won't clash with what OBP is telling us about devices. +/* Interrupt levels used by OBP */ +#define	OBP_INT_LEVEL_SOFT	0x10 +#define	OBP_INT_LEVEL_ONBOARD	0x20 +#define	OBP_INT_LEVEL_SBUS	0x30 +#define	OBP_INT_LEVEL_VME	0x40 + +/* Interrupt level assignment on sun4m: + * + *	level		source + * ------------------------------------------------------------ + *        1		softint-1 + *	  2		softint-2, VME/SBUS level 1 + *	  3		softint-3, VME/SBUS level 2 + *	  4		softint-4, onboard SCSI + *	  5		softint-5, VME/SBUS level 3 + *	  6		softint-6, onboard ETHERNET + *	  7		softint-7, VME/SBUS level 4 + *	  8		softint-8, onboard VIDEO + *	  9		softint-9, VME/SBUS level 5, Module Interrupt + *	 10		softint-10, system counter/timer + *	 11		softint-11, VME/SBUS level 6, Floppy + *	 12		softint-12, Keyboard/Mouse, Serial + *	 13		softint-13, VME/SBUS level 7, ISDN Audio + *	 14		softint-14, per-processor counter/timer + *	 15		softint-15, Asynchronous Errors (broadcast)   * - * take an encoded intr value and lookup if it's valid - * then get the mask bits that match from irq_mask + * Each interrupt source is masked distinctly in the sun4m interrupt + * registers.  The PIL level alone is therefore ambiguous, since multiple + * interrupt sources map to a single PIL.   * - * P3: Translation from irq 0x0d to mask 0x2000 is for MrCoffee. + * This ambiguity is resolved in the 'intr' property for device nodes + * in the OF device tree.  Each 'intr' property entry is composed of + * two 32-bit words.  The first word is the IRQ priority value, which + * is what we're intersted in.  The second word is the IRQ vector, which + * is unused. + * + * The low 4 bits of the IRQ priority indicate the PIL, and the upper + * 4 bits indicate onboard vs. SBUS leveled vs. VME leveled.  0x20 + * means onboard, 0x30 means SBUS leveled, and 0x40 means VME leveled. + * + * For example, an 'intr' IRQ priority value of 0x24 is onboard SCSI + * whereas a value of 0x33 is SBUS level 2.  Here are some sample + * 'intr' property IRQ priority values from ss4, ss5, ss10, ss20, and + * Tadpole S3 GX systems. + * + * esp: 	0x24	onboard ESP SCSI + * le:  	0x26	onboard Lance ETHERNET + * p9100:	0x32	SBUS level 1 P9100 video + * bpp:  	0x33	SBUS level 2 BPP parallel port device + * DBRI:	0x39	SBUS level 5 DBRI ISDN audio + * SUNW,leo:	0x39	SBUS level 5 LEO video + * pcmcia:	0x3b	SBUS level 6 PCMCIA controller + * uctrl:	0x3b	SBUS level 6 UCTRL device + * modem:	0x3d	SBUS level 7 MODEM + * zs:		0x2c	onboard keyboard/mouse/serial + * floppy:	0x2b	onboard Floppy + * power:	0x22	onboard power device (XXX unknown mask bit XXX)   */ -static unsigned char irq_xlate[32] = { -    /*  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  a,  b,  c,  d,  e,  f */ -	0,  0,  0,  0,  1,  0,  2,  0,  3,  0,  4,  5,  6, 14,  0,  7, -	0,  0,  8,  9,  0, 10,  0, 11,  0, 12,  0, 13,  0, 14,  0,  0 -}; -static unsigned long irq_mask[] = { -	0,						  /* illegal index */ -	SUN4M_INT_SCSI,				  	  /*  1 irq 4 */ -	SUN4M_INT_ETHERNET,				  /*  2 irq 6 */ -	SUN4M_INT_VIDEO,				  /*  3 irq 8 */ -	SUN4M_INT_REALTIME,				  /*  4 irq 10 */ -	SUN4M_INT_FLOPPY,				  /*  5 irq 11 */ -	(SUN4M_INT_SERIAL | SUN4M_INT_KBDMS),	  	  /*  6 irq 12 */ -	SUN4M_INT_MODULE_ERR,			  	  /*  7 irq 15 */ -	SUN4M_INT_SBUS(0),				  /*  8 irq 2 */ -	SUN4M_INT_SBUS(1),				  /*  9 irq 3 */ -	SUN4M_INT_SBUS(2),				  /* 10 irq 5 */ -	SUN4M_INT_SBUS(3),				  /* 11 irq 7 */ -	SUN4M_INT_SBUS(4),				  /* 12 irq 9 */ -	SUN4M_INT_SBUS(5),				  /* 13 irq 11 */ -	SUN4M_INT_SBUS(6)				  /* 14 irq 13 */ +static unsigned long irq_mask[0x50] = { +	/* SMP */ +	0,  SUN4M_SOFT_INT(1), +	SUN4M_SOFT_INT(2),  SUN4M_SOFT_INT(3), +	SUN4M_SOFT_INT(4),  SUN4M_SOFT_INT(5), +	SUN4M_SOFT_INT(6),  SUN4M_SOFT_INT(7), +	SUN4M_SOFT_INT(8),  SUN4M_SOFT_INT(9), +	SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11), +	SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13), +	SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15), +	/* soft */ +	0,  SUN4M_SOFT_INT(1), +	SUN4M_SOFT_INT(2),  SUN4M_SOFT_INT(3), +	SUN4M_SOFT_INT(4),  SUN4M_SOFT_INT(5), +	SUN4M_SOFT_INT(6),  SUN4M_SOFT_INT(7), +	SUN4M_SOFT_INT(8),  SUN4M_SOFT_INT(9), +	SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11), +	SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13), +	SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15), +	/* onboard */ +	0, 0, 0, 0, +	SUN4M_INT_SCSI,  0, SUN4M_INT_ETHERNET, 0, +	SUN4M_INT_VIDEO, SUN4M_INT_MODULE, +	SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY, +	(SUN4M_INT_SERIAL | SUN4M_INT_KBDMS), +	SUN4M_INT_AUDIO, 0, SUN4M_INT_MODULE_ERR, +	/* sbus */ +	0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1), +	0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3), +	0, SUN4M_INT_SBUS(4), 0, SUN4M_INT_SBUS(5), +	0, SUN4M_INT_SBUS(6), 0, 0, +	/* vme */ +	0, 0, SUN4M_INT_VME(0), SUN4M_INT_VME(1), +	0, SUN4M_INT_VME(2), 0, SUN4M_INT_VME(3), +	0, SUN4M_INT_VME(4), 0, SUN4M_INT_VME(5), +	0, SUN4M_INT_VME(6), 0, 0  }; -static int sun4m_pil_map[] = { 0, 2, 3, 5, 7, 9, 11, 13 }; - -static unsigned int sun4m_sbint_to_irq(struct sbus_dev *sdev, -				       unsigned int sbint) -{ -	if (sbint >= sizeof(sun4m_pil_map)) { -		printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint); -		BUG(); -	} -	return sun4m_pil_map[sbint] | 0x30; -} -  static unsigned long sun4m_get_irqmask(unsigned int irq)  {  	unsigned long mask; -	if (irq > 0x20) { -		/* OBIO/SBUS interrupts */ -		irq &= 0x1f; -		mask = irq_mask[irq_xlate[irq]]; -		if (!mask) -			printk("sun4m_get_irqmask: IRQ%d has no valid mask!\n",irq); -	} else { -		/* Soft Interrupts will come here. -		 * Currently there is no way to trigger them but I'm sure -		 * something could be cooked up. -		 */ -		irq &= 0xf; -		mask = SUN4M_SOFT_INT(irq); -	} +	if (irq < 0x50) +		mask = irq_mask[irq]; +	else +		mask = 0; + +	if (!mask) +		printk(KERN_ERR "sun4m_get_irqmask: IRQ%d has no valid mask!\n", +		       irq); +  	return mask;  } @@ -193,9 +215,9 @@ static void sun4m_disable_irq(unsigned int irq_nr)  	mask = sun4m_get_irqmask(irq_nr);  	local_irq_save(flags);  	if (irq_nr > 15) -		sun4m_interrupts->set = mask; +		sbus_writel(mask, &sun4m_irq_global->mask_set);  	else -		sun4m_interrupts->cpu_intregs[cpu].set = mask; +		sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);  	local_irq_restore(flags);      } @@ -212,13 +234,13 @@ static void sun4m_enable_irq(unsigned int irq_nr)  		mask = sun4m_get_irqmask(irq_nr);  		local_irq_save(flags);  		if (irq_nr > 15) -			sun4m_interrupts->clear = mask; +			sbus_writel(mask, &sun4m_irq_global->mask_clear);  		else -			sun4m_interrupts->cpu_intregs[cpu].clear = mask; +			sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);  		local_irq_restore(flags);      	} else {  		local_irq_save(flags); -		sun4m_interrupts->clear = SUN4M_INT_FLOPPY; +		sbus_writel(SUN4M_INT_FLOPPY, &sun4m_irq_global->mask_clear);  		local_irq_restore(flags);  	}  } @@ -236,10 +258,10 @@ static unsigned long cpu_pil_to_imask[16] = {  /*9*/	SUN4M_INT_SBUS(4) | SUN4M_INT_VME(4) | SUN4M_INT_MODULE_ERR,  /*10*/	SUN4M_INT_REALTIME,  /*11*/	SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY, -/*12*/	SUN4M_INT_SERIAL | SUN4M_INT_KBDMS, -/*13*/	SUN4M_INT_AUDIO, +/*12*/	SUN4M_INT_SERIAL  | SUN4M_INT_KBDMS, +/*13*/	SUN4M_INT_SBUS(6) | SUN4M_INT_VME(6) | SUN4M_INT_AUDIO,  /*14*/	SUN4M_INT_E14, -/*15*/	0x00000000 +/*15*/	SUN4M_INT_ERROR  };  /* We assume the caller has disabled local interrupts when these are called, @@ -247,126 +269,141 @@ static unsigned long cpu_pil_to_imask[16] = {   */  static void sun4m_disable_pil_irq(unsigned int pil)  { -	sun4m_interrupts->set = cpu_pil_to_imask[pil]; +	sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_set);  }  static void sun4m_enable_pil_irq(unsigned int pil)  { -	sun4m_interrupts->clear = cpu_pil_to_imask[pil]; +	sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_clear);  }  #ifdef CONFIG_SMP  static void sun4m_send_ipi(int cpu, int level)  { -	unsigned long mask; - -	mask = sun4m_get_irqmask(level); -	sun4m_interrupts->cpu_intregs[cpu].set = mask; +	unsigned long mask = sun4m_get_irqmask(level); +	sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);  }  static void sun4m_clear_ipi(int cpu, int level)  { -	unsigned long mask; - -	mask = sun4m_get_irqmask(level); -	sun4m_interrupts->cpu_intregs[cpu].clear = mask; +	unsigned long mask = sun4m_get_irqmask(level); +	sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);  }  static void sun4m_set_udt(int cpu)  { -	sun4m_interrupts->undirected_target = cpu; +	sbus_writel(cpu, &sun4m_irq_global->interrupt_target);  }  #endif -#define OBIO_INTR	0x20 -#define TIMER_IRQ  	(OBIO_INTR | 10) -#define PROFILE_IRQ	(OBIO_INTR | 14) +struct sun4m_timer_percpu { +	u32		l14_limit; +	u32		l14_count; +	u32		l14_limit_noclear; +	u32		user_timer_start_stop; +}; + +static struct sun4m_timer_percpu __iomem *timers_percpu[SUN4M_NCPUS]; + +struct sun4m_timer_global { +	u32		l10_limit; +	u32		l10_count; +	u32		l10_limit_noclear; +	u32		reserved; +	u32		timer_config; +}; + +static struct sun4m_timer_global __iomem *timers_global; + +#define TIMER_IRQ  	(OBP_INT_LEVEL_ONBOARD | 10) -static struct sun4m_timer_regs *sun4m_timers;  unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10);  static void sun4m_clear_clock_irq(void)  { -	volatile unsigned int clear_intr; -	clear_intr = sun4m_timers->l10_timer_limit; +	sbus_readl(&timers_global->l10_limit);  } -static void sun4m_clear_profile_irq(int cpu) +void sun4m_nmi(struct pt_regs *regs)  { -	volatile unsigned int clear; -     -	clear = sun4m_timers->cpu_timers[cpu].l14_timer_limit; +	unsigned long afsr, afar, si; + +	printk(KERN_ERR "Aieee: sun4m NMI received!\n"); +	/* XXX HyperSparc hack XXX */ +	__asm__ __volatile__("mov 0x500, %%g1\n\t" +			     "lda [%%g1] 0x4, %0\n\t" +			     "mov 0x600, %%g1\n\t" +			     "lda [%%g1] 0x4, %1\n\t" : +			     "=r" (afsr), "=r" (afar)); +	printk(KERN_ERR "afsr=%08lx afar=%08lx\n", afsr, afar); +	si = sbus_readl(&sun4m_irq_global->pending); +	printk(KERN_ERR "si=%08lx\n", si); +	if (si & SUN4M_INT_MODULE_ERR) +		printk(KERN_ERR "Module async error\n"); +	if (si & SUN4M_INT_M2S_WRITE_ERR) +		printk(KERN_ERR "MBus/SBus async error\n"); +	if (si & SUN4M_INT_ECC_ERR) +		printk(KERN_ERR "ECC memory error\n"); +	if (si & SUN4M_INT_VME_ERR) +		printk(KERN_ERR "VME async error\n"); +	printk(KERN_ERR "you lose buddy boy...\n"); +	show_regs(regs); +	prom_halt(); +} + +/* Exported for sun4m_smp.c */ +void sun4m_clear_profile_irq(int cpu) +{ +	sbus_readl(&timers_percpu[cpu]->l14_limit);  }  static void sun4m_load_profile_irq(int cpu, unsigned int limit)  { -	sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit; +	sbus_writel(limit, &timers_percpu[cpu]->l14_limit);  }  static void __init sun4m_init_timers(irq_handler_t counter_fn)  { -	int reg_count, irq, cpu; -	struct linux_prom_registers cnt_regs[PROMREG_MAX]; -	int obio_node, cnt_node; -	struct resource r; - -	cnt_node = 0; -	if((obio_node = -	    prom_searchsiblings (prom_getchild(prom_root_node), "obio")) == 0 || -	   (obio_node = prom_getchild (obio_node)) == 0 || -	   (cnt_node = prom_searchsiblings (obio_node, "counter")) == 0) { -		prom_printf("Cannot find /obio/counter node\n"); -		prom_halt(); +	struct device_node *dp = of_find_node_by_name(NULL, "counter"); +	int i, err, len, num_cpu_timers; +	const u32 *addr; + +	if (!dp) { +		printk(KERN_ERR "sun4m_init_timers: No 'counter' node.\n"); +		return;  	} -	reg_count = prom_getproperty(cnt_node, "reg", -				     (void *) cnt_regs, sizeof(cnt_regs)); -	reg_count = (reg_count/sizeof(struct linux_prom_registers)); -     -	/* Apply the obio ranges to the timer registers. */ -	prom_apply_obio_ranges(cnt_regs, reg_count); -     -	cnt_regs[4].phys_addr = cnt_regs[reg_count-1].phys_addr; -	cnt_regs[4].reg_size = cnt_regs[reg_count-1].reg_size; -	cnt_regs[4].which_io = cnt_regs[reg_count-1].which_io; -	for(obio_node = 1; obio_node < 4; obio_node++) { -		cnt_regs[obio_node].phys_addr = -			cnt_regs[obio_node-1].phys_addr + PAGE_SIZE; -		cnt_regs[obio_node].reg_size = cnt_regs[obio_node-1].reg_size; -		cnt_regs[obio_node].which_io = cnt_regs[obio_node-1].which_io; + +	addr = of_get_property(dp, "address", &len); +	if (!addr) { +		printk(KERN_ERR "sun4m_init_timers: No 'address' prop.\n"); +		return;  	} -	memset((char*)&r, 0, sizeof(struct resource)); -	/* Map the per-cpu Counter registers. */ -	r.flags = cnt_regs[0].which_io; -	r.start = cnt_regs[0].phys_addr; -	sun4m_timers = (struct sun4m_timer_regs *) sbus_ioremap(&r, 0, -	    PAGE_SIZE*SUN4M_NCPUS, "sun4m_cpu_cnt"); -	/* Map the system Counter register. */ -	/* XXX Here we expect consequent calls to yeld adjusent maps. */ -	r.flags = cnt_regs[4].which_io; -	r.start = cnt_regs[4].phys_addr; -	sbus_ioremap(&r, 0, cnt_regs[4].reg_size, "sun4m_sys_cnt"); - -	sun4m_timers->l10_timer_limit =  (((1000000/HZ) + 1) << 10); -	master_l10_counter = &sun4m_timers->l10_cur_count; -	master_l10_limit = &sun4m_timers->l10_timer_limit; - -	irq = request_irq(TIMER_IRQ, -			  counter_fn, -			  (IRQF_DISABLED | SA_STATIC_ALLOC), -			  "timer", NULL); -	if (irq) { -		prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ); -		prom_halt(); +	num_cpu_timers = (len / sizeof(u32)) - 1; +	for (i = 0; i < num_cpu_timers; i++) { +		timers_percpu[i] = (void __iomem *) +			(unsigned long) addr[i];  	} -    -	if (!cpu_find_by_instance(1, NULL, NULL)) { -		for(cpu = 0; cpu < 4; cpu++) -			sun4m_timers->cpu_timers[cpu].l14_timer_limit = 0; -		sun4m_interrupts->set = SUN4M_INT_E14; -	} else { -		sun4m_timers->cpu_timers[0].l14_timer_limit = 0; +	timers_global = (void __iomem *) +		(unsigned long) addr[num_cpu_timers]; + +	sbus_writel((((1000000/HZ) + 1) << 10), &timers_global->l10_limit); + +	master_l10_counter = &timers_global->l10_count; + +	err = request_irq(TIMER_IRQ, counter_fn, +			  (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); +	if (err) { +		printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n", +			err); +		return;  	} + +	for (i = 0; i < num_cpu_timers; i++) +		sbus_writel(0, &timers_percpu[i]->l14_limit); +	if (num_cpu_timers == 4) +		sbus_writel(SUN4M_INT_E14, &sun4m_irq_global->mask_set); +  #ifdef CONFIG_SMP  	{  		unsigned long flags; @@ -390,70 +427,43 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)  void __init sun4m_init_IRQ(void)  { -	int ie_node,i; -	struct linux_prom_registers int_regs[PROMREG_MAX]; -	int num_regs; -	struct resource r; -	int mid; -     -	local_irq_disable(); -	if((ie_node = prom_searchsiblings(prom_getchild(prom_root_node), "obio")) == 0 || -	   (ie_node = prom_getchild (ie_node)) == 0 || -	   (ie_node = prom_searchsiblings (ie_node, "interrupt")) == 0) { -		prom_printf("Cannot find /obio/interrupt node\n"); -		prom_halt(); +	struct device_node *dp = of_find_node_by_name(NULL, "interrupt"); +	int len, i, mid, num_cpu_iregs; +	const u32 *addr; + +	if (!dp) { +		printk(KERN_ERR "sun4m_init_IRQ: No 'interrupt' node.\n"); +		return;  	} -	num_regs = prom_getproperty(ie_node, "reg", (char *) int_regs, -				    sizeof(int_regs)); -	num_regs = (num_regs/sizeof(struct linux_prom_registers)); -     -	/* Apply the obio ranges to these registers. */ -	prom_apply_obio_ranges(int_regs, num_regs); -     -	int_regs[4].phys_addr = int_regs[num_regs-1].phys_addr; -	int_regs[4].reg_size = int_regs[num_regs-1].reg_size; -	int_regs[4].which_io = int_regs[num_regs-1].which_io; -	for(ie_node = 1; ie_node < 4; ie_node++) { -		int_regs[ie_node].phys_addr = int_regs[ie_node-1].phys_addr + PAGE_SIZE; -		int_regs[ie_node].reg_size = int_regs[ie_node-1].reg_size; -		int_regs[ie_node].which_io = int_regs[ie_node-1].which_io; + +	addr = of_get_property(dp, "address", &len); +	if (!addr) { +		printk(KERN_ERR "sun4m_init_IRQ: No 'address' prop.\n"); +		return;  	} -	memset((char *)&r, 0, sizeof(struct resource)); -	/* Map the interrupt registers for all possible cpus. */ -	r.flags = int_regs[0].which_io; -	r.start = int_regs[0].phys_addr; -	sun4m_interrupts = (struct sun4m_intregs *) sbus_ioremap(&r, 0, -	    PAGE_SIZE*SUN4M_NCPUS, "interrupts_percpu"); +	num_cpu_iregs = (len / sizeof(u32)) - 1; +	for (i = 0; i < num_cpu_iregs; i++) { +		sun4m_irq_percpu[i] = (void __iomem *) +			(unsigned long) addr[i]; +	} +	sun4m_irq_global = (void __iomem *) +		(unsigned long) addr[num_cpu_iregs]; -	/* Map the system interrupt control registers. */ -	r.flags = int_regs[4].which_io; -	r.start = int_regs[4].phys_addr; -	sbus_ioremap(&r, 0, int_regs[4].reg_size, "interrupts_system"); +	local_irq_disable(); -	sun4m_interrupts->set = ~SUN4M_INT_MASKALL; +	sbus_writel(~SUN4M_INT_MASKALL, &sun4m_irq_global->mask_set);  	for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++) -		sun4m_interrupts->cpu_intregs[mid].clear = ~0x17fff; - -	if (!cpu_find_by_instance(1, NULL, NULL)) { -		/* system wide interrupts go to cpu 0, this should always -		 * be safe because it is guaranteed to be fitted or OBP doesn't -		 * come up -		 * -		 * Not sure, but writing here on SLAVIO systems may puke -		 * so I don't do it unless there is more than 1 cpu. -		 */ -		irq_rcvreg = (unsigned long *) -				&sun4m_interrupts->undirected_target; -		sun4m_interrupts->undirected_target = 0; -	} -	BTFIXUPSET_CALL(sbint_to_irq, sun4m_sbint_to_irq, BTFIXUPCALL_NORM); +		sbus_writel(~0x17fff, &sun4m_irq_percpu[mid]->clear); + +	if (num_cpu_iregs == 4) +		sbus_writel(0, &sun4m_irq_global->interrupt_target); +  	BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(disable_pil_irq, sun4m_disable_pil_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM); -	BTFIXUPSET_CALL(clear_profile_irq, sun4m_clear_profile_irq, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM);  	sparc_init_timers = sun4m_init_timers;  #ifdef CONFIG_SMP @@ -461,5 +471,6 @@ void __init sun4m_init_IRQ(void)  	BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(set_irq_udt, sun4m_set_udt, BTFIXUPCALL_NORM);  #endif +  	/* Cannot enable interrupts until OBP ticker is disabled. */  } diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index a14a76ac7f3..5fc386d08c4 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -17,6 +17,7 @@  #include <linux/swap.h>  #include <linux/profile.h>  #include <linux/delay.h> +#include <linux/cpu.h>  #include <asm/cacheflush.h>  #include <asm/tlbflush.h> @@ -71,6 +72,8 @@ void __cpuinit smp4m_callin(void)  	local_flush_cache_all();  	local_flush_tlb_all(); +	notify_cpu_starting(cpuid); +  	/* Get our local ticker going. */  	smp_setup_percpu_timer(); @@ -313,6 +316,8 @@ void smp4m_cross_call_irq(void)  	ccall_info.processors_out[i] = 1;  } +extern void sun4m_clear_profile_irq(int cpu); +  void smp4m_percpu_timer_interrupt(struct pt_regs *regs)  {  	struct pt_regs *old_regs; @@ -320,7 +325,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)  	old_regs = set_irq_regs(regs); -	clear_profile_irq(cpu); +	sun4m_clear_profile_irq(cpu);  	profile_tick(CPU_PROFILING); diff --git a/arch/sparc/kernel/sun4setup.c b/arch/sparc/kernel/sun4setup.c deleted file mode 100644 index 229a52f55f1..00000000000 --- a/arch/sparc/kernel/sun4setup.c +++ /dev/null @@ -1,75 +0,0 @@ -/* sun4setup.c: Setup the hardware address of various items in the sun4 - * 		architecture. Called from idprom_init - * - * Copyright (C) 1998 Chris G. Davis (cdavis@cois.on.ca) - */ - -#include <asm/page.h> -#include <asm/oplib.h> -#include <asm/idprom.h> -#include <asm/sun4paddr.h> -#include <asm/machines.h> - -int sun4_memreg_physaddr; -int sun4_ie_physaddr; -int sun4_clock_physaddr; -int sun4_timer_physaddr; -int sun4_eth_physaddr; -int sun4_si_physaddr; -int sun4_bwtwo_physaddr; -int sun4_zs0_physaddr; -int sun4_zs1_physaddr; -int sun4_dma_physaddr; -int sun4_esp_physaddr; -int sun4_ie_physaddr;  - -void __init sun4setup(void) -{ -	printk("Sun4 Hardware Setup v1.0 18/May/98 Chris Davis (cdavis@cois.on.ca). "); -	/* -	  setup standard sun4 info -	  */ -	sun4_ie_physaddr=SUN4_IE_PHYSADDR; - -	/* -	  setup model specific info -	  */ -	switch(idprom->id_machtype) { -		case (SM_SUN4 | SM_4_260 ): -			printk("Setup for a SUN4/260\n"); -			sun4_memreg_physaddr=SUN4_200_MEMREG_PHYSADDR; -			sun4_clock_physaddr=SUN4_200_CLOCK_PHYSADDR; -			sun4_timer_physaddr=SUN4_UNUSED_PHYSADDR; -			sun4_eth_physaddr=SUN4_200_ETH_PHYSADDR; -			sun4_si_physaddr=SUN4_200_SI_PHYSADDR; -			sun4_bwtwo_physaddr=SUN4_200_BWTWO_PHYSADDR; -			sun4_dma_physaddr=SUN4_UNUSED_PHYSADDR; -			sun4_esp_physaddr=SUN4_UNUSED_PHYSADDR; -			break; -		case (SM_SUN4 | SM_4_330 ): -			printk("Setup for a SUN4/330\n"); -			sun4_memreg_physaddr=SUN4_300_MEMREG_PHYSADDR; -			sun4_clock_physaddr=SUN4_300_CLOCK_PHYSADDR; -			sun4_timer_physaddr=SUN4_300_TIMER_PHYSADDR; -			sun4_eth_physaddr=SUN4_300_ETH_PHYSADDR; -			sun4_si_physaddr=SUN4_UNUSED_PHYSADDR; -			sun4_bwtwo_physaddr=SUN4_300_BWTWO_PHYSADDR; -			sun4_dma_physaddr=SUN4_300_DMA_PHYSADDR; -			sun4_esp_physaddr=SUN4_300_ESP_PHYSADDR; -			break; -		case (SM_SUN4 | SM_4_470 ): -			printk("Setup for a SUN4/470\n"); -			sun4_memreg_physaddr=SUN4_400_MEMREG_PHYSADDR; -			sun4_clock_physaddr=SUN4_400_CLOCK_PHYSADDR; -			sun4_timer_physaddr=SUN4_400_TIMER_PHYSADDR; -			sun4_eth_physaddr=SUN4_400_ETH_PHYSADDR; -			sun4_si_physaddr=SUN4_UNUSED_PHYSADDR; -			sun4_bwtwo_physaddr=SUN4_400_BWTWO_PHYSADDR; -			sun4_dma_physaddr=SUN4_400_DMA_PHYSADDR; -			sun4_esp_physaddr=SUN4_400_ESP_PHYSADDR; -			break; -		default: -			; -	} -} - diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 4d73421559c..03035c852a4 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -53,7 +53,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi  	/* See asm-sparc/uaccess.h */  	if (len > TASK_SIZE - PAGE_SIZE)  		return -ENOMEM; -	if (ARCH_SUN4C_SUN4 && len > 0x20000000) +	if (ARCH_SUN4C && len > 0x20000000)  		return -ENOMEM;  	if (!addr)  		addr = TASK_UNMAPPED_BASE; @@ -65,7 +65,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi  	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {  		/* At this point:  (!vmm || addr < vmm->vm_end). */ -		if (ARCH_SUN4C_SUN4 && addr < 0xe0000000 && 0x20000000 - len < addr) { +		if (ARCH_SUN4C && addr < 0xe0000000 && 0x20000000 - len < addr) {  			addr = PAGE_OFFSET;  			vmm = find_vma(current->mm, PAGE_OFFSET);  		} @@ -81,7 +81,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi  asmlinkage unsigned long sparc_brk(unsigned long brk)  { -	if(ARCH_SUN4C_SUN4) { +	if(ARCH_SUN4C) {  		if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000))  			return current->mm->brk;  	} @@ -221,7 +221,7 @@ out:  int sparc_mmap_check(unsigned long addr, unsigned long len)  { -	if (ARCH_SUN4C_SUN4 && +	if (ARCH_SUN4C &&  	    (len > 0x20000000 ||  	     (addr < 0xe0000000 && addr + len > 0x20000000)))  		return -EINVAL; diff --git a/arch/sparc/kernel/tick14.c b/arch/sparc/kernel/tick14.c index 707bfda8657..138bbf5f872 100644 --- a/arch/sparc/kernel/tick14.c +++ b/arch/sparc/kernel/tick14.c @@ -1,31 +1,12 @@  /* tick14.c - * linux/arch/sparc/kernel/tick14.c   *   * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk)   *   * This file handles the Sparc specific level14 ticker   * This is really useful for profiling OBP uses it for keyboard   * aborts and other stuff. - * - *   */ -#include <linux/errno.h> -#include <linux/sched.h>  #include <linux/kernel.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/timex.h> -#include <linux/interrupt.h> - -#include <asm/oplib.h> -#include <asm/timer.h> -#include <asm/mostek.h> -#include <asm/system.h> -#include <asm/irq.h> -#include <asm/io.h> - -#include "irq.h"  extern unsigned long lvl14_save[5];  static unsigned long *linux_lvl14 = NULL; @@ -56,31 +37,3 @@ void install_obp_ticker(void)  	linux_lvl14[2] =  obp_lvl14[2];  	linux_lvl14[3] =  obp_lvl14[3];   } - -void claim_ticker14(irq_handler_t handler, -		    int irq_nr, unsigned int timeout ) -{ -	int cpu = smp_processor_id(); - -	/* first we copy the obp handler instructions -	 */ -	__disable_irq(irq_nr); -	if (!handler) -		return; -     -	linux_lvl14 = (unsigned long *)lvl14_save[4]; -	obp_lvl14[0] = linux_lvl14[0]; -	obp_lvl14[1] = linux_lvl14[1]; -	obp_lvl14[2] = linux_lvl14[2]; -	obp_lvl14[3] = linux_lvl14[3]; - -	if (!request_irq(irq_nr, -			 handler, -			 (IRQF_DISABLED | SA_STATIC_ALLOC), -			 "counter14", -			 NULL)) { -		install_linux_ticker(); -		load_profile_irq(cpu, timeout); -		__enable_irq(irq_nr); -	} -} diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 0762f5db192..00f7383c765 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -23,22 +23,24 @@  #include <linux/mm.h>  #include <linux/interrupt.h>  #include <linux/time.h> +#include <linux/rtc.h> +#include <linux/rtc/m48t59.h>  #include <linux/timex.h>  #include <linux/init.h>  #include <linux/pci.h>  #include <linux/ioport.h>  #include <linux/profile.h> +#include <linux/of.h>  #include <linux/of_device.h> +#include <linux/platform_device.h>  #include <asm/oplib.h>  #include <asm/timer.h> -#include <asm/mostek.h>  #include <asm/system.h>  #include <asm/irq.h>  #include <asm/io.h>  #include <asm/idprom.h>  #include <asm/machines.h> -#include <asm/sun4paddr.h>  #include <asm/page.h>  #include <asm/pcic.h>  #include <asm/irq_regs.h> @@ -46,34 +48,9 @@  #include "irq.h"  DEFINE_SPINLOCK(rtc_lock); -static enum sparc_clock_type sp_clock_typ; -DEFINE_SPINLOCK(mostek_lock); -void __iomem *mstk48t02_regs = NULL; -static struct mostek48t08 __iomem *mstk48t08_regs = NULL;  static int set_rtc_mmss(unsigned long);  static int sbus_do_settimeofday(struct timespec *tv); -#ifdef CONFIG_SUN4 -struct intersil *intersil_clock; -#define intersil_cmd(intersil_reg, intsil_cmd) intersil_reg->int_cmd_reg = \ -	(intsil_cmd) - -#define intersil_intr(intersil_reg, intsil_cmd) intersil_reg->int_intr_reg = \ -	(intsil_cmd) - -#define intersil_start(intersil_reg) intersil_cmd(intersil_reg, \ -	( INTERSIL_START | INTERSIL_32K | INTERSIL_NORMAL | INTERSIL_24H |\ -	  INTERSIL_INTR_ENABLE)) - -#define intersil_stop(intersil_reg) intersil_cmd(intersil_reg, \ -	( INTERSIL_STOP | INTERSIL_32K | INTERSIL_NORMAL | INTERSIL_24H |\ -	  INTERSIL_INTR_ENABLE)) - -#define intersil_read_intr(intersil_reg, towhere) towhere = \ -	intersil_reg->int_intr_reg - -#endif -  unsigned long profile_pc(struct pt_regs *regs)  {  	extern char __copy_user_begin[], __copy_user_end[]; @@ -96,7 +73,6 @@ unsigned long profile_pc(struct pt_regs *regs)  EXPORT_SYMBOL(profile_pc);  __volatile__ unsigned int *master_l10_counter; -__volatile__ unsigned int *master_l10_limit;  /*   * timer_interrupt() needs to keep up the real-time clock, @@ -116,15 +92,7 @@ static irqreturn_t timer_interrupt(int dummy, void *dev_id)  	/* Protect counter clear so that do_gettimeoffset works */  	write_seqlock(&xtime_lock); -#ifdef CONFIG_SUN4 -	if((idprom->id_machtype == (SM_SUN4 | SM_4_260)) || -	   (idprom->id_machtype == (SM_SUN4 | SM_4_110))) { -		int temp; -        	intersil_read_intr(intersil_clock, temp); -		/* re-enable the irq */ -		enable_pil_irq(10); -	} -#endif +  	clear_clock_irq();  	do_timer(1); @@ -147,157 +115,37 @@ static irqreturn_t timer_interrupt(int dummy, void *dev_id)  	return IRQ_HANDLED;  } -/* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ -static void __devinit kick_start_clock(void) +static unsigned char mostek_read_byte(struct device *dev, u32 ofs)  { -	struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; -	unsigned char sec; -	int i, count; - -	prom_printf("CLOCK: Clock was stopped. Kick start "); - -	spin_lock_irq(&mostek_lock); - -	/* Turn on the kick start bit to start the oscillator. */ -	regs->creg |= MSTK_CREG_WRITE; -	regs->sec &= ~MSTK_STOP; -	regs->hour |= MSTK_KICK_START; -	regs->creg &= ~MSTK_CREG_WRITE; - -	spin_unlock_irq(&mostek_lock); - -	/* Delay to allow the clock oscillator to start. */ -	sec = MSTK_REG_SEC(regs); -	for (i = 0; i < 3; i++) { -		while (sec == MSTK_REG_SEC(regs)) -			for (count = 0; count < 100000; count++) -				/* nothing */ ; -		prom_printf("."); -		sec = regs->sec; -	} -	prom_printf("\n"); - -	spin_lock_irq(&mostek_lock); - -	/* Turn off kick start and set a "valid" time and date. */ -	regs->creg |= MSTK_CREG_WRITE; -	regs->hour &= ~MSTK_KICK_START; -	MSTK_SET_REG_SEC(regs,0); -	MSTK_SET_REG_MIN(regs,0); -	MSTK_SET_REG_HOUR(regs,0); -	MSTK_SET_REG_DOW(regs,5); -	MSTK_SET_REG_DOM(regs,1); -	MSTK_SET_REG_MONTH(regs,8); -	MSTK_SET_REG_YEAR(regs,1996 - MSTK_YEAR_ZERO); -	regs->creg &= ~MSTK_CREG_WRITE; - -	spin_unlock_irq(&mostek_lock); - -	/* Ensure the kick start bit is off. If it isn't, turn it off. */ -	while (regs->hour & MSTK_KICK_START) { -		prom_printf("CLOCK: Kick start still on!\n"); - -		spin_lock_irq(&mostek_lock); -		regs->creg |= MSTK_CREG_WRITE; -		regs->hour &= ~MSTK_KICK_START; -		regs->creg &= ~MSTK_CREG_WRITE; -		spin_unlock_irq(&mostek_lock); -	} +	struct platform_device *pdev = to_platform_device(dev); +	struct m48t59_plat_data *pdata = pdev->dev.platform_data; -	prom_printf("CLOCK: Kick start procedure successful.\n"); +	return readb(pdata->ioaddr + ofs);  } -/* Return nonzero if the clock chip battery is low. */ -static inline int has_low_battery(void) +static void mostek_write_byte(struct device *dev, u32 ofs, u8 val)  { -	struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; -	unsigned char data1, data2; - -	spin_lock_irq(&mostek_lock); -	data1 = regs->eeprom[0];	/* Read some data. */ -	regs->eeprom[0] = ~data1;	/* Write back the complement. */ -	data2 = regs->eeprom[0];	/* Read back the complement. */ -	regs->eeprom[0] = data1;	/* Restore the original value. */ -	spin_unlock_irq(&mostek_lock); - -	return (data1 == data2);	/* Was the write blocked? */ -} +	struct platform_device *pdev = to_platform_device(dev); +	struct m48t59_plat_data *pdata = pdev->dev.platform_data; -static void __devinit mostek_set_system_time(void) -{ -	unsigned int year, mon, day, hour, min, sec; -	struct mostek48t02 *mregs; - -	mregs = (struct mostek48t02 *)mstk48t02_regs; -	if(!mregs) { -		prom_printf("Something wrong, clock regs not mapped yet.\n"); -		prom_halt(); -	}		 -	spin_lock_irq(&mostek_lock); -	mregs->creg |= MSTK_CREG_READ; -	sec = MSTK_REG_SEC(mregs); -	min = MSTK_REG_MIN(mregs); -	hour = MSTK_REG_HOUR(mregs); -	day = MSTK_REG_DOM(mregs); -	mon = MSTK_REG_MONTH(mregs); -	year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) ); -	xtime.tv_sec = mktime(year, mon, day, hour, min, sec); -	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); -        set_normalized_timespec(&wall_to_monotonic, -                                -xtime.tv_sec, -xtime.tv_nsec); -	mregs->creg &= ~MSTK_CREG_READ; -	spin_unlock_irq(&mostek_lock); +	writeb(val, pdata->ioaddr + ofs);  } -/* Probe for the real time clock chip on Sun4 */ -static inline void sun4_clock_probe(void) -{ -#ifdef CONFIG_SUN4 -	int temp; -	struct resource r; - -	memset(&r, 0, sizeof(r)); -	if( idprom->id_machtype == (SM_SUN4 | SM_4_330) ) { -		sp_clock_typ = MSTK48T02; -		r.start = sun4_clock_physaddr; -		mstk48t02_regs = sbus_ioremap(&r, 0, -				       sizeof(struct mostek48t02), NULL); -		mstk48t08_regs = NULL;  /* To catch weirdness */ -		intersil_clock = NULL;  /* just in case */ - -		/* Kick start the clock if it is completely stopped. */ -		if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP) -			kick_start_clock(); -	} else if( idprom->id_machtype == (SM_SUN4 | SM_4_260)) { -		/* intersil setup code */ -		printk("Clock: INTERSIL at %8x ",sun4_clock_physaddr); -		sp_clock_typ = INTERSIL; -		r.start = sun4_clock_physaddr; -		intersil_clock = (struct intersil *)  -		    sbus_ioremap(&r, 0, sizeof(*intersil_clock), "intersil"); -		mstk48t02_regs = 0;  /* just be sure */ -		mstk48t08_regs = NULL;  /* ditto */ -		/* initialise the clock */ - -		intersil_intr(intersil_clock,INTERSIL_INT_100HZ); - -		intersil_start(intersil_clock); - -		intersil_read_intr(intersil_clock, temp); -                while (!(temp & 0x80)) -                        intersil_read_intr(intersil_clock, temp); - -                intersil_read_intr(intersil_clock, temp); -                while (!(temp & 0x80)) -                        intersil_read_intr(intersil_clock, temp); - -		intersil_stop(intersil_clock); +static struct m48t59_plat_data m48t59_data = { +	.read_byte = mostek_read_byte, +	.write_byte = mostek_write_byte, +}; -	} -#endif -} +/* resource is set at runtime */ +static struct platform_device m48t59_rtc = { +	.name		= "rtc-m48t59", +	.id		= 0, +	.num_resources	= 1, +	.dev	= { +		.platform_data = &m48t59_data, +	}, +}; -#ifndef CONFIG_SUN4  static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)  {  	struct device_node *dp = op->node; @@ -306,38 +154,26 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id  	if (!model)  		return -ENODEV; +	m48t59_rtc.resource = &op->resource[0];  	if (!strcmp(model, "mk48t02")) { -		sp_clock_typ = MSTK48T02; -  		/* Map the clock register io area read-only */ -		mstk48t02_regs = of_ioremap(&op->resource[0], 0, -					    sizeof(struct mostek48t02), -					    "mk48t02"); -		mstk48t08_regs = NULL;  /* To catch weirdness */ +		m48t59_data.ioaddr = of_ioremap(&op->resource[0], 0, +						2048, "rtc-m48t59"); +		m48t59_data.type = M48T59RTC_TYPE_M48T02;  	} else if (!strcmp(model, "mk48t08")) { -		sp_clock_typ = MSTK48T08; -		mstk48t08_regs = of_ioremap(&op->resource[0], 0, -					    sizeof(struct mostek48t08), -					    "mk48t08"); - -		mstk48t02_regs = &mstk48t08_regs->regs; +		m48t59_data.ioaddr = of_ioremap(&op->resource[0], 0, +						8192, "rtc-m48t59"); +		m48t59_data.type = M48T59RTC_TYPE_M48T08;  	} else  		return -ENODEV; -	/* Report a low battery voltage condition. */ -	if (has_low_battery()) -		printk(KERN_CRIT "NVRAM: Low battery voltage!\n"); - -	/* Kick start the clock if it is completely stopped. */ -	if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP) -		kick_start_clock(); - -	mostek_set_system_time(); +	if (platform_device_register(&m48t59_rtc) < 0) +		printk(KERN_ERR "Registering RTC device failed\n");  	return 0;  } -static struct of_device_id clock_match[] = { +static struct of_device_id __initdata clock_match[] = {  	{  		.name = "eeprom",  	}, @@ -348,7 +184,7 @@ static struct of_platform_driver clock_driver = {  	.match_table	= clock_match,  	.probe		= clock_probe,  	.driver		= { -		.name	= "clock", +		.name	= "rtc",  	},  }; @@ -364,7 +200,6 @@ static int __init clock_init(void)   * need to see the clock registers.   */  fs_initcall(clock_init); -#endif /* !CONFIG_SUN4 */  static void __init sbus_time_init(void)  { @@ -372,51 +207,8 @@ static void __init sbus_time_init(void)  	BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);  	btfixup(); -	if (ARCH_SUN4) -		sun4_clock_probe(); -  	sparc_init_timers(timer_interrupt); -#ifdef CONFIG_SUN4 -	if(idprom->id_machtype == (SM_SUN4 | SM_4_330)) { -		mostek_set_system_time(); -	} else if(idprom->id_machtype == (SM_SUN4 | SM_4_260) ) { -		/* initialise the intersil on sun4 */ -		unsigned int year, mon, day, hour, min, sec; -		int temp; -		struct intersil *iregs; - -		iregs=intersil_clock; -		if(!iregs) { -			prom_printf("Something wrong, clock regs not mapped yet.\n"); -			prom_halt(); -		} - -		intersil_intr(intersil_clock,INTERSIL_INT_100HZ); -		disable_pil_irq(10); -		intersil_stop(iregs); -		intersil_read_intr(intersil_clock, temp); - -		temp = iregs->clk.int_csec; - -		sec = iregs->clk.int_sec; -		min = iregs->clk.int_min; -		hour = iregs->clk.int_hour; -		day = iregs->clk.int_day; -		mon = iregs->clk.int_month; -		year = MSTK_CVT_YEAR(iregs->clk.int_year); - -		enable_pil_irq(10); -		intersil_start(iregs); - -		xtime.tv_sec = mktime(year, mon, day, hour, min, sec); -		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); -	        set_normalized_timespec(&wall_to_monotonic, - 	                               -xtime.tv_sec, -xtime.tv_nsec); -		printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec); -	} -#endif -  	/* Now that OBP ticker has been silenced, it is safe to enable IRQ. */  	local_irq_enable();  } @@ -522,80 +314,15 @@ static int sbus_do_settimeofday(struct timespec *tv)  	return 0;  } -/* - * BUG: This routine does not handle hour overflow properly; it just - *      sets the minutes. Usually you won't notice until after reboot! - */ -static int set_rtc_mmss(unsigned long nowtime) +static int set_rtc_mmss(unsigned long secs)  { -	int real_seconds, real_minutes, mostek_minutes; -	struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; -	unsigned long flags; -#ifdef CONFIG_SUN4 -	struct intersil *iregs = intersil_clock; -	int temp; -#endif +	struct rtc_device *rtc = rtc_class_open("rtc0"); +	int err = -1; -	/* Not having a register set can lead to trouble. */ -	if (!regs) { -#ifdef CONFIG_SUN4 -		if(!iregs) -		return -1; -	 	else { -			temp = iregs->clk.int_csec; - -			mostek_minutes = iregs->clk.int_min; - -			real_seconds = nowtime % 60; -			real_minutes = nowtime / 60; -			if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1) -				real_minutes += 30;	/* correct for half hour time zone */ -			real_minutes %= 60; - -			if (abs(real_minutes - mostek_minutes) < 30) { -				intersil_stop(iregs); -				iregs->clk.int_sec=real_seconds; -				iregs->clk.int_min=real_minutes; -				intersil_start(iregs); -			} else { -				printk(KERN_WARNING -			       "set_rtc_mmss: can't update from %d to %d\n", -				       mostek_minutes, real_minutes); -				return -1; -			} -			 -			return 0; -		} -#endif +	if (rtc) { +		err = rtc_set_mmss(rtc, secs); +		rtc_class_close(rtc);  	} -	spin_lock_irqsave(&mostek_lock, flags); -	/* Read the current RTC minutes. */ -	regs->creg |= MSTK_CREG_READ; -	mostek_minutes = MSTK_REG_MIN(regs); -	regs->creg &= ~MSTK_CREG_READ; - -	/* -	 * since we're only adjusting minutes and seconds, -	 * don't interfere with hour overflow. This avoids -	 * messing with unknown time zones but requires your -	 * RTC not to be off by more than 15 minutes -	 */ -	real_seconds = nowtime % 60; -	real_minutes = nowtime / 60; -	if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1) -		real_minutes += 30;	/* correct for half hour time zone */ -	real_minutes %= 60; - -	if (abs(real_minutes - mostek_minutes) < 30) { -		regs->creg |= MSTK_CREG_WRITE; -		MSTK_SET_REG_SEC(regs,real_seconds); -		MSTK_SET_REG_MIN(regs,real_minutes); -		regs->creg &= ~MSTK_CREG_WRITE; -		spin_unlock_irqrestore(&mostek_lock, flags); -		return 0; -	} else { -		spin_unlock_irqrestore(&mostek_lock, flags); -		return -1; -	} +	return err;  } diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c index 5d45d5fd8c9..2b7d5065903 100644 --- a/arch/sparc/kernel/traps.c +++ b/arch/sparc/kernel/traps.c @@ -43,23 +43,6 @@ void syscall_trace_exit(struct pt_regs *regs)  {  } -void sun4m_nmi(struct pt_regs *regs) -{ -	unsigned long afsr, afar; - -	printk("Aieee: sun4m NMI received!\n"); -	/* XXX HyperSparc hack XXX */ -	__asm__ __volatile__("mov 0x500, %%g1\n\t" -			     "lda [%%g1] 0x4, %0\n\t" -			     "mov 0x600, %%g1\n\t" -			     "lda [%%g1] 0x4, %1\n\t" : -			     "=r" (afsr), "=r" (afar)); -	printk("afsr=%08lx afar=%08lx\n", afsr, afar); -	printk("you lose buddy boy...\n"); -	show_regs(regs); -	prom_halt(); -} -  void sun4d_nmi(struct pt_regs *regs)  {  	printk("Aieee: sun4d NMI received!\n"); diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 109c8b22cb3..ea88955d97f 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile @@ -3,13 +3,8 @@  EXTRA_AFLAGS := -ansi -obj-y    := fault.o init.o loadmmu.o generic.o extable.o btfixup.o - -ifeq ($(CONFIG_SUN4),y) -obj-y	 += nosrmmu.o -else -obj-y	 += srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o swift.o -endif +obj-y	:= fault.o init.o loadmmu.o generic.o extable.o btfixup.o \ +	    srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o swift.o  ifdef CONFIG_HIGHMEM  obj-y	+= highmem.o diff --git a/arch/sparc/mm/btfixup.c b/arch/sparc/mm/btfixup.c index a312d127d47..5175ac2f482 100644 --- a/arch/sparc/mm/btfixup.c +++ b/arch/sparc/mm/btfixup.c @@ -20,11 +20,7 @@  extern char *srmmu_name;  static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for "; -#ifdef CONFIG_SUN4 -static char str_sun4c[] __initdata = "sun4\n"; -#else  static char str_sun4c[] __initdata = "sun4c\n"; -#endif  static char str_srmmu[] __initdata = "srmmu[%s]/";  static char str_iommu[] __initdata = "iommu\n";  static char str_iounit[] __initdata = "io-unit\n"; @@ -86,7 +82,7 @@ void __init btfixup(void)  	if (!visited) {  		visited++;  		printk(version); -		if (ARCH_SUN4C_SUN4) +		if (ARCH_SUN4C)  			printk(str_sun4c);  		else {  			printk(str_srmmu, srmmu_name); diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c index 3604c2e8670..a507e117466 100644 --- a/arch/sparc/mm/fault.c +++ b/arch/sparc/mm/fault.c @@ -191,7 +191,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,  	 * only copy the information from the master page table,  	 * nothing more.  	 */ -	if (!ARCH_SUN4C_SUN4 && address >= TASK_SIZE) +	if (!ARCH_SUN4C && address >= TASK_SIZE)  		goto vmalloc_fault;  	info.si_code = SEGV_MAPERR; diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index e103f1bb377..677c1e187a2 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -23,6 +23,7 @@  #include <linux/highmem.h>  #include <linux/bootmem.h>  #include <linux/pagemap.h> +#include <linux/poison.h>  #include <asm/system.h>  #include <asm/vac-ops.h> @@ -480,6 +481,7 @@ void free_initmem (void)  	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {  		struct page *p; +		memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);  		p = virt_to_page(addr);  		ClearPageReserved(p); @@ -488,20 +490,26 @@ void free_initmem (void)  		totalram_pages++;  		num_physpages++;  	} -	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); +	printk(KERN_INFO "Freeing unused kernel memory: %dk freed\n", +		(&__init_end - &__init_begin) >> 10);  }  #ifdef CONFIG_BLK_DEV_INITRD  void free_initrd_mem(unsigned long start, unsigned long end)  {  	if (start < end) -		printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); +		printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", +			(end - start) >> 10);  	for (; start < end; start += PAGE_SIZE) { -		struct page *p = virt_to_page(start); +		struct page *p; + +		memset((void *)start, POISON_FREE_INITMEM, PAGE_SIZE); +		p = virt_to_page(start);  		ClearPageReserved(p);  		init_page_count(p);  		__free_page(p); +		totalram_pages++;  		num_physpages++;  	}  } diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index f167835db3d..daadf5f8805 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -12,10 +12,11 @@  #include <linux/highmem.h>	/* pte_offset_map => kmap_atomic */  #include <linux/bitops.h>  #include <linux/scatterlist.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include <asm/pgalloc.h>  #include <asm/pgtable.h> -#include <asm/sbus.h>  #include <asm/io.h>  #include <asm/io-unit.h>  #include <asm/mxcc.h> @@ -34,13 +35,10 @@  #define IOPERM        (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID)  #define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM) -void __init -iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) +static void __init iounit_iommu_init(struct of_device *op)  { -	iopte_t *xpt, *xptend;  	struct iounit_struct *iounit; -	struct linux_prom_registers iommu_promregs[PROMREG_MAX]; -	struct resource r; +	iopte_t *xpt, *xptend;  	iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC);  	if (!iounit) { @@ -55,18 +53,13 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)  	iounit->rotor[1] = IOUNIT_BMAP2_START;  	iounit->rotor[2] = IOUNIT_BMAPM_START; -	xpt = NULL; -	if(prom_getproperty(sbi_node, "reg", (void *) iommu_promregs, -			    sizeof(iommu_promregs)) != -1) { -		prom_apply_generic_ranges(io_node, 0, iommu_promregs, 3); -		memset(&r, 0, sizeof(r)); -		r.flags = iommu_promregs[2].which_io; -		r.start = iommu_promregs[2].phys_addr; -		xpt = (iopte_t *) sbus_ioremap(&r, 0, PAGE_SIZE * 16, "XPT"); +	xpt = of_ioremap(&op->resource[2], 0, PAGE_SIZE * 16, "XPT"); +	if (!xpt) { +		prom_printf("SUN4D: Cannot map External Page Table."); +		prom_halt();  	} -	if(!xpt) panic("Cannot map External Page Table."); -	sbus->ofdev.dev.archdata.iommu = iounit; +	op->dev.archdata.iommu = iounit;  	iounit->page_table = xpt;  	spin_lock_init(&iounit->lock); @@ -75,6 +68,25 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)  	     	iopte_val(*xpt++) = 0;  } +static int __init iounit_init(void) +{ +	extern void sun4d_init_sbi_irq(void); +	struct device_node *dp; + +	for_each_node_by_name(dp, "sbi") { +		struct of_device *op = of_find_device_by_node(dp); + +		iounit_iommu_init(op); +		of_propagate_archdata(op); +	} + +	sun4d_init_sbi_irq(); + +	return 0; +} + +subsys_initcall(iounit_init); +  /* One has to hold iounit->lock to call this */  static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size)  { @@ -124,10 +136,10 @@ nexti:	scan = find_next_zero_bit(iounit->bmap, limit, scan);  	return vaddr;  } -static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus *sbus) +static __u32 iounit_get_scsi_one(struct device *dev, char *vaddr, unsigned long len)  { +	struct iounit_struct *iounit = dev->archdata.iommu;  	unsigned long ret, flags; -	struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;  	spin_lock_irqsave(&iounit->lock, flags);  	ret = iounit_get_area(iounit, (unsigned long)vaddr, len); @@ -135,10 +147,10 @@ static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus  	return ret;  } -static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) +static void iounit_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)  { +	struct iounit_struct *iounit = dev->archdata.iommu;  	unsigned long flags; -	struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;  	/* FIXME: Cache some resolved pages - often several sg entries are to the same page */  	spin_lock_irqsave(&iounit->lock, flags); @@ -151,10 +163,10 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus  	spin_unlock_irqrestore(&iounit->lock, flags);  } -static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) +static void iounit_release_scsi_one(struct device *dev, __u32 vaddr, unsigned long len)  { +	struct iounit_struct *iounit = dev->archdata.iommu;  	unsigned long flags; -	struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;  	spin_lock_irqsave(&iounit->lock, flags);  	len = ((vaddr & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT; @@ -165,11 +177,11 @@ static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_  	spin_unlock_irqrestore(&iounit->lock, flags);  } -static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) +static void iounit_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)  { +	struct iounit_struct *iounit = dev->archdata.iommu;  	unsigned long flags;  	unsigned long vaddr, len; -	struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;  	spin_lock_irqsave(&iounit->lock, flags);  	while (sz != 0) { @@ -185,12 +197,12 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_  }  #ifdef CONFIG_SBUS -static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, int len) +static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, __u32 addr, int len)  { +	struct iounit_struct *iounit = dev->archdata.iommu;  	unsigned long page, end;  	pgprot_t dvma_prot;  	iopte_t *iopte; -	struct sbus_bus *sbus;  	*pba = addr; @@ -212,12 +224,8 @@ static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, in  			i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT); -			for_each_sbus(sbus) { -				struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; - -				iopte = (iopte_t *)(iounit->page_table + i); -				*iopte = MKIOPTE(__pa(page)); -			} +			iopte = (iopte_t *)(iounit->page_table + i); +			*iopte = MKIOPTE(__pa(page));  		}  		addr += PAGE_SIZE;  		va += PAGE_SIZE; @@ -228,23 +236,10 @@ static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, in  	return 0;  } -static void iounit_unmap_dma_area(unsigned long addr, int len) +static void iounit_unmap_dma_area(struct device *dev, unsigned long addr, int len)  {  	/* XXX Somebody please fill this in */  } - -/* XXX We do not pass sbus device here, bad. */ -static struct page *iounit_translate_dvma(unsigned long addr) -{ -	struct sbus_bus *sbus = sbus_root;	/* They are all the same */ -	struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; -	int i; -	iopte_t *iopte; - -	i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT); -	iopte = (iopte_t *)(iounit->page_table + i); -	return pfn_to_page(iopte_val(*iopte) >> (PAGE_SHIFT-4)); /* XXX sun4d guru, help */ -}  #endif  static char *iounit_lockarea(char *vaddr, unsigned long len) @@ -271,54 +266,5 @@ void __init ld_mmu_iounit(void)  #ifdef CONFIG_SBUS  	BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM); -	BTFIXUPSET_CALL(mmu_translate_dvma, iounit_translate_dvma, BTFIXUPCALL_NORM);  #endif  } - -__u32 iounit_map_dma_init(struct sbus_bus *sbus, int size) -{ -	int i, j, k, npages; -	unsigned long rotor, scan, limit; -	unsigned long flags; -	__u32 ret; -	struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; - -        npages = (size + (PAGE_SIZE-1)) >> PAGE_SHIFT; -	i = 0x0213; -	spin_lock_irqsave(&iounit->lock, flags); -next:	j = (i & 15); -	rotor = iounit->rotor[j - 1]; -	limit = iounit->limit[j]; -	scan = rotor; -nexti:	scan = find_next_zero_bit(iounit->bmap, limit, scan); -	if (scan + npages > limit) { -		if (limit != rotor) { -			limit = rotor; -			scan = iounit->limit[j - 1]; -			goto nexti; -		} -		i >>= 4; -		if (!(i & 15)) -			panic("iounit_map_dma_init: Couldn't find free iopte slots for %d bytes\n", size); -		goto next; -	} -	for (k = 1, scan++; k < npages; k++) -		if (test_bit(scan++, iounit->bmap)) -			goto nexti; -	iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1]; -	scan -= npages; -	ret = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT); -	for (k = 0; k < npages; k++, scan++) -		set_bit(scan, iounit->bmap); -	spin_unlock_irqrestore(&iounit->lock, flags); -	return ret; -} - -__u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus) -{ -	int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT; -	struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; -	 -	iounit->page_table[scan] = MKIOPTE(__pa(((unsigned long)addr) & PAGE_MASK)); -	return vaddr + (((unsigned long)addr) & ~PAGE_MASK); -} diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 4b934270f05..e7a499e3aa3 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -13,10 +13,11 @@  #include <linux/slab.h>  #include <linux/highmem.h>	/* pte_offset_map => kmap_atomic */  #include <linux/scatterlist.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include <asm/pgalloc.h>  #include <asm/pgtable.h> -#include <asm/sbus.h>  #include <asm/io.h>  #include <asm/mxcc.h>  #include <asm/mbus.h> @@ -55,30 +56,21 @@ static pgprot_t dvma_prot;		/* Consistent mapping pte flags */  #define IOPERM        (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID)  #define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ) -void __init -iommu_init(int iommund, struct sbus_bus *sbus) +static void __init sbus_iommu_init(struct of_device *op)  { -	unsigned int impl, vers; -	unsigned long tmp;  	struct iommu_struct *iommu; -	struct linux_prom_registers iommu_promregs[PROMREG_MAX]; -	struct resource r; +	unsigned int impl, vers;  	unsigned long *bitmap; +	unsigned long tmp;  	iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC);  	if (!iommu) {  		prom_printf("Unable to allocate iommu structure\n");  		prom_halt();  	} -	iommu->regs = NULL; -	if (prom_getproperty(iommund, "reg", (void *) iommu_promregs, -			 sizeof(iommu_promregs)) != -1) { -		memset(&r, 0, sizeof(r)); -		r.flags = iommu_promregs[0].which_io; -		r.start = iommu_promregs[0].phys_addr; -		iommu->regs = (struct iommu_regs *) -			sbus_ioremap(&r, 0, PAGE_SIZE * 3, "iommu_regs"); -	} + +	iommu->regs = of_ioremap(&op->resource[0], 0, PAGE_SIZE * 3, +				 "iommu_regs");  	if (!iommu->regs) {  		prom_printf("Cannot map IOMMU registers\n");  		prom_halt(); @@ -128,13 +120,29 @@ iommu_init(int iommund, struct sbus_bus *sbus)  	else  		iommu->usemap.num_colors = 1; -	printk("IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n", -	    impl, vers, iommu->page_table, -	    (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); +	printk(KERN_INFO "IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n", +	       impl, vers, iommu->page_table, +	       (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); + +	op->dev.archdata.iommu = iommu; +} + +static int __init iommu_init(void) +{ +	struct device_node *dp; + +	for_each_node_by_name(dp, "iommu") { +		struct of_device *op = of_find_device_by_node(dp); + +		sbus_iommu_init(op); +		of_propagate_archdata(op); +	} -	sbus->ofdev.dev.archdata.iommu = iommu; +	return 0;  } +subsys_initcall(iommu_init); +  /* This begs to be btfixup-ed by srmmu. */  /* Flush the iotlb entries to ram. */  /* This could be better if we didn't have to flush whole pages. */ @@ -164,9 +172,9 @@ static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte)  	}  } -static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus) +static u32 iommu_get_one(struct device *dev, struct page *page, int npages)  { -	struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; +	struct iommu_struct *iommu = dev->archdata.iommu;  	int ioptex;  	iopte_t *iopte, *iopte0;  	unsigned int busa, busa0; @@ -194,8 +202,7 @@ static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus)  	return busa0;  } -static u32 iommu_get_scsi_one(char *vaddr, unsigned int len, -    struct sbus_bus *sbus) +static u32 iommu_get_scsi_one(struct device *dev, char *vaddr, unsigned int len)  {  	unsigned long off;  	int npages; @@ -205,22 +212,22 @@ static u32 iommu_get_scsi_one(char *vaddr, unsigned int len,  	off = (unsigned long)vaddr & ~PAGE_MASK;  	npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT;  	page = virt_to_page((unsigned long)vaddr & PAGE_MASK); -	busa = iommu_get_one(page, npages, sbus); +	busa = iommu_get_one(dev, page, npages);  	return busa + off;  } -static __u32 iommu_get_scsi_one_noflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) +static __u32 iommu_get_scsi_one_noflush(struct device *dev, char *vaddr, unsigned long len)  { -	return iommu_get_scsi_one(vaddr, len, sbus); +	return iommu_get_scsi_one(dev, vaddr, len);  } -static __u32 iommu_get_scsi_one_gflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) +static __u32 iommu_get_scsi_one_gflush(struct device *dev, char *vaddr, unsigned long len)  {  	flush_page_for_dma(0); -	return iommu_get_scsi_one(vaddr, len, sbus); +	return iommu_get_scsi_one(dev, vaddr, len);  } -static __u32 iommu_get_scsi_one_pflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) +static __u32 iommu_get_scsi_one_pflush(struct device *dev, char *vaddr, unsigned long len)  {  	unsigned long page = ((unsigned long) vaddr) & PAGE_MASK; @@ -228,23 +235,23 @@ static __u32 iommu_get_scsi_one_pflush(char *vaddr, unsigned long len, struct sb  		flush_page_for_dma(page);  		page += PAGE_SIZE;  	} -	return iommu_get_scsi_one(vaddr, len, sbus); +	return iommu_get_scsi_one(dev, vaddr, len);  } -static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) +static void iommu_get_scsi_sgl_noflush(struct device *dev, struct scatterlist *sg, int sz)  {  	int n;  	while (sz != 0) {  		--sz;  		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; -		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset; +		sg->dvma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;  		sg->dvma_length = (__u32) sg->length;  		sg = sg_next(sg);  	}  } -static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) +static void iommu_get_scsi_sgl_gflush(struct device *dev, struct scatterlist *sg, int sz)  {  	int n; @@ -252,13 +259,13 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu  	while (sz != 0) {  		--sz;  		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; -		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset; +		sg->dvma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;  		sg->dvma_length = (__u32) sg->length;  		sg = sg_next(sg);  	}  } -static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) +static void iommu_get_scsi_sgl_pflush(struct device *dev, struct scatterlist *sg, int sz)  {  	unsigned long page, oldpage = 0;  	int n, i; @@ -283,15 +290,15 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu  			}  		} -		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset; +		sg->dvma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;  		sg->dvma_length = (__u32) sg->length;  		sg = sg_next(sg);  	}  } -static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus) +static void iommu_release_one(struct device *dev, u32 busa, int npages)  { -	struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; +	struct iommu_struct *iommu = dev->archdata.iommu;  	int ioptex;  	int i; @@ -305,17 +312,17 @@ static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus)  	bit_map_clear(&iommu->usemap, ioptex, npages);  } -static void iommu_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) +static void iommu_release_scsi_one(struct device *dev, __u32 vaddr, unsigned long len)  {  	unsigned long off;  	int npages;  	off = vaddr & ~PAGE_MASK;  	npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT; -	iommu_release_one(vaddr & PAGE_MASK, npages, sbus); +	iommu_release_one(dev, vaddr & PAGE_MASK, npages);  } -static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) +static void iommu_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)  {  	int n; @@ -323,18 +330,18 @@ static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b  		--sz;  		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; -		iommu_release_one(sg->dvma_address & PAGE_MASK, n, sbus); +		iommu_release_one(dev, sg->dvma_address & PAGE_MASK, n);  		sg->dvma_address = 0x21212121;  		sg = sg_next(sg);  	}  }  #ifdef CONFIG_SBUS -static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, -    unsigned long addr, int len) +static int iommu_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, +			      unsigned long addr, int len)  { +	struct iommu_struct *iommu = dev->archdata.iommu;  	unsigned long page, end; -	struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu;  	iopte_t *iopte = iommu->page_table;  	iopte_t *first;  	int ioptex; @@ -397,9 +404,9 @@ static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va,  	return 0;  } -static void iommu_unmap_dma_area(unsigned long busa, int len) +static void iommu_unmap_dma_area(struct device *dev, unsigned long busa, int len)  { -	struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; +	struct iommu_struct *iommu = dev->archdata.iommu;  	iopte_t *iopte = iommu->page_table;  	unsigned long end;  	int ioptex = (busa - iommu->start) >> PAGE_SHIFT; @@ -417,15 +424,6 @@ static void iommu_unmap_dma_area(unsigned long busa, int len)  	iommu_invalidate(iommu->regs);  	bit_map_clear(&iommu->usemap, ioptex, len >> PAGE_SHIFT);  } - -static struct page *iommu_translate_dvma(unsigned long busa) -{ -	struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; -	iopte_t *iopte = iommu->page_table; - -	iopte += ((busa - iommu->start) >> PAGE_SHIFT); -	return pfn_to_page((iopte_val(*iopte) & IOPTE_PAGE) >> (PAGE_SHIFT-4)); -}  #endif  static char *iommu_lockarea(char *vaddr, unsigned long len) @@ -461,7 +459,6 @@ void __init ld_mmu_iommu(void)  #ifdef CONFIG_SBUS  	BTFIXUPSET_CALL(mmu_map_dma_area, iommu_map_dma_area, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(mmu_unmap_dma_area, iommu_unmap_dma_area, BTFIXUPCALL_NORM); -	BTFIXUPSET_CALL(mmu_translate_dvma, iommu_translate_dvma, BTFIXUPCALL_NORM);  #endif  	if (viking_mxcc_present || srmmu_modtype == HyperSparc) { diff --git a/arch/sparc/mm/nosrmmu.c b/arch/sparc/mm/nosrmmu.c deleted file mode 100644 index 3701f70fc30..00000000000 --- a/arch/sparc/mm/nosrmmu.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * nosrmmu.c: This file is a bunch of dummies for sun4 compiles,  - *         so that it does not need srmmu and avoid ifdefs. - * - * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ - -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <asm/mbus.h> -#include <asm/sbus.h> - -static char shouldnothappen[] __initdata = "SUN4 kernel can only run on SUN4\n"; - -enum mbus_module srmmu_modtype; -void *srmmu_nocache_pool; - -int vac_cache_size = 0; - -static void __init should_not_happen(void) -{ -	prom_printf(shouldnothappen); -	prom_halt(); -} - -void __init srmmu_frob_mem_map(unsigned long start_mem) -{ -	should_not_happen(); -} - -unsigned long __init srmmu_paging_init(unsigned long start_mem, unsigned long end_mem) -{ -	should_not_happen(); -	return 0; -} - -void __init ld_mmu_srmmu(void) -{ -	should_not_happen(); -} - -void srmmu_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly) -{ -} - -void srmmu_unmapioaddr(unsigned long virt_addr) -{ -} - -__u32 iounit_map_dma_init(struct sbus_bus *sbus, int size) -{ -	return 0; -} - -__u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus) -{ -	return 0; -} diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index ee30462598f..6a5d7cabc04 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -31,7 +31,6 @@  #include <asm/mbus.h>  #include <asm/cache.h>  #include <asm/oplib.h> -#include <asm/sbus.h>  #include <asm/asi.h>  #include <asm/msi.h>  #include <asm/mmu_context.h> diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index d1782f6368b..fe65aeeb394 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -31,7 +31,6 @@  #include <asm/oplib.h>  #include <asm/openprom.h>  #include <asm/mmu_context.h> -#include <asm/sun4paddr.h>  #include <asm/highmem.h>  #include <asm/btfixup.h>  #include <asm/cacheflush.h> @@ -52,15 +51,11 @@ extern int num_segmaps, num_contexts;  extern unsigned long page_kernel; -#ifdef CONFIG_SUN4 -#define SUN4C_VAC_SIZE sun4c_vacinfo.num_bytes -#else  /* That's it, we prom_halt() on sun4c if the cache size is something other than 65536.   * So let's save some cycles and just use that everywhere except for that bootup   * sanity check.   */  #define SUN4C_VAC_SIZE 65536 -#endif  #define SUN4C_KERNEL_BUCKETS 32 @@ -285,75 +280,32 @@ void __init sun4c_probe_vac(void)  {  	sun4c_disable_vac(); -	if (ARCH_SUN4) { -		switch (idprom->id_machtype) { - -		case (SM_SUN4|SM_4_110): -			sun4c_vacinfo.type = VAC_NONE; -			sun4c_vacinfo.num_bytes = 0; -			sun4c_vacinfo.linesize = 0; -			sun4c_vacinfo.do_hwflushes = 0; -			prom_printf("No VAC. Get some bucks and buy a real computer."); -			prom_halt(); -			break; - -		case (SM_SUN4|SM_4_260): -			sun4c_vacinfo.type = VAC_WRITE_BACK; -			sun4c_vacinfo.num_bytes = 128 * 1024; -			sun4c_vacinfo.linesize = 16; -			sun4c_vacinfo.do_hwflushes = 0; -			break; - -		case (SM_SUN4|SM_4_330): -			sun4c_vacinfo.type = VAC_WRITE_THROUGH; -			sun4c_vacinfo.num_bytes = 128 * 1024; -			sun4c_vacinfo.linesize = 16; -			sun4c_vacinfo.do_hwflushes = 0; -			break; - -		case (SM_SUN4|SM_4_470): -			sun4c_vacinfo.type = VAC_WRITE_BACK; -			sun4c_vacinfo.num_bytes = 128 * 1024; -			sun4c_vacinfo.linesize = 32; -			sun4c_vacinfo.do_hwflushes = 0; -			break; - -		default: -			prom_printf("Cannot initialize VAC - weird sun4 model idprom->id_machtype = %d", idprom->id_machtype); -			prom_halt(); -		}; +	if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || +	    (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { +		/* PROM on SS1 lacks this info, to be super safe we +		 * hard code it here since this arch is cast in stone. +		 */ +		sun4c_vacinfo.num_bytes = 65536; +		sun4c_vacinfo.linesize = 16;  	} else { -		sun4c_vacinfo.type = VAC_WRITE_THROUGH; +		sun4c_vacinfo.num_bytes = +		 prom_getintdefault(prom_root_node, "vac-size", 65536); +		sun4c_vacinfo.linesize = +		 prom_getintdefault(prom_root_node, "vac-linesize", 16); +	} +	sun4c_vacinfo.do_hwflushes = +	 prom_getintdefault(prom_root_node, "vac-hwflush", 0); -		if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || -		    (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { -			/* PROM on SS1 lacks this info, to be super safe we -			 * hard code it here since this arch is cast in stone. -			 */ -			sun4c_vacinfo.num_bytes = 65536; -			sun4c_vacinfo.linesize = 16; -		} else { -			sun4c_vacinfo.num_bytes = -			 prom_getintdefault(prom_root_node, "vac-size", 65536); -			sun4c_vacinfo.linesize = -			 prom_getintdefault(prom_root_node, "vac-linesize", 16); -		} +	if (sun4c_vacinfo.do_hwflushes == 0)  		sun4c_vacinfo.do_hwflushes = -		 prom_getintdefault(prom_root_node, "vac-hwflush", 0); - -		if (sun4c_vacinfo.do_hwflushes == 0) -			sun4c_vacinfo.do_hwflushes = -			 prom_getintdefault(prom_root_node, "vac_hwflush", 0); +		 prom_getintdefault(prom_root_node, "vac_hwflush", 0); -		if (sun4c_vacinfo.num_bytes != 65536) { -			prom_printf("WEIRD Sun4C VAC cache size, " -				    "tell sparclinux@vger.kernel.org"); -			prom_halt(); -		} +	if (sun4c_vacinfo.num_bytes != 65536) { +		prom_printf("WEIRD Sun4C VAC cache size, " +			    "tell sparclinux@vger.kernel.org"); +		prom_halt();  	} -	sun4c_vacinfo.num_lines = -		(sun4c_vacinfo.num_bytes / sun4c_vacinfo.linesize);  	switch (sun4c_vacinfo.linesize) {  	case 16:  		sun4c_vacinfo.log2lsize = 4; @@ -447,49 +399,18 @@ static void __init patch_kernel_fault_handler(void)  static void __init sun4c_probe_mmu(void)  { -	if (ARCH_SUN4) { -		switch (idprom->id_machtype) { -		case (SM_SUN4|SM_4_110): -			prom_printf("No support for 4100 yet\n"); -			prom_halt(); -			num_segmaps = 256; -			num_contexts = 8; -			break; - -		case (SM_SUN4|SM_4_260): -			/* should be 512 segmaps. when it get fixed */ -			num_segmaps = 256; -			num_contexts = 16; -			break; - -		case (SM_SUN4|SM_4_330): -			num_segmaps = 256; -			num_contexts = 16; -			break; - -		case (SM_SUN4|SM_4_470): -			/* should be 1024 segmaps. when it get fixed */ -			num_segmaps = 256; -			num_contexts = 64; -			break; -		default: -			prom_printf("Invalid SUN4 model\n"); -			prom_halt(); -		}; +	if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || +	    (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { +		/* Hardcode these just to be safe, PROM on SS1 does +		* not have this info available in the root node. +		*/ +		num_segmaps = 128; +		num_contexts = 8;  	} else { -		if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || -		    (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { -			/* Hardcode these just to be safe, PROM on SS1 does -		 	* not have this info available in the root node. -		 	*/ -			num_segmaps = 128; -			num_contexts = 8; -		} else { -			num_segmaps = -			    prom_getintdefault(prom_root_node, "mmu-npmg", 128); -			num_contexts = -			    prom_getintdefault(prom_root_node, "mmu-nctx", 0x8); -		} +		num_segmaps = +		    prom_getintdefault(prom_root_node, "mmu-npmg", 128); +		num_contexts = +		    prom_getintdefault(prom_root_node, "mmu-nctx", 0x8);  	}  	patch_kernel_fault_handler();  } @@ -501,18 +422,14 @@ void __init sun4c_probe_memerr_reg(void)  	int node;  	struct linux_prom_registers regs[1]; -	if (ARCH_SUN4) { -		sun4c_memerr_reg = ioremap(sun4_memreg_physaddr, PAGE_SIZE); -	} else { -		node = prom_getchild(prom_root_node); -		node = prom_searchsiblings(prom_root_node, "memory-error"); -		if (!node) -			return; -		if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0) -			return; -		/* hmm I think regs[0].which_io is zero here anyways */ -		sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size); -	} +	node = prom_getchild(prom_root_node); +	node = prom_searchsiblings(prom_root_node, "memory-error"); +	if (!node) +		return; +	if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0) +		return; +	/* hmm I think regs[0].which_io is zero here anyways */ +	sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size);  }  static inline void sun4c_init_ss2_cache_bug(void) @@ -521,7 +438,6 @@ static inline void sun4c_init_ss2_cache_bug(void)  	if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) ||  	    (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) || -	    (idprom->id_machtype == (SM_SUN4 | SM_4_330)) ||  	    (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) {  		/* Whee.. */  		printk("SS2 cache bug detected, uncaching trap table page\n"); @@ -532,8 +448,8 @@ static inline void sun4c_init_ss2_cache_bug(void)  }  /* Addr is always aligned on a page boundary for us already. */ -static int sun4c_map_dma_area(dma_addr_t *pba, unsigned long va, -    unsigned long addr, int len) +static int sun4c_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, +			      unsigned long addr, int len)  {  	unsigned long page, end; @@ -555,14 +471,7 @@ static int sun4c_map_dma_area(dma_addr_t *pba, unsigned long va,  	return 0;  } -static struct page *sun4c_translate_dvma(unsigned long busa) -{ -	/* Fortunately for us, bus_addr == uncached_virt in sun4c. */ -	unsigned long pte = sun4c_get_pte(busa); -	return pfn_to_page(pte & SUN4C_PFN_MASK); -} - -static void sun4c_unmap_dma_area(unsigned long busa, int len) +static void sun4c_unmap_dma_area(struct device *dev, unsigned long busa, int len)  {  	/* Fortunately for us, bus_addr == uncached_virt in sun4c. */  	/* XXX Implement this */ @@ -624,11 +533,7 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)  {  	unsigned long vaddr;  	unsigned char pseg, ctx; -#ifdef CONFIG_SUN4 -	/* sun4/110 and 260 have no kadb. */ -	if ((idprom->id_machtype != (SM_SUN4 | SM_4_260)) &&  -	    (idprom->id_machtype != (SM_SUN4 | SM_4_110))) { -#endif +  	for (vaddr = KADB_DEBUGGER_BEGVM;  	     vaddr < LINUX_OPPROM_ENDVM;  	     vaddr += SUN4C_REAL_PGDIR_SIZE) { @@ -640,9 +545,7 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)  			fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0);  		}  	} -#ifdef CONFIG_SUN4 -	} -#endif +  	for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) {  		pseg = sun4c_get_segmap(vaddr);  		mmu_entry_pool[pseg].locked = 1; @@ -1048,14 +951,10 @@ static struct thread_info *sun4c_alloc_thread_info(void)  	 * so we must flush the cache to guarantee consistency.  	 */  	sun4c_flush_page(pages); -#ifndef CONFIG_SUN4	  	sun4c_flush_page(pages + PAGE_SIZE); -#endif  	sun4c_put_pte(addr, BUCKET_PTE(pages)); -#ifndef CONFIG_SUN4	  	sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE)); -#endif  #ifdef CONFIG_DEBUG_STACK_USAGE  	memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER); @@ -1072,13 +971,11 @@ static void sun4c_free_thread_info(struct thread_info *ti)  	/* We are deleting a mapping, so the flush here is mandatory. */  	sun4c_flush_page(tiaddr); -#ifndef CONFIG_SUN4	  	sun4c_flush_page(tiaddr + PAGE_SIZE); -#endif +  	sun4c_put_pte(tiaddr, 0); -#ifndef CONFIG_SUN4	  	sun4c_put_pte(tiaddr + PAGE_SIZE, 0); -#endif +  	sun4c_bucket[entry] = BUCKET_EMPTY;  	if (entry < sun4c_lowbucket_avail)  		sun4c_lowbucket_avail = entry; @@ -1211,7 +1108,7 @@ static void sun4c_unlockarea(char *vaddr, unsigned long size)   * by implication and fool the page locking code above   * if passed to by mistake.   */ -static __u32 sun4c_get_scsi_one(char *bufptr, unsigned long len, struct sbus_bus *sbus) +static __u32 sun4c_get_scsi_one(struct device *dev, char *bufptr, unsigned long len)  {  	unsigned long page; @@ -1223,7 +1120,7 @@ static __u32 sun4c_get_scsi_one(char *bufptr, unsigned long len, struct sbus_bus  	return (__u32)sun4c_lockarea(bufptr, len);  } -static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) +static void sun4c_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)  {  	while (sz != 0) {  		--sz; @@ -1233,14 +1130,14 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *  	}  } -static void sun4c_release_scsi_one(__u32 bufptr, unsigned long len, struct sbus_bus *sbus) +static void sun4c_release_scsi_one(struct device *dev, __u32 bufptr, unsigned long len)  {  	if (bufptr < sun4c_iobuffer_start)  		return; /* On kernel stack or similar, see above */  	sun4c_unlockarea((char *)bufptr, len);  } -static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) +static void sun4c_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)  {  	while (sz != 0) {  		--sz; @@ -2263,7 +2160,6 @@ void __init ld_mmu_sun4c(void)  	BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM); -	BTFIXUPSET_CALL(mmu_translate_dvma, sun4c_translate_dvma, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(sparc_mapiorange, sun4c_mapiorange, BTFIXUPCALL_NORM);  	BTFIXUPSET_CALL(sparc_unmapiorange, sun4c_unmapiorange, BTFIXUPCALL_NORM); diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c index 9ab815b95b5..17bb6035069 100644 --- a/arch/sparc/oprofile/init.c +++ b/arch/sparc/oprofile/init.c @@ -12,7 +12,7 @@  #include <linux/errno.h>  #include <linux/init.h> -int __init oprofile_arch_init(struct oprofile_operations * ops) +int __init oprofile_arch_init(struct oprofile_operations *ops)  {  	return -ENODEV;  } diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile index 7f5eacfcfbc..8f7e18546c9 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile @@ -4,5 +4,3 @@  lib-y := bootstr.o devmap.o devops.o init.o memory.o misc.o mp.o \  	 palloc.o ranges.o segment.o console.o printf.o tree.o - -lib-$(CONFIG_SUN4) += sun4prom.o diff --git a/arch/sparc/prom/bootstr.c b/arch/sparc/prom/bootstr.c index 5a35c768ff7..916831da7e6 100644 --- a/arch/sparc/prom/bootstr.c +++ b/arch/sparc/prom/bootstr.c @@ -6,15 +6,12 @@  #include <linux/string.h>  #include <asm/oplib.h> -#include <asm/sun4prom.h>  #include <linux/init.h>  #define BARG_LEN  256  static char barg_buf[BARG_LEN] = { 0 };  static char fetched __initdata = 0; -extern linux_sun4_romvec *sun4_romvec; -  char * __init  prom_getbootargs(void)  { @@ -28,7 +25,6 @@ prom_getbootargs(void)  	switch(prom_vers) {  	case PROM_V0: -	case PROM_SUN4:  		cp = barg_buf;  		/* Start from 1 and go over fd(0,0,0)kernel */  		for(iter = 1; iter < 8; iter++) { diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c index 790057a3461..b3075d73fc1 100644 --- a/arch/sparc/prom/console.c +++ b/arch/sparc/prom/console.c @@ -10,7 +10,6 @@  #include <linux/kernel.h>  #include <linux/sched.h>  #include <asm/openprom.h> -#include <asm/sun4prom.h>  #include <asm/oplib.h>  #include <asm/system.h>  #include <linux/string.h> @@ -30,7 +29,6 @@ prom_nbgetchar(void)  	spin_lock_irqsave(&prom_lock, flags);  	switch(prom_vers) {  	case PROM_V0: -	case PROM_SUN4:  		i = (*(romvec->pv_nbgetchar))();  		break;  	case PROM_V2: @@ -63,7 +61,6 @@ prom_nbputchar(char c)  	spin_lock_irqsave(&prom_lock, flags);  	switch(prom_vers) {  	case PROM_V0: -	case PROM_SUN4:  		i = (*(romvec->pv_nbputchar))(c);  		break;  	case PROM_V2: diff --git a/arch/sparc/prom/init.c b/arch/sparc/prom/init.c index 729f8706694..873217c6d82 100644 --- a/arch/sparc/prom/init.c +++ b/arch/sparc/prom/init.c @@ -11,12 +11,10 @@  #include <asm/openprom.h>  #include <asm/oplib.h> -#include <asm/sun4prom.h>  struct linux_romvec *romvec;  enum prom_major_version prom_vers;  unsigned int prom_rev, prom_prev; -linux_sun4_romvec *sun4_romvec;  /* The root node of the prom device tree. */  int prom_root_node; @@ -34,10 +32,6 @@ extern void prom_ranges_init(void);  void __init prom_init(struct linux_romvec *rp)  { -#ifdef CONFIG_SUN4 -	extern struct linux_romvec *sun4_prom_init(void); -	rp = sun4_prom_init(); -#endif  	romvec = rp;  	switch(romvec->pv_romvers) { @@ -50,9 +44,6 @@ void __init prom_init(struct linux_romvec *rp)  	case 3:  		prom_vers = PROM_V3;  		break; -	case 40: -		prom_vers = PROM_SUN4; -		break;  	default:  		prom_printf("PROMLIB: Bad PROM version %d\n",  			    romvec->pv_romvers); @@ -76,11 +67,8 @@ void __init prom_init(struct linux_romvec *rp)  	prom_ranges_init(); -#ifndef CONFIG_SUN4 -	/* SUN4 prints this in sun4_prom_init */  	printk("PROMLIB: Sun Boot Prom Version %d Revision %d\n",  	       romvec->pv_romvers, prom_rev); -#endif  	/* Initialization successful. */  	return; diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c index 947f047dc95..fac7899a29c 100644 --- a/arch/sparc/prom/memory.c +++ b/arch/sparc/prom/memory.c @@ -10,7 +10,6 @@  #include <linux/init.h>  #include <asm/openprom.h> -#include <asm/sun4prom.h>  #include <asm/oplib.h>  #include <asm/page.h> @@ -46,15 +45,6 @@ static int __init prom_meminit_v2(void)  	return num_ents;  } -static int __init prom_meminit_sun4(void) -{ -#ifdef CONFIG_SUN4 -	sp_banks[0].base_addr = 0; -	sp_banks[0].num_bytes = *(sun4_romvec->memoryavail); -#endif -	return 1; -} -  static int sp_banks_cmp(const void *a, const void *b)  {  	const struct sparc_phys_banks *x = a, *y = b; @@ -81,10 +71,6 @@ void __init prom_meminit(void)  		num_ents = prom_meminit_v2();  		break; -	case PROM_SUN4: -		num_ents = prom_meminit_sun4(); -		break; -  	default:  		break;  	} diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c index f9b7def35f6..64579a37641 100644 --- a/arch/sparc/prom/ranges.c +++ b/arch/sparc/prom/ranges.c @@ -9,7 +9,6 @@  #include <asm/openprom.h>  #include <asm/oplib.h>  #include <asm/types.h> -#include <asm/sbus.h>  #include <asm/system.h>  struct linux_prom_ranges promlib_obio_ranges[PROMREG_MAX]; diff --git a/arch/sparc/prom/sun4prom.c b/arch/sparc/prom/sun4prom.c deleted file mode 100644 index 00390a2652a..00000000000 --- a/arch/sparc/prom/sun4prom.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 1996 The Australian National University. - * Copyright (C) 1996 Fujitsu Laboratories Limited - * Copyright (C) 1997 Michael A. Griffith (grif@acm.org) - * Copyright (C) 1997 Sun Weenie (ko@ko.reno.nv.us) - * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - *  - * This software may be distributed under the terms of the Gnu - * Public License version 2 or later - * - * fake a really simple Sun prom for the SUN4 - */ - -#include <linux/kernel.h> -#include <linux/string.h> -#include <asm/oplib.h> -#include <asm/idprom.h>  -#include <asm/machines.h>  -#include <asm/sun4prom.h> -#include <asm/asi.h> -#include <asm/contregs.h> -#include <linux/init.h> - -static struct linux_romvec sun4romvec; -static struct idprom sun4_idprom; - -struct property { -	char *name; -	char *value; -	int length; -}; - -struct node { -	int level; -	struct property *properties; -}; - -struct property null_properties = { NULL, NULL, -1 }; - -struct property root_properties[] = { -	{"device_type", "cpu", 4}, -	{"idprom", (char *)&sun4_idprom, sizeof(struct idprom)}, -	{NULL, NULL, -1} -}; - -struct node nodes[] = { -	{ 0, &null_properties },  -	{ 0, root_properties }, -	{ -1,&null_properties } -}; - - -static int no_nextnode(int node) -{ -	if (nodes[node].level == nodes[node+1].level) -		return node+1; -	return -1; -} - -static int no_child(int node) -{ -	if (nodes[node].level == nodes[node+1].level-1) -		return node+1; -	return -1; -} - -static struct property *find_property(int node,char *name) -{ -	struct property *prop = &nodes[node].properties[0]; -	while (prop && prop->name) { -		if (strcmp(prop->name,name) == 0) return prop; -		prop++; -	} -	return NULL; -} - -static int no_proplen(int node,char *name) -{ -	struct property *prop = find_property(node,name); -	if (prop) return prop->length; -	return -1; -} - -static int no_getprop(int node,char *name,char *value) -{ -	struct property *prop = find_property(node,name); -	if (prop) { -		memcpy(value,prop->value,prop->length); -		return 1; -	} -	return -1; -} - -static int no_setprop(int node,char *name,char *value,int len) -{ -	return -1; -} - -static char *no_nextprop(int node,char *name) -{ -	struct property *prop = find_property(node,name); -	if (prop) return prop[1].name; -	return NULL; -} - -static struct linux_nodeops sun4_nodeops = { -	no_nextnode, -	no_child, -	no_proplen, -	no_getprop, -	no_setprop, -	no_nextprop -}; -	 -static int synch_hook; - -struct linux_romvec * __init sun4_prom_init(void) -{ -	int i; -	unsigned char x; -	char *p; -                                 -	p = (char *)&sun4_idprom; -	for (i = 0; i < sizeof(sun4_idprom); i++) { -		__asm__ __volatile__ ("lduba [%1] %2, %0" : "=r" (x) : -				      "r" (AC_IDPROM + i), "i" (ASI_CONTROL)); -		*p++ = x; -	} - -	memset(&sun4romvec,0,sizeof(sun4romvec)); - -	sun4_romvec = (linux_sun4_romvec *) SUN4_PROM_VECTOR; - -	sun4romvec.pv_romvers = 40; -	sun4romvec.pv_nodeops = &sun4_nodeops; -	sun4romvec.pv_reboot = sun4_romvec->reboot; -	sun4romvec.pv_abort = sun4_romvec->abortentry; -	sun4romvec.pv_halt = sun4_romvec->exittomon; -	sun4romvec.pv_synchook = (void (**)(void))&synch_hook; -	sun4romvec.pv_setctxt = sun4_romvec->setcxsegmap; -	sun4romvec.pv_v0bootargs = sun4_romvec->bootParam; -	sun4romvec.pv_nbgetchar = sun4_romvec->mayget; -	sun4romvec.pv_nbputchar = sun4_romvec->mayput; -	sun4romvec.pv_stdin = sun4_romvec->insource; -	sun4romvec.pv_stdout = sun4_romvec->outsink; -	 -	/* -	 * We turn on the LEDs to let folks without monitors or -	 * terminals know we booted.   Nothing too fancy now.  They -	 * are all on, except for LED 5, which blinks.   When we -	 * have more time, we can teach the penguin to say "By your -	 * command" or "Activating turbo boost, Michael". :-) -	 */ -	sun4_romvec->setLEDs(NULL); -	 -	printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n", -		sun4_romvec->monid, -		sun4_romvec->romvecversion); - -	return &sun4romvec; -}  | 
