Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9cb0fbf7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (47 commits)
  MIPS: Add hibernation support
  MIPS: Move Cavium CP0 hwrena impl bits to cpu-feature-overrides.h
  MIPS: Allow CPU specific overriding of CP0 hwrena impl bits.
  MIPS: Kconfig Add SYS_SUPPORTS_HUGETLBFS and enable it for some systems.
  Hugetlbfs: Enable hugetlbfs for more systems in Kconfig.
  MIPS: TLB support for hugetlbfs.
  MIPS: Add hugetlbfs page defines.
  MIPS: Add support files for hugetlbfs.
  MIPS: Remove unused parameters from iPTE_LW.
  Staging: Add octeon-ethernet driver files.
  MIPS: Export erratum function needed by octeon-ethernet driver.
  MIPS: Cavium-Octeon: Add more chip specific feature tests.
  MIPS: Cavium-Octeon: Add more board type constants.
  MIPS: Export cvmx_sysinfo_get needed by octeon-ethernet driver.
  MIPS: Add named alloc functions to OCTEON boot monitor memory allocator.
  MIPS: Alchemy: devboards: Convert to gpio calls.
  MIPS: Alchemy: xxs1500: use linux gpio api.
  MIPS: Alchemy: MTX-1: Use linux gpio api.
  MIPS: Alchemy: Rewrite GPIO support.
  MIPS: Alchemy: Remove unused au1000_gpio.h header
  ...
parents feb72ce8 363c55ca
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -618,6 +618,8 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
	select SYS_HAS_EARLY_PRINTK
	select SYS_HAS_CPU_CAVIUM_OCTEON
	select SWAP_IO_SPACE
	select HW_HAS_PCI
	select ARCH_SUPPORTS_MSI
	help
	  This option supports all of the Octeon reference boards from Cavium
	  Networks. It builds a kernel that dynamically determines the Octeon
@@ -851,6 +853,11 @@ config SYS_SUPPORTS_BIG_ENDIAN
config SYS_SUPPORTS_LITTLE_ENDIAN
	bool

config SYS_SUPPORTS_HUGETLBFS
	bool
	depends on CPU_SUPPORTS_HUGEPAGES && 64BIT
	default y

config IRQ_CPU
	bool

@@ -1055,6 +1062,7 @@ config CPU_MIPS64_R1
	select CPU_SUPPORTS_32BIT_KERNEL
	select CPU_SUPPORTS_64BIT_KERNEL
	select CPU_SUPPORTS_HIGHMEM
	select CPU_SUPPORTS_HUGEPAGES
	help
	  Choose this option to build a kernel for release 1 or later of the
	  MIPS64 architecture.  Many modern embedded systems with a 64-bit
@@ -1074,6 +1082,7 @@ config CPU_MIPS64_R2
	select CPU_SUPPORTS_32BIT_KERNEL
	select CPU_SUPPORTS_64BIT_KERNEL
	select CPU_SUPPORTS_HIGHMEM
	select CPU_SUPPORTS_HUGEPAGES
	help
	  Choose this option to build a kernel for release 2 or later of the
	  MIPS64 architecture.  Many modern embedded systems with a 64-bit
@@ -1160,6 +1169,7 @@ config CPU_R5500
	select CPU_HAS_LLSC
	select CPU_SUPPORTS_32BIT_KERNEL
	select CPU_SUPPORTS_64BIT_KERNEL
	select CPU_SUPPORTS_HUGEPAGES
	help
	  NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
	  instruction set.
@@ -1245,6 +1255,7 @@ config CPU_CAVIUM_OCTEON
	select WEAK_ORDERING
	select WEAK_REORDERING_BEYOND_LLSC
	select CPU_SUPPORTS_HIGHMEM
	select CPU_SUPPORTS_HUGEPAGES
	help
	  The Cavium Octeon processor is a highly integrated chip containing
	  many ethernet hardware widgets for networking tasks. The processor
@@ -1364,6 +1375,8 @@ config CPU_SUPPORTS_32BIT_KERNEL
	bool
config CPU_SUPPORTS_64BIT_KERNEL
	bool
config CPU_SUPPORTS_HUGEPAGES
	bool

#
# Set to y for ptrace access to watch registers.
@@ -2121,6 +2134,10 @@ endmenu

menu "Power management options"

config ARCH_HIBERNATION_POSSIBLE
	def_bool y
	depends on !SMP

config ARCH_SUSPEND_POSSIBLE
	def_bool y
	depends on !SMP
+7 −2
Original line number Diff line number Diff line
@@ -167,7 +167,6 @@ libs-$(CONFIG_ARC) += arch/mips/fw/arc/
libs-$(CONFIG_CFE)		+= arch/mips/fw/cfe/
libs-$(CONFIG_SNIPROM)		+= arch/mips/fw/sni/
libs-y				+= arch/mips/fw/lib/
libs-$(CONFIG_SIBYTE_CFE)	+= arch/mips/sibyte/cfe/

#
# Board-dependent options and extra files
@@ -184,7 +183,6 @@ load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000
# Common Alchemy Au1x00 stuff
#
core-$(CONFIG_SOC_AU1X00)	+= arch/mips/alchemy/common/
cflags-$(CONFIG_SOC_AU1X00)	+= -I$(srctree)/arch/mips/include/asm/mach-au1x00

#
# AMD Alchemy Pb1000 eval board
@@ -282,6 +280,10 @@ load-$(CONFIG_MIPS_MTX1) += 0xffffffff80100000
libs-$(CONFIG_MIPS_XXS1500)	+= arch/mips/alchemy/xxs1500/
load-$(CONFIG_MIPS_XXS1500)	+= 0xffffffff80100000

# must be last for Alchemy systems for GPIO to work properly
cflags-$(CONFIG_SOC_AU1X00)	+= -I$(srctree)/arch/mips/include/asm/mach-au1x00


#
# Cobalt Server
#
@@ -675,6 +677,9 @@ core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/

drivers-$(CONFIG_OPROFILE)	+= arch/mips/oprofile/

# suspend and hibernation support
drivers-$(CONFIG_PM)	+= arch/mips/power/

ifdef CONFIG_LASAT
rom.bin rom.sw: vmlinux
	$(Q)$(MAKE) $(build)=arch/mips/lasat/image $@
+18 −1
Original line number Diff line number Diff line
# au1000-style gpio
config ALCHEMY_GPIO_AU1000
	bool

# select this in your board config if you don't want to use the gpio
# namespace as documented in the manuals.  In this case however you need
# to create the necessary gpio_* functions in your board code/headers!
# see arch/mips/include/asm/mach-au1x00/gpio.h   for more information.
config ALCHEMY_GPIO_INDIRECT
	def_bool n

choice
	prompt "Machine type"
	depends on MACH_ALCHEMY
@@ -108,22 +119,27 @@ endchoice
config SOC_AU1000
	bool
	select SOC_AU1X00
	select ALCHEMY_GPIO_AU1000

config SOC_AU1100
	bool
	select SOC_AU1X00
	select ALCHEMY_GPIO_AU1000

config SOC_AU1500
	bool
	select SOC_AU1X00
	select ALCHEMY_GPIO_AU1000

config SOC_AU1550
	bool
	select SOC_AU1X00
	select ALCHEMY_GPIO_AU1000

config SOC_AU1200
	bool
	select SOC_AU1X00
	select ALCHEMY_GPIO_AU1000

config SOC_AU1X00
	bool
@@ -134,4 +150,5 @@ config SOC_AU1X00
	select SYS_HAS_CPU_MIPS32_R1
	select SYS_SUPPORTS_32BIT_KERNEL
	select SYS_SUPPORTS_APM_EMULATION
	select ARCH_REQUIRE_GPIOLIB
	select GENERIC_GPIO
	select ARCH_WANT_OPTIONAL_GPIOLIB
+8 −1
Original line number Diff line number Diff line
@@ -7,7 +7,14 @@

obj-y += prom.o irq.o puts.o time.o reset.o \
	clocks.o platform.o power.o setup.o \
	sleeper.o dma.o dbdma.o gpio.o
	sleeper.o dma.o dbdma.o

