>From aad407e2deb6a634e8cc8a6d0822ae7999fdc6c4 Mon Sep 17 00:00:00 2001 From: Jean-Nicolas Graux Date: Mon, 11 Feb 2013 11:34:59 +0100 Subject: [PATCH 2/2] ARM: ux500: remove hardware observer machine code This patch to remove the quick and dirty "hw-observer-debug.c" pseudo driver and to register new "ux500_hwobs.c" platform device driver. This new driver is pinctrl compatible. ST-Ericsson-ID: 478266 ST-Ericsson-FOSS-OUT-ID: Trivial Change-Id: I180da4c2027e3e75cf18b7712831fad489696b79 Signed-off-by: Jean-Nicolas Graux --- arch/arm/configs/ux500_ux540_defconfig | 1 + arch/arm/mach-ux500/Kconfig | 7 - arch/arm/mach-ux500/Makefile | 1 - arch/arm/mach-ux500/board-ccu8540-pins.c | 22 ++ arch/arm/mach-ux500/board-ccu8540.c | 18 +- arch/arm/mach-ux500/board-ccu9540-pins.c | 23 +- arch/arm/mach-ux500/board-ccu9540.c | 17 ++ arch/arm/mach-ux500/board-mop500-pins.c | 22 ++ arch/arm/mach-ux500/board-mop500.c | 19 ++ arch/arm/mach-ux500/hw-observer-debug.c | 462 ------------------------------ 10 files changed, 120 insertions(+), 472 deletions(-) delete mode 100644 arch/arm/mach-ux500/hw-observer-debug.c diff --git a/arch/arm/configs/ux500_ux540_defconfig b/arch/arm/configs/ux500_ux540_defconfig index f269689..da8d10a 100644 --- a/arch/arm/configs/ux500_ux540_defconfig +++ b/arch/arm/configs/ux500_ux540_defconfig @@ -162,6 +162,7 @@ CONFIG_STM_TRACE=y CONFIG_STM_DEFAULT_MASTERS_MODES=0x20 CONFIG_CG1960=y CONFIG_CG1960_SPI=y +CONFIG_UX500_HWOBS=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_MD=y diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 6d2f87b..4445b6f 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -279,13 +279,6 @@ config RTC_HCTOHC the value read from the 1st RTC device. This is useful when the 1st RTC is battery backed but not the 2nd. -config UX500_HW_OBSERVER - bool "Add debug IF for HW Observer" - depends on (DEBUG_FS || UX500_SOC_DB8500) - default y - help - Add interface to configure Hw Observer lines. - config UX500_ESRAM_ALLOCATOR bool "Add ESRAM allocator" select GENERIC_ALLOCATOR diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 75964b4..93ffd95 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -82,7 +82,6 @@ obj-$(CONFIG_UX500_L2X0_PREFETCH_CTRL) += l2x0-prefetch.o obj-$(CONFIG_UX500_ROMCODE_SHARED_MUTEX) += romcode-shared_mutex.o obj-$(CONFIG_UX500_DB_DUMP) += dbx500_dump.o obj-$(CONFIG_RTC_HCTOHC) += hctohc.o -obj-$(CONFIG_UX500_HW_OBSERVER) += hw-observer-debug.o obj-$(CONFIG_UX500_ESRAM_ALLOCATOR) += esram-allocator.o ifeq ($(CONFIG_UX500_SOC_DB8500), y) obj-$(CONFIG_STM_TRACE) += board-mop500-stm.o diff --git a/arch/arm/mach-ux500/board-ccu8540-pins.c b/arch/arm/mach-ux500/board-ccu8540-pins.c index 6b1b9a1..e02a880 100644 --- a/arch/arm/mach-ux500/board-ccu8540-pins.c +++ b/arch/arm/mach-ux500/board-ccu8540-pins.c @@ -95,6 +95,7 @@ BIAS(slpm_out_lo, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_LOW| PIN_SLPM_GPIO); BIAS(slpm_out_hi, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_HIGH| PIN_SLPM_GPIO); +BIAS(noslpm, PIN_SLPM_ALTFUNC); BIAS(noslpm_in_pu, PIN_INPUT_PULLUP|PIN_SLPM_ALTFUNC); BIAS(noslpm_in_nopull, PIN_INPUT_NOPULL|PIN_SLPM_ALTFUNC); @@ -473,6 +474,27 @@ static struct pinctrl_map __initdata ccu8540_pinmap[] = { DB8540_PIN_STATE("GPIO86_T25", slpm_out_lo, "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat0 */ + /* Hardware Observer */ + DB8540_MUX("hwobs_oc4_1", "hwobs", "hwobs"), + DB8540_PIN("GPIO64_M26", noslpm, "hwobs"), + DB8540_PIN("GPIO65_M25", noslpm, "hwobs"), + DB8540_PIN("GPIO66_M27", noslpm, "hwobs"), + DB8540_PIN("GPIO67_N25", noslpm, "hwobs"), + DB8540_PIN("GPIO70_M28", noslpm, "hwobs"), + DB8540_PIN("GPIO71_N26", noslpm, "hwobs"), + DB8540_PIN("GPIO72_M22", noslpm, "hwobs"), + DB8540_PIN("GPIO73_N22", noslpm, "hwobs"), + DB8540_PIN("GPIO74_N27", noslpm, "hwobs"), + DB8540_PIN("GPIO75_N28", noslpm, "hwobs"), + DB8540_PIN("GPIO76_P22", noslpm, "hwobs"), + DB8540_PIN("GPIO77_P28", noslpm, "hwobs"), + DB8540_PIN("GPIO78_P26", noslpm, "hwobs"), + DB8540_PIN("GPIO79_T22", noslpm, "hwobs"), + DB8540_PIN("GPIO80_R27", noslpm, "hwobs"), + DB8540_PIN("GPIO81_P27", noslpm, "hwobs"), + DB8540_PIN("GPIO82_R26", noslpm, "hwobs"), + DB8540_PIN("GPIO83_R25", noslpm, "hwobs"), + /* Mux in I2C blocks */ /* I2C0 : HDMI, External StepUp Audio 4.5V, IO Expander, KP Expander */ /* default state */ diff --git a/arch/arm/mach-ux500/board-ccu8540.c b/arch/arm/mach-ux500/board-ccu8540.c index 539e0a9..f4fc68a 100644 --- a/arch/arm/mach-ux500/board-ccu8540.c +++ b/arch/arm/mach-ux500/board-ccu8540.c @@ -57,6 +57,7 @@ #include "board-ccu8540-esram.h" #include "board-ccux540-ver.h" #include "hwmem-int.h" +#include "ux500_hwobs.h" #ifdef CONFIG_INPUT_AB8500_ACCDET static struct abx500_accdet_platform_data ab8540_accdet_pdata = { @@ -158,7 +159,22 @@ static struct platform_device db8540_pwl_device = { } }; +struct hwobs_platform_data db8540_hwobs_pdata = { + .variant_id = HWOBS_SOC_8540, + .regs_phys_base = U8500_PRCMU_BASE, + .gpio_base = 64, +}; + +struct platform_device db8540_hwobs_device = { + .name = HWOBS_DEV_NAME, + .id = -1, + .dev = { + .platform_data = &db8540_hwobs_pdata, + }, +}; + static struct platform_device *u8540_platform_devs[] __initdata = { + &db8540_hwobs_device, &db8540_romcode_sm_device, &ux500_mmio_device, &ux500_mmio_raw_device, @@ -522,7 +538,6 @@ static void __init u8540_init_machine(void) platform_device_register(&db8540_xmip_device); platform_device_register(&ccu8540_esram_visual_device); platform_device_register(&ccu8540_esram_video_device); - mop500_msp_init(parent); } @@ -547,6 +562,7 @@ MACHINE_END #ifdef CONFIG_MACH_UX500_DT static struct platform_device *u8540_of_platform_devs[] __initdata = { + &db8540_hwobs_device, &db8540_romcode_sm_device, &ux500_mmio_device, &ux500_mmio_raw_device, diff --git a/arch/arm/mach-ux500/board-ccu9540-pins.c b/arch/arm/mach-ux500/board-ccu9540-pins.c index 34d6fb6..7b4c2fd 100644 --- a/arch/arm/mach-ux500/board-ccu9540-pins.c +++ b/arch/arm/mach-ux500/board-ccu9540-pins.c @@ -81,7 +81,7 @@ BIAS(slpm_in_wkup, PIN_SLEEPMODE_ENABLED|PIN_SLPM_DIR_INPUT| BIAS(slpm_out_hi, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_HIGH); BIAS(slpm_in_wkup_dis_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_DIR_INPUT| PIN_SLPM_WAKEUP_DISABLE|PIN_SLPM_PDIS_DISABLED); - +BIAS(noslpm, PIN_SLPM_ALTFUNC); /* We use these to define hog settings that are always done on boot */ #define DB8500_MUX_HOG(group, func) \ @@ -479,6 +479,27 @@ static struct pinctrl_map __initdata ccu9540_pinmap[] = { DB8500_PIN_STATE("GPIO28_AA1", slpm_in_wkup_pdis, "stm", "ape_microsd_sleep"), /* dat3 */ + /* Hardware Observer */ + DB8500_MUX("hwobs_oc4_1", "hwobs", "hwobs"), + DB8500_PIN("GPIO151_D17", noslpm, "hwobs"), + DB8500_PIN("GPIO152_D16", noslpm, "hwobs"), + DB8500_PIN("GPIO153_B17", noslpm, "hwobs"), + DB8500_PIN("GPIO154_C16", noslpm, "hwobs"), + DB8500_PIN("GPIO155_C19", noslpm, "hwobs"), + DB8500_PIN("GPIO156_C17", noslpm, "hwobs"), + DB8500_PIN("GPIO157_A18", noslpm, "hwobs"), + DB8500_PIN("GPIO158_C18", noslpm, "hwobs"), + DB8500_PIN("GPIO159_B19", noslpm, "hwobs"), + DB8500_PIN("GPIO160_B20", noslpm, "hwobs"), + DB8500_PIN("GPIO161_D21", noslpm, "hwobs"), + DB8500_PIN("GPIO162_D20", noslpm, "hwobs"), + DB8500_PIN("GPIO163_C20", noslpm, "hwobs"), + DB8500_PIN("GPIO164_B21", noslpm, "hwobs"), + DB8500_PIN("GPIO165_C21", noslpm, "hwobs"), + DB8500_PIN("GPIO166_A22", noslpm, "hwobs"), + DB8500_PIN("GPIO167_B24", noslpm, "hwobs"), + DB8500_PIN("GPIO168_C22", noslpm, "hwobs"), + /* * The following pin sets were known as "runtime pins" before being * converted to the pinctrl model. Here we model them as "default" diff --git a/arch/arm/mach-ux500/board-ccu9540.c b/arch/arm/mach-ux500/board-ccu9540.c index 7826f92..387e052 100644 --- a/arch/arm/mach-ux500/board-ccu9540.c +++ b/arch/arm/mach-ux500/board-ccu9540.c @@ -60,6 +60,7 @@ #include "board-mop500.h" #include "board-ccux540-ver.h" #include "hwmem-int.h" +#include "ux500_hwobs.h" #ifdef CONFIG_INPUT_AB8500_ACCDET static struct abx500_accdet_platform_data ab8500_accdet_pdata = { @@ -276,7 +277,22 @@ static struct platform_device db9540_romcode_sm_device = { }; #endif +struct hwobs_platform_data db9540_hwobs_pdata = { + .variant_id = HWOBS_SOC_9540, + .regs_phys_base = U8500_PRCMU_BASE, + .gpio_base = 151, +}; + +struct platform_device db9540_hwobs_device = { + .name = HWOBS_DEV_NAME, + .id = -1, + .dev = { + .platform_data = &db9540_hwobs_pdata, + }, +}; + static struct platform_device *u9540_platform_devs[] __initdata = { + &db9540_hwobs_device, &ste_ff_vibra_device, #ifdef CONFIG_U8500_MMIO &ux500_mmio_device, @@ -718,6 +734,7 @@ MACHINE_END #ifdef CONFIG_MACH_UX500_DT static struct platform_device *u9540_of_platform_devs[] __initdata = { + &db9540_hwobs_device, &ste_ff_vibra_device, #ifdef CONFIG_U8500_MMIO &ux500_mmio_device, diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index 5edbbdf..81ab6fb 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -75,6 +75,7 @@ BIAS(slpm_wkup_pdis_en, PIN_SLEEPMODE_ENABLED|PIN_SLPM_WAKEUP_ENABLE| PIN_SLPM_PDIS_ENABLED); BIAS(slpm_in_wkup_pdis_en, PIN_SLEEPMODE_ENABLED|PIN_SLPM_WAKEUP_ENABLE| PIN_SLPM_DIR_INPUT|PIN_SLPM_PDIS_ENABLED); +BIAS(noslpm, PIN_SLPM_ALTFUNC); /* We use these to define hog settings that are always done on boot */ #define DB8500_MUX_HOG(group,func) \ @@ -768,6 +769,27 @@ static struct pinctrl_map __initdata mop500_family_pinmap[] = { "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat1 */ DB8500_PIN_STATE("GPIO159_B19", slpm_in_wkup_pdis, "stm", "mod_mipi34_ape_mipi60_sleep"), /* dat0 */ + + /* Hardware Observer */ + DB8500_MUX("hwobs_oc4_1", "hwobs", "hwobs"), + DB8500_PIN("GPIO151_D17", noslpm, "hwobs"), + DB8500_PIN("GPIO152_D16", noslpm, "hwobs"), + DB8500_PIN("GPIO153_B17", noslpm, "hwobs"), + DB8500_PIN("GPIO154_C16", noslpm, "hwobs"), + DB8500_PIN("GPIO155_C19", noslpm, "hwobs"), + DB8500_PIN("GPIO156_C17", noslpm, "hwobs"), + DB8500_PIN("GPIO157_A18", noslpm, "hwobs"), + DB8500_PIN("GPIO158_C18", noslpm, "hwobs"), + DB8500_PIN("GPIO159_B19", noslpm, "hwobs"), + DB8500_PIN("GPIO160_B20", noslpm, "hwobs"), + DB8500_PIN("GPIO161_D21", noslpm, "hwobs"), + DB8500_PIN("GPIO162_D20", noslpm, "hwobs"), + DB8500_PIN("GPIO163_C20", noslpm, "hwobs"), + DB8500_PIN("GPIO164_B21", noslpm, "hwobs"), + DB8500_PIN("GPIO165_C21", noslpm, "hwobs"), + DB8500_PIN("GPIO166_A22", noslpm, "hwobs"), + DB8500_PIN("GPIO167_B24", noslpm, "hwobs"), + DB8500_PIN("GPIO168_C22", noslpm, "hwobs"), }; /* diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 3798de5..28b36ca 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -82,6 +82,7 @@ #include "board-mop500-wlan.h" #endif #include "hwmem-int.h" +#include "ux500_hwobs.h" #ifdef CONFIG_AB8500_DENC static struct ab8500_denc_platform_data ab8500_denc_pdata = { @@ -764,8 +765,23 @@ static struct hash_platform_data u8500_hash1_platform_data = { }; #endif +struct hwobs_platform_data db8500_hwobs_pdata = { + .variant_id = HWOBS_SOC_8500, + .regs_phys_base = U8500_PRCMU_BASE, + .gpio_base = 151, +}; + +struct platform_device db8500_hwobs_device = { + .name = HWOBS_DEV_NAME, + .id = -1, + .dev = { + .platform_data = &db8500_hwobs_pdata, + }, +}; + /* add any platform devices here - TODO */ static struct platform_device *mop500_platform_devs[] __initdata = { + &db8500_hwobs_device, #ifdef CONFIG_U8500_SIM_DETECT &u8500_sim_detect_device, #endif @@ -956,6 +972,7 @@ static void __init u8500_tee_init(void) } static struct platform_device *snowball_platform_devs[] __initdata = { + &db8500_hwobs_device, #ifdef CONFIG_HWMEM &ux500_hwmem_device, #endif @@ -1195,6 +1212,7 @@ MACHINE_END /* add any platform devices here - TODO */ static struct platform_device *of_mop500_platform_devs[] __initdata = { + &db8500_hwobs_device, #ifdef CONFIG_U8500_SIM_DETECT &u8500_sim_detect_device, #endif @@ -1236,6 +1254,7 @@ static struct platform_device *of_mop500_platform_devs[] __initdata = { }; static struct platform_device *of_snowball_platform_devs[] __initdata = { + &db8500_hwobs_device, #ifdef CONFIG_HWMEM &ux500_hwmem_device, #endif diff --git a/arch/arm/mach-ux500/hw-observer-debug.c b/arch/arm/mach-ux500/hw-observer-debug.c deleted file mode 100644 index 735de50..0000000 --- a/arch/arm/mach-ux500/hw-observer-debug.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2011 - * - * License terms: GNU General Public License (GPL) version 2 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "id.h" - -#define HWOBS_NB 18 /* nb HWOBS pads */ -#define HWOBS_MASK_FOR_MODE_CFG 3 - -#define PRCM_HWOBS_H IO_ADDRESS(U8500_PRCMU_BASE + 0x4B0) -#define PRCM_HWOBS_L IO_ADDRESS(U8500_PRCMU_BASE + 0x4B4) -#define PRCM_GPIOCR IO_ADDRESS(U8500_PRCMU_BASE + 0x138) -#define PRCM_GPIOB4 IO_ADDRESS(U8500_GPIOBANK4_BASE) -#define PRCM_GPIOB5 IO_ADDRESS(U8500_GPIOBANK5_BASE) - -#define PRCM_ENABLE_HW_OBS 0x00000010 -#define PRCM_DDRCFG_HW_OBS 0x00000100 -#define PRCM_GPIOCR_HW_OBS 0x03000000 -#define PRCM_BITS_IN_BANK4 0xFF800000 -#define PRCM_BITS_IN_BANK5 0x000001FF - -/* hw_obs_cfg - configrations for a single ux500 HW_OBSERVERs - * - * @name: label used as debugfs entry - * @offset: offset - * @reg: register - * @mode: human readable current config - */ -struct hw_obs_cfg { - const char *name; - unsigned int offset; - unsigned int reg; - char mode[32]; - int gpio; - int gpio_req; -}; - -/* ux500_hw_obs - configrations all all ux500 HW_OBSERVERs - * - * @cfg: target HW observers config - * @enable: non-zero if a HW observer is setup. - * @save_gpiocr: store HW cfg before enabling HW Obs - * @save_afsla_bank4: store HW cfg before enabling HW Obs - * @save_afsla_bank5: store HW cfg before enabling HW Obs - * @save_afslb_bank4: store HW cfg before enabling HW Obs - * @save_afslb_bank5: store HW cfg before enabling HW Obs - * @dir: debugfs directory dentry reference - */ -struct ux500_hw_obs { - struct hw_obs_cfg cfg[HWOBS_NB]; - int enable; - struct dentry *dir; - struct mutex mutex; -}; - -enum hwobs_cfg { - HWOBS_CFG_C2C = 0, - HWOBS_CFG_MODEM, - HWOBS_CFG_WAKE_UP, - HWOBS_CFG_DDR, - HWOBS_CFG_DDR0, - HWOBS_CFG_DDR1, - HWOBS_CFG_CLOCKING, - HWOBS_CFG_GPIOH, - HWOBS_CFG_GPIOL, - HWOBS_CFG_MAX -}; - -static char **modes = NULL; - -static const char *available_mode_ux540[HWOBS_CFG_MAX] = { - [HWOBS_CFG_C2C] = "c2c", - [HWOBS_CFG_WAKE_UP] = "wake-up", - [HWOBS_CFG_DDR0] = "ddr0", - [HWOBS_CFG_DDR1] = "ddr1", - [HWOBS_CFG_CLOCKING] = "clocking", - [HWOBS_CFG_GPIOH] = "gpioH", - [HWOBS_CFG_GPIOL] = "gpioL", -}; - -static const char *available_mode_ux500[HWOBS_CFG_MAX] = { - [HWOBS_CFG_MODEM] = "modem", - [HWOBS_CFG_WAKE_UP] = "wake-up", - [HWOBS_CFG_DDR] = "ddr", - [HWOBS_CFG_CLOCKING] = "clocking", - [HWOBS_CFG_GPIOH] = "gpioH", - [HWOBS_CFG_GPIOL] = "gpioL", -}; - -#define HWOBS_INST(n, o, r, g) { .name = n, .offset = o, .reg = r, .gpio = g } - -static struct ux500_hw_obs hwobs = { - .cfg = { - HWOBS_INST("hw_obs_0_mode", 0, PRCM_HWOBS_L, 168), - HWOBS_INST("hw_obs_1_mode", 2, PRCM_HWOBS_L, 167), - HWOBS_INST("hw_obs_2_mode", 4, PRCM_HWOBS_L, 166), - HWOBS_INST("hw_obs_3_mode", 6, PRCM_HWOBS_L, 165), - HWOBS_INST("hw_obs_4_mode", 8, PRCM_HWOBS_L, 164), - HWOBS_INST("hw_obs_5_mode", 10, PRCM_HWOBS_L, 163), - HWOBS_INST("hw_obs_6_mode", 12, PRCM_HWOBS_L, 162), - HWOBS_INST("hw_obs_7_mode", 14, PRCM_HWOBS_L, 161), - HWOBS_INST("hw_obs_8_mode", 16, PRCM_HWOBS_L, 160), - HWOBS_INST("hw_obs_9_mode", 18, PRCM_HWOBS_L, 159), - HWOBS_INST("hw_obs_10_mode", 20, PRCM_HWOBS_L, 158), - HWOBS_INST("hw_obs_11_mode", 22, PRCM_HWOBS_L, 157), - HWOBS_INST("hw_obs_12_mode", 24, PRCM_HWOBS_L, 156), - HWOBS_INST("hw_obs_13_mode", 26, PRCM_HWOBS_L, 155), - HWOBS_INST("hw_obs_14_mode", 28, PRCM_HWOBS_L, 154), - HWOBS_INST("hw_obs_15_mode", 30, PRCM_HWOBS_L, 153), - HWOBS_INST("hw_obs_16_mode", 0, PRCM_HWOBS_H, 152), - HWOBS_INST("hw_obs_17_mode", 2, PRCM_HWOBS_H, 151), - }, -}; - -static inline enum hwobs_cfg str2mode(char *s) -{ - int i; - for (i = 0; i < HWOBS_CFG_MAX; i++) { - if (modes[i] && (!strncmp(s, modes[i], strlen(modes[i])))) - return i; - } - return HWOBS_CFG_MAX; -} - -/* configure_mode - config target HW_OBS pads - * - * HW_OBS pad can be configure either in a HW_OBS mode or in - * GPIO mode, set High or Low. GPIO High/Low modes help validating - * the board HW_OBS test points. - */ -#define MUX_HWOBS(i) (PIN_CFG(i, ALT_C) | PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP) -#define MUX_GPIO(i) (PIN_CFG(i, GPIO) | PIN_DIR_OUTPUT | \ - PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP) -static void configure_mode(struct hw_obs_cfg *hw_obs, enum hwobs_cfg cfg) -{ - u32 temp; - - mutex_lock(&hwobs.mutex); - - if (!(hw_obs->gpio_req)) { - if (gpio_request(hw_obs->gpio, "hwobs") < 0) { - /* GPIO already reserved */ - hw_obs->gpio_req = -1; - strncpy(hw_obs->mode, "GPIO reserved", - sizeof(hw_obs->mode)); - return; - } else - hw_obs->gpio_req = 1; - } - - /* mux pad */ - temp = readl(hw_obs->reg); - temp &= ~(HWOBS_MASK_FOR_MODE_CFG << hw_obs->offset); - - switch (cfg) { - case HWOBS_CFG_C2C: - case HWOBS_CFG_MODEM: - nmk_config_pin(MUX_HWOBS(hw_obs->gpio), false); - writel(temp, hw_obs->reg); - break; - case HWOBS_CFG_WAKE_UP: - nmk_config_pin(MUX_HWOBS(hw_obs->gpio), false); - writel(temp | (1 << hw_obs->offset), hw_obs->reg); - break; - case HWOBS_CFG_DDR: - nmk_config_pin(MUX_HWOBS(hw_obs->gpio), false); - writel(temp | (2 << hw_obs->offset), hw_obs->reg); - break; - case HWOBS_CFG_DDR0: - nmk_config_pin(MUX_HWOBS(hw_obs->gpio), false); - writel(temp | (2 << hw_obs->offset), hw_obs->reg); - temp = readl(PRCM_HWOBS_H); - writel(temp & ~PRCM_DDRCFG_HW_OBS, PRCM_HWOBS_H); - break; - case HWOBS_CFG_DDR1: - nmk_config_pin(MUX_HWOBS(hw_obs->gpio), false); - writel(temp | (2 << hw_obs->offset), hw_obs->reg); - temp = readl(PRCM_HWOBS_H); - writel(temp | PRCM_DDRCFG_HW_OBS, PRCM_HWOBS_H); - break; - case HWOBS_CFG_CLOCKING: - nmk_config_pin(MUX_HWOBS(hw_obs->gpio), false); - writel(temp | (3 << hw_obs->offset), hw_obs->reg); - break; - case HWOBS_CFG_GPIOH: - nmk_config_pin(MUX_GPIO(hw_obs->gpio), false); - gpio_set_value_cansleep(hw_obs->gpio, 1); - break; - case HWOBS_CFG_GPIOL: - nmk_config_pin(MUX_GPIO(hw_obs->gpio), false); - gpio_set_value_cansleep(hw_obs->gpio, 0); - break; - default: - return; - } - strncpy(hw_obs->mode, modes[cfg], sizeof(hw_obs->mode)); - - mutex_unlock(&hwobs.mutex); -} - -/* - * hwobs_enable - request gpios and enable HW_OBS in HWOBS - * GPIO will be configured on demand - */ -static int hwobs_enable(void) -{ - mutex_lock(&hwobs.mutex); - writel(readl(PRCM_HWOBS_H) | PRCM_ENABLE_HW_OBS, PRCM_HWOBS_H); - writel(readl(PRCM_GPIOCR) | PRCM_GPIOCR_HW_OBS, PRCM_GPIOCR); - mutex_unlock(&hwobs.mutex); - - return 0; -} -/* hwobs_disable - reconfig/free gpios and disable hw obs */ -static int hwobs_disable(void) -{ - struct hw_obs_cfg *hw_obs; - int i; - - mutex_lock(&hwobs.mutex); - for (i = 0, hw_obs = hwobs.cfg; i < HWOBS_NB; i++, hw_obs++) { - if (hw_obs->gpio_req > 0) { - /* reconfig pin as GPIO/input/SleepSupport */ - nmk_config_pin(PIN_CFG(hw_obs->gpio, GPIO), false); - gpio_free(hw_obs->gpio); - hw_obs->gpio_req = 0; - } - } - writel(readl(PRCM_HWOBS_H) & ~PRCM_ENABLE_HW_OBS, PRCM_HWOBS_H); - writel(readl(PRCM_GPIOCR) & ~PRCM_GPIOCR_HW_OBS, PRCM_GPIOCR); - mutex_unlock(&hwobs.mutex); - return 0; -} - -static const char readme[] = - "How to use hw observer debufs:\n" - "------------------------------\n" - "\n" - "./show_all_status: show current status of all hw observers.\n" - "\n" - "./enable_hwobs: set/get hw observer feature 'enable' state.\n" - " 0 disable HW_OBS\n" - " 1 enable HW_OBS\n" - " set all HW_OBS in target MODE (see available_mode)\n" - "\n" - "./hw_obs_x_mode: set/get each hw observer 'mode' configuration.\n" - " refer to 'available_mode' for supported values.\n" - "\n" - "./available_mode: list of supported configuration values.\n"; - -static int hwobs_readme(struct seq_file *s, void *p) -{ - return seq_printf(s, "%s", readme); -} - -static int hwobs_showall(struct seq_file *s, void *p) -{ - int i; - - if (hwobs.enable == 0) - return seq_printf(s, "Not available, feature disabled.\n"); - - for (i = 0; i < HWOBS_NB; i++) - seq_printf(s, "%s: %s\n", hwobs.cfg[i].name, hwobs.cfg[i].mode); - return 0; -} - -static int hwobs_avmodes(struct seq_file *s, void *p) -{ - int i; - - for (i = 0; i < HWOBS_CFG_MAX; i++) - if(modes[i] != NULL) - seq_printf(s, "%s\n", modes[i]); - return 0; -} - -static int hwobs_mode_read(struct seq_file *s, void *p) -{ - struct hw_obs_cfg *cfg = ((struct hw_obs_cfg *)(s->private)); - - if (hwobs.enable) - return seq_printf(s,"Mode: %s \n", cfg->mode); - - return seq_printf(s, "HW OBS disable, no mode available\n"); -} - -static ssize_t hwobs_mode_write(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - struct hw_obs_cfg *cfg; - char buf[32]; - int bsize, id; - - /* Get userspace string and assure termination */ - bsize = min(count, (sizeof(buf) - 1)); - if (copy_from_user(buf, user_buf, bsize)) - return -EFAULT; - buf[bsize] = 0; - - cfg = ((struct seq_file *)(file->private_data))->private; - id = str2mode(buf); - if (id == HWOBS_CFG_MAX) - return -EINVAL; - configure_mode(cfg, id); - return count; -} - -static int hwobs_enable_read(struct seq_file *s, void *p) -{ - return seq_printf(s, "%d (hw observers %s)\n", - hwobs.enable, (hwobs.enable) ? "enabled" : "disabled"); -} - -static ssize_t hwobs_enable_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - long int user_val; - char buf[32]; - int bsize, err; - u32 temp = 0, i; - - /* Get userspace string and assure termination */ - bsize = min(count, (sizeof(buf) - 1)); - if (copy_from_user(buf, user_buf, bsize)) - return -EFAULT; - buf[bsize] = 0; - - /* check if oneshot config of all HW_OBS */ - temp = str2mode(buf); - if (temp != HWOBS_CFG_MAX) { - if (hwobs_enable()) - goto disable; - hwobs.enable = 1; - for (i = 0; i < HWOBS_NB; i++) - configure_mode(&hwobs.cfg[i], temp); - return count; - } - - /* arg = 0/1 => disable/enable HW_OBS */ - err = strict_strtol(buf, 0, &user_val); - if (err) - return err; - - if ((user_val == 1) && (hwobs.enable == 0)) { - if (hwobs_enable()) - goto disable; - hwobs.enable = 1; - } else if ((user_val == 0) && hwobs.enable) { - hwobs_disable(); - hwobs.enable = 0; - } else - return -EINVAL; - - return count; -disable: - hwobs_disable(); - hwobs.enable = 0; - return -EIO; -} - -static int hwobs_mode_open(struct inode *inode, struct file *file) -{ - return single_open(file, hwobs_mode_read, inode->i_private); -} -static int hwobs_enable_open(struct inode *inode, struct file *file) -{ - return single_open(file, hwobs_enable_read, inode->i_private); -} -static int hwobs_showall_open(struct inode *inode, struct file *file) -{ - return single_open(file, hwobs_showall, inode->i_private); -} -static int hwobs_avmodes_open(struct inode *inode, struct file *file) -{ - return single_open(file, hwobs_avmodes, inode->i_private); -} -static int hwobs_readme_open(struct inode *inode, struct file *file) -{ - return single_open(file, hwobs_readme, inode->i_private); -} - -#define HWOBS_SEQF_FOPS(fops, op, wr) \ - static const struct file_operations fops = { \ - .open = op, \ - .write = wr, \ - .read = seq_read, \ - .llseek = seq_lseek, \ - .release = single_release, \ - .owner = THIS_MODULE, \ - } - -HWOBS_SEQF_FOPS(hwobs_mode_fops, hwobs_mode_open, hwobs_mode_write); -HWOBS_SEQF_FOPS(hwobs_enable_fops, hwobs_enable_open, hwobs_enable_write); -HWOBS_SEQF_FOPS(hwobs_showall_fops, hwobs_showall_open, NULL); -HWOBS_SEQF_FOPS(hwobs_avmodes_fops, hwobs_avmodes_open, NULL); -HWOBS_SEQF_FOPS(hwobs_readme_fops, hwobs_readme_open, NULL); - -static int __init dbx500_hw_obs_debug_init(void) -{ - int i; - - mutex_init(&hwobs.mutex); - - if (cpu_is_ux540_family()) - modes = (char**)available_mode_ux540; - else - modes = (char**)available_mode_ux500; - - hwobs.dir = debugfs_create_dir("hw_observer", NULL); - if (hwobs.dir == NULL) - goto fail; - - /* create file entry for each HW observer line */ - for (i = 0; i < HWOBS_NB; i++) { - if (!debugfs_create_file(hwobs.cfg[i].name, S_IRUGO | S_IWUSR | S_IWGRP, - hwobs.dir, &hwobs.cfg[i], &hwobs_mode_fops)) - goto fail; - } - if (!debugfs_create_file("show_all_status", S_IRUGO, - hwobs.dir, NULL, &hwobs_showall_fops)) - goto fail; - if (!debugfs_create_file("enable_hwobs", S_IRUGO | S_IWUSR | S_IWGRP, - hwobs.dir, NULL, &hwobs_enable_fops)) - goto fail; - if (!debugfs_create_file("available_mode", S_IRUGO, - hwobs.dir, NULL, &hwobs_avmodes_fops)) - goto fail; - if (!debugfs_create_file("README", S_IRUGO, - hwobs.dir, NULL, &hwobs_readme_fops)) - goto fail; - hwobs.enable = 0; - - printk(KERN_INFO "hw observer intialized\n"); - return 0; - -fail: - - if (hwobs.dir) { - debugfs_remove_recursive(hwobs.dir); - hwobs.dir = NULL; - } - printk(KERN_ERR "hw observer debug: debugfs entry failed\n"); - return -ENOMEM; -} -module_init(dbx500_hw_obs_debug_init); -- 1.7.10