Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 platform changes from Ingo Molnar: "This tree includes assorted platform driver updates and a preparatory series for a platform with custom DMA remapping semantics (sta2x11 I/O hub)." * 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/vsmp: Fix number of CPUs when vsmp is disabled keyboard: Use BIOS Keyboard variable to set Numlock x86/olpc/xo1/sci: Report RTC wakeup events x86/olpc/xo1/sci: Produce wakeup events for buttons and switches x86, platform: Initial support for sta2x11 I/O hub x86: Introduce CONFIG_X86_DMA_REMAP x86-32: Introduce CONFIG_X86_DEV_DMA_OPS
This commit is contained in:
commit
44bc40e148
19
arch/parisc/include/asm/kbdleds.h
Normal file
19
arch/parisc/include/asm/kbdleds.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef _ASM_PARISC_KBDLEDS_H
|
||||||
|
#define _ASM_PARISC_KBDLEDS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On HIL keyboards of PARISC machines there is no NumLock key and
|
||||||
|
* everyone expects the keypad to be used for numbers. That's why
|
||||||
|
* we can safely turn on the NUMLOCK bit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline int kbd_defleds(void)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD)
|
||||||
|
return 1 << VC_NUMLOCK;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ASM_PARISC_KBDLEDS_H */
|
|
@ -12,6 +12,7 @@ config X86_32
|
||||||
|
|
||||||
config X86_64
|
config X86_64
|
||||||
def_bool 64BIT
|
def_bool 64BIT
|
||||||
|
select X86_DEV_DMA_OPS
|
||||||
|
|
||||||
### Arch settings
|
### Arch settings
|
||||||
config X86
|
config X86
|
||||||
|
@ -327,6 +328,7 @@ config X86_EXTENDED_PLATFORM
|
||||||
NUMAQ (IBM/Sequent)
|
NUMAQ (IBM/Sequent)
|
||||||
RDC R-321x SoC
|
RDC R-321x SoC
|
||||||
SGI 320/540 (Visual Workstation)
|
SGI 320/540 (Visual Workstation)
|
||||||
|
STA2X11-based (e.g. Northville)
|
||||||
Summit/EXA (IBM x440)
|
Summit/EXA (IBM x440)
|
||||||
Unisys ES7000 IA32 series
|
Unisys ES7000 IA32 series
|
||||||
Moorestown MID devices
|
Moorestown MID devices
|
||||||
|
@ -373,6 +375,7 @@ config X86_VSMP
|
||||||
select PARAVIRT
|
select PARAVIRT
|
||||||
depends on X86_64 && PCI
|
depends on X86_64 && PCI
|
||||||
depends on X86_EXTENDED_PLATFORM
|
depends on X86_EXTENDED_PLATFORM
|
||||||
|
depends on SMP
|
||||||
---help---
|
---help---
|
||||||
Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is
|
Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is
|
||||||
supposed to run on these EM64T-based machines. Only choose this option
|
supposed to run on these EM64T-based machines. Only choose this option
|
||||||
|
@ -459,10 +462,10 @@ config X86_32_NON_STANDARD
|
||||||
depends on X86_32 && SMP
|
depends on X86_32 && SMP
|
||||||
depends on X86_EXTENDED_PLATFORM
|
depends on X86_EXTENDED_PLATFORM
|
||||||
---help---
|
---help---
|
||||||
This option compiles in the NUMAQ, Summit, bigsmp, ES7000, default
|
This option compiles in the NUMAQ, Summit, bigsmp, ES7000,
|
||||||
subarchitectures. It is intended for a generic binary kernel.
|
STA2X11, default subarchitectures. It is intended for a generic
|
||||||
if you select them all, kernel will probe it one by one. and will
|
binary kernel. If you select them all, kernel will probe it
|
||||||
fallback to default.
|
one by one and will fallback to default.
|
||||||
|
|
||||||
# Alphabetically sorted list of Non standard 32 bit platforms
|
# Alphabetically sorted list of Non standard 32 bit platforms
|
||||||
|
|
||||||
|
@ -502,6 +505,22 @@ config X86_VISWS
|
||||||
A kernel compiled for the Visual Workstation will run on general
|
A kernel compiled for the Visual Workstation will run on general
|
||||||
PCs as well. See <file:Documentation/sgi-visws.txt> for details.
|
PCs as well. See <file:Documentation/sgi-visws.txt> for details.
|
||||||
|
|
||||||
|
config STA2X11
|
||||||
|
bool "STA2X11 Companion Chip Support"
|
||||||
|
depends on X86_32_NON_STANDARD && PCI
|
||||||
|
select X86_DEV_DMA_OPS
|
||||||
|
select X86_DMA_REMAP
|
||||||
|
select SWIOTLB
|
||||||
|
select MFD_STA2X11
|
||||||
|
select ARCH_REQUIRE_GPIOLIB
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
This adds support for boards based on the STA2X11 IO-Hub,
|
||||||
|
a.k.a. "ConneXt". The chip is used in place of the standard
|
||||||
|
PC chipset, so all "standard" peripherals are missing. If this
|
||||||
|
option is selected the kernel will still be able to boot on
|
||||||
|
standard PC machines.
|
||||||
|
|
||||||
config X86_SUMMIT
|
config X86_SUMMIT
|
||||||
bool "Summit/EXA (IBM x440)"
|
bool "Summit/EXA (IBM x440)"
|
||||||
depends on X86_32_NON_STANDARD
|
depends on X86_32_NON_STANDARD
|
||||||
|
@ -2210,6 +2229,14 @@ config HAVE_TEXT_POKE_SMP
|
||||||
bool
|
bool
|
||||||
select STOP_MACHINE if SMP
|
select STOP_MACHINE if SMP
|
||||||
|
|
||||||
|
config X86_DEV_DMA_OPS
|
||||||
|
bool
|
||||||
|
depends on X86_64 || STA2X11
|
||||||
|
|
||||||
|
config X86_DMA_REMAP
|
||||||
|
bool
|
||||||
|
depends on STA2X11
|
||||||
|
|
||||||
source "net/Kconfig"
|
source "net/Kconfig"
|
||||||
|
|
||||||
source "drivers/Kconfig"
|
source "drivers/Kconfig"
|
||||||
|
|
|
@ -57,14 +57,20 @@ static void copy_boot_params(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the keyboard repeat rate to maximum. Unclear why this
|
* Query the keyboard lock status as given by the BIOS, and
|
||||||
|
* set the keyboard repeat rate to maximum. Unclear why the latter
|
||||||
* is done here; this might be possible to kill off as stale code.
|
* is done here; this might be possible to kill off as stale code.
|
||||||
*/
|
*/
|
||||||
static void keyboard_set_repeat(void)
|
static void keyboard_init(void)
|
||||||
{
|
{
|
||||||
struct biosregs ireg;
|
struct biosregs ireg, oreg;
|
||||||
initregs(&ireg);
|
initregs(&ireg);
|
||||||
ireg.ax = 0x0305;
|
|
||||||
|
ireg.ah = 0x02; /* Get keyboard status */
|
||||||
|
intcall(0x16, &ireg, &oreg);
|
||||||
|
boot_params.kbd_status = oreg.al;
|
||||||
|
|
||||||
|
ireg.ax = 0x0305; /* Set keyboard repeat rate */
|
||||||
intcall(0x16, &ireg, NULL);
|
intcall(0x16, &ireg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,8 +157,8 @@ void main(void)
|
||||||
/* Detect memory layout */
|
/* Detect memory layout */
|
||||||
detect_memory();
|
detect_memory();
|
||||||
|
|
||||||
/* Set keyboard repeat rate (why?) */
|
/* Set keyboard repeat rate (why?) and query the lock flags */
|
||||||
keyboard_set_repeat();
|
keyboard_init();
|
||||||
|
|
||||||
/* Query MCA information */
|
/* Query MCA information */
|
||||||
query_mca();
|
query_mca();
|
||||||
|
|
|
@ -112,7 +112,8 @@ struct boot_params {
|
||||||
__u8 e820_entries; /* 0x1e8 */
|
__u8 e820_entries; /* 0x1e8 */
|
||||||
__u8 eddbuf_entries; /* 0x1e9 */
|
__u8 eddbuf_entries; /* 0x1e9 */
|
||||||
__u8 edd_mbr_sig_buf_entries; /* 0x1ea */
|
__u8 edd_mbr_sig_buf_entries; /* 0x1ea */
|
||||||
__u8 _pad6[6]; /* 0x1eb */
|
__u8 kbd_status; /* 0x1eb */
|
||||||
|
__u8 _pad6[5]; /* 0x1ec */
|
||||||
struct setup_header hdr; /* setup header */ /* 0x1f1 */
|
struct setup_header hdr; /* setup header */ /* 0x1f1 */
|
||||||
__u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
|
__u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
|
||||||
__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
|
__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
|
||||||
|
|
|
@ -5,8 +5,8 @@ struct dev_archdata {
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
void *acpi_handle;
|
void *acpi_handle;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_DEV_DMA_OPS
|
||||||
struct dma_map_ops *dma_ops;
|
struct dma_map_ops *dma_ops;
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_INTEL_IOMMU) || defined(CONFIG_AMD_IOMMU)
|
#if defined(CONFIG_INTEL_IOMMU) || defined(CONFIG_AMD_IOMMU)
|
||||||
void *iommu; /* hook for IOMMU specific extension */
|
void *iommu; /* hook for IOMMU specific extension */
|
||||||
|
|
|
@ -30,7 +30,7 @@ extern struct dma_map_ops *dma_ops;
|
||||||
|
|
||||||
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
|
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_32
|
#ifndef CONFIG_X86_DEV_DMA_OPS
|
||||||
return dma_ops;
|
return dma_ops;
|
||||||
#else
|
#else
|
||||||
if (unlikely(!dev) || !dev->archdata.dma_ops)
|
if (unlikely(!dev) || !dev->archdata.dma_ops)
|
||||||
|
@ -62,6 +62,12 @@ extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
|
||||||
dma_addr_t *dma_addr, gfp_t flag,
|
dma_addr_t *dma_addr, gfp_t flag,
|
||||||
struct dma_attrs *attrs);
|
struct dma_attrs *attrs);
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_DMA_REMAP /* Platform code defines bridge-specific code */
|
||||||
|
extern bool dma_capable(struct device *dev, dma_addr_t addr, size_t size);
|
||||||
|
extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
|
||||||
|
extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
|
||||||
|
#else
|
||||||
|
|
||||||
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
|
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
|
||||||
{
|
{
|
||||||
if (!dev->dma_mask)
|
if (!dev->dma_mask)
|
||||||
|
@ -79,6 +85,7 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
|
||||||
{
|
{
|
||||||
return daddr;
|
return daddr;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_X86_DMA_REMAP */
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||||
|
|
17
arch/x86/include/asm/kbdleds.h
Normal file
17
arch/x86/include/asm/kbdleds.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef _ASM_X86_KBDLEDS_H
|
||||||
|
#define _ASM_X86_KBDLEDS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
|
||||||
|
* This seems a good reason to start with NumLock off. That's why on X86 we
|
||||||
|
* ask the bios for the correct state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/setup.h>
|
||||||
|
|
||||||
|
static inline int kbd_defleds(void)
|
||||||
|
{
|
||||||
|
return boot_params.kbd_status & 0x20 ? (1 << VC_NUMLOCK) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_KBDLEDS_H */
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/pci_ids.h>
|
#include <linux/pci_ids.h>
|
||||||
#include <linux/pci_regs.h>
|
#include <linux/pci_regs.h>
|
||||||
|
#include <linux/smp.h>
|
||||||
|
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/pci-direct.h>
|
#include <asm/pci-direct.h>
|
||||||
|
@ -22,6 +23,8 @@
|
||||||
#include <asm/paravirt.h>
|
#include <asm/paravirt.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
|
||||||
|
#define TOPOLOGY_REGISTER_OFFSET 0x10
|
||||||
|
|
||||||
#if defined CONFIG_PCI && defined CONFIG_PARAVIRT
|
#if defined CONFIG_PCI && defined CONFIG_PARAVIRT
|
||||||
/*
|
/*
|
||||||
* Interrupt control on vSMPowered systems:
|
* Interrupt control on vSMPowered systems:
|
||||||
|
@ -149,12 +152,49 @@ int is_vsmp_box(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void __init vsmp_cap_cpus(void)
|
||||||
|
{
|
||||||
|
#if !defined(CONFIG_X86_VSMP) && defined(CONFIG_SMP)
|
||||||
|
void __iomem *address;
|
||||||
|
unsigned int cfg, topology, node_shift, maxcpus;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CONFIG_X86_VSMP is not configured, so limit the number CPUs to the
|
||||||
|
* ones present in the first board, unless explicitly overridden by
|
||||||
|
* setup_max_cpus
|
||||||
|
*/
|
||||||
|
if (setup_max_cpus != NR_CPUS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Read the vSMP Foundation topology register */
|
||||||
|
cfg = read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0);
|
||||||
|
address = early_ioremap(cfg + TOPOLOGY_REGISTER_OFFSET, 4);
|
||||||
|
if (WARN_ON(!address))
|
||||||
|
return;
|
||||||
|
|
||||||
|
topology = readl(address);
|
||||||
|
node_shift = (topology >> 16) & 0x7;
|
||||||
|
if (!node_shift)
|
||||||
|
/* The value 0 should be decoded as 8 */
|
||||||
|
node_shift = 8;
|
||||||
|
maxcpus = (topology & ((1 << node_shift) - 1)) + 1;
|
||||||
|
|
||||||
|
pr_info("vSMP CTL: Capping CPUs to %d (CONFIG_X86_VSMP is unset)\n",
|
||||||
|
maxcpus);
|
||||||
|
setup_max_cpus = maxcpus;
|
||||||
|
early_iounmap(address, 4);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void __init vsmp_init(void)
|
void __init vsmp_init(void)
|
||||||
{
|
{
|
||||||
detect_vsmp_box();
|
detect_vsmp_box();
|
||||||
if (!is_vsmp_box())
|
if (!is_vsmp_box())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
vsmp_cap_cpus();
|
||||||
|
|
||||||
set_vsmp_pv_ops();
|
set_vsmp_pv_ops();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ obj-$(CONFIG_X86_INTEL_CE) += ce4100.o
|
||||||
obj-$(CONFIG_ACPI) += acpi.o
|
obj-$(CONFIG_ACPI) += acpi.o
|
||||||
obj-y += legacy.o irq.o
|
obj-y += legacy.o irq.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_STA2X11) += sta2x11-fixup.o
|
||||||
|
|
||||||
obj-$(CONFIG_X86_VISWS) += visws.o
|
obj-$(CONFIG_X86_VISWS) += visws.o
|
||||||
|
|
||||||
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
|
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
|
||||||
|
|
366
arch/x86/pci/sta2x11-fixup.c
Normal file
366
arch/x86/pci/sta2x11-fixup.c
Normal file
|
@ -0,0 +1,366 @@
|
||||||
|
/*
|
||||||
|
* arch/x86/pci/sta2x11-fixup.c
|
||||||
|
* glue code for lib/swiotlb.c and DMA translation between STA2x11
|
||||||
|
* AMBA memory mapping and the X86 memory mapping
|
||||||
|
*
|
||||||
|
* ST Microelectronics ConneXt (STA2X11/STA2X10)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2011 Wind River Systems, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/pci_ids.h>
|
||||||
|
#include <linux/export.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
|
||||||
|
#define STA2X11_SWIOTLB_SIZE (4*1024*1024)
|
||||||
|
extern int swiotlb_late_init_with_default_size(size_t default_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We build a list of bus numbers that are under the ConneXt. The
|
||||||
|
* main bridge hosts 4 busses, which are the 4 endpoints, in order.
|
||||||
|
*/
|
||||||
|
#define STA2X11_NR_EP 4 /* 0..3 included */
|
||||||
|
#define STA2X11_NR_FUNCS 8 /* 0..7 included */
|
||||||
|
#define STA2X11_AMBA_SIZE (512 << 20)
|
||||||
|
|
||||||
|
struct sta2x11_ahb_regs { /* saved during suspend */
|
||||||
|
u32 base, pexlbase, pexhbase, crw;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sta2x11_mapping {
|
||||||
|
u32 amba_base;
|
||||||
|
int is_suspended;
|
||||||
|
struct sta2x11_ahb_regs regs[STA2X11_NR_FUNCS];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sta2x11_instance {
|
||||||
|
struct list_head list;
|
||||||
|
int bus0;
|
||||||
|
struct sta2x11_mapping map[STA2X11_NR_EP];
|
||||||
|
};
|
||||||
|
|
||||||
|
static LIST_HEAD(sta2x11_instance_list);
|
||||||
|
|
||||||
|
/* At probe time, record new instances of this bridge (likely one only) */
|
||||||
|
static void sta2x11_new_instance(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_instance *instance;
|
||||||
|
|
||||||
|
instance = kzalloc(sizeof(*instance), GFP_ATOMIC);
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
/* This has a subordinate bridge, with 4 more-subordinate ones */
|
||||||
|
instance->bus0 = pdev->subordinate->number + 1;
|
||||||
|
|
||||||
|
if (list_empty(&sta2x11_instance_list)) {
|
||||||
|
int size = STA2X11_SWIOTLB_SIZE;
|
||||||
|
/* First instance: register your own swiotlb area */
|
||||||
|
dev_info(&pdev->dev, "Using SWIOTLB (size %i)\n", size);
|
||||||
|
if (swiotlb_late_init_with_default_size(size))
|
||||||
|
dev_emerg(&pdev->dev, "init swiotlb failed\n");
|
||||||
|
}
|
||||||
|
list_add(&instance->list, &sta2x11_instance_list);
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, 0xcc17, sta2x11_new_instance);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility functions used in this file from below
|
||||||
|
*/
|
||||||
|
static struct sta2x11_instance *sta2x11_pdev_to_instance(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_instance *instance;
|
||||||
|
int ep;
|
||||||
|
|
||||||
|
list_for_each_entry(instance, &sta2x11_instance_list, list) {
|
||||||
|
ep = pdev->bus->number - instance->bus0;
|
||||||
|
if (ep >= 0 && ep < STA2X11_NR_EP)
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sta2x11_pdev_to_ep(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_instance *instance;
|
||||||
|
|
||||||
|
instance = sta2x11_pdev_to_instance(pdev);
|
||||||
|
if (!instance)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return pdev->bus->number - instance->bus0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct sta2x11_mapping *sta2x11_pdev_to_mapping(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_instance *instance;
|
||||||
|
int ep;
|
||||||
|
|
||||||
|
instance = sta2x11_pdev_to_instance(pdev);
|
||||||
|
if (!instance)
|
||||||
|
return NULL;
|
||||||
|
ep = sta2x11_pdev_to_ep(pdev);
|
||||||
|
return instance->map + ep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is exported, as some devices need to access the MFD registers */
|
||||||
|
struct sta2x11_instance *sta2x11_get_instance(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
return sta2x11_pdev_to_instance(pdev);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(sta2x11_get_instance);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* p2a - Translate physical address to STA2x11 AMBA address,
|
||||||
|
* used for DMA transfers to STA2x11
|
||||||
|
* @p: Physical address
|
||||||
|
* @pdev: PCI device (must be hosted within the connext)
|
||||||
|
*/
|
||||||
|
static dma_addr_t p2a(dma_addr_t p, struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_mapping *map;
|
||||||
|
dma_addr_t a;
|
||||||
|
|
||||||
|
map = sta2x11_pdev_to_mapping(pdev);
|
||||||
|
a = p + map->amba_base;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a2p - Translate STA2x11 AMBA address to physical address
|
||||||
|
* used for DMA transfers from STA2x11
|
||||||
|
* @a: STA2x11 AMBA address
|
||||||
|
* @pdev: PCI device (must be hosted within the connext)
|
||||||
|
*/
|
||||||
|
static dma_addr_t a2p(dma_addr_t a, struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_mapping *map;
|
||||||
|
dma_addr_t p;
|
||||||
|
|
||||||
|
map = sta2x11_pdev_to_mapping(pdev);
|
||||||
|
p = a - map->amba_base;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sta2x11_swiotlb_alloc_coherent - Allocate swiotlb bounce buffers
|
||||||
|
* returns virtual address. This is the only "special" function here.
|
||||||
|
* @dev: PCI device
|
||||||
|
* @size: Size of the buffer
|
||||||
|
* @dma_handle: DMA address
|
||||||
|
* @flags: memory flags
|
||||||
|
*/
|
||||||
|
static void *sta2x11_swiotlb_alloc_coherent(struct device *dev,
|
||||||
|
size_t size,
|
||||||
|
dma_addr_t *dma_handle,
|
||||||
|
gfp_t flags,
|
||||||
|
struct dma_attrs *attrs)
|
||||||
|
{
|
||||||
|
void *vaddr;
|
||||||
|
|
||||||
|
vaddr = dma_generic_alloc_coherent(dev, size, dma_handle, flags, attrs);
|
||||||
|
if (!vaddr)
|
||||||
|
vaddr = swiotlb_alloc_coherent(dev, size, dma_handle, flags);
|
||||||
|
*dma_handle = p2a(*dma_handle, to_pci_dev(dev));
|
||||||
|
return vaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have our own dma_ops: the same as swiotlb but from alloc (above) */
|
||||||
|
static struct dma_map_ops sta2x11_dma_ops = {
|
||||||
|
.alloc = sta2x11_swiotlb_alloc_coherent,
|
||||||
|
.free = swiotlb_free_coherent,
|
||||||
|
.map_page = swiotlb_map_page,
|
||||||
|
.unmap_page = swiotlb_unmap_page,
|
||||||
|
.map_sg = swiotlb_map_sg_attrs,
|
||||||
|
.unmap_sg = swiotlb_unmap_sg_attrs,
|
||||||
|
.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
|
||||||
|
.sync_single_for_device = swiotlb_sync_single_for_device,
|
||||||
|
.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
|
||||||
|
.sync_sg_for_device = swiotlb_sync_sg_for_device,
|
||||||
|
.mapping_error = swiotlb_dma_mapping_error,
|
||||||
|
.dma_supported = NULL, /* FIXME: we should use this instead! */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* At setup time, we use our own ops if the device is a ConneXt one */
|
||||||
|
static void sta2x11_setup_pdev(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_instance *instance = sta2x11_pdev_to_instance(pdev);
|
||||||
|
|
||||||
|
if (!instance) /* either a sta2x11 bridge or another ST device */
|
||||||
|
return;
|
||||||
|
pci_set_consistent_dma_mask(pdev, STA2X11_AMBA_SIZE - 1);
|
||||||
|
pci_set_dma_mask(pdev, STA2X11_AMBA_SIZE - 1);
|
||||||
|
pdev->dev.archdata.dma_ops = &sta2x11_dma_ops;
|
||||||
|
|
||||||
|
/* We must enable all devices as master, for audio DMA to work */
|
||||||
|
pci_set_master(pdev);
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_setup_pdev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following three functions are exported (used in swiotlb: FIXME)
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* dma_capable - Check if device can manage DMA transfers (FIXME: kill it)
|
||||||
|
* @dev: device for a PCI device
|
||||||
|
* @addr: DMA address
|
||||||
|
* @size: DMA size
|
||||||
|
*/
|
||||||
|
bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
|
||||||
|
{
|
||||||
|
struct sta2x11_mapping *map;
|
||||||
|
|
||||||
|
if (dev->archdata.dma_ops != &sta2x11_dma_ops) {
|
||||||
|
if (!dev->dma_mask)
|
||||||
|
return false;
|
||||||
|
return addr + size - 1 <= *dev->dma_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
map = sta2x11_pdev_to_mapping(to_pci_dev(dev));
|
||||||
|
|
||||||
|
if (!map || (addr < map->amba_base))
|
||||||
|
return false;
|
||||||
|
if (addr + size >= map->amba_base + STA2X11_AMBA_SIZE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phys_to_dma - Return the DMA AMBA address used for this STA2x11 device
|
||||||
|
* @dev: device for a PCI device
|
||||||
|
* @paddr: Physical address
|
||||||
|
*/
|
||||||
|
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
|
||||||
|
{
|
||||||
|
if (dev->archdata.dma_ops != &sta2x11_dma_ops)
|
||||||
|
return paddr;
|
||||||
|
return p2a(paddr, to_pci_dev(dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dma_to_phys - Return the physical address used for this STA2x11 DMA address
|
||||||
|
* @dev: device for a PCI device
|
||||||
|
* @daddr: STA2x11 AMBA DMA address
|
||||||
|
*/
|
||||||
|
phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
|
||||||
|
{
|
||||||
|
if (dev->archdata.dma_ops != &sta2x11_dma_ops)
|
||||||
|
return daddr;
|
||||||
|
return a2p(daddr, to_pci_dev(dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At boot we must set up the mappings for the pcie-to-amba bridge.
|
||||||
|
* It involves device access, and the same happens at suspend/resume time
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define AHB_MAPB 0xCA4
|
||||||
|
#define AHB_CRW(i) (AHB_MAPB + 0 + (i) * 0x10)
|
||||||
|
#define AHB_CRW_SZMASK 0xfffffc00UL
|
||||||
|
#define AHB_CRW_ENABLE (1 << 0)
|
||||||
|
#define AHB_CRW_WTYPE_MEM (2 << 1)
|
||||||
|
#define AHB_CRW_ROE (1UL << 3) /* Relax Order Ena */
|
||||||
|
#define AHB_CRW_NSE (1UL << 4) /* No Snoop Enable */
|
||||||
|
#define AHB_BASE(i) (AHB_MAPB + 4 + (i) * 0x10)
|
||||||
|
#define AHB_PEXLBASE(i) (AHB_MAPB + 8 + (i) * 0x10)
|
||||||
|
#define AHB_PEXHBASE(i) (AHB_MAPB + 12 + (i) * 0x10)
|
||||||
|
|
||||||
|
/* At probe time, enable mapping for each endpoint, using the pdev */
|
||||||
|
static void sta2x11_map_ep(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!map)
|
||||||
|
return;
|
||||||
|
pci_read_config_dword(pdev, AHB_BASE(0), &map->amba_base);
|
||||||
|
|
||||||
|
/* Configure AHB mapping */
|
||||||
|
pci_write_config_dword(pdev, AHB_PEXLBASE(0), 0);
|
||||||
|
pci_write_config_dword(pdev, AHB_PEXHBASE(0), 0);
|
||||||
|
pci_write_config_dword(pdev, AHB_CRW(0), STA2X11_AMBA_SIZE |
|
||||||
|
AHB_CRW_WTYPE_MEM | AHB_CRW_ENABLE);
|
||||||
|
|
||||||
|
/* Disable all the other windows */
|
||||||
|
for (i = 1; i < STA2X11_NR_FUNCS; i++)
|
||||||
|
pci_write_config_dword(pdev, AHB_CRW(i), 0);
|
||||||
|
|
||||||
|
dev_info(&pdev->dev,
|
||||||
|
"sta2x11: Map EP %i: AMBA address %#8x-%#8x\n",
|
||||||
|
sta2x11_pdev_to_ep(pdev), map->amba_base,
|
||||||
|
map->amba_base + STA2X11_AMBA_SIZE - 1);
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_map_ep);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM /* Some register values must be saved and restored */
|
||||||
|
|
||||||
|
static void suspend_mapping(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!map)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (map->is_suspended)
|
||||||
|
return;
|
||||||
|
map->is_suspended = 1;
|
||||||
|
|
||||||
|
/* Save all window configs */
|
||||||
|
for (i = 0; i < STA2X11_NR_FUNCS; i++) {
|
||||||
|
struct sta2x11_ahb_regs *regs = map->regs + i;
|
||||||
|
|
||||||
|
pci_read_config_dword(pdev, AHB_BASE(i), ®s->base);
|
||||||
|
pci_read_config_dword(pdev, AHB_PEXLBASE(i), ®s->pexlbase);
|
||||||
|
pci_read_config_dword(pdev, AHB_PEXHBASE(i), ®s->pexhbase);
|
||||||
|
pci_read_config_dword(pdev, AHB_CRW(i), ®s->crw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, suspend_mapping);
|
||||||
|
|
||||||
|
static void resume_mapping(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!map)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
if (!map->is_suspended)
|
||||||
|
goto out;
|
||||||
|
map->is_suspended = 0;
|
||||||
|
|
||||||
|
/* Restore all window configs */
|
||||||
|
for (i = 0; i < STA2X11_NR_FUNCS; i++) {
|
||||||
|
struct sta2x11_ahb_regs *regs = map->regs + i;
|
||||||
|
|
||||||
|
pci_write_config_dword(pdev, AHB_BASE(i), regs->base);
|
||||||
|
pci_write_config_dword(pdev, AHB_PEXLBASE(i), regs->pexlbase);
|
||||||
|
pci_write_config_dword(pdev, AHB_PEXHBASE(i), regs->pexhbase);
|
||||||
|
pci_write_config_dword(pdev, AHB_CRW(i), regs->crw);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
pci_set_master(pdev); /* Like at boot, enable master on all devices */
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, resume_mapping);
|
||||||
|
|
||||||
|
#endif /* CONFIG_PM */
|
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
|
#include <linux/pm_wakeup.h>
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/power_supply.h>
|
#include <linux/power_supply.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
|
@ -83,8 +84,12 @@ static void send_ebook_state(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!!test_bit(SW_TABLET_MODE, ebook_switch_idev->sw) == state)
|
||||||
|
return; /* Nothing new to report. */
|
||||||
|
|
||||||
input_report_switch(ebook_switch_idev, SW_TABLET_MODE, state);
|
input_report_switch(ebook_switch_idev, SW_TABLET_MODE, state);
|
||||||
input_sync(ebook_switch_idev);
|
input_sync(ebook_switch_idev);
|
||||||
|
pm_wakeup_event(&ebook_switch_idev->dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flip_lid_inverter(void)
|
static void flip_lid_inverter(void)
|
||||||
|
@ -123,8 +128,12 @@ static void detect_lid_state(void)
|
||||||
/* Report current lid switch state through input layer */
|
/* Report current lid switch state through input layer */
|
||||||
static void send_lid_state(void)
|
static void send_lid_state(void)
|
||||||
{
|
{
|
||||||
|
if (!!test_bit(SW_LID, lid_switch_idev->sw) == !lid_open)
|
||||||
|
return; /* Nothing new to report. */
|
||||||
|
|
||||||
input_report_switch(lid_switch_idev, SW_LID, !lid_open);
|
input_report_switch(lid_switch_idev, SW_LID, !lid_open);
|
||||||
input_sync(lid_switch_idev);
|
input_sync(lid_switch_idev);
|
||||||
|
pm_wakeup_event(&lid_switch_idev->dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t lid_wake_mode_show(struct device *dev,
|
static ssize_t lid_wake_mode_show(struct device *dev,
|
||||||
|
@ -213,11 +222,30 @@ static irqreturn_t xo1_sci_intr(int irq, void *dev_id)
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "sts %x gpe %x\n", sts, gpe);
|
dev_dbg(&pdev->dev, "sts %x gpe %x\n", sts, gpe);
|
||||||
|
|
||||||
if (sts & CS5536_PWRBTN_FLAG && !(sts & CS5536_WAK_FLAG)) {
|
if (sts & CS5536_PWRBTN_FLAG) {
|
||||||
input_report_key(power_button_idev, KEY_POWER, 1);
|
if (!(sts & CS5536_WAK_FLAG)) {
|
||||||
input_sync(power_button_idev);
|
/* Only report power button input when it was pressed
|
||||||
input_report_key(power_button_idev, KEY_POWER, 0);
|
* during regular operation (as opposed to when it
|
||||||
input_sync(power_button_idev);
|
* was used to wake the system). */
|
||||||
|
input_report_key(power_button_idev, KEY_POWER, 1);
|
||||||
|
input_sync(power_button_idev);
|
||||||
|
input_report_key(power_button_idev, KEY_POWER, 0);
|
||||||
|
input_sync(power_button_idev);
|
||||||
|
}
|
||||||
|
/* Report the wakeup event in all cases. */
|
||||||
|
pm_wakeup_event(&power_button_idev->dev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sts & (CS5536_RTC_FLAG | CS5536_WAK_FLAG)) ==
|
||||||
|
(CS5536_RTC_FLAG | CS5536_WAK_FLAG)) {
|
||||||
|
/* When the system is woken by the RTC alarm, report the
|
||||||
|
* event on the rtc device. */
|
||||||
|
struct device *rtc = bus_find_device_by_name(
|
||||||
|
&platform_bus_type, NULL, "rtc_cmos");
|
||||||
|
if (rtc) {
|
||||||
|
pm_wakeup_event(rtc, 0);
|
||||||
|
put_device(rtc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpe & CS5536_GPIOM7_PME_FLAG) { /* EC GPIO */
|
if (gpe & CS5536_GPIOM7_PME_FLAG) { /* EC GPIO */
|
||||||
|
@ -310,9 +338,10 @@ static int __devinit setup_sci_interrupt(struct platform_device *pdev)
|
||||||
outb(lo, CS5536_PIC_INT_SEL2);
|
outb(lo, CS5536_PIC_INT_SEL2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable SCI from power button, and clear pending interrupts */
|
/* Enable interesting SCI events, and clear pending interrupts */
|
||||||
sts = inl(acpi_base + CS5536_PM1_STS);
|
sts = inl(acpi_base + CS5536_PM1_STS);
|
||||||
outl((CS5536_PM_PWRBTN << 16) | 0xffff, acpi_base + CS5536_PM1_STS);
|
outl(((CS5536_PM_PWRBTN | CS5536_PM_RTC) << 16) | 0xffff,
|
||||||
|
acpi_base + CS5536_PM1_STS);
|
||||||
|
|
||||||
r = request_irq(sci_irq, xo1_sci_intr, 0, DRV_NAME, pdev);
|
r = request_irq(sci_irq, xo1_sci_intr, 0, DRV_NAME, pdev);
|
||||||
if (r)
|
if (r)
|
||||||
|
|
|
@ -53,17 +53,13 @@ extern void ctrl_alt_del(void);
|
||||||
|
|
||||||
#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
|
#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
|
||||||
|
|
||||||
/*
|
#if defined(CONFIG_X86) || defined(CONFIG_PARISC)
|
||||||
* Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
|
#include <asm/kbdleds.h>
|
||||||
* This seems a good reason to start with NumLock off. On HIL keyboards
|
|
||||||
* of PARISC machines however there is no NumLock key and everyone expects the
|
|
||||||
* keypad to be used for numbers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
|
|
||||||
#define KBD_DEFLEDS (1 << VC_NUMLOCK)
|
|
||||||
#else
|
#else
|
||||||
#define KBD_DEFLEDS 0
|
static inline int kbd_defleds(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KBD_DEFLOCK 0
|
#define KBD_DEFLOCK 0
|
||||||
|
@ -1524,8 +1520,8 @@ int __init kbd_init(void)
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
for (i = 0; i < MAX_NR_CONSOLES; i++) {
|
for (i = 0; i < MAX_NR_CONSOLES; i++) {
|
||||||
kbd_table[i].ledflagstate = KBD_DEFLEDS;
|
kbd_table[i].ledflagstate = kbd_defleds();
|
||||||
kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
|
kbd_table[i].default_ledflagstate = kbd_defleds();
|
||||||
kbd_table[i].ledmode = LED_SHOW_FLAGS;
|
kbd_table[i].ledmode = LED_SHOW_FLAGS;
|
||||||
kbd_table[i].lockstate = KBD_DEFLOCK;
|
kbd_table[i].lockstate = KBD_DEFLOCK;
|
||||||
kbd_table[i].slockstate = 0;
|
kbd_table[i].slockstate = 0;
|
||||||
|
|
|
@ -95,6 +95,7 @@ static inline int cs5535_pic_unreqz_select_high(unsigned int group,
|
||||||
|
|
||||||
/* CS5536_PM1_STS bits */
|
/* CS5536_PM1_STS bits */
|
||||||
#define CS5536_WAK_FLAG (1 << 15)
|
#define CS5536_WAK_FLAG (1 << 15)
|
||||||
|
#define CS5536_RTC_FLAG (1 << 10)
|
||||||
#define CS5536_PWRBTN_FLAG (1 << 8)
|
#define CS5536_PWRBTN_FLAG (1 << 8)
|
||||||
|
|
||||||
/* CS5536_PM1_EN bits */
|
/* CS5536_PM1_EN bits */
|
||||||
|
|
Loading…
Reference in a new issue