mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 10:57:46 +00:00
Merge branch 'master' into devel
This commit is contained in:
commit
fc7736688b
16 changed files with 133 additions and 84 deletions
|
@ -603,6 +603,7 @@ config ARCH_SA1100
|
||||||
select ARCH_SPARSEMEM_ENABLE
|
select ARCH_SPARSEMEM_ENABLE
|
||||||
select ARCH_MTD_XIP
|
select ARCH_MTD_XIP
|
||||||
select ARCH_HAS_CPUFREQ
|
select ARCH_HAS_CPUFREQ
|
||||||
|
select CPU_FREQ
|
||||||
select GENERIC_GPIO
|
select GENERIC_GPIO
|
||||||
select GENERIC_TIME
|
select GENERIC_TIME
|
||||||
select GENERIC_CLOCKEVENTS
|
select GENERIC_CLOCKEVENTS
|
||||||
|
@ -1359,13 +1360,9 @@ source "drivers/cpufreq/Kconfig"
|
||||||
|
|
||||||
config CPU_FREQ_SA1100
|
config CPU_FREQ_SA1100
|
||||||
bool
|
bool
|
||||||
depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
|
|
||||||
default y
|
|
||||||
|
|
||||||
config CPU_FREQ_SA1110
|
config CPU_FREQ_SA1110
|
||||||
bool
|
bool
|
||||||
depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3)
|
|
||||||
default y
|
|
||||||
|
|
||||||
config CPU_FREQ_INTEGRATOR
|
config CPU_FREQ_INTEGRATOR
|
||||||
tristate "CPUfreq driver for ARM Integrator CPUs"
|
tristate "CPUfreq driver for ARM Integrator CPUs"
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
|
#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
|
||||||
#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
|
#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
|
||||||
|
#define __pfn_to_bus(x) (__pfn_to_phys(x) - PHYS_OFFSET)
|
||||||
|
#define __bus_to_pfn(x) __phys_to_pfn((x) + PHYS_OFFSET)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -201,6 +201,11 @@ void __init footbridge_map_io(void)
|
||||||
|
|
||||||
#ifdef CONFIG_FOOTBRIDGE_ADDIN
|
#ifdef CONFIG_FOOTBRIDGE_ADDIN
|
||||||
|
|
||||||
|
static inline unsigned long fb_bus_sdram_offset(void)
|
||||||
|
{
|
||||||
|
return *CSR_PCISDRAMBASE & 0xfffffff0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These two functions convert virtual addresses to PCI addresses and PCI
|
* These two functions convert virtual addresses to PCI addresses and PCI
|
||||||
* addresses to virtual addresses. Note that it is only legal to use these
|
* addresses to virtual addresses. Note that it is only legal to use these
|
||||||
|
@ -210,14 +215,13 @@ unsigned long __virt_to_bus(unsigned long res)
|
||||||
{
|
{
|
||||||
WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
|
WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
|
||||||
|
|
||||||
return (res - PAGE_OFFSET) + (*CSR_PCISDRAMBASE & 0xfffffff0);
|
return res + (fb_bus_sdram_offset() - PAGE_OFFSET);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__virt_to_bus);
|
EXPORT_SYMBOL(__virt_to_bus);
|
||||||
|
|
||||||
unsigned long __bus_to_virt(unsigned long res)
|
unsigned long __bus_to_virt(unsigned long res)
|
||||||
{
|
{
|
||||||
res -= (*CSR_PCISDRAMBASE & 0xfffffff0);
|
res = res - (fb_bus_sdram_offset() - PAGE_OFFSET);
|
||||||
res += PAGE_OFFSET;
|
|
||||||
|
|
||||||
WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
|
WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
|
||||||
|
|
||||||
|
@ -225,4 +229,16 @@ unsigned long __bus_to_virt(unsigned long res)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__bus_to_virt);
|
EXPORT_SYMBOL(__bus_to_virt);
|
||||||
|
|
||||||
|
unsigned long __pfn_to_bus(unsigned long pfn)
|
||||||
|
{
|
||||||
|
return __pfn_to_phys(pfn) + (fb_bus_sdram_offset() - PHYS_OFFSET));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__pfn_to_bus);
|
||||||
|
|
||||||
|
unsigned long __bus_to_pfn(unsigned long bus)
|
||||||
|
{
|
||||||
|
return __phys_to_pfn(bus - (fb_bus_sdram_offset() - PHYS_OFFSET));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__bus_to_pfn);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
extern unsigned long __virt_to_bus(unsigned long);
|
extern unsigned long __virt_to_bus(unsigned long);
|
||||||
extern unsigned long __bus_to_virt(unsigned long);
|
extern unsigned long __bus_to_virt(unsigned long);
|
||||||
|
extern unsigned long __pfn_to_bus(unsigned long);
|
||||||
|
extern unsigned long __bus_to_pfn(unsigned long);
|
||||||
#endif
|
#endif
|
||||||
#define __virt_to_bus __virt_to_bus
|
#define __virt_to_bus __virt_to_bus
|
||||||
#define __bus_to_virt __bus_to_virt
|
#define __bus_to_virt __bus_to_virt
|
||||||
|
@ -36,14 +38,15 @@ extern unsigned long __bus_to_virt(unsigned long);
|
||||||
#elif defined(CONFIG_FOOTBRIDGE_HOST)
|
#elif defined(CONFIG_FOOTBRIDGE_HOST)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The footbridge is programmed to expose the system RAM at the corresponding
|
* The footbridge is programmed to expose the system RAM at 0xe0000000.
|
||||||
* address. So, if PAGE_OFFSET is 0xc0000000, RAM appears at 0xe0000000.
|
* The requirement is that the RAM isn't placed at bus address 0, which
|
||||||
* If 0x80000000, then its exposed at 0xa0000000 on the bus. etc.
|
|
||||||
* The only requirement is that the RAM isn't placed at bus address 0 which
|
|
||||||
* would clash with VGA cards.
|
* would clash with VGA cards.
|
||||||
*/
|
*/
|
||||||
#define __virt_to_bus(x) ((x) - 0xe0000000)
|
#define BUS_OFFSET 0xe0000000
|
||||||
#define __bus_to_virt(x) ((x) + 0xe0000000)
|
#define __virt_to_bus(x) ((x) + (BUS_OFFSET - PAGE_OFFSET))
|
||||||
|
#define __bus_to_virt(x) ((x) - (BUS_OFFSET - PAGE_OFFSET))
|
||||||
|
#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET))
|
||||||
|
#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#define BUS_OFFSET UL(0x80000000)
|
#define BUS_OFFSET UL(0x80000000)
|
||||||
#define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET)
|
#define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET)
|
||||||
#define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET)
|
#define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET)
|
||||||
#define __pfn_to_bus(x) (((x) << PAGE_SHIFT) + BUS_OFFSET)
|
#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET))
|
||||||
|
#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,11 +17,15 @@
|
||||||
|
|
||||||
#include <mach/ixp2000-regs.h>
|
#include <mach/ixp2000-regs.h>
|
||||||
|
|
||||||
#define __virt_to_bus(v) \
|
#define IXP2000_PCI_SDRAM_OFFSET (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0)
|
||||||
(((__virt_to_phys(v) - 0x0) + (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0)))
|
|
||||||
|
|
||||||
#define __bus_to_virt(b) \
|
#define __phys_to_bus(x) ((x) + (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET))
|
||||||
__phys_to_virt((((b - (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0)) + 0x0)))
|
#define __bus_to_phys(x) ((x) - (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET))
|
||||||
|
|
||||||
|
#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v))
|
||||||
|
#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b))
|
||||||
|
#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p))
|
||||||
|
#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,15 @@
|
||||||
*/
|
*/
|
||||||
#define PHYS_OFFSET (0x00000000)
|
#define PHYS_OFFSET (0x00000000)
|
||||||
|
|
||||||
#define __virt_to_bus(v) \
|
#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0))
|
||||||
({ unsigned int ret; \
|
|
||||||
ret = ((__virt_to_phys(v) - 0x00000000) + \
|
|
||||||
(*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)); \
|
|
||||||
ret; })
|
|
||||||
|
|
||||||
#define __bus_to_virt(b) \
|
#define __phys_to_bus(x) ((x) + (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
|
||||||
({ unsigned int data; \
|
#define __bus_to_phys(x) ((x) - (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
|
||||||
data = *((volatile int *)IXP23XX_PCI_SDRAM_BAR); \
|
|
||||||
__phys_to_virt((((b - (data & 0xfffffff0)) + 0x00000000))); })
|
#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v))
|
||||||
|
#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b))
|
||||||
|
#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p))
|
||||||
|
#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b))
|
||||||
|
|
||||||
#define arch_is_coherent() 1
|
#define arch_is_coherent() 1
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
* version 2 as published by the Free Software Foundation.
|
* version 2 as published by the Free Software Foundation.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/cpufreq.h>
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <mach/clocks.h>
|
#include <mach/clocks.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
@ -31,12 +29,6 @@ struct clk {
|
||||||
#define HCLKDIV(c) (((c) >> 0) & 0x02)
|
#define HCLKDIV(c) (((c) >> 0) & 0x02)
|
||||||
#define PCLKDIV(c) (((c) >> 16) & 0x03)
|
#define PCLKDIV(c) (((c) >> 16) & 0x03)
|
||||||
|
|
||||||
unsigned int cpufreq_get (unsigned int cpu) /* in kHz */
|
|
||||||
{
|
|
||||||
return fclkfreq_get ()/1000;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(cpufreq_get);
|
|
||||||
|
|
||||||
unsigned int fclkfreq_get (void)
|
unsigned int fclkfreq_get (void)
|
||||||
{
|
{
|
||||||
unsigned int clkset = CSC_CLKSET;
|
unsigned int clkset = CSC_CLKSET;
|
||||||
|
|
|
@ -15,5 +15,7 @@
|
||||||
|
|
||||||
#define __virt_to_bus(x) __virt_to_phys(x)
|
#define __virt_to_bus(x) __virt_to_phys(x)
|
||||||
#define __bus_to_virt(x) __phys_to_virt(x)
|
#define __bus_to_virt(x) __phys_to_virt(x)
|
||||||
|
#define __pfn_to_bus(x) __pfn_to_phys(x)
|
||||||
|
#define __bus_to_pfn(x) __phys_to_pfn(x)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,6 +4,7 @@ menu "SA11x0 Implementations"
|
||||||
|
|
||||||
config SA1100_ASSABET
|
config SA1100_ASSABET
|
||||||
bool "Assabet"
|
bool "Assabet"
|
||||||
|
select CPU_FREQ_SA1110
|
||||||
help
|
help
|
||||||
Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
|
Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
|
||||||
Microprocessor Development Board (also known as the Assabet).
|
Microprocessor Development Board (also known as the Assabet).
|
||||||
|
@ -19,6 +20,7 @@ config ASSABET_NEPONSET
|
||||||
|
|
||||||
config SA1100_CERF
|
config SA1100_CERF
|
||||||
bool "CerfBoard"
|
bool "CerfBoard"
|
||||||
|
select CPU_FREQ_SA1110
|
||||||
help
|
help
|
||||||
The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
|
The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
|
||||||
More information is available at:
|
More information is available at:
|
||||||
|
@ -45,6 +47,7 @@ endchoice
|
||||||
|
|
||||||
config SA1100_COLLIE
|
config SA1100_COLLIE
|
||||||
bool "Sharp Zaurus SL5500"
|
bool "Sharp Zaurus SL5500"
|
||||||
|
# FIXME: select CPU_FREQ_SA11x0
|
||||||
select SHARP_LOCOMO
|
select SHARP_LOCOMO
|
||||||
select SHARP_SCOOP
|
select SHARP_SCOOP
|
||||||
select SHARP_PARAM
|
select SHARP_PARAM
|
||||||
|
@ -54,6 +57,7 @@ config SA1100_COLLIE
|
||||||
config SA1100_H3100
|
config SA1100_H3100
|
||||||
bool "Compaq iPAQ H3100"
|
bool "Compaq iPAQ H3100"
|
||||||
select HTC_EGPIO
|
select HTC_EGPIO
|
||||||
|
select CPU_FREQ_SA1100
|
||||||
help
|
help
|
||||||
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
||||||
H3100 handheld computer. Information about this machine and the
|
H3100 handheld computer. Information about this machine and the
|
||||||
|
@ -64,6 +68,7 @@ config SA1100_H3100
|
||||||
config SA1100_H3600
|
config SA1100_H3600
|
||||||
bool "Compaq iPAQ H3600/H3700"
|
bool "Compaq iPAQ H3600/H3700"
|
||||||
select HTC_EGPIO
|
select HTC_EGPIO
|
||||||
|
select CPU_FREQ_SA1100
|
||||||
help
|
help
|
||||||
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
||||||
H3600 handheld computer. Information about this machine and the
|
H3600 handheld computer. Information about this machine and the
|
||||||
|
@ -74,6 +79,7 @@ config SA1100_H3600
|
||||||
config SA1100_BADGE4
|
config SA1100_BADGE4
|
||||||
bool "HP Labs BadgePAD 4"
|
bool "HP Labs BadgePAD 4"
|
||||||
select SA1111
|
select SA1111
|
||||||
|
select CPU_FREQ_SA1100
|
||||||
help
|
help
|
||||||
Say Y here if you want to build a kernel for the HP Laboratories
|
Say Y here if you want to build a kernel for the HP Laboratories
|
||||||
BadgePAD 4.
|
BadgePAD 4.
|
||||||
|
@ -81,6 +87,7 @@ config SA1100_BADGE4
|
||||||
config SA1100_JORNADA720
|
config SA1100_JORNADA720
|
||||||
bool "HP Jornada 720"
|
bool "HP Jornada 720"
|
||||||
select SA1111
|
select SA1111
|
||||||
|
# FIXME: select CPU_FREQ_SA11x0
|
||||||
help
|
help
|
||||||
Say Y here if you want to build a kernel for the HP Jornada 720
|
Say Y here if you want to build a kernel for the HP Jornada 720
|
||||||
handheld computer. See <http://www.hp.com/jornada/products/720>
|
handheld computer. See <http://www.hp.com/jornada/products/720>
|
||||||
|
@ -98,12 +105,14 @@ config SA1100_JORNADA720_SSP
|
||||||
|
|
||||||
config SA1100_HACKKIT
|
config SA1100_HACKKIT
|
||||||
bool "HackKit Core CPU Board"
|
bool "HackKit Core CPU Board"
|
||||||
|
select CPU_FREQ_SA1100
|
||||||
help
|
help
|
||||||
Say Y here to support the HackKit Core CPU Board
|
Say Y here to support the HackKit Core CPU Board
|
||||||
<http://hackkit.eletztrick.de>;
|
<http://hackkit.eletztrick.de>;
|
||||||
|
|
||||||
config SA1100_LART
|
config SA1100_LART
|
||||||
bool "LART"
|
bool "LART"
|
||||||
|
select CPU_FREQ_SA1100
|
||||||
help
|
help
|
||||||
Say Y here if you are using the Linux Advanced Radio Terminal
|
Say Y here if you are using the Linux Advanced Radio Terminal
|
||||||
(also known as the LART). See <http://www.lartmaker.nl/> for
|
(also known as the LART). See <http://www.lartmaker.nl/> for
|
||||||
|
@ -111,6 +120,7 @@ config SA1100_LART
|
||||||
|
|
||||||
config SA1100_PLEB
|
config SA1100_PLEB
|
||||||
bool "PLEB"
|
bool "PLEB"
|
||||||
|
select CPU_FREQ_SA1100
|
||||||
help
|
help
|
||||||
Say Y here if you are using version 1 of the Portable Linux
|
Say Y here if you are using version 1 of the Portable Linux
|
||||||
Embedded Board (also known as PLEB).
|
Embedded Board (also known as PLEB).
|
||||||
|
@ -119,6 +129,7 @@ config SA1100_PLEB
|
||||||
|
|
||||||
config SA1100_SHANNON
|
config SA1100_SHANNON
|
||||||
bool "Shannon"
|
bool "Shannon"
|
||||||
|
select CPU_FREQ_SA1100
|
||||||
help
|
help
|
||||||
The Shannon (also known as a Tuxscreen, and also as a IS2630) was a
|
The Shannon (also known as a Tuxscreen, and also as a IS2630) was a
|
||||||
limited edition webphone produced by Philips. The Shannon is a SA1100
|
limited edition webphone produced by Philips. The Shannon is a SA1100
|
||||||
|
@ -127,6 +138,7 @@ config SA1100_SHANNON
|
||||||
|
|
||||||
config SA1100_SIMPAD
|
config SA1100_SIMPAD
|
||||||
bool "Simpad"
|
bool "Simpad"
|
||||||
|
select CPU_FREQ_SA1110
|
||||||
help
|
help
|
||||||
The SIEMENS webpad SIMpad is based on the StrongARM 1110. There
|
The SIEMENS webpad SIMpad is based on the StrongARM 1110. There
|
||||||
are two different versions CL4 and SL4. CL4 has 32MB RAM and 16MB
|
are two different versions CL4 and SL4. CL4 has 32MB RAM and 16MB
|
||||||
|
@ -145,3 +157,4 @@ config SA1100_SSP
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,6 @@ static const unsigned short cclk_frequency_100khz[NR_FREQS] = {
|
||||||
2802 /* 280.2 MHz */
|
2802 /* 280.2 MHz */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_FREQ_SA1100) || defined(CONFIG_CPU_FREQ_SA1110)
|
|
||||||
/* rounds up(!) */
|
/* rounds up(!) */
|
||||||
unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
|
unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
|
||||||
{
|
{
|
||||||
|
@ -110,17 +109,6 @@ unsigned int sa11x0_getspeed(unsigned int cpu)
|
||||||
return cclk_frequency_100khz[PPCR & 0xf] * 100;
|
return cclk_frequency_100khz[PPCR & 0xf] * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* We still need to provide this so building without cpufreq works.
|
|
||||||
*/
|
|
||||||
unsigned int cpufreq_get(unsigned int cpu)
|
|
||||||
{
|
|
||||||
return cclk_frequency_100khz[PPCR & 0xf] * 100;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(cpufreq_get);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the SA11x0 sched_clock implementation. This has
|
* This is the SA11x0 sched_clock implementation. This has
|
||||||
* a resolution of 271ns, and a maximum value of 32025597s (370 days).
|
* a resolution of 271ns, and a maximum value of 32025597s (370 days).
|
||||||
|
|
|
@ -38,16 +38,72 @@ union vfp_state *last_VFP_context[NR_CPUS];
|
||||||
*/
|
*/
|
||||||
unsigned int VFP_arch;
|
unsigned int VFP_arch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Per-thread VFP initialization.
|
||||||
|
*/
|
||||||
|
static void vfp_thread_flush(struct thread_info *thread)
|
||||||
|
{
|
||||||
|
union vfp_state *vfp = &thread->vfpstate;
|
||||||
|
unsigned int cpu;
|
||||||
|
|
||||||
|
memset(vfp, 0, sizeof(union vfp_state));
|
||||||
|
|
||||||
|
vfp->hard.fpexc = FPEXC_EN;
|
||||||
|
vfp->hard.fpscr = FPSCR_ROUND_NEAREST;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable VFP to ensure we initialize it first. We must ensure
|
||||||
|
* that the modification of last_VFP_context[] and hardware disable
|
||||||
|
* are done for the same CPU and without preemption.
|
||||||
|
*/
|
||||||
|
cpu = get_cpu();
|
||||||
|
if (last_VFP_context[cpu] == vfp)
|
||||||
|
last_VFP_context[cpu] = NULL;
|
||||||
|
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
|
||||||
|
put_cpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vfp_thread_release(struct thread_info *thread)
|
||||||
|
{
|
||||||
|
/* release case: Per-thread VFP cleanup. */
|
||||||
|
union vfp_state *vfp = &thread->vfpstate;
|
||||||
|
unsigned int cpu = thread->cpu;
|
||||||
|
|
||||||
|
if (last_VFP_context[cpu] == vfp)
|
||||||
|
last_VFP_context[cpu] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When this function is called with the following 'cmd's, the following
|
||||||
|
* is true while this function is being run:
|
||||||
|
* THREAD_NOFTIFY_SWTICH:
|
||||||
|
* - the previously running thread will not be scheduled onto another CPU.
|
||||||
|
* - the next thread to be run (v) will not be running on another CPU.
|
||||||
|
* - thread->cpu is the local CPU number
|
||||||
|
* - not preemptible as we're called in the middle of a thread switch
|
||||||
|
* THREAD_NOTIFY_FLUSH:
|
||||||
|
* - the thread (v) will be running on the local CPU, so
|
||||||
|
* v === current_thread_info()
|
||||||
|
* - thread->cpu is the local CPU number at the time it is accessed,
|
||||||
|
* but may change at any time.
|
||||||
|
* - we could be preempted if tree preempt rcu is enabled, so
|
||||||
|
* it is unsafe to use thread->cpu.
|
||||||
|
* THREAD_NOTIFY_RELEASE:
|
||||||
|
* - the thread (v) will not be running on any CPU; it is a dead thread.
|
||||||
|
* - thread->cpu will be the last CPU the thread ran on, which may not
|
||||||
|
* be the current CPU.
|
||||||
|
* - we could be preempted if tree preempt rcu is enabled.
|
||||||
|
*/
|
||||||
static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
|
static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
|
||||||
{
|
{
|
||||||
struct thread_info *thread = v;
|
struct thread_info *thread = v;
|
||||||
union vfp_state *vfp;
|
|
||||||
__u32 cpu = thread->cpu;
|
|
||||||
|
|
||||||
if (likely(cmd == THREAD_NOTIFY_SWITCH)) {
|
if (likely(cmd == THREAD_NOTIFY_SWITCH)) {
|
||||||
u32 fpexc = fmrx(FPEXC);
|
u32 fpexc = fmrx(FPEXC);
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
unsigned int cpu = thread->cpu;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On SMP, if VFP is enabled, save the old state in
|
* On SMP, if VFP is enabled, save the old state in
|
||||||
* case the thread migrates to a different CPU. The
|
* case the thread migrates to a different CPU. The
|
||||||
|
@ -74,25 +130,10 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
vfp = &thread->vfpstate;
|
if (cmd == THREAD_NOTIFY_FLUSH)
|
||||||
if (cmd == THREAD_NOTIFY_FLUSH) {
|
vfp_thread_flush(thread);
|
||||||
/*
|
else
|
||||||
* Per-thread VFP initialisation.
|
vfp_thread_release(thread);
|
||||||
*/
|
|
||||||
memset(vfp, 0, sizeof(union vfp_state));
|
|
||||||
|
|
||||||
vfp->hard.fpexc = FPEXC_EN;
|
|
||||||
vfp->hard.fpscr = FPSCR_ROUND_NEAREST;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Disable VFP to ensure we initialise it first.
|
|
||||||
*/
|
|
||||||
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flush and release case: Per-thread VFP cleanup. */
|
|
||||||
if (last_VFP_context[cpu] == vfp)
|
|
||||||
last_VFP_context[cpu] = NULL;
|
|
||||||
|
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,7 @@ int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
|
||||||
|
|
||||||
return soc_pcmcia_add_one(skt);
|
return soc_pcmcia_add_one(skt);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(pxa2xx_drv_pcmcia_add_one);
|
||||||
|
|
||||||
void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
|
void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
|
||||||
{
|
{
|
||||||
|
@ -262,19 +263,19 @@ void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
|
||||||
ops->frequency_change = pxa2xx_pcmcia_frequency_change;
|
ops->frequency_change = pxa2xx_pcmcia_frequency_change;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(pxa2xx_drv_pcmcia_ops);
|
||||||
|
|
||||||
int __pxa2xx_drv_pcmcia_probe(struct device *dev)
|
static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
struct pcmcia_low_level *ops;
|
struct pcmcia_low_level *ops;
|
||||||
struct skt_dev_info *sinfo;
|
struct skt_dev_info *sinfo;
|
||||||
struct soc_pcmcia_socket *skt;
|
struct soc_pcmcia_socket *skt;
|
||||||
|
|
||||||
if (!dev || !dev->platform_data)
|
ops = (struct pcmcia_low_level *)dev->dev.platform_data;
|
||||||
|
if (!ops)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
ops = (struct pcmcia_low_level *)dev->platform_data;
|
|
||||||
|
|
||||||
pxa2xx_drv_pcmcia_ops(ops);
|
pxa2xx_drv_pcmcia_ops(ops);
|
||||||
|
|
||||||
sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
|
sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
|
||||||
|
@ -309,13 +310,6 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__pxa2xx_drv_pcmcia_probe);
|
|
||||||
|
|
||||||
|
|
||||||
static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
|
|
||||||
{
|
|
||||||
return __pxa2xx_drv_pcmcia_probe(&dev->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
|
static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
/* temporary measure */
|
|
||||||
extern int __pxa2xx_drv_pcmcia_probe(struct device *);
|
|
||||||
|
|
||||||
int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
|
int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
|
||||||
void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
|
void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err7;
|
goto err7;
|
||||||
|
|
||||||
skt->irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
|
skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err7:
|
err7:
|
||||||
|
|
|
@ -40,7 +40,7 @@ static struct pcmcia_irqs irqs[] = {
|
||||||
|
|
||||||
static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
||||||
{
|
{
|
||||||
skt->irq = IRQ_GPIO(SG2_S0_GPIO_READY);
|
skt->socket.pci_irq = IRQ_GPIO(SG2_S0_GPIO_READY);
|
||||||
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue