From b8a16e1fdfe9caed734df0e157ad74ae2b13e3bd Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Tue, 9 Sep 2008 09:36:50 -0700 Subject: [ARM] msm: add proc_comm support, necessary for clock and power control The proc_comm protocol is the lowest level protocol available for communicating with the modem core. It provides access to clock and power control, among other things, and is safe for use from atomic contexts, unlike the higher level SMD and RPC transports. Signed-off-by: Brian Swetland --- arch/arm/mach-msm/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/mach-msm/Makefile') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index d12f2365585..ae96ffff494 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,4 +1,5 @@ obj-y += io.o idle.o irq.o timer.o dma.o +obj-y += proc_comm.o # Common code for board init obj-y += common.o -- cgit v1.2.3-70-g09d2 From bcc0f6af0798e60e7527485f7125ed26632ce698 Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Wed, 10 Sep 2008 14:00:53 -0700 Subject: [ARM] msm: clean up iomap and devices - Add some more peripherals (sdcc, etc) to the iomap. - Remove virtual base addresses for devices that we should be passing physical addresses to drivers via resources and ioremap()ing. - don't try to use uarts for ll debug once the mmu is enabled due to problems with the peripheral window - make base addresses void __iomem * and fixup irq.c and timer.c - Remove common.c and bring in devices.c/devices.h similar to the PXA architecture. Signed-off-by: Brian Swetland --- arch/arm/mach-msm/Makefile | 4 +- arch/arm/mach-msm/board-halibut.c | 37 +--- arch/arm/mach-msm/common.c | 116 ------------ arch/arm/mach-msm/devices.c | 267 +++++++++++++++++++++++++++ arch/arm/mach-msm/devices.h | 36 ++++ arch/arm/mach-msm/include/mach/debug-macro.S | 8 +- arch/arm/mach-msm/include/mach/msm_iomap.h | 69 ++++--- arch/arm/mach-msm/io.c | 12 +- arch/arm/mach-msm/irq.c | 10 +- arch/arm/mach-msm/timer.c | 2 +- 10 files changed, 368 insertions(+), 193 deletions(-) delete mode 100644 arch/arm/mach-msm/common.c create mode 100644 arch/arm/mach-msm/devices.c create mode 100644 arch/arm/mach-msm/devices.h (limited to 'arch/arm/mach-msm/Makefile') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index ae96ffff494..d4d1deabce4 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,8 +1,6 @@ obj-y += io.o idle.o irq.o timer.o dma.o +obj-y += devices.o obj-y += proc_comm.o -# Common code for board init -obj-y += common.o - obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index a24259133e0..b263783dadb 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -33,6 +33,8 @@ #include #include +#include "devices.h" + static struct resource smc91x_resources[] = { [0] = { .start = 0x9C004300, @@ -53,31 +55,12 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; -static void mddi0_panel_power(int on) -{ -} - -static struct msm_mddi_platform_data msm_mddi0_pdata = { - .panel_power = mddi0_panel_power, - .has_vsync_irq = 0, -}; - -static struct platform_device msm_mddi0_device = { - .name = "msm_mddi", - .id = 0, - .dev = { - .platform_data = &msm_mddi0_pdata - }, -}; - -static struct platform_device msm_serial0_device = { - .name = "msm_serial", - .id = 0, -}; - static struct platform_device *devices[] __initdata = { - &msm_serial0_device, - &msm_mddi0_device, + &msm_device_uart3, + &msm_device_smd, + &msm_device_nand, + &msm_device_hsusb, + &msm_device_i2c, &smc91x_device, }; @@ -91,7 +74,6 @@ static void __init halibut_init_irq(void) static void __init halibut_init(void) { platform_add_devices(devices, ARRAY_SIZE(devices)); - msm_add_devices(); } static void __init halibut_map_io(void) @@ -100,11 +82,6 @@ static void __init halibut_map_io(void) } MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") - -/* UART for LL DEBUG */ - .phys_io = MSM_UART1_PHYS, - .io_pg_offst = ((MSM_UART1_BASE) >> 18) & 0xfffc, - .boot_params = 0x10000100, .map_io = halibut_map_io, .init_irq = halibut_init_irq, diff --git a/arch/arm/mach-msm/common.c b/arch/arm/mach-msm/common.c deleted file mode 100644 index 604f8ade958..00000000000 --- a/arch/arm/mach-msm/common.c +++ /dev/null @@ -1,116 +0,0 @@ -/* linux/arch/arm/mach-msm/common.c - * - * Common setup code for MSM7K Boards - * - * Copyright (C) 2007 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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 - -struct flash_platform_data msm_nand_data = { - .parts = 0, - .nr_parts = 0, -}; - -static struct resource msm_nand_resources[] = { - [0] = { - .start = 7, - .end = 7, - .flags = IORESOURCE_DMA, - }, -}; - -static struct platform_device msm_nand_device = { - .name = "msm_nand", - .id = -1, - .num_resources = ARRAY_SIZE(msm_nand_resources), - .resource = msm_nand_resources, - .dev = { - .platform_data = &msm_nand_data, - }, -}; - -static struct platform_device msm_smd_device = { - .name = "msm_smd", - .id = -1, -}; - -static struct resource msm_i2c_resources[] = { - { - .start = MSM_I2C_BASE, - .end = MSM_I2C_BASE + MSM_I2C_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_PWB_I2C, - .end = INT_PWB_I2C, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device msm_i2c_device = { - .name = "msm_i2c", - .id = 0, - .num_resources = ARRAY_SIZE(msm_i2c_resources), - .resource = msm_i2c_resources, -}; - -static struct resource usb_resources[] = { - { - .start = MSM_HSUSB_PHYS, - .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_USB_HS, - .end = INT_USB_HS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device msm_hsusb_device = { - .name = "msm_hsusb", - .id = -1, - .num_resources = ARRAY_SIZE(usb_resources), - .resource = usb_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, -}; - -static struct platform_device *devices[] __initdata = { - &msm_nand_device, - &msm_smd_device, - &msm_i2c_device, - &msm_hsusb_device, -}; - -void __init msm_add_devices(void) -{ - platform_add_devices(devices, ARRAY_SIZE(devices)); -} diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices.c new file mode 100644 index 00000000000..f2a74b92a97 --- /dev/null +++ b/arch/arm/mach-msm/devices.c @@ -0,0 +1,267 @@ +/* linux/arch/arm/mach-msm/devices.c + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 "devices.h" + +#include +#include +#include + +static struct resource resources_uart1[] = { + { + .start = INT_UART1, + .end = INT_UART1, + .flags = IORESOURCE_IRQ, + }, + { + .start = MSM_UART1_PHYS, + .end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource resources_uart2[] = { + { + .start = INT_UART2, + .end = INT_UART2, + .flags = IORESOURCE_IRQ, + }, + { + .start = MSM_UART2_PHYS, + .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource resources_uart3[] = { + { + .start = INT_UART3, + .end = INT_UART3, + .flags = IORESOURCE_IRQ, + }, + { + .start = MSM_UART3_PHYS, + .end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device msm_device_uart1 = { + .name = "msm_serial", + .id = 0, + .num_resources = ARRAY_SIZE(resources_uart1), + .resource = resources_uart1, +}; + +struct platform_device msm_device_uart2 = { + .name = "msm_serial", + .id = 1, + .num_resources = ARRAY_SIZE(resources_uart2), + .resource = resources_uart2, +}; + +struct platform_device msm_device_uart3 = { + .name = "msm_serial", + .id = 2, + .num_resources = ARRAY_SIZE(resources_uart3), + .resource = resources_uart3, +}; + +static struct resource resources_i2c[] = { + { + .start = MSM_I2C_PHYS, + .end = MSM_I2C_PHYS + MSM_I2C_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_PWB_I2C, + .end = INT_PWB_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device msm_device_i2c = { + .name = "msm_i2c", + .id = 0, + .num_resources = ARRAY_SIZE(resources_i2c), + .resource = resources_i2c, +}; + +static struct resource resources_hsusb[] = { + { + .start = MSM_HSUSB_PHYS, + .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_USB_HS, + .end = INT_USB_HS, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device msm_device_hsusb = { + .name = "msm_hsusb", + .id = -1, + .num_resources = ARRAY_SIZE(resources_hsusb), + .resource = resources_hsusb, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +struct flash_platform_data msm_nand_data = { + .parts = NULL, + .nr_parts = 0, +}; + +static struct resource resources_nand[] = { + [0] = { + .start = 7, + .end = 7, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device msm_device_nand = { + .name = "msm_nand", + .id = -1, + .num_resources = ARRAY_SIZE(resources_nand), + .resource = resources_nand, + .dev = { + .platform_data = &msm_nand_data, + }, +}; + +struct platform_device msm_device_smd = { + .name = "msm_smd", + .id = -1, +}; + +static struct resource resources_sdc1[] = { + { + .start = MSM_SDC1_PHYS, + .end = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_SDC1_0, + .end = INT_SDC1_1, + .flags = IORESOURCE_IRQ, + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource resources_sdc2[] = { + { + .start = MSM_SDC2_PHYS, + .end = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_SDC2_0, + .end = INT_SDC2_1, + .flags = IORESOURCE_IRQ, + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource resources_sdc3[] = { + { + .start = MSM_SDC3_PHYS, + .end = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_SDC3_0, + .end = INT_SDC3_1, + .flags = IORESOURCE_IRQ, + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_DMA, + }, +}; + +static struct resource resources_sdc4[] = { + { + .start = MSM_SDC4_PHYS, + .end = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_SDC4_0, + .end = INT_SDC4_1, + .flags = IORESOURCE_IRQ, + }, + { + .start = 8, + .end = 8, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device msm_device_sdc1 = { + .name = "msm_sdcc", + .id = 1, + .num_resources = ARRAY_SIZE(resources_sdc1), + .resource = resources_sdc1, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +struct platform_device msm_device_sdc2 = { + .name = "msm_sdcc", + .id = 2, + .num_resources = ARRAY_SIZE(resources_sdc2), + .resource = resources_sdc2, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +struct platform_device msm_device_sdc3 = { + .name = "msm_sdcc", + .id = 3, + .num_resources = ARRAY_SIZE(resources_sdc3), + .resource = resources_sdc3, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +struct platform_device msm_device_sdc4 = { + .name = "msm_sdcc", + .id = 4, + .num_resources = ARRAY_SIZE(resources_sdc4), + .resource = resources_sdc4, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h new file mode 100644 index 00000000000..0744c4a27d6 --- /dev/null +++ b/arch/arm/mach-msm/devices.h @@ -0,0 +1,36 @@ +/* linux/arch/arm/mach-msm/devices.h + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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_DEVICES_H +#define __ARCH_ARM_MACH_MSM_DEVICES_H + +extern struct platform_device msm_device_uart1; +extern struct platform_device msm_device_uart2; +extern struct platform_device msm_device_uart3; + +extern struct platform_device msm_device_sdc1; +extern struct platform_device msm_device_sdc2; +extern struct platform_device msm_device_sdc3; +extern struct platform_device msm_device_sdc4; + +extern struct platform_device msm_device_hsusb; + +extern struct platform_device msm_device_i2c; + +extern struct platform_device msm_device_smd; + +extern struct platform_device msm_device_nand; + +#endif diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S index 528eef4b605..1db3c97dbc4 100644 --- a/arch/arm/mach-msm/include/mach/debug-macro.S +++ b/arch/arm/mach-msm/include/mach/debug-macro.S @@ -22,18 +22,22 @@ mrc p15, 0, \rx, c1, c0 tst \rx, #1 ldreq \rx, =MSM_UART1_PHYS - ldrne \rx, =MSM_UART1_BASE + movne \rx, #0 .endm .macro senduart,rd,rx - str \rd, [\rx, #0x0C] + teq \rx, #0 + strne \rd, [\rx, #0x0C] .endm .macro waituart,rd,rx @ wait for TX_READY + teq \rx, #0 + bne 2f 1: ldr \rd, [\rx, #0x08] tst \rd, #0x04 beq 1b +2: .endm .macro busyuart,rd,rx diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index e221f58ceea..2f7b4c8620d 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -37,11 +37,17 @@ * */ -#define MSM_VIC_BASE 0xE0000000 +#ifdef __ASSEMBLY__ +#define IOMEM(x) x +#else +#define IOMEM(x) ((void __force __iomem *)(x)) +#endif + +#define MSM_VIC_BASE IOMEM(0xE0000000) #define MSM_VIC_PHYS 0xC0000000 #define MSM_VIC_SIZE SZ_4K -#define MSM_CSR_BASE 0xE0001000 +#define MSM_CSR_BASE IOMEM(0xE0001000) #define MSM_CSR_PHYS 0xC0100000 #define MSM_CSR_SIZE SZ_4K @@ -49,56 +55,67 @@ #define MSM_GPT_BASE MSM_CSR_BASE #define MSM_GPT_SIZE SZ_4K -#define MSM_DMOV_BASE 0xE0002000 +#define MSM_DMOV_BASE IOMEM(0xE0002000) #define MSM_DMOV_PHYS 0xA9700000 #define MSM_DMOV_SIZE SZ_4K -#define MSM_UART1_BASE 0xE0003000 +#define MSM_GPIO1_BASE IOMEM(0xE0003000) +#define MSM_GPIO1_PHYS 0xA9200000 +#define MSM_GPIO1_SIZE SZ_4K + +#define MSM_GPIO2_BASE IOMEM(0xE0004000) +#define MSM_GPIO2_PHYS 0xA9300000 +#define MSM_GPIO2_SIZE SZ_4K + +#define MSM_CLK_CTL_BASE IOMEM(0xE0005000) +#define MSM_CLK_CTL_PHYS 0xA8600000 +#define MSM_CLK_CTL_SIZE SZ_4K + +#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000) +#define MSM_SHARED_RAM_PHYS 0x01F00000 +#define MSM_SHARED_RAM_SIZE SZ_1M + #define MSM_UART1_PHYS 0xA9A00000 #define MSM_UART1_SIZE SZ_4K -#define MSM_UART2_BASE 0xE0004000 #define MSM_UART2_PHYS 0xA9B00000 #define MSM_UART2_SIZE SZ_4K -#define MSM_UART3_BASE 0xE0005000 #define MSM_UART3_PHYS 0xA9C00000 #define MSM_UART3_SIZE SZ_4K -#define MSM_I2C_BASE 0xE0006000 -#define MSM_I2C_PHYS 0xA9900000 -#define MSM_I2C_SIZE SZ_4K +#define MSM_SDC1_PHYS 0xA0400000 +#define MSM_SDC1_SIZE SZ_4K -#define MSM_GPIO1_BASE 0xE0007000 -#define MSM_GPIO1_PHYS 0xA9200000 -#define MSM_GPIO1_SIZE SZ_4K +#define MSM_SDC2_PHYS 0xA0500000 +#define MSM_SDC2_SIZE SZ_4K -#define MSM_GPIO2_BASE 0xE0008000 -#define MSM_GPIO2_PHYS 0xA9300000 -#define MSM_GPIO2_SIZE SZ_4K +#define MSM_SDC3_PHYS 0xA0600000 +#define MSM_SDC3_SIZE SZ_4K + +#define MSM_SDC4_PHYS 0xA0700000 +#define MSM_SDC4_SIZE SZ_4K + +#define MSM_I2C_PHYS 0xA9900000 +#define MSM_I2C_SIZE SZ_4K -#define MSM_HSUSB_BASE 0xE0009000 #define MSM_HSUSB_PHYS 0xA0800000 #define MSM_HSUSB_SIZE SZ_4K -#define MSM_CLK_CTL_BASE 0xE000A000 -#define MSM_CLK_CTL_PHYS 0xA8600000 -#define MSM_CLK_CTL_SIZE SZ_4K - -#define MSM_PMDH_BASE 0xE000B000 #define MSM_PMDH_PHYS 0xAA600000 #define MSM_PMDH_SIZE SZ_4K -#define MSM_EMDH_BASE 0xE000C000 #define MSM_EMDH_PHYS 0xAA700000 #define MSM_EMDH_SIZE SZ_4K -#define MSM_MDP_BASE 0xE0010000 #define MSM_MDP_PHYS 0xAA200000 #define MSM_MDP_SIZE 0x000F0000 -#define MSM_SHARED_RAM_BASE 0xE0100000 -#define MSM_SHARED_RAM_PHYS 0x01F00000 -#define MSM_SHARED_RAM_SIZE SZ_1M +#define MSM_MDC_PHYS 0xAA500000 +#define MSM_MDC_SIZE SZ_1M + +#define MSM_AD5_PHYS 0xAC000000 +#define MSM_AD5_SIZE (SZ_1M*13) + #endif diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 7999e4ba8e2..6e7692ff6f2 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -28,7 +28,7 @@ #include #define MSM_DEVICE(name) { \ - .virtual = MSM_##name##_BASE, \ + .virtual = (unsigned long) MSM_##name##_BASE, \ .pfn = __phys_to_pfn(MSM_##name##_PHYS), \ .length = MSM_##name##_SIZE, \ .type = MT_DEVICE_NONSHARED, \ @@ -39,19 +39,11 @@ static struct map_desc msm_io_desc[] __initdata = { MSM_DEVICE(CSR), MSM_DEVICE(GPT), MSM_DEVICE(DMOV), - MSM_DEVICE(UART1), - MSM_DEVICE(UART2), - MSM_DEVICE(UART3), - MSM_DEVICE(I2C), MSM_DEVICE(GPIO1), MSM_DEVICE(GPIO2), - MSM_DEVICE(HSUSB), MSM_DEVICE(CLK_CTL), - MSM_DEVICE(PMDH), - MSM_DEVICE(EMDH), - MSM_DEVICE(MDP), { - .virtual = MSM_SHARED_RAM_BASE, + .virtual = (unsigned long) MSM_SHARED_RAM_BASE, .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), .length = MSM_SHARED_RAM_SIZE, .type = MT_DEVICE, diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c index 04b8d182ff8..69ca0dd79bd 100644 --- a/arch/arm/mach-msm/irq.c +++ b/arch/arm/mach-msm/irq.c @@ -66,20 +66,20 @@ static void msm_irq_ack(unsigned int irq) { - unsigned reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0); + void __iomem *reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0); irq = 1 << (irq & 31); writel(irq, reg); } static void msm_irq_mask(unsigned int irq) { - unsigned reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0); + void __iomem *reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0); writel(1 << (irq & 31), reg); } static void msm_irq_unmask(unsigned int irq) { - unsigned reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0); + void __iomem *reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0); writel(1 << (irq & 31), reg); } @@ -90,8 +90,8 @@ static int msm_irq_set_wake(unsigned int irq, unsigned int on) static int msm_irq_set_type(unsigned int irq, unsigned int flow_type) { - unsigned treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0); - unsigned preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0); + void __iomem *treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0); + void __iomem *preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0); int b = 1 << (irq & 31); if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 2bffe9b7e9f..345a14cb73c 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -45,7 +45,7 @@ struct msm_clock { struct clock_event_device clockevent; struct clocksource clocksource; struct irqaction irq; - uint32_t regbase; + void __iomem *regbase; uint32_t freq; uint32_t shift; }; -- cgit v1.2.3-70-g09d2 From 600f7cfebeef74a6ba961c507079e3629da5dd7a Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Tue, 9 Sep 2008 11:04:14 -0700 Subject: [ARM] msm: clock: provide clk_*() api support for Makes use of the proc_comm interface to provide clock control on MSM7X01A family SoCs. Signed-off-by: Brian Swetland --- arch/arm/mach-msm/Makefile | 1 + arch/arm/mach-msm/board-halibut.c | 1 + arch/arm/mach-msm/clock-7x01a.c | 126 +++++++++++++++++++ arch/arm/mach-msm/clock.c | 218 +++++++++++++++++++++++++++++++++ arch/arm/mach-msm/clock.h | 48 ++++++++ arch/arm/mach-msm/include/mach/board.h | 1 + 6 files changed, 395 insertions(+) create mode 100644 arch/arm/mach-msm/clock-7x01a.c create mode 100644 arch/arm/mach-msm/clock.c create mode 100644 arch/arm/mach-msm/clock.h (limited to 'arch/arm/mach-msm/Makefile') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index d4d1deabce4..bfcb2518ba5 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,6 +1,7 @@ obj-y += io.o idle.o irq.o timer.o dma.o obj-y += devices.o obj-y += proc_comm.o +obj-y += clock.o clock-7x01a.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index b263783dadb..c2a96e3965a 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -79,6 +79,7 @@ static void __init halibut_init(void) static void __init halibut_map_io(void) { msm_map_common_io(); + msm_clock_init(); } MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c new file mode 100644 index 00000000000..62230a3428e --- /dev/null +++ b/arch/arm/mach-msm/clock-7x01a.c @@ -0,0 +1,126 @@ +/* arch/arm/mach-msm/clock-7x01a.c + * + * Clock tables for MSM7X01A + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007 QUALCOMM Incorporated + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 "clock.h" +#include "devices.h" + +/* clock IDs used by the modem processor */ + +#define ACPU_CLK 0 /* Applications processor clock */ +#define ADM_CLK 1 /* Applications data mover clock */ +#define ADSP_CLK 2 /* ADSP clock */ +#define EBI1_CLK 3 /* External bus interface 1 clock */ +#define EBI2_CLK 4 /* External bus interface 2 clock */ +#define ECODEC_CLK 5 /* External CODEC clock */ +#define EMDH_CLK 6 /* External MDDI host clock */ +#define GP_CLK 7 /* General purpose clock */ +#define GRP_CLK 8 /* Graphics clock */ +#define I2C_CLK 9 /* I2C clock */ +#define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */ +#define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */ +#define IMEM_CLK 12 /* Internal graphics memory clock */ +#define MDC_CLK 13 /* MDDI client clock */ +#define MDP_CLK 14 /* Mobile display processor clock */ +#define PBUS_CLK 15 /* Peripheral bus clock */ +#define PCM_CLK 16 /* PCM clock */ +#define PMDH_CLK 17 /* Primary MDDI host clock */ +#define SDAC_CLK 18 /* Stereo DAC clock */ +#define SDC1_CLK 19 /* Secure Digital Card clocks */ +#define SDC1_PCLK 20 +#define SDC2_CLK 21 +#define SDC2_PCLK 22 +#define SDC3_CLK 23 +#define SDC3_PCLK 24 +#define SDC4_CLK 25 +#define SDC4_PCLK 26 +#define TSIF_CLK 27 /* Transport Stream Interface clocks */ +#define TSIF_REF_CLK 28 +#define TV_DAC_CLK 29 /* TV clocks */ +#define TV_ENC_CLK 30 +#define UART1_CLK 31 /* UART clocks */ +#define UART2_CLK 32 +#define UART3_CLK 33 +#define UART1DM_CLK 34 +#define UART2DM_CLK 35 +#define USB_HS_CLK 36 /* High speed USB core clock */ +#define USB_HS_PCLK 37 /* High speed USB pbus clock */ +#define USB_OTG_CLK 38 /* Full speed USB clock */ +#define VDC_CLK 39 /* Video controller clock */ +#define VFE_CLK 40 /* Camera / Video Front End clock */ +#define VFE_MDC_CLK 41 /* VFE MDDI client clock */ + +#define NR_CLKS 42 + +#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \ + .name = clk_name, \ + .id = clk_id, \ + .flags = clk_flags, \ + .dev = clk_dev, \ + } + +#define OFF CLKFLAG_AUTO_OFF +#define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET + +struct clk msm_clocks[] = { + CLOCK("adm_clk", ADM_CLK, NULL, 0), + CLOCK("adsp_clk", ADSP_CLK, NULL, 0), + CLOCK("ebi1_clk", EBI1_CLK, NULL, 0), + CLOCK("ebi2_clk", EBI2_CLK, NULL, 0), + CLOCK("ecodec_clk", ECODEC_CLK, NULL, 0), + CLOCK("emdh_clk", EMDH_CLK, NULL, OFF), + CLOCK("gp_clk", GP_CLK, NULL, 0), + CLOCK("grp_clk", GRP_CLK, NULL, OFF), + CLOCK("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0), + CLOCK("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), + CLOCK("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), + CLOCK("imem_clk", IMEM_CLK, NULL, OFF), + CLOCK("mdc_clk", MDC_CLK, NULL, 0), + CLOCK("mdp_clk", MDP_CLK, NULL, OFF), + CLOCK("pbus_clk", PBUS_CLK, NULL, 0), + CLOCK("pcm_clk", PCM_CLK, NULL, 0), + CLOCK("pmdh_clk", PMDH_CLK, NULL, OFF | MINMAX), + CLOCK("sdac_clk", SDAC_CLK, NULL, OFF), + CLOCK("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), + CLOCK("sdc_pclk", SDC1_PCLK, &msm_device_sdc1.dev, OFF), + CLOCK("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF), + CLOCK("sdc_pclk", SDC2_PCLK, &msm_device_sdc2.dev, OFF), + CLOCK("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF), + CLOCK("sdc_pclk", SDC3_PCLK, &msm_device_sdc3.dev, OFF), + CLOCK("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF), + CLOCK("sdc_pclk", SDC4_PCLK, &msm_device_sdc4.dev, OFF), + CLOCK("tsif_clk", TSIF_CLK, NULL, 0), + CLOCK("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), + CLOCK("tv_dac_clk", TV_DAC_CLK, NULL, 0), + CLOCK("tv_enc_clk", TV_ENC_CLK, NULL, 0), + CLOCK("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF), + CLOCK("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), + CLOCK("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), + CLOCK("uart1dm_clk", UART1DM_CLK, NULL, OFF), + CLOCK("uart2dm_clk", UART2DM_CLK, NULL, 0), + CLOCK("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF), + CLOCK("usb_hs_pclk", USB_HS_PCLK, &msm_device_hsusb.dev, OFF), + CLOCK("usb_otg_clk", USB_OTG_CLK, NULL, 0), + CLOCK("vdc_clk", VDC_CLK, NULL, OFF | MINMAX), + CLOCK("vfe_clk", VFE_CLK, NULL, OFF), + CLOCK("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), +}; + +unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks); diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c new file mode 100644 index 00000000000..3b1ce36f103 --- /dev/null +++ b/arch/arm/mach-msm/clock.c @@ -0,0 +1,218 @@ +/* arch/arm/mach-msm/clock.c + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007 QUALCOMM Incorporated + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 "clock.h" +#include "proc_comm.h" + +static DEFINE_MUTEX(clocks_mutex); +static DEFINE_SPINLOCK(clocks_lock); +static LIST_HEAD(clocks); + +/* + * glue for the proc_comm interface + */ +static inline int pc_clk_enable(unsigned id) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL); +} + +static inline void pc_clk_disable(unsigned id) +{ + msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL); +} + +static inline int pc_clk_set_rate(unsigned id, unsigned rate) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); +} + +static inline int pc_clk_set_min_rate(unsigned id, unsigned rate) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate); +} + +static inline int pc_clk_set_max_rate(unsigned id, unsigned rate) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate); +} + +static inline int pc_clk_set_flags(unsigned id, unsigned flags) +{ + return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags); +} + +static inline unsigned pc_clk_get_rate(unsigned id) +{ + if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL)) + return 0; + else + return id; +} + +static inline unsigned pc_clk_is_enabled(unsigned id) +{ + if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL)) + return 0; + else + return id; +} + +static inline int pc_pll_request(unsigned id, unsigned on) +{ + on = !!on; + return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on); +} + +/* + * Standard clock functions defined in include/linux/clk.h + */ +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *clk; + + mutex_lock(&clocks_mutex); + + list_for_each_entry(clk, &clocks, list) + if (!strcmp(id, clk->name) && clk->dev == dev) + goto found_it; + + list_for_each_entry(clk, &clocks, list) + if (!strcmp(id, clk->name) && clk->dev == NULL) + goto found_it; + + clk = ERR_PTR(-ENOENT); +found_it: + mutex_unlock(&clocks_mutex); + return clk; +} +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + spin_lock_irqsave(&clocks_lock, flags); + clk->count++; + if (clk->count == 1) + pc_clk_enable(clk->id); + spin_unlock_irqrestore(&clocks_lock, flags); + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + spin_lock_irqsave(&clocks_lock, flags); + BUG_ON(clk->count == 0); + clk->count--; + if (clk->count == 0) + pc_clk_disable(clk->id); + spin_unlock_irqrestore(&clocks_lock, flags); +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return pc_clk_get_rate(clk->id); +} +EXPORT_SYMBOL(clk_get_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret; + if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) { + ret = pc_clk_set_max_rate(clk->id, rate); + if (ret) + return ret; + return pc_clk_set_min_rate(clk->id, rate); + } + return pc_clk_set_rate(clk->id, rate); +} +EXPORT_SYMBOL(clk_set_rate); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + return -ENOSYS; +} +EXPORT_SYMBOL(clk_set_parent); + +struct clk *clk_get_parent(struct clk *clk) +{ + return ERR_PTR(-ENOSYS); +} +EXPORT_SYMBOL(clk_get_parent); + +int clk_set_flags(struct clk *clk, unsigned long flags) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + return pc_clk_set_flags(clk->id, flags); +} +EXPORT_SYMBOL(clk_set_flags); + + +void __init msm_clock_init(void) +{ + unsigned n; + + spin_lock_init(&clocks_lock); + mutex_lock(&clocks_mutex); + for (n = 0; n < msm_num_clocks; n++) + list_add_tail(&msm_clocks[n].list, &clocks); + mutex_unlock(&clocks_mutex); +} + +/* The bootloader and/or AMSS may have left various clocks enabled. + * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have + * not been explicitly enabled by a clk_enable() call. + */ +static int __init clock_late_init(void) +{ + unsigned long flags; + struct clk *clk; + unsigned count = 0; + + mutex_lock(&clocks_mutex); + list_for_each_entry(clk, &clocks, list) { + if (clk->flags & CLKFLAG_AUTO_OFF) { + spin_lock_irqsave(&clocks_lock, flags); + if (!clk->count) { + count++; + pc_clk_disable(clk->id); + } + spin_unlock_irqrestore(&clocks_lock, flags); + } + } + mutex_unlock(&clocks_mutex); + pr_info("clock_late_init() disabled %d unused clocks\n", count); + return 0; +} + +late_initcall(clock_late_init); diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h new file mode 100644 index 00000000000..f875e1544e5 --- /dev/null +++ b/arch/arm/mach-msm/clock.h @@ -0,0 +1,48 @@ +/* arch/arm/mach-msm/clock.h + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007 QUALCOMM Incorporated + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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_CLOCK_H +#define __ARCH_ARM_MACH_MSM_CLOCK_H + +#include + +#define CLKFLAG_INVERT 0x00000001 +#define CLKFLAG_NOINVERT 0x00000002 +#define CLKFLAG_NONEST 0x00000004 +#define CLKFLAG_NORESET 0x00000008 + +#define CLK_FIRST_AVAILABLE_FLAG 0x00000100 +#define CLKFLAG_USE_MIN_MAX_TO_SET 0x00000200 +#define CLKFLAG_AUTO_OFF 0x00000400 + +struct clk { + uint32_t id; + uint32_t count; + uint32_t flags; + const char *name; + struct list_head list; + struct device *dev; +}; + +#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100) +#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) +#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) + +extern struct clk msm_clocks[]; +extern unsigned msm_num_clocks; + +#endif + diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h index a7639493c09..264d62e519f 100644 --- a/arch/arm/mach-msm/include/mach/board.h +++ b/arch/arm/mach-msm/include/mach/board.h @@ -33,5 +33,6 @@ void __init msm_add_devices(void); void __init msm_map_common_io(void); void __init msm_init_irq(void); void __init msm_init_gpio(void); +void __init msm_clock_init(void); #endif -- cgit v1.2.3-70-g09d2 From f030d7b65e4e6399f23de2a41a58d1b607b6bd89 Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Mon, 29 Sep 2008 14:07:14 -0700 Subject: [ARM] msm: vreg interface to msm7k pmic The baseband cpu owns the pmic, so voltage regulator control is only available via a relatively limited interface through the proc_comm transport. Signed-off-by: Brian Swetland --- arch/arm/mach-msm/Makefile | 1 + arch/arm/mach-msm/include/mach/vreg.h | 29 +++++++ arch/arm/mach-msm/vreg.c | 143 ++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 arch/arm/mach-msm/include/mach/vreg.h create mode 100644 arch/arm/mach-msm/vreg.c (limited to 'arch/arm/mach-msm/Makefile') diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index bfcb2518ba5..1aa47001aa3 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,6 +1,7 @@ obj-y += io.o idle.o irq.o timer.o dma.o obj-y += devices.o obj-y += proc_comm.o +obj-y += vreg.o obj-y += clock.o clock-7x01a.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o diff --git a/arch/arm/mach-msm/include/mach/vreg.h b/arch/arm/mach-msm/include/mach/vreg.h new file mode 100644 index 00000000000..9f9e25cb718 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/vreg.h @@ -0,0 +1,29 @@ +/* linux/include/asm-arm/arch-msm/vreg.h + * + * Copyright (C) 2008 Google, Inc. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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_VREG_H +#define __ARCH_ARM_MACH_MSM_VREG_H + +struct vreg; + +struct vreg *vreg_get(struct device *dev, const char *id); +void vreg_put(struct vreg *vreg); + +int vreg_enable(struct vreg *vreg); +void vreg_disable(struct vreg *vreg); +int vreg_set_level(struct vreg *vreg, unsigned mv); + +#endif diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c new file mode 100644 index 00000000000..fcb0b9f2568 --- /dev/null +++ b/arch/arm/mach-msm/vreg.c @@ -0,0 +1,143 @@ +/* arch/arm/mach-msm/vreg.c + * + * Copyright (C) 2008 Google, Inc. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 "proc_comm.h" + +struct vreg { + const char *name; + unsigned id; +}; + +#define VREG(_name, _id) { .name = _name, .id = _id, } + +static struct vreg vregs[] = { + VREG("msma", 0), + VREG("msmp", 1), + VREG("msme1", 2), + VREG("msmc1", 3), + VREG("msmc2", 4), + VREG("gp3", 5), + VREG("msme2", 6), + VREG("gp4", 7), + VREG("gp1", 8), + VREG("tcxo", 9), + VREG("pa", 10), + VREG("rftx", 11), + VREG("rfrx1", 12), + VREG("rfrx2", 13), + VREG("synt", 14), + VREG("wlan", 15), + VREG("usb", 16), + VREG("boost", 17), + VREG("mmc", 18), + VREG("ruim", 19), + VREG("msmc0", 20), + VREG("gp2", 21), + VREG("gp5", 22), + VREG("gp6", 23), + VREG("rf", 24), + VREG("rf_vco", 26), + VREG("mpll", 27), + VREG("s2", 28), + VREG("s3", 29), + VREG("rfubm", 30), + VREG("ncp", 31), +}; + +struct vreg *vreg_get(struct device *dev, const char *id) +{ + int n; + for (n = 0; n < ARRAY_SIZE(vregs); n++) { + if (!strcmp(vregs[n].name, id)) + return vregs + n; + } + return 0; +} + +void vreg_put(struct vreg *vreg) +{ +} + +int vreg_enable(struct vreg *vreg) +{ + unsigned id = vreg->id; + unsigned enable = 1; + return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); +} + +void vreg_disable(struct vreg *vreg) +{ + unsigned id = vreg->id; + unsigned enable = 0; + msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); +} + +int vreg_set_level(struct vreg *vreg, unsigned mv) +{ + unsigned id = vreg->id; + return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv); +} + +#if defined(CONFIG_DEBUG_FS) + +static int vreg_debug_set(void *data, u64 val) +{ + struct vreg *vreg = data; + switch (val) { + case 0: + vreg_disable(vreg); + break; + case 1: + vreg_enable(vreg); + break; + default: + vreg_set_level(vreg, val); + break; + } + return 0; +} + +static int vreg_debug_get(void *data, u64 *val) +{ + return -ENOSYS; +} + +DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n"); + +static int __init vreg_debug_init(void) +{ + struct dentry *dent; + int n; + + dent = debugfs_create_dir("vreg", 0); + if (IS_ERR(dent)) + return 0; + + for (n = 0; n < ARRAY_SIZE(vregs); n++) + (void) debugfs_create_file(vregs[n].name, 0644, + dent, vregs + n, &vreg_fops); + + return 0; +} + +device_initcall(vreg_debug_init); +#endif -- cgit v1.2.3-70-g09d2