# optional gpiolib support
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
 ifeq ($(CONFIG_GPIOLIB),y)
  obj-$(CONFIG_ALCHEMY_GPIO_AU1000) += gpiolib-au1000.o
 endif
endif

obj-$(CONFIG_PCI)		+= pci.o

+130 −0
Original line number Diff line number Diff line
/*
 *  Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
 *  	Architecture specific GPIO support
 *  	GPIOLIB support for Au1000, Au1500, Au1100, Au1550 and Au12x0.
 *
 *  This program is free software; you can redistribute	 it and/or modify it
 *  under  the terms of	 the GNU General  Public License as published by the
@@ -23,8 +23,8 @@
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Notes :
 * 	au1000 SoC have only one GPIO line : GPIO1
 * 	others have a second one : GPIO2
 * 	au1000 SoC have only one GPIO block : GPIO1
 * 	Au1100, Au15x0, Au12x0 have a second one : GPIO2
 */

#include <linux/kernel.h>
@@ -34,168 +34,97 @@
#include <linux/gpio.h>

#include <asm/mach-au1x00/au1000.h>
#include <asm/gpio.h>

struct au1000_gpio_chip {
	struct gpio_chip	chip;
	void __iomem		*regbase;
};
#include <asm/mach-au1x00/gpio.h>

#if !defined(CONFIG_SOC_AU1000)
static int au1000_gpio2_get(struct gpio_chip *chip, unsigned offset)
static int gpio2_get(struct gpio_chip *chip, unsigned offset)
{
	u32 mask = 1 << offset;
	struct au1000_gpio_chip *gpch;

	gpch = container_of(chip, struct au1000_gpio_chip, chip);
	return readl(gpch->regbase + AU1000_GPIO2_ST) & mask;
	return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
}

static void au1000_gpio2_set(struct gpio_chip *chip,
				unsigned offset, int value)
static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
{
	u32 mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
	struct au1000_gpio_chip *gpch;
	unsigned long flags;

	gpch = container_of(chip, struct au1000_gpio_chip, chip);

	local_irq_save(flags);
	writel(mask, gpch->regbase + AU1000_GPIO2_OUT);
	local_irq_restore(flags);
	alchemy_gpio2_set_value(offset + ALCHEMY_GPIO2_BASE, value);
}

static int au1000_gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
static int gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
{
	u32 mask = 1 << offset;
	u32 tmp;
	struct au1000_gpio_chip *gpch;
	unsigned long flags;

	gpch = container_of(chip, struct au1000_gpio_chip, chip);

	local_irq_save(flags);
	tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
	tmp &= ~mask;
	writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
	local_irq_restore(flags);

	return 0;
	return alchemy_gpio2_direction_input(offset + ALCHEMY_GPIO2_BASE);
}

static int au1000_gpio2_direction_output(struct gpio_chip *chip,
					unsigned offset, int value)
static int gpio2_direction_output(struct gpio_chip *chip, unsigned offset,
				  int value)
{
	u32 mask = 1 << offset;
	u32 out_mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
	u32 tmp;
	struct au1000_gpio_chip *gpch;
	unsigned long flags;

	gpch = container_of(chip, struct au1000_gpio_chip, chip);

	local_irq_save(flags);
	tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
	tmp |= mask;
	writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
	writel(out_mask, gpch->regbase + AU1000_GPIO2_OUT);
	local_irq_restore(flags);
	return alchemy_gpio2_direction_output(offset + ALCHEMY_GPIO2_BASE,
						value);
}

	return 0;
static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
{
	return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE);
}
#endif /* !defined(CONFIG_SOC_AU1000) */

static int au1000_gpio1_get(struct gpio_chip *chip, unsigned offset)
static int gpio1_get(struct gpio_chip *chip, unsigned offset)
{
	u32 mask = 1 << offset;
	struct au1000_gpio_chip *gpch;

	gpch = container_of(chip, struct au1000_gpio_chip, chip);
	return readl(gpch->regbase + AU1000_GPIO1_ST) & mask;
	return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
}

