Cleanups for MSM for 3.11
These are a handful of cleanups to the MSM tree. The gpio cleanups get us closer to having proper pinmux and gpio support. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJRu1dSAAoJEOa6n1xeVN+CbG4QAMxPKNDgBcX+UHRLMBh5YkbP ePoWz8QhQ/OWo3Oef6IBEwA3n2jfSF3hTYnXJI/LqRibL8yCDWKlSI6b52/vZsDg r2J4FMiHtBc0Wk+JGhKszdS+eLnljOljz49L5YEMCRglFVMveXqbKeTvbzfaGR6u SAJca3roEVo2Vgdf36CnYEHNxHrfK6yMzPVqiVgasPWnst10WguV+dhX9+REwT2p kp99U8wBEAp84nb2KzoVwKpzUpWWPcFWiaB1/EE6jB5+d3U0CLBWp+6E12m9tOTU L8Hx417zmwV/YvNfVb//SnTnBGYMybXDVlIzRQUuJimPm96SFw1Uw6+0+V+sAv3N T7WmyiyZ6UaDyQB1VCQNzIqEOq8qBacRaXH6kxk6T8UW8l08tSuSf/piiSw5wZLD 6QJ1RFkjrcEulh0DDOcf6Fg34jVk3hjQFF86sBN+JTQfIQ1VBHDLSGuF+RjYk5LW gNN5xGuqHjDdbK/HNvMhIF8MN/B64Wm4PsOHRsN5RP9EXVIB5kEGUMwEEEa/jO8m rhWUPjFq7nE4BNNvrhKShjxtKJGi5OmYx5GYw189rJ5bzVQH68ZSIAGTh8TySpfB N/G82J+bGXz0xq8z81dKRsru+kdv2MkNL9mlJzYNbKhQP64ukD1XMmrWlH8DxtzY CPNWs8m5QCI4R1WiaP2W =9wS3 -----END PGP SIGNATURE----- Merge tag 'msm-cleanup-for-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/davidb/linux-msm into next/cleanup From David Brown: Cleanups for MSM for 3.11 These are a handful of cleanups to the MSM tree. The gpio cleanups get us closer to having proper pinmux and gpio support. * tag 'msm-cleanup-for-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/davidb/linux-msm: mfd: ssbi: Use devm_* and simplify code gpio: msm: Add device tree and irqdomain support for gpio-msm-v2 ARM: msm: Remove gpiomux-v2 and re-organize MSM_GPIOMUX configs msm: iomap: Remove unused bases and mappings msm: Remove unused file core.h ARM: msm: Remove init_irq declaration in machine description Signed-off-by: Olof Johansson <olof@lixom.net> Conflicts: arch/arm/boot/dts/msm8660-surf.dts arch/arm/boot/dts/msm8960-cdp.dts
This commit is contained in:
Коммит
e45600107b
|
@ -0,0 +1,26 @@
|
|||
MSM GPIO controller bindings
|
||||
|
||||
Required properties:
|
||||
- compatible:
|
||||
- "qcom,msm-gpio" for MSM controllers
|
||||
- #gpio-cells : Should be two.
|
||||
- first cell is the pin number
|
||||
- second cell is used to specify optional parameters (unused)
|
||||
- gpio-controller : Marks the device node as a GPIO controller.
|
||||
- #interrupt-cells : Should be 2.
|
||||
- interrupt-controller: Mark the device node as an interrupt controller
|
||||
- interrupts : Specify the TLMM summary interrupt number
|
||||
- ngpio : Specify the number of MSM GPIOs
|
||||
|
||||
Example:
|
||||
|
||||
msmgpio: gpio@fd510000 {
|
||||
compatible = "qcom,msm-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
reg = <0xfd510000 0x4000>;
|
||||
interrupts = <0 208 0>;
|
||||
ngpio = <150>;
|
||||
};
|
|
@ -26,6 +26,17 @@
|
|||
cpu-offset = <0x40000>;
|
||||
};
|
||||
|
||||
msmgpio: gpio@800000 {
|
||||
compatible = "qcom,msm-gpio";
|
||||
reg = <0x00800000 0x1000>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpio = <173>;
|
||||
interrupts = <0 32 0x4>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
serial@19c40000 {
|
||||
compatible = "qcom,msm-hsuart", "qcom,msm-uart";
|
||||
reg = <0x19c40000 0x1000>,
|
||||
|
|
|
@ -26,7 +26,18 @@
|
|||
cpu-offset = <0x80000>;
|
||||
};
|
||||
|
||||
serial@16440000 {
|
||||
msmgpio: gpio@fd510000 {
|
||||
compatible = "qcom,msm-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpio = <150>;
|
||||
interrupts = <0 32 0x4>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
reg = <0xfd510000 0x4000>;
|
||||
};
|
||||
|
||||
serial@19440000 {
|
||||
compatible = "qcom,msm-hsuart", "qcom,msm-uart";
|
||||
reg = <0x16440000 0x1000>,
|
||||
<0x16400000 0x1000>;
|
||||
|
|
|
@ -48,9 +48,7 @@ config ARCH_MSM8X60
|
|||
select CPU_V7
|
||||
select GPIO_MSM_V2
|
||||
select HAVE_SMP
|
||||
select MSM_GPIOMUX
|
||||
select MSM_SCM if SMP
|
||||
select MSM_V2_TLMM
|
||||
select USE_OF
|
||||
|
||||
config ARCH_MSM8960
|
||||
|
@ -58,9 +56,8 @@ config ARCH_MSM8960
|
|||
select ARM_GIC
|
||||
select CPU_V7
|
||||
select HAVE_SMP
|
||||
select MSM_GPIOMUX
|
||||
select GPIO_MSM_V2
|
||||
select MSM_SCM if SMP
|
||||
select MSM_V2_TLMM
|
||||
select USE_OF
|
||||
|
||||
config MSM_HAS_DEBUG_UART_HS
|
||||
|
@ -124,10 +121,10 @@ config MSM_SMD
|
|||
bool
|
||||
|
||||
config MSM_GPIOMUX
|
||||
bool
|
||||
|
||||
config MSM_V2_TLMM
|
||||
bool
|
||||
depends on !(ARCH_MSM8X60 || ARCH_MSM8960)
|
||||
bool "MSM V1 TLMM GPIOMUX architecture"
|
||||
help
|
||||
Support for MSM V1 TLMM GPIOMUX architecture.
|
||||
|
||||
config MSM_SCM
|
||||
bool
|
||||
|
|
|
@ -27,7 +27,5 @@ obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
|
|||
obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
|
||||
obj-$(CONFIG_ARCH_MSM8X60) += board-dt-8660.o
|
||||
obj-$(CONFIG_ARCH_MSM8960) += board-dt-8960.o
|
||||
|
||||
obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-v1.o gpiomux.o
|
||||
obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
|
||||
obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
|
||||
obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
|
||||
obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
|
@ -44,7 +43,6 @@ static const char *msm8x60_fluid_match[] __initdata = {
|
|||
DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
|
||||
.smp = smp_ops(msm_smp_ops),
|
||||
.map_io = msm_map_msm8x60_io,
|
||||
.init_irq = irqchip_init,
|
||||
.init_machine = msm8x60_dt_init,
|
||||
.init_late = msm8x60_init_late,
|
||||
.init_time = msm_dt_timer_init,
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
@ -31,7 +30,6 @@ static const char * const msm8960_dt_match[] __initconst = {
|
|||
DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)")
|
||||
.smp = smp_ops(msm_smp_ops),
|
||||
.map_io = msm_map_msm8960_io,
|
||||
.init_irq = irqchip_init,
|
||||
.init_time = msm_dt_timer_init,
|
||||
.init_machine = msm_dt_init,
|
||||
.dt_compat = msm8960_dt_match,
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
extern struct smp_operations msm_smp_ops;
|
||||
extern void msm_cpu_die(unsigned int cpu);
|
|
@ -1,19 +0,0 @@
|
|||
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
#include "gpiomux.h"
|
||||
|
||||
struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {};
|
|
@ -1,25 +0,0 @@
|
|||
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
#include <linux/io.h>
|
||||
#include <mach/msm_iomap.h>
|
||||
#include "gpiomux.h"
|
||||
|
||||
void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
|
||||
{
|
||||
writel(val & ~GPIOMUX_CTL_MASK,
|
||||
MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
|
||||
#define __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
|
||||
|
||||
#define GPIOMUX_NGPIOS 173
|
||||
|
||||
typedef u16 gpiomux_config_t;
|
||||
|
||||
enum {
|
||||
GPIOMUX_DRV_2MA = 0UL << 6,
|
||||
GPIOMUX_DRV_4MA = 1UL << 6,
|
||||
GPIOMUX_DRV_6MA = 2UL << 6,
|
||||
GPIOMUX_DRV_8MA = 3UL << 6,
|
||||
GPIOMUX_DRV_10MA = 4UL << 6,
|
||||
GPIOMUX_DRV_12MA = 5UL << 6,
|
||||
GPIOMUX_DRV_14MA = 6UL << 6,
|
||||
GPIOMUX_DRV_16MA = 7UL << 6,
|
||||
};
|
||||
|
||||
enum {
|
||||
GPIOMUX_FUNC_GPIO = 0UL << 2,
|
||||
GPIOMUX_FUNC_1 = 1UL << 2,
|
||||
GPIOMUX_FUNC_2 = 2UL << 2,
|
||||
GPIOMUX_FUNC_3 = 3UL << 2,
|
||||
GPIOMUX_FUNC_4 = 4UL << 2,
|
||||
GPIOMUX_FUNC_5 = 5UL << 2,
|
||||
GPIOMUX_FUNC_6 = 6UL << 2,
|
||||
GPIOMUX_FUNC_7 = 7UL << 2,
|
||||
GPIOMUX_FUNC_8 = 8UL << 2,
|
||||
GPIOMUX_FUNC_9 = 9UL << 2,
|
||||
GPIOMUX_FUNC_A = 10UL << 2,
|
||||
GPIOMUX_FUNC_B = 11UL << 2,
|
||||
GPIOMUX_FUNC_C = 12UL << 2,
|
||||
GPIOMUX_FUNC_D = 13UL << 2,
|
||||
GPIOMUX_FUNC_E = 14UL << 2,
|
||||
GPIOMUX_FUNC_F = 15UL << 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
GPIOMUX_PULL_NONE = 0UL,
|
||||
GPIOMUX_PULL_DOWN = 1UL,
|
||||
GPIOMUX_PULL_KEEPER = 2UL,
|
||||
GPIOMUX_PULL_UP = 3UL,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -17,9 +17,24 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include "gpiomux.h"
|
||||
#include "proc_comm.h"
|
||||
|
||||
static DEFINE_SPINLOCK(gpiomux_lock);
|
||||
|
||||
static void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
|
||||
{
|
||||
unsigned tlmm_config = (val & ~GPIOMUX_CTL_MASK) |
|
||||
((gpio & 0x3ff) << 4);
|
||||
unsigned tlmm_disable = 0;
|
||||
int rc;
|
||||
|
||||
rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
|
||||
&tlmm_config, &tlmm_disable);
|
||||
if (rc)
|
||||
pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n",
|
||||
__func__, rc, tlmm_config, tlmm_disable);
|
||||
}
|
||||
|
||||
int msm_gpiomux_write(unsigned gpio,
|
||||
gpiomux_config_t active,
|
||||
gpiomux_config_t suspended)
|
||||
|
|
|
@ -20,12 +20,7 @@
|
|||
#include <linux/bitops.h>
|
||||
#include <linux/errno.h>
|
||||
#include <mach/msm_gpiomux.h>
|
||||
|
||||
#if defined(CONFIG_MSM_V2_TLMM)
|
||||
#include "gpiomux-v2.h"
|
||||
#else
|
||||
#include "gpiomux-v1.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct msm_gpiomux_config: gpiomux settings for one gpio line.
|
||||
|
|
|
@ -32,13 +32,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#define MSM8960_QGIC_DIST_PHYS 0x02000000
|
||||
#define MSM8960_QGIC_DIST_SIZE SZ_4K
|
||||
|
||||
#define MSM8960_QGIC_CPU_PHYS 0x02002000
|
||||
#define MSM8960_QGIC_CPU_SIZE SZ_4K
|
||||
|
||||
#define MSM8960_TMR_PHYS 0x0200A000
|
||||
#define MSM8960_TMR_SIZE SZ_4K
|
||||
|
||||
|
|
|
@ -35,12 +35,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define MSM8X60_QGIC_DIST_PHYS 0x02080000
|
||||
#define MSM8X60_QGIC_DIST_SIZE SZ_4K
|
||||
|
||||
#define MSM8X60_QGIC_CPU_PHYS 0x02081000
|
||||
#define MSM8X60_QGIC_CPU_SIZE SZ_4K
|
||||
|
||||
#define MSM_TLMM_BASE IOMEM(0xF0004000)
|
||||
#define MSM_TLMM_PHYS 0x00800000
|
||||
#define MSM_TLMM_SIZE SZ_16K
|
||||
|
|
|
@ -62,8 +62,6 @@
|
|||
|
||||
/* Virtual addresses shared across all MSM targets. */
|
||||
#define MSM_CSR_BASE IOMEM(0xE0001000)
|
||||
#define MSM_QGIC_DIST_BASE IOMEM(0xF0000000)
|
||||
#define MSM_QGIC_CPU_BASE IOMEM(0xF0001000)
|
||||
#define MSM_TMR_BASE IOMEM(0xF0200000)
|
||||
#define MSM_TMR0_BASE IOMEM(0xF0201000)
|
||||
#define MSM_GPIO1_BASE IOMEM(0xE0003000)
|
||||
|
|
|
@ -107,8 +107,6 @@ void __init msm_map_qsd8x50_io(void)
|
|||
|
||||
#ifdef CONFIG_ARCH_MSM8X60
|
||||
static struct map_desc msm8x60_io_desc[] __initdata = {
|
||||
MSM_CHIP_DEVICE(QGIC_DIST, MSM8X60),
|
||||
MSM_CHIP_DEVICE(QGIC_CPU, MSM8X60),
|
||||
MSM_CHIP_DEVICE(TMR, MSM8X60),
|
||||
MSM_CHIP_DEVICE(TMR0, MSM8X60),
|
||||
#ifdef CONFIG_DEBUG_MSM8660_UART
|
||||
|
@ -124,8 +122,6 @@ void __init msm_map_msm8x60_io(void)
|
|||
|
||||
#ifdef CONFIG_ARCH_MSM8960
|
||||
static struct map_desc msm8960_io_desc[] __initdata = {
|
||||
MSM_CHIP_DEVICE(QGIC_DIST, MSM8960),
|
||||
MSM_CHIP_DEVICE(QGIC_CPU, MSM8960),
|
||||
MSM_CHIP_DEVICE(TMR, MSM8960),
|
||||
MSM_CHIP_DEVICE(TMR0, MSM8960),
|
||||
#ifdef CONFIG_DEBUG_MSM8960_UART
|
||||
|
|
|
@ -165,7 +165,7 @@ config GPIO_MSM_V1
|
|||
|
||||
config GPIO_MSM_V2
|
||||
tristate "Qualcomm MSM GPIO v2"
|
||||
depends on GPIOLIB && ARCH_MSM
|
||||
depends on GPIOLIB && OF && ARCH_MSM
|
||||
help
|
||||
Say yes here to support the GPIO interface on ARM v7 based
|
||||
Qualcomm MSM chips. Most of the pins on the MSM can be
|
||||
|
|
|
@ -19,18 +19,21 @@
|
|||
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <mach/msm_gpiomux.h>
|
||||
#include <mach/msm_iomap.h>
|
||||
#define MAX_NR_GPIO 300
|
||||
|
||||
/* Bits of interest in the GPIO_IN_OUT register.
|
||||
*/
|
||||
|
@ -77,13 +80,6 @@ enum {
|
|||
TARGET_PROC_NONE = 7,
|
||||
};
|
||||
|
||||
|
||||
#define GPIO_INTR_CFG_SU(gpio) (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio)))
|
||||
#define GPIO_CONFIG(gpio) (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio)))
|
||||
#define GPIO_IN_OUT(gpio) (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio)))
|
||||
#define GPIO_INTR_CFG(gpio) (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio)))
|
||||
#define GPIO_INTR_STATUS(gpio) (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio)))
|
||||
|
||||
/**
|
||||
* struct msm_gpio_dev: the MSM8660 SoC GPIO device structure
|
||||
*
|
||||
|
@ -102,11 +98,27 @@ enum {
|
|||
*/
|
||||
struct msm_gpio_dev {
|
||||
struct gpio_chip gpio_chip;
|
||||
DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS);
|
||||
DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS);
|
||||
DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS);
|
||||
DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
|
||||
DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
|
||||
DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
|
||||
struct irq_domain *domain;
|
||||
unsigned int summary_irq;
|
||||
void __iomem *msm_tlmm_base;
|
||||
};
|
||||
|
||||
struct msm_gpio_dev msm_gpio;
|
||||
|
||||
#define GPIO_INTR_CFG_SU(gpio) (msm_gpio.msm_tlmm_base + 0x0400 + \
|
||||
(0x04 * (gpio)))
|
||||
#define GPIO_CONFIG(gpio) (msm_gpio.msm_tlmm_base + 0x1000 + \
|
||||
(0x10 * (gpio)))
|
||||
#define GPIO_IN_OUT(gpio) (msm_gpio.msm_tlmm_base + 0x1004 + \
|
||||
(0x10 * (gpio)))
|
||||
#define GPIO_INTR_CFG(gpio) (msm_gpio.msm_tlmm_base + 0x1008 + \
|
||||
(0x10 * (gpio)))
|
||||
#define GPIO_INTR_STATUS(gpio) (msm_gpio.msm_tlmm_base + 0x100c + \
|
||||
(0x10 * (gpio)))
|
||||
|
||||
static DEFINE_SPINLOCK(tlmm_lock);
|
||||
|
||||
static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
|
||||
|
@ -159,37 +171,29 @@ static int msm_gpio_direction_output(struct gpio_chip *chip,
|
|||
|
||||
static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return msm_gpiomux_get(chip->base + offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
msm_gpiomux_put(chip->base + offset);
|
||||
return;
|
||||
}
|
||||
|
||||
static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return MSM_GPIO_TO_INT(chip->base + offset);
|
||||
struct msm_gpio_dev *g_dev = to_msm_gpio_dev(chip);
|
||||
struct irq_domain *domain = g_dev->domain;
|
||||
|
||||
return irq_create_mapping(domain, offset);
|
||||
}
|
||||
|
||||
static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq)
|
||||
{
|
||||
return irq - MSM_GPIO_TO_INT(chip->base);
|
||||
struct irq_data *irq_data = irq_get_irq_data(irq);
|
||||
|
||||
return irq_data->hwirq;
|
||||
}
|
||||
|
||||
static struct msm_gpio_dev msm_gpio = {
|
||||
.gpio_chip = {
|
||||
.base = 0,
|
||||
.ngpio = NR_GPIO_IRQS,
|
||||
.direction_input = msm_gpio_direction_input,
|
||||
.direction_output = msm_gpio_direction_output,
|
||||
.get = msm_gpio_get,
|
||||
.set = msm_gpio_set,
|
||||
.to_irq = msm_gpio_to_irq,
|
||||
.request = msm_gpio_request,
|
||||
.free = msm_gpio_free,
|
||||
},
|
||||
};
|
||||
|
||||
/* For dual-edge interrupts in software, since the hardware has no
|
||||
* such support:
|
||||
|
@ -227,9 +231,9 @@ static void msm_gpio_update_dual_edge_pos(unsigned gpio)
|
|||
if (intstat || val == val2)
|
||||
return;
|
||||
} while (loop_limit-- > 0);
|
||||
pr_err("dual-edge irq failed to stabilize, "
|
||||
pr_err("%s: dual-edge irq failed to stabilize, "
|
||||
"interrupts dropped. %#08x != %#08x\n",
|
||||
val, val2);
|
||||
__func__, val, val2);
|
||||
}
|
||||
|
||||
static void msm_gpio_irq_ack(struct irq_data *d)
|
||||
|
@ -316,10 +320,10 @@ static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
for_each_set_bit(i, msm_gpio.enabled_irqs, NR_GPIO_IRQS) {
|
||||
for_each_set_bit(i, msm_gpio.enabled_irqs, MAX_NR_GPIO) {
|
||||
if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS))
|
||||
generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
|
||||
i));
|
||||
generic_handle_irq(irq_find_mapping(msm_gpio.domain,
|
||||
i));
|
||||
}
|
||||
|
||||
chained_irq_exit(chip, desc);
|
||||
|
@ -330,13 +334,13 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
|
|||
int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
|
||||
|
||||
if (on) {
|
||||
if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
|
||||
irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
|
||||
if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
|
||||
irq_set_irq_wake(msm_gpio.summary_irq, 1);
|
||||
set_bit(gpio, msm_gpio.wake_irqs);
|
||||
} else {
|
||||
clear_bit(gpio, msm_gpio.wake_irqs);
|
||||
if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
|
||||
irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
|
||||
if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
|
||||
irq_set_irq_wake(msm_gpio.summary_irq, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -351,30 +355,86 @@ static struct irq_chip msm_gpio_irq_chip = {
|
|||
.irq_set_wake = msm_gpio_irq_set_wake,
|
||||
};
|
||||
|
||||
static int msm_gpio_probe(struct platform_device *dev)
|
||||
static struct lock_class_key msm_gpio_lock_class;
|
||||
|
||||
static int msm_gpio_irq_domain_map(struct irq_domain *d, unsigned int irq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
int i, irq, ret;
|
||||
irq_set_lockdep_class(irq, &msm_gpio_lock_class);
|
||||
irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
|
||||
bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS);
|
||||
bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS);
|
||||
msm_gpio.gpio_chip.label = dev->name;
|
||||
ret = gpiochip_add(&msm_gpio.gpio_chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
|
||||
irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
|
||||
irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
}
|
||||
|
||||
irq_set_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
|
||||
msm_summary_irq_handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops msm_gpio_irq_domain_ops = {
|
||||
.xlate = irq_domain_xlate_twocell,
|
||||
.map = msm_gpio_irq_domain_map,
|
||||
};
|
||||
|
||||
static int msm_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret, ngpio;
|
||||
struct resource *res;
|
||||
|
||||
if (!of_property_read_u32(pdev->dev.of_node, "ngpio", &ngpio)) {
|
||||
dev_err(&pdev->dev, "%s: ngpio property missing\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ngpio > MAX_NR_GPIO)
|
||||
WARN(1, "ngpio exceeds the MAX_NR_GPIO. Increase MAX_NR_GPIO\n");
|
||||
|
||||
bitmap_zero(msm_gpio.enabled_irqs, MAX_NR_GPIO);
|
||||
bitmap_zero(msm_gpio.wake_irqs, MAX_NR_GPIO);
|
||||
bitmap_zero(msm_gpio.dual_edge_irqs, MAX_NR_GPIO);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
msm_gpio.msm_tlmm_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(msm_gpio.msm_tlmm_base))
|
||||
return PTR_ERR(msm_gpio.msm_tlmm_base);
|
||||
|
||||
msm_gpio.gpio_chip.ngpio = ngpio;
|
||||
msm_gpio.gpio_chip.label = pdev->name;
|
||||
msm_gpio.gpio_chip.dev = &pdev->dev;
|
||||
msm_gpio.gpio_chip.base = 0;
|
||||
msm_gpio.gpio_chip.direction_input = msm_gpio_direction_input;
|
||||
msm_gpio.gpio_chip.direction_output = msm_gpio_direction_output;
|
||||
msm_gpio.gpio_chip.get = msm_gpio_get;
|
||||
msm_gpio.gpio_chip.set = msm_gpio_set;
|
||||
msm_gpio.gpio_chip.to_irq = msm_gpio_to_irq;
|
||||
msm_gpio.gpio_chip.request = msm_gpio_request;
|
||||
msm_gpio.gpio_chip.free = msm_gpio_free;
|
||||
|
||||
ret = gpiochip_add(&msm_gpio.gpio_chip);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "gpiochip_add failed with error %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
msm_gpio.summary_irq = platform_get_irq(pdev, 0);
|
||||
if (msm_gpio.summary_irq < 0) {
|
||||
dev_err(&pdev->dev, "No Summary irq defined for msmgpio\n");
|
||||
return msm_gpio.summary_irq;
|
||||
}
|
||||
|
||||
msm_gpio.domain = irq_domain_add_linear(pdev->dev.of_node, ngpio,
|
||||
&msm_gpio_irq_domain_ops,
|
||||
&msm_gpio);
|
||||
if (!msm_gpio.domain)
|
||||
return -ENODEV;
|
||||
|
||||
irq_set_chained_handler(msm_gpio.summary_irq, msm_summary_irq_handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id msm_gpio_of_match[] = {
|
||||
{ .compatible = "qcom,msm-gpio", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int msm_gpio_remove(struct platform_device *dev)
|
||||
{
|
||||
int ret = gpiochip_remove(&msm_gpio.gpio_chip);
|
||||
|
@ -382,7 +442,7 @@ static int msm_gpio_remove(struct platform_device *dev)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
irq_set_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
|
||||
irq_set_handler(msm_gpio.summary_irq, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -393,36 +453,11 @@ static struct platform_driver msm_gpio_driver = {
|
|||
.driver = {
|
||||
.name = "msmgpio",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = msm_gpio_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device msm_device_gpio = {
|
||||
.name = "msmgpio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static int __init msm_gpio_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = platform_driver_register(&msm_gpio_driver);
|
||||
if (!rc) {
|
||||
rc = platform_device_register(&msm_device_gpio);
|
||||
if (rc)
|
||||
platform_driver_unregister(&msm_gpio_driver);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __exit msm_gpio_exit(void)
|
||||
{
|
||||
platform_device_unregister(&msm_device_gpio);
|
||||
platform_driver_unregister(&msm_gpio_driver);
|
||||
}
|
||||
|
||||
postcore_initcall(msm_gpio_init);
|
||||
module_exit(msm_gpio_exit);
|
||||
module_platform_driver(msm_gpio_driver)
|
||||
|
||||
MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
|
||||
MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs");
|
||||
|
|
|
@ -268,35 +268,23 @@ static int ssbi_probe(struct platform_device *pdev)
|
|||
struct device_node *np = pdev->dev.of_node;
|
||||
struct resource *mem_res;
|
||||
struct ssbi *ssbi;
|
||||
int ret = 0;
|
||||
const char *type;
|
||||
|
||||
ssbi = kzalloc(sizeof(struct ssbi), GFP_KERNEL);
|
||||
if (!ssbi) {
|
||||
pr_err("can not allocate ssbi_data\n");
|
||||
ssbi = devm_kzalloc(&pdev->dev, sizeof(*ssbi), GFP_KERNEL);
|
||||
if (!ssbi)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!mem_res) {
|
||||
pr_err("missing mem resource\n");
|
||||
ret = -EINVAL;
|
||||
goto err_get_mem_res;
|
||||
}
|
||||
ssbi->base = devm_ioremap_resource(&pdev->dev, mem_res);
|
||||
if (IS_ERR(ssbi->base))
|
||||
return PTR_ERR(ssbi->base);
|
||||
|
||||
ssbi->base = ioremap(mem_res->start, resource_size(mem_res));
|
||||
if (!ssbi->base) {
|
||||
pr_err("ioremap of 0x%p failed\n", (void *)mem_res->start);
|
||||
ret = -EINVAL;
|
||||
goto err_ioremap;
|
||||
}
|
||||
platform_set_drvdata(pdev, ssbi);
|
||||
|
||||
type = of_get_property(np, "qcom,controller-type", NULL);
|
||||
if (type == NULL) {
|
||||
pr_err("Missing qcom,controller-type property\n");
|
||||
ret = -EINVAL;
|
||||
goto err_ssbi_controller;
|
||||
dev_err(&pdev->dev, "Missing qcom,controller-type property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type);
|
||||
if (strcmp(type, "ssbi") == 0)
|
||||
|
@ -306,9 +294,8 @@ static int ssbi_probe(struct platform_device *pdev)
|
|||
else if (strcmp(type, "pmic-arbiter") == 0)
|
||||
ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER;
|
||||
else {
|
||||
pr_err("Unknown qcom,controller-type\n");
|
||||
ret = -EINVAL;
|
||||
goto err_ssbi_controller;
|
||||
dev_err(&pdev->dev, "Unknown qcom,controller-type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
|
||||
|
@ -321,29 +308,7 @@ static int ssbi_probe(struct platform_device *pdev)
|
|||
|
||||
spin_lock_init(&ssbi->lock);
|
||||
|
||||
ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
|
||||
if (ret)
|
||||
goto err_ssbi_controller;
|
||||
|
||||
return 0;
|
||||
|
||||
err_ssbi_controller:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
iounmap(ssbi->base);
|
||||
err_ioremap:
|
||||
err_get_mem_res:
|
||||
kfree(ssbi);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ssbi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ssbi *ssbi = platform_get_drvdata(pdev);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
iounmap(ssbi->base);
|
||||
kfree(ssbi);
|
||||
return 0;
|
||||
return of_platform_populate(np, NULL, NULL, &pdev->dev);
|
||||
}
|
||||
|
||||
static struct of_device_id ssbi_match_table[] = {
|
||||
|
@ -354,25 +319,13 @@ MODULE_DEVICE_TABLE(of, ssbi_match_table);
|
|||
|
||||
static struct platform_driver ssbi_driver = {
|
||||
.probe = ssbi_probe,
|
||||
.remove = ssbi_remove,
|
||||
.driver = {
|
||||
.name = "ssbi",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ssbi_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ssbi_init(void)
|
||||
{
|
||||
return platform_driver_register(&ssbi_driver);
|
||||
}
|
||||
module_init(ssbi_init);
|
||||
|
||||
static void __exit ssbi_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ssbi_driver);
|
||||
}
|
||||
module_exit(ssbi_exit)
|
||||
module_platform_driver(ssbi_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_VERSION("1.0");
|
||||
|
|
Загрузка…
Ссылка в новой задаче