diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 321040eb223..400f859e49e 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -75,7 +75,7 @@ target += smd_rpc_sym.c $(obj)/smd_rpc_sym.c: $(src)/smd_rpc_sym $(src)/mkrpcsym.pl $(call if_changed,mkrpcsym) -obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o remote_spinlock.o smd_private.o +obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o remote_spinlock.o smd_private.o smem.o obj-$(CONFIG_MSM_SMP2P) += smp2p.o smp2p_debug.o smp2p_gpio.o obj-$(CONFIG_MSM_SMP2P_TEST) += smp2p_loopback.o smp2p_test.o smp2p_gpio_test.o smp2p_spinlock_test.o obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c index d2be1f9ddd6..8d99ad1d339 100644 --- a/arch/arm/mach-msm/clock-pll.c +++ b/arch/arm/mach-msm/clock-pll.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013, The Linux Foundation. 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 @@ -19,10 +19,10 @@ #include #include +#include #include "clock.h" #include "clock-pll.h" -#include "smd_private.h" #ifdef CONFIG_MSM_SECURE_IO #undef readl_relaxed diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h index d155c6fdb75..2cc7b1094c8 100644 --- a/arch/arm/mach-msm/include/mach/msm_smd.h +++ b/arch/arm/mach-msm/include/mach/msm_smd.h @@ -19,7 +19,9 @@ #define __ASM_ARCH_MSM_SMD_H #include -#include +#include + +#include typedef struct smd_channel smd_channel_t; @@ -40,13 +42,13 @@ typedef struct smd_channel smd_channel_t; * SMD, the entry will only exist in this enum. */ enum { - SMD_APPS = SMSM_APPS, - SMD_MODEM = SMSM_MODEM, - SMD_Q6 = SMSM_Q6, - SMD_WCNSS = SMSM_WCNSS, - SMD_DSPS = SMSM_DSPS, - SMD_MODEM_Q6_FW, - SMD_RPM, + SMD_APPS = SMEM_APPS, + SMD_MODEM = SMEM_MODEM, + SMD_Q6 = SMEM_Q6, + SMD_DSPS = SMEM_DSPS, + SMD_WCNSS = SMEM_WCNSS, + SMD_MODEM_Q6_FW = SMEM_MODEM_Q6_FW, + SMD_RPM = SMEM_RPM, NUM_SMD_SUBSYSTEMS, }; diff --git a/arch/arm/mach-msm/include/mach/msm_smem.h b/arch/arm/mach-msm/include/mach/msm_smem.h new file mode 100644 index 00000000000..57f22cc1ab7 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_smem.h @@ -0,0 +1,180 @@ +/* Copyright (c) 2013, The Linux Foundation. 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. + */ + +#ifndef _ARCH_ARM_MACH_MSM_SMEM_H_ +#define _ARCH_ARM_MACH_MSM_SMEM_H_ + +#include + +enum { + SMEM_APPS, + SMEM_MODEM, + SMEM_Q6, + SMEM_DSPS, + SMEM_WCNSS, + SMEM_MODEM_Q6_FW, + SMEM_RPM, + NUM_SMEM_SUBSYSTEMS, +}; + +#define SMEM_NUM_SMD_STREAM_CHANNELS 64 +#define SMEM_NUM_SMD_BLOCK_CHANNELS 64 + +enum { + /* fixed items */ + SMEM_PROC_COMM = 0, + SMEM_HEAP_INFO, + SMEM_ALLOCATION_TABLE, + SMEM_VERSION_INFO, + SMEM_HW_RESET_DETECT, + SMEM_AARM_WARM_BOOT, + SMEM_DIAG_ERR_MESSAGE, + SMEM_SPINLOCK_ARRAY, + SMEM_MEMORY_BARRIER_LOCATION, + SMEM_FIXED_ITEM_LAST = SMEM_MEMORY_BARRIER_LOCATION, + + /* dynamic items */ + SMEM_AARM_PARTITION_TABLE, + SMEM_AARM_BAD_BLOCK_TABLE, + SMEM_RESERVE_BAD_BLOCKS, + SMEM_WM_UUID, + SMEM_CHANNEL_ALLOC_TBL, + SMEM_SMD_BASE_ID, + SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_STREAM_CHANNELS, + SMEM_SMEM_LOG_EVENTS, + SMEM_SMEM_STATIC_LOG_IDX, + SMEM_SMEM_STATIC_LOG_EVENTS, + SMEM_SMEM_SLOW_CLOCK_SYNC, + SMEM_SMEM_SLOW_CLOCK_VALUE, + SMEM_BIO_LED_BUF, + SMEM_SMSM_SHARED_STATE, + SMEM_SMSM_INT_INFO, + SMEM_SMSM_SLEEP_DELAY, + SMEM_SMSM_LIMIT_SLEEP, + SMEM_SLEEP_POWER_COLLAPSE_DISABLED, + SMEM_KEYPAD_KEYS_PRESSED, + SMEM_KEYPAD_STATE_UPDATED, + SMEM_KEYPAD_STATE_IDX, + SMEM_GPIO_INT, + SMEM_MDDI_LCD_IDX, + SMEM_MDDI_HOST_DRIVER_STATE, + SMEM_MDDI_LCD_DISP_STATE, + SMEM_LCD_CUR_PANEL, + SMEM_MARM_BOOT_SEGMENT_INFO, + SMEM_AARM_BOOT_SEGMENT_INFO, + SMEM_SLEEP_STATIC, + SMEM_SCORPION_FREQUENCY, + SMEM_SMD_PROFILES, + SMEM_TSSC_BUSY, + SMEM_HS_SUSPEND_FILTER_INFO, + SMEM_BATT_INFO, + SMEM_APPS_BOOT_MODE, + SMEM_VERSION_FIRST, + SMEM_VERSION_SMD = SMEM_VERSION_FIRST, + SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24, + SMEM_OSS_RRCASN1_BUF1, + SMEM_OSS_RRCASN1_BUF2, + SMEM_ID_VENDOR0, + SMEM_ID_VENDOR1, + SMEM_ID_VENDOR2, + SMEM_HW_SW_BUILD_ID, + SMEM_SMD_BLOCK_PORT_BASE_ID, + SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID + + SMEM_NUM_SMD_BLOCK_CHANNELS, + SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP + + SMEM_NUM_SMD_BLOCK_CHANNELS, + SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP + + SMEM_NUM_SMD_BLOCK_CHANNELS, + SMEM_SCLK_CONVERSION, + SMEM_SMD_SMSM_INTR_MUX, + SMEM_SMSM_CPU_INTR_MASK, + SMEM_APPS_DEM_SLAVE_DATA, + SMEM_QDSP6_DEM_SLAVE_DATA, + SMEM_CLKREGIM_BSP, + SMEM_CLKREGIM_SOURCES, + SMEM_SMD_FIFO_BASE_ID, + SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID + + SMEM_NUM_SMD_STREAM_CHANNELS, + SMEM_POWER_ON_STATUS_INFO, + SMEM_DAL_AREA, + SMEM_SMEM_LOG_POWER_IDX, + SMEM_SMEM_LOG_POWER_WRAP, + SMEM_SMEM_LOG_POWER_EVENTS, + SMEM_ERR_CRASH_LOG, + SMEM_ERR_F3_TRACE_LOG, + SMEM_SMD_BRIDGE_ALLOC_TABLE, + SMEM_SMDLITE_TABLE, + SMEM_SD_IMG_UPGRADE_STATUS, + SMEM_SEFS_INFO, + SMEM_RESET_LOG, + SMEM_RESET_LOG_SYMBOLS, + SMEM_MODEM_SW_BUILD_ID, + SMEM_SMEM_LOG_MPROC_WRAP, + SMEM_BOOT_INFO_FOR_APPS, + SMEM_SMSM_SIZE_INFO, + SMEM_SMD_LOOPBACK_REGISTER, + SMEM_SSR_REASON_MSS0, + SMEM_SSR_REASON_WCNSS0, + SMEM_SSR_REASON_LPASS0, + SMEM_SSR_REASON_DSPS0, + SMEM_SSR_REASON_VCODEC0, + SMEM_SMP2P_APPS_BASE = 427, + SMEM_SMP2P_MODEM_BASE = SMEM_SMP2P_APPS_BASE + 8, /* 435 */ + SMEM_SMP2P_AUDIO_BASE = SMEM_SMP2P_MODEM_BASE + 8, /* 443 */ + SMEM_SMP2P_WIRLESS_BASE = SMEM_SMP2P_AUDIO_BASE + 8, /* 451 */ + SMEM_SMP2P_POWER_BASE = SMEM_SMP2P_WIRLESS_BASE + 8, /* 459 */ + SMEM_FLASH_DEVICE_INFO = SMEM_SMP2P_POWER_BASE + 8, /* 467 */ + SMEM_BAM_PIPE_MEMORY, /* 468 */ + SMEM_IMAGE_VERSION_TABLE, /* 469 */ + SMEM_LC_DEBUGGER, /* 470 */ + SMEM_NUM_ITEMS, +}; + +#ifdef CONFIG_MSM_SMD +void *smem_alloc(unsigned id, unsigned size); +void *smem_alloc2(unsigned id, unsigned size_in); +void *smem_get_entry(unsigned id, unsigned *size); +void *smem_find(unsigned id, unsigned size); +/** + * smem_virt_to_phys() - Convert SMEM address to physical address. + * + * @smem_address: Virtual address returned by smem_alloc()/smem_alloc2() + * @returns: Physical address (or NULL if there is a failure) + * + * This function should only be used if an SMEM item needs to be handed + * off to a DMA engine. + */ +phys_addr_t smem_virt_to_phys(void *smem_address); + +#else +static inline void *smem_alloc(unsigned id, unsigned size) +{ + return NULL; +} +static inline void *smem_alloc2(unsigned id, unsigned size_in) +{ + return NULL; +} +static inline void *smem_get_entry(unsigned id, unsigned *size) +{ + return NULL; +} +static inline void *smem_find(unsigned id, unsigned size) +{ + return NULL; +} +static inline phys_addr_t smem_virt_to_phys(void *smem_address) +{ + return (phys_addr_t) NULL; +} +#endif /* CONFIG_MSM_SMD */ +#endif /* _ARCH_ARM_MACH_MSM_SMEM_H_ */ diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h index 5173c1247f6..733f5a9eea3 100644 --- a/arch/arm/mach-msm/include/mach/msm_smsm.h +++ b/arch/arm/mach-msm/include/mach/msm_smsm.h @@ -14,6 +14,9 @@ #define _ARCH_ARM_MACH_MSM_SMSM_H_ #include + +#include + #if defined(CONFIG_MSM_N_WAY_SMSM) enum { SMSM_APPS_STATE, @@ -37,11 +40,11 @@ enum { #endif enum { - SMSM_APPS, - SMSM_MODEM, - SMSM_Q6, - SMSM_WCNSS, - SMSM_DSPS, + SMSM_APPS = SMEM_APPS, + SMSM_MODEM = SMEM_MODEM, + SMSM_Q6 = SMEM_Q6, + SMSM_DSPS = SMEM_DSPS, + SMSM_WCNSS = SMEM_WCNSS, }; extern uint32_t SMSM_NUM_HOSTS; @@ -97,119 +100,6 @@ extern uint32_t SMSM_NUM_HOSTS; #define SMSM_SUBSYS2AP_STATUS 0x00008000 -#define SMEM_NUM_SMD_STREAM_CHANNELS 64 -#define SMEM_NUM_SMD_BLOCK_CHANNELS 64 - -enum { - /* fixed items */ - SMEM_PROC_COMM = 0, - SMEM_HEAP_INFO, - SMEM_ALLOCATION_TABLE, - SMEM_VERSION_INFO, - SMEM_HW_RESET_DETECT, - SMEM_AARM_WARM_BOOT, - SMEM_DIAG_ERR_MESSAGE, - SMEM_SPINLOCK_ARRAY, - SMEM_MEMORY_BARRIER_LOCATION, - SMEM_FIXED_ITEM_LAST = SMEM_MEMORY_BARRIER_LOCATION, - - /* dynamic items */ - SMEM_AARM_PARTITION_TABLE, - SMEM_AARM_BAD_BLOCK_TABLE, - SMEM_RESERVE_BAD_BLOCKS, - SMEM_WM_UUID, - SMEM_CHANNEL_ALLOC_TBL, - SMEM_SMD_BASE_ID, - SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_STREAM_CHANNELS, - SMEM_SMEM_LOG_EVENTS, - SMEM_SMEM_STATIC_LOG_IDX, - SMEM_SMEM_STATIC_LOG_EVENTS, - SMEM_SMEM_SLOW_CLOCK_SYNC, - SMEM_SMEM_SLOW_CLOCK_VALUE, - SMEM_BIO_LED_BUF, - SMEM_SMSM_SHARED_STATE, - SMEM_SMSM_INT_INFO, - SMEM_SMSM_SLEEP_DELAY, - SMEM_SMSM_LIMIT_SLEEP, - SMEM_SLEEP_POWER_COLLAPSE_DISABLED, - SMEM_KEYPAD_KEYS_PRESSED, - SMEM_KEYPAD_STATE_UPDATED, - SMEM_KEYPAD_STATE_IDX, - SMEM_GPIO_INT, - SMEM_MDDI_LCD_IDX, - SMEM_MDDI_HOST_DRIVER_STATE, - SMEM_MDDI_LCD_DISP_STATE, - SMEM_LCD_CUR_PANEL, - SMEM_MARM_BOOT_SEGMENT_INFO, - SMEM_AARM_BOOT_SEGMENT_INFO, - SMEM_SLEEP_STATIC, - SMEM_SCORPION_FREQUENCY, - SMEM_SMD_PROFILES, - SMEM_TSSC_BUSY, - SMEM_HS_SUSPEND_FILTER_INFO, - SMEM_BATT_INFO, - SMEM_APPS_BOOT_MODE, - SMEM_VERSION_FIRST, - SMEM_VERSION_SMD = SMEM_VERSION_FIRST, - SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24, - SMEM_OSS_RRCASN1_BUF1, - SMEM_OSS_RRCASN1_BUF2, - SMEM_ID_VENDOR0, - SMEM_ID_VENDOR1, - SMEM_ID_VENDOR2, - SMEM_HW_SW_BUILD_ID, - SMEM_SMD_BLOCK_PORT_BASE_ID, - SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID + - SMEM_NUM_SMD_BLOCK_CHANNELS, - SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP + - SMEM_NUM_SMD_BLOCK_CHANNELS, - SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP + - SMEM_NUM_SMD_BLOCK_CHANNELS, - SMEM_SCLK_CONVERSION, - SMEM_SMD_SMSM_INTR_MUX, - SMEM_SMSM_CPU_INTR_MASK, - SMEM_APPS_DEM_SLAVE_DATA, - SMEM_QDSP6_DEM_SLAVE_DATA, - SMEM_CLKREGIM_BSP, - SMEM_CLKREGIM_SOURCES, - SMEM_SMD_FIFO_BASE_ID, - SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID + - SMEM_NUM_SMD_STREAM_CHANNELS, - SMEM_POWER_ON_STATUS_INFO, - SMEM_DAL_AREA, - SMEM_SMEM_LOG_POWER_IDX, - SMEM_SMEM_LOG_POWER_WRAP, - SMEM_SMEM_LOG_POWER_EVENTS, - SMEM_ERR_CRASH_LOG, - SMEM_ERR_F3_TRACE_LOG, - SMEM_SMD_BRIDGE_ALLOC_TABLE, - SMEM_SMDLITE_TABLE, - SMEM_SD_IMG_UPGRADE_STATUS, - SMEM_SEFS_INFO, - SMEM_RESET_LOG, - SMEM_RESET_LOG_SYMBOLS, - SMEM_MODEM_SW_BUILD_ID, - SMEM_SMEM_LOG_MPROC_WRAP, - SMEM_BOOT_INFO_FOR_APPS, - SMEM_SMSM_SIZE_INFO, - SMEM_SMD_LOOPBACK_REGISTER, - SMEM_SSR_REASON_MSS0, - SMEM_SSR_REASON_WCNSS0, - SMEM_SSR_REASON_LPASS0, - SMEM_SSR_REASON_DSPS0, - SMEM_SSR_REASON_VCODEC0, - SMEM_SMP2P_APPS_BASE = 427, - SMEM_SMP2P_MODEM_BASE = SMEM_SMP2P_APPS_BASE + 8, /* 435 */ - SMEM_SMP2P_AUDIO_BASE = SMEM_SMP2P_MODEM_BASE + 8, /* 443 */ - SMEM_SMP2P_WIRLESS_BASE = SMEM_SMP2P_AUDIO_BASE + 8, /* 451 */ - SMEM_SMP2P_POWER_BASE = SMEM_SMP2P_WIRLESS_BASE + 8, /* 459 */ - SMEM_FLASH_DEVICE_INFO = SMEM_SMP2P_POWER_BASE + 8, /* 467 */ - SMEM_BAM_PIPE_MEMORY, /* 468 */ - SMEM_IMAGE_VERSION_TABLE, /* 469 */ - SMEM_LC_DEBUGGER, /* 470 */ - SMEM_NUM_ITEMS, -}; - enum { SMEM_APPS_Q6_SMSM = 3, SMEM_Q6_APPS_SMSM = 5, @@ -217,9 +107,6 @@ enum { }; #ifdef CONFIG_MSM_SMD -void *smem_alloc(unsigned id, unsigned size); -void *smem_alloc2(unsigned id, unsigned size_in); -void *smem_get_entry(unsigned id, unsigned *size); int smsm_change_state(uint32_t smsm_entry, uint32_t clear_mask, uint32_t set_mask); @@ -254,36 +141,8 @@ void smd_sleep_exit(void); int smsm_check_for_modem_crash(void); -void *smem_find(unsigned id, unsigned size); -void *smem_get_entry(unsigned id, unsigned *size); - -/** - * smem_virt_to_phys() - Convert SMEM address to physical address. - * - * @smem_address: Virtual address returned by smem_alloc()/smem_alloc2() - * @returns: Physical address (or NULL if there is a failure) - * - * This function should only be used if an SMEM item needs to be handed - * off to a DMA engine. - */ -phys_addr_t smem_virt_to_phys(void *smem_address); #else -static inline void *smem_alloc(unsigned id, unsigned size) -{ - return NULL; -} - -static inline void *smem_alloc2(unsigned id, unsigned size_in) -{ - return NULL; -} - -static inline void *smem_get_entry(unsigned id, unsigned *size) -{ - return NULL; -} - static inline int smsm_change_state(uint32_t smsm_entry, uint32_t clear_mask, uint32_t set_mask) { @@ -347,13 +206,5 @@ static inline int smsm_check_for_modem_crash(void) { return -ENODEV; } -static inline void *smem_find(unsigned id, unsigned size) -{ - return NULL; -} -static inline phys_addr_t smem_virt_to_phys(void *smem_address) -{ - return (phys_addr_t) NULL; -} #endif #endif diff --git a/arch/arm/mach-msm/memory_topology.c b/arch/arm/mach-msm/memory_topology.c index 781cd69dd69..97195e36269 100644 --- a/arch/arm/mach-msm/memory_topology.c +++ b/arch/arm/mach-msm/memory_topology.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2013, The Linux Foundation. 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 @@ -19,6 +19,7 @@ #include #include #include +#include #include "smd_private.h" #if defined(CONFIG_ARCH_MSM8960) diff --git a/arch/arm/mach-msm/msm_smem_iface.h b/arch/arm/mach-msm/msm_smem_iface.h index bc3e73b836a..c9c56d991d9 100644 --- a/arch/arm/mach-msm/msm_smem_iface.h +++ b/arch/arm/mach-msm/msm_smem_iface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013, The Linux Foundation. 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 @@ -16,6 +16,7 @@ #define __ARCH_ARM_MACH_MSM_SMEM_IFACE_H #include +#include #define MAX_KEY_EVENTS 10 #define MAX_SEC_KEY_PAYLOAD 32 diff --git a/arch/arm/mach-msm/nand_partitions.c b/arch/arm/mach-msm/nand_partitions.c index ea5fb9c622f..ad2a10ec164 100644 --- a/arch/arm/mach-msm/nand_partitions.c +++ b/arch/arm/mach-msm/nand_partitions.c @@ -4,7 +4,7 @@ * bootloader. * * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2008-2009,2011 The Linux Foundation. All rights reserved. + * Copyright (c) 2008-2009,2011,2013 The Linux Foundation. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -34,7 +34,7 @@ #include #ifdef CONFIG_MSM_SMD -#include "smd_private.h" +#include #endif /* configuration tags specific to msm */ diff --git a/arch/arm/mach-msm/pil-dsps.c b/arch/arm/mach-msm/pil-dsps.c index df5ea35585e..73b58ab28a4 100644 --- a/arch/arm/mach-msm/pil-dsps.c +++ b/arch/arm/mach-msm/pil-dsps.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "peripheral-loader.h" #include "scm-pas.h" diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c index 65f86bc30df..840c90f5759 100644 --- a/arch/arm/mach-msm/pil-gss.c +++ b/arch/arm/mach-msm/pil-gss.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "peripheral-loader.h" #include "scm-pas.h" diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c index b186a4dfaf0..30168b88fce 100644 --- a/arch/arm/mach-msm/pil-pronto.c +++ b/arch/arm/mach-msm/pil-pronto.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "peripheral-loader.h" #include "scm-pas.h" diff --git a/arch/arm/mach-msm/pil-q6v4-lpass.c b/arch/arm/mach-msm/pil-q6v4-lpass.c index f05bcdbd336..7acb59900f6 100644 --- a/arch/arm/mach-msm/pil-q6v4-lpass.c +++ b/arch/arm/mach-msm/pil-q6v4-lpass.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "smd_private.h" #include "sysmon.h" diff --git a/arch/arm/mach-msm/pil-q6v4-mss.c b/arch/arm/mach-msm/pil-q6v4-mss.c index 1821ab17852..c4b60380c07 100644 --- a/arch/arm/mach-msm/pil-q6v4-mss.c +++ b/arch/arm/mach-msm/pil-q6v4-mss.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "smd_private.h" #include "peripheral-loader.h" diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c index 6e8e79e007a..9a5883f13b1 100644 --- a/arch/arm/mach-msm/pil-q6v5-lpass.c +++ b/arch/arm/mach-msm/pil-q6v5-lpass.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "peripheral-loader.h" #include "pil-q6v5.h" diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c index 979458ed927..5ef66384a18 100644 --- a/arch/arm/mach-msm/pil-q6v5-mss.c +++ b/arch/arm/mach-msm/pil-q6v5-mss.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "peripheral-loader.h" #include "pil-q6v5.h" diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c index d72b848a3fe..5419bf08f6d 100644 --- a/arch/arm/mach-msm/pil-riva.c +++ b/arch/arm/mach-msm/pil-riva.c @@ -24,6 +24,7 @@ #include #include +#include #include "peripheral-loader.h" #include "scm-pas.h" diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c index a2da8b095f5..9f97a59d512 100644 --- a/arch/arm/mach-msm/pm2.c +++ b/arch/arm/mach-msm/pm2.c @@ -3,7 +3,7 @@ * MSM Power Management Routines * * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2008-2012 The Linux Foundation. All rights reserved. + * Copyright (c) 2008-2013 The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -44,9 +44,10 @@ #endif #include #include +#include +#include #include -#include "smd_private.h" #include "smd_rpcrouter.h" #include "acpuclock.h" #include "clock.h" diff --git a/arch/arm/mach-msm/remote_spinlock.c b/arch/arm/mach-msm/remote_spinlock.c index 62e3e05c928..a9ebd7c167d 100644 --- a/arch/arm/mach-msm/remote_spinlock.c +++ b/arch/arm/mach-msm/remote_spinlock.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "smd_private.h" diff --git a/arch/arm/mach-msm/rmt_storage_client.c b/arch/arm/mach-msm/rmt_storage_client.c index a4562e9364f..550624ce4e9 100644 --- a/arch/arm/mach-msm/rmt_storage_client.c +++ b/arch/arm/mach-msm/rmt_storage_client.c @@ -35,7 +35,7 @@ #ifdef CONFIG_MSM_SDIO_SMEM #include #endif -#include "smd_private.h" +#include enum { RMT_STORAGE_EVNT_OPEN = 0, diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 3590e6b4884..194565107b5 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -47,11 +47,13 @@ #include #include #include +#include #include #include "smd_private.h" #include "modem_notifier.h" +#include "smem_private.h" #if defined(CONFIG_ARCH_QSD8X50) || defined(CONFIG_ARCH_MSM8X60) \ || defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_FSM9XXX) \ @@ -175,16 +177,6 @@ static struct interrupt_config private_intr_config[NUM_SMD_SUBSYSTEMS] = { }, }; -struct smem_area { - phys_addr_t phys_addr; - resource_size_t size; - void __iomem *virt_addr; -}; -static uint32_t num_smem_areas; -static struct smem_area *smem_areas; -static struct ramdump_segment *smem_ramdump_segments; -static void *smem_ramdump_dev; -static void *smem_phys_to_virt(phys_addr_t base, unsigned offset); static void *smd_dev; struct interrupt_stat interrupt_stats[NUM_SMD_SUBSYSTEMS]; @@ -380,9 +372,6 @@ static inline void smd_write_intr(unsigned int val, #define SMD_LOOPBACK_CID 100 -#define SMEM_SPINLOCK_SMEM_ALLOC "S:3" -static remote_spinlock_t remote_spinlock; - static LIST_HEAD(smd_ch_list_loopback); static void smd_fake_irq_handler(unsigned long arg); static void smsm_cb_snapshot(uint32_t use_wakelock); @@ -392,7 +381,6 @@ static void notify_smsm_cb_clients_worker(struct work_struct *work); static DECLARE_WORK(smsm_cb_work, notify_smsm_cb_clients_worker); static DEFINE_MUTEX(smsm_lock); static struct smsm_state_info *smsm_states; -static int spinlocks_initialized; /** * Variables to indicate smd module initialization. @@ -2408,222 +2396,6 @@ int smd_is_pkt_avail(smd_channel_t *ch) } EXPORT_SYMBOL(smd_is_pkt_avail); - -/* -------------------------------------------------------------------------- */ - -/** - * smem_phys_to_virt() - Convert a physical base and offset to virtual address - * - * @base: physical base address to check - * @offset: offset from the base to get the final address - * @returns: virtual SMEM address; NULL for failure - * - * Takes a physical address and an offset and checks if the resulting physical - * address would fit into one of the smem regions. If so, returns the - * corresponding virtual address. Otherwise returns NULL. - */ -static void *smem_phys_to_virt(phys_addr_t base, unsigned offset) -{ - int i; - phys_addr_t phys_addr; - resource_size_t size; - - if (OVERFLOW_ADD_UNSIGNED(phys_addr_t, base, offset)) - return NULL; - - if (!smem_areas) { - /* - * Early boot - no area configuration yet, so default - * to using the main memory region. - * - * To remove the MSM_SHARED_RAM_BASE and the static - * mapping of SMEM in the future, add dump_stack() - * to identify the early callers of smem_get_entry() - * (which calls this function) and replace those calls - * with a new function that knows how to lookup the - * SMEM base address before SMEM has been probed. - */ - phys_addr = msm_shared_ram_phys; - size = MSM_SHARED_RAM_SIZE; - - if (base >= phys_addr && base + offset < phys_addr + size) { - if (OVERFLOW_ADD_UNSIGNED(uintptr_t, - (uintptr_t)MSM_SHARED_RAM_BASE, offset)) { - pr_err("%s: overflow %p %x\n", __func__, - MSM_SHARED_RAM_BASE, offset); - return NULL; - } - - return MSM_SHARED_RAM_BASE + offset; - } else { - return NULL; - } - } - for (i = 0; i < num_smem_areas; ++i) { - phys_addr = smem_areas[i].phys_addr; - size = smem_areas[i].size; - - if (base < phys_addr || base + offset >= phys_addr + size) - continue; - - if (OVERFLOW_ADD_UNSIGNED(uintptr_t, - (uintptr_t)smem_areas[i].virt_addr, offset)) { - pr_err("%s: overflow %p %x\n", __func__, - smem_areas[i].virt_addr, offset); - return NULL; - } - - return smem_areas[i].virt_addr + offset; - } - - return NULL; -} - -/** - * smem_virt_to_phys() - Convert SMEM address to physical address. - * - * @smem_address: Address of SMEM item (returned by smem_alloc(), etc) - * @returns: Physical address (or NULL if there is a failure) - * - * This function should only be used if an SMEM item needs to be handed - * off to a DMA engine. - */ -phys_addr_t smem_virt_to_phys(void *smem_address) -{ - phys_addr_t phys_addr = 0; - int i; - void *vend; - - if (!smem_areas) - return phys_addr; - - for (i = 0; i < num_smem_areas; ++i) { - vend = (void *)(smem_areas[i].virt_addr + smem_areas[i].size); - - if (smem_address >= smem_areas[i].virt_addr && - smem_address < vend) { - phys_addr = smem_address - smem_areas[i].virt_addr; - phys_addr += smem_areas[i].phys_addr; - break; - } - } - - return phys_addr; -} -EXPORT_SYMBOL(smem_virt_to_phys); - -/* smem_alloc returns the pointer to smem item if it is already allocated. - * Otherwise, it returns NULL. - */ -void *smem_alloc(unsigned id, unsigned size) -{ - return smem_find(id, size); -} -EXPORT_SYMBOL(smem_alloc); - -/* smem_alloc2 returns the pointer to smem item. If it is not allocated, - * it allocates it and then returns the pointer to it. - */ -void *smem_alloc2(unsigned id, unsigned size_in) -{ - struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; - struct smem_heap_entry *toc = shared->heap_toc; - unsigned long flags; - void *ret = NULL; - - if (!shared->heap_info.initialized) { - pr_err("%s: smem heap info not initialized\n", __func__); - return NULL; - } - - if (id >= SMEM_NUM_ITEMS) - return NULL; - - size_in = ALIGN(size_in, 8); - remote_spin_lock_irqsave(&remote_spinlock, flags); - if (toc[id].allocated) { - SMD_DBG("%s: %u already allocated\n", __func__, id); - if (size_in != toc[id].size) - pr_err("%s: wrong size %u (expected %u)\n", - __func__, toc[id].size, size_in); - else - ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset); - } else if (id > SMEM_FIXED_ITEM_LAST) { - SMD_DBG("%s: allocating %u\n", __func__, id); - if (shared->heap_info.heap_remaining >= size_in) { - toc[id].offset = shared->heap_info.free_offset; - toc[id].size = size_in; - wmb(); - toc[id].allocated = 1; - - shared->heap_info.free_offset += size_in; - shared->heap_info.heap_remaining -= size_in; - ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset); - } else - pr_err("%s: not enough memory %u (required %u)\n", - __func__, shared->heap_info.heap_remaining, - size_in); - } - wmb(); - remote_spin_unlock_irqrestore(&remote_spinlock, flags); - return ret; -} -EXPORT_SYMBOL(smem_alloc2); - -void *smem_get_entry(unsigned id, unsigned *size) -{ - struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; - struct smem_heap_entry *toc = shared->heap_toc; - int use_spinlocks = spinlocks_initialized; - void *ret = 0; - unsigned long flags = 0; - - if (id >= SMEM_NUM_ITEMS) - return ret; - - if (use_spinlocks) - remote_spin_lock_irqsave(&remote_spinlock, flags); - /* toc is in device memory and cannot be speculatively accessed */ - if (toc[id].allocated) { - phys_addr_t phys_base; - - *size = toc[id].size; - barrier(); - - phys_base = toc[id].reserved & BASE_ADDR_MASK; - if (!phys_base) - phys_base = (phys_addr_t)msm_shared_ram_phys; - ret = smem_phys_to_virt(phys_base, toc[id].offset); - } else { - *size = 0; - } - if (use_spinlocks) - remote_spin_unlock_irqrestore(&remote_spinlock, flags); - - return ret; -} -EXPORT_SYMBOL(smem_get_entry); - -void *smem_find(unsigned id, unsigned size_in) -{ - unsigned size; - void *ptr; - - ptr = smem_get_entry(id, &size); - if (!ptr) - return 0; - - size_in = ALIGN(size_in, 8); - if (size_in != size) { - pr_err("smem_find(%d, %d): wrong size %d\n", - id, size_in, size); - return 0; - } - - return ptr; -} -EXPORT_SYMBOL(smem_find); - static int smsm_cb_init(void) { struct smsm_state_info *state_info; @@ -3313,17 +3085,6 @@ int smsm_state_cb_deregister(uint32_t smsm_entry, uint32_t mask, } EXPORT_SYMBOL(smsm_state_cb_deregister); -/** - * smem_get_remote_spinlock - Remote spinlock pointer for unit testing. - * - * @returns: pointer to SMEM remote spinlock - */ -remote_spinlock_t *smem_get_remote_spinlock(void) -{ - return &remote_spinlock; -} -EXPORT_SYMBOL(smem_get_remote_spinlock); - int smd_module_init_notifier_register(struct notifier_block *nb) { int ret; @@ -4126,23 +3887,6 @@ static int restart_notifier_cb(struct notifier_block *this, remote_spin_release(&remote_spinlock, notifier->processor); remote_spin_release_all(notifier->processor); - if (smem_ramdump_dev) { - int ret; - - SMD_INFO("%s: saving ramdump\n", __func__); - /* - * XPU protection does not currently allow the - * auxiliary memory regions to be dumped. If this - * changes, then num_smem_areas + 1 should be passed - * into do_elf_ramdump() to dump all regions. - */ - ret = do_elf_ramdump(smem_ramdump_dev, - smem_ramdump_segments, 1); - if (ret < 0) - pr_err("%s: unable to dump smem %d\n", __func__, - ret); - } - smd_channel_reset(notifier->processor); } @@ -4155,13 +3899,6 @@ static __init int modem_restart_late_init(void) void *handle; struct restart_notifier_block *nb; - smem_ramdump_dev = create_ramdump_device("smem-smd", smd_dev); - if (IS_ERR_OR_NULL(smem_ramdump_dev)) { - pr_err("%s: Unable to create smem ramdump device.\n", - __func__); - smem_ramdump_dev = NULL; - } - for (i = 0; i < ARRAY_SIZE(restart_notifiers); i++) { nb = &restart_notifiers[i]; handle = subsys_notif_register_notifier(nb->name, &nb->nb); diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c index 4dcf72febc1..b66e2585958 100644 --- a/arch/arm/mach-msm/smd_debug.c +++ b/arch/arm/mach-msm/smd_debug.c @@ -21,8 +21,10 @@ #include #include +#include #include "smd_private.h" +#include "smem_private.h" #if defined(CONFIG_DEBUG_FS) diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 4a6a50918de..4fe9592c203 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -34,37 +34,6 @@ #define VERSION_MODEM 9 #define VERSION_DSPS 10 -#define SMD_HEAP_SIZE 512 - -struct smem_heap_info { - unsigned initialized; - unsigned free_offset; - unsigned heap_remaining; - unsigned reserved; -}; - -struct smem_heap_entry { - unsigned allocated; - unsigned offset; - unsigned size; - unsigned reserved; /* bits 1:0 reserved, bits 31:2 aux smem base addr */ -}; -#define BASE_ADDR_MASK 0xfffffffc - -struct smem_proc_comm { - unsigned command; - unsigned status; - unsigned data1; - unsigned data2; -}; - -struct smem_shared { - struct smem_proc_comm proc_comm[4]; - unsigned version[32]; - struct smem_heap_info heap_info; - struct smem_heap_entry heap_toc[SMD_HEAP_SIZE]; -}; - #if defined(CONFIG_MSM_SMD_PKG4) struct smsm_interrupt_info { uint32_t aArm_en_mask; @@ -313,7 +282,4 @@ struct interrupt_stat { uint32_t smsm_interrupt_id; }; extern struct interrupt_stat interrupt_stats[NUM_SMD_SUBSYSTEMS]; - -/* used for unit testing spinlocks */ -remote_spinlock_t *smem_get_remote_spinlock(void); #endif diff --git a/arch/arm/mach-msm/smem.c b/arch/arm/mach-msm/smem.c new file mode 100644 index 00000000000..c00f96fa86e --- /dev/null +++ b/arch/arm/mach-msm/smem.c @@ -0,0 +1,363 @@ +/* Copyright (c) 2013, The Linux Foundation. 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. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "smem_private.h" + +/** + * OVERFLOW_ADD_UNSIGNED() - check for unsigned overflow + * + * @type: type to check for overflow + * @a: left value to use + * @b: right value to use + * @returns: true if a + b will result in overflow; false otherwise + */ +#define OVERFLOW_ADD_UNSIGNED(type, a, b) \ + (((type)~0 - (a)) < (b) ? true : false) + +enum { + MSM_SMEM_DEBUG = 1U << 0, + MSM_SMEM_INFO = 1U << 1, +}; + +static int msm_smem_debug_mask; +module_param_named(debug_mask, msm_smem_debug_mask, + int, S_IRUGO | S_IWUSR | S_IWGRP); + +#define SMEM_DBG(x...) do { \ + if (msm_smem_debug_mask & MSM_SMEM_DEBUG) \ + pr_debug(x); \ + } while (0) + +remote_spinlock_t remote_spinlock; +int spinlocks_initialized; +uint32_t num_smem_areas; +struct smem_area *smem_areas; +struct ramdump_segment *smem_ramdump_segments; + +static void *smem_ramdump_dev; + +struct restart_notifier_block { + unsigned processor; + char *name; + struct notifier_block nb; +}; + +static int restart_notifier_cb(struct notifier_block *this, + unsigned long code, + void *data); + +static struct restart_notifier_block restart_notifiers[] = { + {SMEM_MODEM, "modem", .nb.notifier_call = restart_notifier_cb}, + {SMEM_Q6, "lpass", .nb.notifier_call = restart_notifier_cb}, + {SMEM_WCNSS, "wcnss", .nb.notifier_call = restart_notifier_cb}, + {SMEM_DSPS, "dsps", .nb.notifier_call = restart_notifier_cb}, + {SMEM_MODEM, "gss", .nb.notifier_call = restart_notifier_cb}, + {SMEM_Q6, "adsp", .nb.notifier_call = restart_notifier_cb}, +}; + +/** + * smem_phys_to_virt() - Convert a physical base and offset to virtual address + * + * @base: physical base address to check + * @offset: offset from the base to get the final address + * @returns: virtual SMEM address; NULL for failure + * + * Takes a physical address and an offset and checks if the resulting physical + * address would fit into one of the smem regions. If so, returns the + * corresponding virtual address. Otherwise returns NULL. + */ +static void *smem_phys_to_virt(phys_addr_t base, unsigned offset) +{ + int i; + phys_addr_t phys_addr; + resource_size_t size; + + if (OVERFLOW_ADD_UNSIGNED(phys_addr_t, base, offset)) + return NULL; + + if (!smem_areas) { + /* + * Early boot - no area configuration yet, so default + * to using the main memory region. + * + * To remove the MSM_SHARED_RAM_BASE and the static + * mapping of SMEM in the future, add dump_stack() + * to identify the early callers of smem_get_entry() + * (which calls this function) and replace those calls + * with a new function that knows how to lookup the + * SMEM base address before SMEM has been probed. + */ + phys_addr = msm_shared_ram_phys; + size = MSM_SHARED_RAM_SIZE; + + if (base >= phys_addr && base + offset < phys_addr + size) { + if (OVERFLOW_ADD_UNSIGNED(uintptr_t, + (uintptr_t)MSM_SHARED_RAM_BASE, offset)) { + pr_err("%s: overflow %p %x\n", __func__, + MSM_SHARED_RAM_BASE, offset); + return NULL; + } + + return MSM_SHARED_RAM_BASE + offset; + } else { + return NULL; + } + } + for (i = 0; i < num_smem_areas; ++i) { + phys_addr = smem_areas[i].phys_addr; + size = smem_areas[i].size; + + if (base < phys_addr || base + offset >= phys_addr + size) + continue; + + if (OVERFLOW_ADD_UNSIGNED(uintptr_t, + (uintptr_t)smem_areas[i].virt_addr, offset)) { + pr_err("%s: overflow %p %x\n", __func__, + smem_areas[i].virt_addr, offset); + return NULL; + } + + return smem_areas[i].virt_addr + offset; + } + + return NULL; +} + +/** + * smem_virt_to_phys() - Convert SMEM address to physical address. + * + * @smem_address: Address of SMEM item (returned by smem_alloc(), etc) + * @returns: Physical address (or NULL if there is a failure) + * + * This function should only be used if an SMEM item needs to be handed + * off to a DMA engine. + */ +phys_addr_t smem_virt_to_phys(void *smem_address) +{ + phys_addr_t phys_addr = 0; + int i; + void *vend; + + if (!smem_areas) + return phys_addr; + + for (i = 0; i < num_smem_areas; ++i) { + vend = (void *)(smem_areas[i].virt_addr + smem_areas[i].size); + + if (smem_address >= smem_areas[i].virt_addr && + smem_address < vend) { + phys_addr = smem_address - smem_areas[i].virt_addr; + phys_addr += smem_areas[i].phys_addr; + break; + } + } + + return phys_addr; +} +EXPORT_SYMBOL(smem_virt_to_phys); + +/* smem_alloc returns the pointer to smem item if it is already allocated. + * Otherwise, it returns NULL. + */ +void *smem_alloc(unsigned id, unsigned size) +{ + return smem_find(id, size); +} +EXPORT_SYMBOL(smem_alloc); + +void *smem_find(unsigned id, unsigned size_in) +{ + unsigned size; + void *ptr; + + ptr = smem_get_entry(id, &size); + if (!ptr) + return 0; + + size_in = ALIGN(size_in, 8); + if (size_in != size) { + pr_err("smem_find(%d, %d): wrong size %d\n", + id, size_in, size); + return 0; + } + + return ptr; +} +EXPORT_SYMBOL(smem_find); + +/* smem_alloc2 returns the pointer to smem item. If it is not allocated, + * it allocates it and then returns the pointer to it. + */ +void *smem_alloc2(unsigned id, unsigned size_in) +{ + struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; + struct smem_heap_entry *toc = shared->heap_toc; + unsigned long flags; + void *ret = NULL; + + if (!shared->heap_info.initialized) { + pr_err("%s: smem heap info not initialized\n", __func__); + return NULL; + } + + if (id >= SMEM_NUM_ITEMS) + return NULL; + + size_in = ALIGN(size_in, 8); + remote_spin_lock_irqsave(&remote_spinlock, flags); + if (toc[id].allocated) { + SMEM_DBG("%s: %u already allocated\n", __func__, id); + if (size_in != toc[id].size) + pr_err("%s: wrong size %u (expected %u)\n", + __func__, toc[id].size, size_in); + else + ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset); + } else if (id > SMEM_FIXED_ITEM_LAST) { + SMEM_DBG("%s: allocating %u\n", __func__, id); + if (shared->heap_info.heap_remaining >= size_in) { + toc[id].offset = shared->heap_info.free_offset; + toc[id].size = size_in; + wmb(); + toc[id].allocated = 1; + + shared->heap_info.free_offset += size_in; + shared->heap_info.heap_remaining -= size_in; + ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset); + } else + pr_err("%s: not enough memory %u (required %u)\n", + __func__, shared->heap_info.heap_remaining, + size_in); + } + wmb(); + remote_spin_unlock_irqrestore(&remote_spinlock, flags); + return ret; +} +EXPORT_SYMBOL(smem_alloc2); + +void *smem_get_entry(unsigned id, unsigned *size) +{ + struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; + struct smem_heap_entry *toc = shared->heap_toc; + int use_spinlocks = spinlocks_initialized; + void *ret = 0; + unsigned long flags = 0; + + if (id >= SMEM_NUM_ITEMS) + return ret; + + if (use_spinlocks) + remote_spin_lock_irqsave(&remote_spinlock, flags); + /* toc is in device memory and cannot be speculatively accessed */ + if (toc[id].allocated) { + phys_addr_t phys_base; + + *size = toc[id].size; + barrier(); + + phys_base = toc[id].reserved & BASE_ADDR_MASK; + if (!phys_base) + phys_base = (phys_addr_t)msm_shared_ram_phys; + ret = smem_phys_to_virt(phys_base, toc[id].offset); + } else { + *size = 0; + } + if (use_spinlocks) + remote_spin_unlock_irqrestore(&remote_spinlock, flags); + + return ret; +} +EXPORT_SYMBOL(smem_get_entry); + + +/** + * smem_get_remote_spinlock - Remote spinlock pointer for unit testing. + * + * @returns: pointer to SMEM remote spinlock + */ +remote_spinlock_t *smem_get_remote_spinlock(void) +{ + return &remote_spinlock; +} +EXPORT_SYMBOL(smem_get_remote_spinlock); + +static int restart_notifier_cb(struct notifier_block *this, + unsigned long code, + void *data) +{ + if (code == SUBSYS_AFTER_SHUTDOWN) { + struct restart_notifier_block *notifier; + + notifier = container_of(this, + struct restart_notifier_block, nb); + SMEM_DBG("%s: ssrestart for processor %d ('%s')\n", + __func__, notifier->processor, + notifier->name); + + remote_spin_release(&remote_spinlock, notifier->processor); + remote_spin_release_all(notifier->processor); + + if (smem_ramdump_dev) { + int ret; + + SMEM_DBG("%s: saving ramdump\n", __func__); + /* + * XPU protection does not currently allow the + * auxiliary memory regions to be dumped. If this + * changes, then num_smem_areas + 1 should be passed + * into do_elf_ramdump() to dump all regions. + */ + ret = do_elf_ramdump(smem_ramdump_dev, + smem_ramdump_segments, 1); + if (ret < 0) + pr_err("%s: unable to dump smem %d\n", __func__, + ret); + } + } + + return NOTIFY_DONE; +} + +static __init int modem_restart_late_init(void) +{ + int i; + void *handle; + struct restart_notifier_block *nb; + + smem_ramdump_dev = create_ramdump_device("smem", NULL); + if (IS_ERR_OR_NULL(smem_ramdump_dev)) { + pr_err("%s: Unable to create smem ramdump device.\n", + __func__); + smem_ramdump_dev = NULL; + } + + for (i = 0; i < ARRAY_SIZE(restart_notifiers); i++) { + nb = &restart_notifiers[i]; + handle = subsys_notif_register_notifier(nb->name, &nb->nb); + SMEM_DBG("%s: registering notif for '%s', handle=%p\n", + __func__, nb->name, handle); + } + + return 0; +} +late_initcall(modem_restart_late_init); diff --git a/arch/arm/mach-msm/smem_log.c b/arch/arm/mach-msm/smem_log.c index 361df3309c1..87f141d2210 100644 --- a/arch/arm/mach-msm/smem_log.c +++ b/arch/arm/mach-msm/smem_log.c @@ -32,6 +32,7 @@ #include #include +#include #include diff --git a/arch/arm/mach-msm/smem_private.h b/arch/arm/mach-msm/smem_private.h new file mode 100644 index 00000000000..89b2b7b7f7f --- /dev/null +++ b/arch/arm/mach-msm/smem_private.h @@ -0,0 +1,68 @@ +/* Copyright (c) 2013, The Linux Foundation. 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. + */ + +#ifndef _ARCH_ARM_MACH_MSM_SMEM_PRIVATE_H_ +#define _ARCH_ARM_MACH_MSM_SMEM_PRIVATE_H_ + +#include + +#include + +#define SMEM_SPINLOCK_SMEM_ALLOC "S:3" +extern remote_spinlock_t remote_spinlock; +extern int spinlocks_initialized; + +#define SMD_HEAP_SIZE 512 + +struct smem_heap_info { + unsigned initialized; + unsigned free_offset; + unsigned heap_remaining; + unsigned reserved; +}; + +struct smem_heap_entry { + unsigned allocated; + unsigned offset; + unsigned size; + unsigned reserved; /* bits 1:0 reserved, bits 31:2 aux smem base addr */ +}; +#define BASE_ADDR_MASK 0xfffffffc + +struct smem_proc_comm { + unsigned command; + unsigned status; + unsigned data1; + unsigned data2; +}; + +struct smem_shared { + struct smem_proc_comm proc_comm[4]; + unsigned version[32]; + struct smem_heap_info heap_info; + struct smem_heap_entry heap_toc[SMD_HEAP_SIZE]; +}; + +struct smem_area { + phys_addr_t phys_addr; + resource_size_t size; + void __iomem *virt_addr; +}; + +extern uint32_t num_smem_areas; +extern struct smem_area *smem_areas; + +extern struct ramdump_segment *smem_ramdump_segments; + +/* used for unit testing spinlocks */ +remote_spinlock_t *smem_get_remote_spinlock(void); +#endif /* _ARCH_ARM_MACH_MSM_SMEM_PRIVATE_H_ */ diff --git a/arch/arm/mach-msm/smp2p.c b/arch/arm/mach-msm/smp2p.c index 7bdcce9b97f..ee262b01664 100644 --- a/arch/arm/mach-msm/smp2p.c +++ b/arch/arm/mach-msm/smp2p.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include "smp2p_private_api.h" #include "smp2p_private.h" diff --git a/arch/arm/mach-msm/smp2p_loopback.c b/arch/arm/mach-msm/smp2p_loopback.c index d95c93fd041..5df3d705fa2 100644 --- a/arch/arm/mach-msm/smp2p_loopback.c +++ b/arch/arm/mach-msm/smp2p_loopback.c @@ -21,7 +21,7 @@ #include #include #include -#include "smd_private.h" +#include "smem_private.h" #include "smp2p_private.h" /** diff --git a/arch/arm/mach-msm/smp2p_spinlock_test.c b/arch/arm/mach-msm/smp2p_spinlock_test.c index 09d7c0dfe7f..c14bac0a779 100644 --- a/arch/arm/mach-msm/smp2p_spinlock_test.c +++ b/arch/arm/mach-msm/smp2p_spinlock_test.c @@ -17,8 +17,8 @@ #include #include #include -#include -#include "smd_private.h" +#include +#include "smem_private.h" #include "smp2p_private.h" #include "smp2p_test_common.h" diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c index abc63ef4c1d..0c02b517a93 100644 --- a/arch/arm/mach-msm/socinfo.c +++ b/arch/arm/mach-msm/socinfo.c @@ -27,8 +27,8 @@ #include #include +#include -#include "smd_private.h" #include "boot_stats.h" #define BUILD_ID_LENGTH 32 diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 06a4c2905cc..1ea0f2dc621 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -36,7 +36,8 @@ #include #if defined(CONFIG_MSM_SMD) -#include "smd_private.h" +#include +#include #endif #include "timer.h" diff --git a/drivers/gpio/gpio-msm-v1.c b/drivers/gpio/gpio-msm-v1.c index f28ebb4c2ff..058a3f9e424 100644 --- a/drivers/gpio/gpio-msm-v1.c +++ b/drivers/gpio/gpio-msm-v1.c @@ -1,7 +1,7 @@ /* linux/arch/arm/mach-msm/gpio.c * * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include diff --git a/drivers/iommu/msm_iommu-v0.c b/drivers/iommu/msm_iommu-v0.c index b92ec7fcba9..06f4a0f5a55 100644 --- a/drivers/iommu/msm_iommu-v0.c +++ b/drivers/iommu/msm_iommu-v0.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #define MRC(reg, processor, op1, crn, crm, op2) \ __asm__ __volatile__ ( \ diff --git a/drivers/mtd/devices/msm_qpic_nand.c b/drivers/mtd/devices/msm_qpic_nand.c index 0b04bbfb068..5fda3431ca9 100644 --- a/drivers/mtd/devices/msm_qpic_nand.c +++ b/drivers/mtd/devices/msm_qpic_nand.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #define PAGE_SIZE_2K 2048 #define PAGE_SIZE_4K 4096 #define WRITE 1 diff --git a/drivers/platform/msm/ipa/ipa_bridge.c b/drivers/platform/msm/ipa/ipa_bridge.c index 3ff604cf098..919a119936f 100644 --- a/drivers/platform/msm/ipa/ipa_bridge.c +++ b/drivers/platform/msm/ipa/ipa_bridge.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include "ipa_i.h" /*