static void au1000_gpio1_set(struct gpio_chip *chip,
static void gpio1_set(struct gpio_chip *chip,
				unsigned offset, int value)
{
	u32 mask = 1 << offset;
	u32 reg_offset;
	struct au1000_gpio_chip *gpch;
	unsigned long flags;

	gpch = container_of(chip, struct au1000_gpio_chip, chip);

	if (value)
		reg_offset = AU1000_GPIO1_OUT;
	else
		reg_offset = AU1000_GPIO1_CLR;

	local_irq_save(flags);
	writel(mask, gpch->regbase + reg_offset);
	local_irq_restore(flags);
	alchemy_gpio1_set_value(offset + ALCHEMY_GPIO1_BASE, value);
}

static int au1000_gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
static int gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
{
	u32 mask = 1 << offset;
	struct au1000_gpio_chip *gpch;

	gpch = container_of(chip, struct au1000_gpio_chip, chip);
	writel(mask, gpch->regbase + AU1000_GPIO1_ST);

	return 0;
	return alchemy_gpio1_direction_input(offset + ALCHEMY_GPIO1_BASE);
}

static int au1000_gpio1_direction_output(struct gpio_chip *chip,
static int gpio1_direction_output(struct gpio_chip *chip,
					unsigned offset, int value)
{
	u32 mask = 1 << offset;
	struct au1000_gpio_chip *gpch;

	gpch = container_of(chip, struct au1000_gpio_chip, chip);

	writel(mask, gpch->regbase + AU1000_GPIO1_TRI_OUT);
	au1000_gpio1_set(chip, offset, value);
	return alchemy_gpio1_direction_output(offset + ALCHEMY_GPIO1_BASE,
					     value);
}

	return 0;
static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset)
{
	return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE);
}

struct au1000_gpio_chip au1000_gpio_chip[] = {
struct gpio_chip alchemy_gpio_chip[] = {
	[0] = {
		.regbase			= (void __iomem *)SYS_BASE,
		.chip = {
			.label			= "au1000-gpio1",
			.direction_input	= au1000_gpio1_direction_input,
			.direction_output	= au1000_gpio1_direction_output,
			.get			= au1000_gpio1_get,
			.set			= au1000_gpio1_set,
			.base			= 0,
			.ngpio			= 32,
		},
		.label			= "alchemy-gpio1",
		.direction_input	= gpio1_direction_input,
		.direction_output	= gpio1_direction_output,
		.get			= gpio1_get,
		.set			= gpio1_set,
		.to_irq			= gpio1_to_irq,
		.base			= ALCHEMY_GPIO1_BASE,
		.ngpio			= ALCHEMY_GPIO1_NUM,
	},
#if !defined(CONFIG_SOC_AU1000)
	[1] = {
		.regbase                        = (void __iomem *)GPIO2_BASE,
		.chip = {
			.label                  = "au1000-gpio2",
			.direction_input        = au1000_gpio2_direction_input,
			.direction_output       = au1000_gpio2_direction_output,
			.get                    = au1000_gpio2_get,
			.set                    = au1000_gpio2_set,
			.base                   = AU1XXX_GPIO_BASE,
			.ngpio                  = 32,
		},
		.label                  = "alchemy-gpio2",
		.direction_input        = gpio2_direction_input,
		.direction_output       = gpio2_direction_output,
		.get                    = gpio2_get,
		.set                    = gpio2_set,
		.to_irq			= gpio2_to_irq,
		.base                   = ALCHEMY_GPIO2_BASE,
		.ngpio                  = ALCHEMY_GPIO2_NUM,
	},
#endif
};

static int __init au1000_gpio_init(void)
static int __init alchemy_gpiolib_init(void)
{
	gpiochip_add(&au1000_gpio_chip[0].chip);
	gpiochip_add(&alchemy_gpio_chip[0]);
#if !defined(CONFIG_SOC_AU1000)
	gpiochip_add(&au1000_gpio_chip[1].chip);
	gpiochip_add(&alchemy_gpio_chip[1]);
#endif

	return 0;
}
arch_initcall(au1000_gpio_init);
arch_initcall(alchemy_gpiolib_init);
Loading