OMAP System Control Module
Subsystems (10)
cover OMAP System Control Module
Hello Paul and Tony,
This is a series of patches adding a basic support for system control module, on OMAP4+ context. It is a working in progress, but I wanted to share already to get your feedback.
I've modeled the driver as an MFD. You will see in this series:
. A rework of the system control module header (patch from Santosh, picked from the list) . Device creation for control module core
. Early device creation for control module core
. The MFD core driver for system control module
. The MFD child for usb-phy pin control
. The MFD child for bandgap sensor
. Very early exposure of OMAP4 thermal zone
. All added drivers are only supporting DT probing
. The series is based on linux-omap master, as it has the hwmod entries for SCM.
The overall idea of this series is to put in place the infrastructure. It is not touching nor removing the existing APIs under mach-omap2/control.c for now. But the target is to have these APIs moved to the MFD core driver.
For early access, like ID checking, I have written the platform driver as an early platform driver and you will see also early device addition and probing under device.c for this case. This is of course a proposal. I see that there are people that thing this is a bit of an overkill. Konstantin (CCd) was proposing a simpler solution by having APIs with early_* prefixes, and solve the IO address mapping with a DT entry, for instance. But feel free to propose better ways.
This code has been ripped off from the Android 3.1 branch. I have rewritten a couple of things, but the major driver functions and API's entries are kept.
So, based on this series, I see as a TODO list, for system control core driver:
- Start to move all the existing APIs under mach-omap2/control.c to the mfd core.
- Rewrite the users of the existing APIs, mentioned on previous item Once we decide the API and agree on how to deal with early calls.
- Add remaining children (from top of my head, the CAM is one of them, but I also think we should prob have one for HWOBS for instance)
- Test on boards that use the existing APIs.
TODO list for bandgap driver:
- Improve thermal zone definition for OMAP4
- Introduce the thermal zones for OMAP5
Amit, due to hwmod dep, I didn't include any cooling binding in this series, based on the generic CPU cooling device.
Overall series has been tested only with panda board OMAP4460.
Your comments are welcome.
All best,
Eduardo Valentin (9):
ARM: OMAP: expose control.h to mach area
OMAP: Add early device for system control module
mfd: omap: control: core system control driver
OMAP2+: use control module mfd driver in omap_type
mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
ARM: OMAP4+: Adding the temperature sensor register set bit fields
ARM: OMAP4+: thermal: introduce bandgap temperature sensor
omap4: thermal: add basic CPU thermal zone
ARM: DT: Add support to system control module for OMAP4
Kishon Vijay Abraham I (1):
arm: omap: device: create a device for system control module
Santosh Shilimkar (1):
ARM: OMAP4: Remove un-used control module headers and defines.
.../devicetree/bindings/mfd/omap_control.txt | 44 +
.../devicetree/bindings/thermal/omap_bandgap.txt | 27 +
arch/arm/boot/dts/omap4.dtsi | 13 +
arch/arm/mach-omap2/Kconfig | 1 +
arch/arm/mach-omap2/am35xx-emac.c | 2 +-
arch/arm/mach-omap2/board-3430sdp.c | 2 +-
arch/arm/mach-omap2/board-4430sdp.c | 2 +-
arch/arm/mach-omap2/board-am3517crane.c | 2 +-
arch/arm/mach-omap2/board-am3517evm.c | 2 +-
arch/arm/mach-omap2/board-apollon.c | 2 +-
arch/arm/mach-omap2/board-cm-t3517.c | 2 +-
arch/arm/mach-omap2/board-h4.c | 2 +-
arch/arm/mach-omap2/board-igep0020.c | 2 +-
arch/arm/mach-omap2/board-ldp.c | 2 +-
arch/arm/mach-omap2/board-omap3logic.c | 2 +-
arch/arm/mach-omap2/board-omap4panda.c | 2 +-
arch/arm/mach-omap2/board-omap4pcm049.c | 2 +-
arch/arm/mach-omap2/clock2420_data.c | 2 +-
arch/arm/mach-omap2/clock2430_data.c | 2 +-
arch/arm/mach-omap2/clock3xxx_data.c | 2 +-
arch/arm/mach-omap2/clock44xx_data.c | 2 +-
arch/arm/mach-omap2/common.c | 2 +-
arch/arm/mach-omap2/control.c | 2 +-
arch/arm/mach-omap2/cpuidle34xx.c | 2 +-
arch/arm/mach-omap2/devices.c | 57 +-
arch/arm/mach-omap2/display.c | 2 +-
arch/arm/mach-omap2/hsmmc.c | 2 +-
arch/arm/mach-omap2/id.c | 18 +-
arch/arm/mach-omap2/{ => include/mach}/control.h | 163 ++-
.../include/mach/ctrl_module_core_44xx.h | 391 -----
.../include/mach/ctrl_module_pad_core_44xx.h | 1409 -----------------
.../include/mach/ctrl_module_pad_wkup_44xx.h | 236 ---
.../include/mach/ctrl_module_wkup_44xx.h | 92 --
arch/arm/mach-omap2/mcbsp.c | 2 +-
arch/arm/mach-omap2/mux.c | 2 +-
arch/arm/mach-omap2/omap_phy_internal.c | 2 +-
arch/arm/mach-omap2/opp3xxx_data.c | 2 +-
arch/arm/mach-omap2/opp4xxx_data.c | 2 +-
arch/arm/mach-omap2/pm24xx.c | 2 +-
arch/arm/mach-omap2/pm34xx.c | 2 +-
arch/arm/mach-omap2/prcm.c | 2 +-
arch/arm/mach-omap2/serial.c | 2 +-
arch/arm/mach-omap2/sleep34xx.S | 2 +-
arch/arm/mach-omap2/sr_device.c | 2 +-
arch/arm/mach-omap2/usb-fs.c | 2 +-
arch/arm/mach-omap2/voltage.c | 2 +-
arch/arm/plat-omap/Kconfig | 3 +
drivers/mfd/Kconfig | 9 +
drivers/mfd/Makefile | 1 +
drivers/mfd/omap-control-core.c | 211 +++
drivers/thermal/Kconfig | 25 +
drivers/thermal/Makefile | 5 +-
drivers/thermal/omap-bandgap.c | 1602 ++++++++++++++++++++
drivers/thermal/omap-bandgap.h | 75 +
drivers/thermal/omap4-thermal.c | 72 +
drivers/usb/otg/Kconfig | 13 +
drivers/usb/otg/Makefile | 1 +
drivers/usb/otg/omap4-usb-phy.c | 130 ++
include/linux/mfd/omap_control.h | 69 +
include/linux/usb/omap4_usb_phy.h | 53 +
60 files changed, 2617 insertions(+), 2173 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/omap_control.txt
create mode 100644 Documentation/devicetree/bindings/thermal/omap_bandgap.txt
rename arch/arm/mach-omap2/{ => include/mach}/control.h (75%)
delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h
delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h
delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
create mode 100644 drivers/mfd/omap-control-core.c
create mode 100644 drivers/thermal/omap-bandgap.c
create mode 100644 drivers/thermal/omap-bandgap.h
create mode 100644 drivers/thermal/omap4-thermal.c
create mode 100644 drivers/usb/otg/omap4-usb-phy.c
create mode 100644 include/linux/mfd/omap_control.h
create mode 100644 include/linux/usb/omap4_usb_phy.hSignature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 1/11 ARM: OMAP4: Remove un-used control module headers and defines.
From: Santosh Shilimkar <[email protected]>
Most of the OMAP4 control module register defines are not used and can be removed. Keep only needed defines and move them to common control module header just like other OMAP versions.
--- arch/arm/mach-omap2/control.h | 45 +- .../include/mach/ctrl_module_core_44xx.h | 391 ------ .../include/mach/ctrl_module_pad_core_44xx.h | 1409 -------------------- .../include/mach/ctrl_module_pad_wkup_44xx.h | 236 ---- .../include/mach/ctrl_module_wkup_44xx.h | 92 -- 5 files changed, 40 insertions(+), 2133 deletions(-) delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
arch/arm/mach-omap2/control.h +40 -5
@@ -16,11 +16,6 @@#ifndef __ARCH_ARM_MACH_OMAP2_CONTROL_H#define __ARCH_ARM_MACH_OMAP2_CONTROL_H -#include <mach/ctrl_module_core_44xx.h> -#include <mach/ctrl_module_wkup_44xx.h> -#include <mach/ctrl_module_pad_core_44xx.h> -#include <mach/ctrl_module_pad_wkup_44xx.h> -#ifndef __ASSEMBLY__#define OMAP242X_CTRL_REGADDR (reg) \ OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
@@ -183,6 +178,43 @@#define OMAP3630_CONTROL_FUSE_OPP50_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)#define OMAP3630_CONTROL_FUSE_OPP100_VDD2 (OMAP2_CONTROL_GENERAL + 0x012C) +/* OMAP4 IDCODE CONTROL */ +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1 0x0218 +#define OMAP4_CTRL_MODULE_CORE_STATUS 0x02c4 + +/* CONTROL_I2C_1 */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1 0x0624 +#define OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK (1 << 28) +#define OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK (1 << 24) + +/* DSI CONTROL_DSIPHY */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY 0x0618 +#define OMAP4_DSI2_LANEENABLE_SHIFT 29 +#define OMAP4_DSI2_LANEENABLE_MASK (0x7 << 29) +#define OMAP4_DSI1_LANEENABLE_SHIFT 24 +#define OMAP4_DSI1_LANEENABLE_MASK (0x1f << 24) +#define OMAP4_DSI1_PIPD_SHIFT 19 +#define OMAP4_DSI1_PIPD_MASK (0x1f << 19) +#define OMAP4_DSI2_PIPD_SHIFT 14 +#define OMAP4_DSI2_PIPD_MASK (0x1f << 14) + +/* CONTROL_PBIASLITE */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE 0x0600 +#define OMAP4_MMC1_PWRDNZ_MASK (1 << 26) +#define OMAP4_MMC1_PBIASLITE_VMODE_MASK (1 << 21) +#define OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK (1 << 22) +#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK (1 << 23) + +/* CONTROL_MMC1 */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1 0x0628 +#define OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK (1 << 31) +#define OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK (1 << 30) +#define OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK (1 << 29) +#define OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK (1 << 28) +#define OMAP4_SDMMC1_DR0_SPEEDCTRL_MASK (1 << 27) +#define OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK (1 << 26) +#define OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK (1 << 25) +/* OMAP44xx control efuse offsets */ #define OMAP44XX_CONTROL_FUSE_IVA_OPP50 0x22C#define OMAP44XX_CONTROL_FUSE_IVA_OPP100 0x22F
@@ -195,6 +227,9 @@#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257 +/* OMAP44xx control McBSP padconf */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP 0x061c +/* AM35XX only CONTROL_GENERAL register offsets */ #define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h deleted +0 -391
391 lines not on this page · raw message
arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h deleted +0 -1409
1,409 lines not on this page · raw message
arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h deleted +0 -236
236 lines not on this page · raw message
arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h deleted +0 -92
92 lines not on this page · raw message
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 1/11 ARM: OMAP4: Remove un-used control module headers and defines.
Quoted 9 lines · Eduardo Valentin
From: Santosh Shilimkar <[email protected]>
Most of the OMAP4 control module register defines are not used and can be removed. Keep only needed defines and move them to common control module header just like other OMAP versions.
Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>---
Thanks for picking this up in your series
Regards
Santposh
RFC PATCH 2/11 ARM: OMAP: expose control.h to mach area
In reply to Eduardo ValentinThis patch exposes the definitions under control.h to drivers outside the machine code.
---
arch/arm/mach-omap2/am35xx-emac.c | 2 +-
arch/arm/mach-omap2/board-3430sdp.c | 2 +-
arch/arm/mach-omap2/board-4430sdp.c | 2 +-
arch/arm/mach-omap2/board-am3517crane.c | 2 +-
arch/arm/mach-omap2/board-am3517evm.c | 2 +-
arch/arm/mach-omap2/board-apollon.c | 2 +-
arch/arm/mach-omap2/board-cm-t3517.c | 2 +-
arch/arm/mach-omap2/board-h4.c | 2 +-
arch/arm/mach-omap2/board-igep0020.c | 2 +-
arch/arm/mach-omap2/board-ldp.c | 2 +-
arch/arm/mach-omap2/board-omap3logic.c | 2 +-
arch/arm/mach-omap2/board-omap4panda.c | 2 +-
arch/arm/mach-omap2/board-omap4pcm049.c | 2 +-
arch/arm/mach-omap2/clock2420_data.c | 2 +-
arch/arm/mach-omap2/clock2430_data.c | 2 +-
arch/arm/mach-omap2/clock3xxx_data.c | 2 +-
arch/arm/mach-omap2/clock44xx_data.c | 2 +-
arch/arm/mach-omap2/common.c | 2 +-
arch/arm/mach-omap2/control.c | 2 +-
arch/arm/mach-omap2/cpuidle34xx.c | 2 +-
arch/arm/mach-omap2/devices.c | 2 +-
arch/arm/mach-omap2/display.c | 2 +-
arch/arm/mach-omap2/hsmmc.c | 2 +-
arch/arm/mach-omap2/id.c | 2 +-
arch/arm/mach-omap2/{ => include/mach}/control.h | 2 +-
arch/arm/mach-omap2/mcbsp.c | 2 +-
arch/arm/mach-omap2/mux.c | 2 +-
arch/arm/mach-omap2/omap_phy_internal.c | 2 +-
arch/arm/mach-omap2/opp3xxx_data.c | 2 +-
arch/arm/mach-omap2/opp4xxx_data.c | 2 +-
arch/arm/mach-omap2/pm24xx.c | 2 +-
arch/arm/mach-omap2/pm34xx.c | 2 +-
arch/arm/mach-omap2/prcm.c | 2 +-
arch/arm/mach-omap2/serial.c | 2 +-
arch/arm/mach-omap2/sleep34xx.S | 2 +-
arch/arm/mach-omap2/sr_device.c | 2 +-
arch/arm/mach-omap2/usb-fs.c | 2 +-
arch/arm/mach-omap2/voltage.c | 2 +-
38 files changed, 38 insertions(+), 38 deletions(-)
rename arch/arm/mach-omap2/{ => include/mach}/control.h (99%)arch/arm/mach-omap2/am35xx-emac.c +1 -1
@@ -21,7 +21,7 @@#include <plat/irqs.h> #include <mach/am35xx.h> -#include "control.h" +#include <mach/control.h> static struct mdio_platform_data am35xx_emac_mdio_pdata;
arch/arm/mach-omap2/board-3430sdp.c +1 -1
@@ -46,7 +46,7 @@#include "sdram-qimonda-hyb18m512160af-6.h" #include "hsmmc.h" #include "pm.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #define CONFIG_DISABLE_HFCLK 1
arch/arm/mach-omap2/board-4430sdp.c +1 -1
@@ -47,7 +47,7 @@#include "mux.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #define ETH_KS8851_IRQ 34
arch/arm/mach-omap2/board-am3517crane.c +1 -1
@@ -32,7 +32,7 @@#include "am35xx-emac.h" #include "mux.h" -#include "control.h" +#include <mach/control.h> #define GPIO_USB_POWER 35#define GPIO_USB_NRESET 38
arch/arm/mach-omap2/board-am3517evm.c +1 -1
@@ -41,7 +41,7 @@#include "am35xx-emac.h" #include "mux.h" -#include "control.h" +#include <mach/control.h> #include "hsmmc.h" #define LCD_PANEL_PWR 176
arch/arm/mach-omap2/board-apollon.c +1 -1
@@ -44,7 +44,7 @@#include <video/omap-panel-generic-dpi.h> #include "mux.h" -#include "control.h" +#include <mach/control.h> /* LED & Switch macros */ #define LED0_GPIO13 13
arch/arm/mach-omap2/board-cm-t3517.c +1 -1
@@ -47,7 +47,7 @@#include <mach/am35xx.h> #include "mux.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #include "am35xx-emac.h"
arch/arm/mach-omap2/board-h4.c +1 -1
@@ -43,7 +43,7 @@#include <video/omap-panel-generic-dpi.h> #include "mux.h" -#include "control.h" +#include <mach/control.h> #define H4_FLASH_CS 0#define H4_SMC91X_CS 1
arch/arm/mach-omap2/board-igep0020.c +1 -1
@@ -42,7 +42,7 @@#include "sdram-numonyx-m65kxxxxam.h" #include "common-board-devices.h" #include "board-flash.h" -#include "control.h" +#include <mach/control.h> #define IGEP2_SMSC911X_CS 5#define IGEP2_SMSC911X_GPIO 176
arch/arm/mach-omap2/board-ldp.c +1 -1
@@ -50,7 +50,7 @@#include "board-flash.h" #include "mux.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #define LDP_SMSC911X_CS 1
arch/arm/mach-omap2/board-omap3logic.c +1 -1
@@ -37,7 +37,7 @@#include "mux.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #include <plat/mux.h>
arch/arm/mach-omap2/board-omap4panda.c +1 -1
@@ -45,7 +45,7 @@#include <video/omap-panel-tfp410.h> #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "mux.h" #include "common-board-devices.h"
arch/arm/mach-omap2/board-omap4pcm049.c +1 -1
@@ -48,7 +48,7 @@#include "common.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "mux.h" #include "common-board-devices.h"
arch/arm/mach-omap2/clock2420_data.c +1 -1
@@ -30,7 +30,7 @@#include "prm-regbits-24xx.h" #include "cm-regbits-24xx.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> #define OMAP_CM_REGADDR OMAP2420_CM_REGADDR
arch/arm/mach-omap2/clock2430_data.c +1 -1
@@ -29,7 +29,7 @@#include "prm-regbits-24xx.h" #include "cm-regbits-24xx.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> #define OMAP_CM_REGADDR OMAP2430_CM_REGADDR
arch/arm/mach-omap2/clock3xxx_data.c +1 -1
@@ -34,7 +34,7 @@#include "cm-regbits-34xx.h" #include "prm2xxx_3xxx.h" #include "prm-regbits-34xx.h" -#include "control.h" +#include <mach/control.h> /* * clocks
arch/arm/mach-omap2/clock44xx_data.c +1 -1
@@ -39,7 +39,7 @@#include "cm-regbits-44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" -#include "control.h" +#include <mach/control.h> #include "scrm44xx.h" /* OMAP4 modulemode control */
arch/arm/mach-omap2/common.c +1 -1
@@ -25,7 +25,7 @@#include "iomap.h" #include "common.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> /* Global address base setup code */
arch/arm/mach-omap2/control.c +1 -1
@@ -26,7 +26,7 @@#include "cm2xxx_3xxx.h" #include "sdrc.h" #include "pm.h" -#include "control.h" +#include <mach/control.h> /* Used by omap3_ctrl_save_padconf() */ #define START_PADCONF_SAVE 0x2
arch/arm/mach-omap2/cpuidle34xx.c +1 -1
@@ -33,7 +33,7 @@#include "clockdomain.h" #include "pm.h" -#include "control.h" +#include <mach/control.h> #include "common.h" #ifdef CONFIG_CPU_IDLE
arch/arm/mach-omap2/devices.c +1 -1
@@ -34,7 +34,7 @@#include <plat/omap4-keypad.h> #include "mux.h" -#include "control.h" +#include <mach/control.h> #include "devices.h" #define L3_MODULES_MAX_LEN 12
arch/arm/mach-omap2/display.c +1 -1
@@ -32,7 +32,7 @@#include "iomap.h" #include "mux.h" -#include "control.h" +#include <mach/control.h> #include "display.h" #define DISPC_CONTROL 0x0040
arch/arm/mach-omap2/hsmmc.c +1 -1
@@ -22,7 +22,7 @@#include "mux.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #if defined(CONFIG_MMC_OMAP_HS ) || defined(CONFIG_MMC_OMAP_HS_MODULE )
arch/arm/mach-omap2/id.c +1 -1
@@ -26,7 +26,7 @@#include <mach/id.h> -#include "control.h" +#include <mach/control.h> static unsigned int omap_revision;static const char *cpu_rev;
arch/arm/mach-omap2/include/mach/control.h renamed from arch/arm/mach-omap2/control.h +1 -1
@@ -1,5 +1,5 @@/* -* arch/arm/mach-omap2/control.h +* arch/arm/mach-omap2/include/mach/control.h * * OMAP2/3/4 System Control Module definitions *
arch/arm/mach-omap2/mcbsp.c +1 -1
@@ -25,7 +25,7 @@#include <plat/omap_device.h> #include <linux/pm_runtime.h> -#include "control.h" +#include <mach/control.h> /* * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
arch/arm/mach-omap2/mux.c +1 -1
@@ -38,7 +38,7 @@#include <plat/omap_hwmod.h> -#include "control.h" +#include <mach/control.h> #include "mux.h" #include "prm.h"
arch/arm/mach-omap2/omap_phy_internal.c +1 -1
@@ -29,7 +29,7 @@#include <linux/usb.h> #include <plat/usb.h> -#include "control.h" +#include <mach/control.h> /* OMAP control module register for UTMI PHY */ #define CONTROL_DEV_CONF 0x300
arch/arm/mach-omap2/opp3xxx_data.c +1 -1
@@ -21,7 +21,7 @@#include <plat/cpu.h> -#include "control.h" +#include <mach/control.h> #include "omap_opp_data.h" #include "pm.h"
arch/arm/mach-omap2/opp4xxx_data.c +1 -1
@@ -22,7 +22,7 @@#include <plat/cpu.h> -#include "control.h" +#include <mach/control.h> #include "omap_opp_data.h" #include "pm.h"
arch/arm/mach-omap2/pm24xx.c +1 -1
@@ -49,7 +49,7 @@#include "cm-regbits-24xx.h" #include "sdrc.h" #include "pm.h" -#include "control.h" +#include <mach/control.h> #include "powerdomain.h" #include "clockdomain.h"
arch/arm/mach-omap2/pm34xx.c +1 -1
@@ -49,7 +49,7 @@#include "prm2xxx_3xxx.h" #include "pm.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> /* pm34xx errata defined in pm.h */ u16 pm34xx_errata;
arch/arm/mach-omap2/prcm.c +1 -1
@@ -37,7 +37,7 @@#include "prminst44xx.h" #include "prm-regbits-24xx.h" #include "prm-regbits-44xx.h" -#include "control.h" +#include <mach/control.h> void __iomem *prm_base;void __iomem *cm_base;
arch/arm/mach-omap2/serial.c +1 -1
@@ -39,7 +39,7 @@#include "pm.h" #include "cm2xxx_3xxx.h" #include "prm-regbits-34xx.h" -#include "control.h" +#include <mach/control.h> #include "mux.h" /*
arch/arm/mach-omap2/sleep34xx.S +1 -1
@@ -33,7 +33,7 @@ #include "cm2xxx_3xxx.h" #include "prm2xxx_3xxx.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> /* * Registers access definitions
arch/arm/mach-omap2/sr_device.c +1 -1
@@ -26,7 +26,7 @@#include "smartreflex.h" #include "voltage.h" -#include "control.h" +#include <mach/control.h> #include "pm.h" static bool sr_enable_on_init;
arch/arm/mach-omap2/usb-fs.c +1 -1
@@ -32,7 +32,7 @@#include <plat/usb.h> #include <plat/board.h> -#include "control.h" +#include <mach/control.h> #include "mux.h" #define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN
arch/arm/mach-omap2/voltage.c +1 -1
@@ -34,7 +34,7 @@#include "prm44xx.h" #include "prcm44xx.h" #include "prminst44xx.h" -#include "control.h" +#include <mach/control.h> #include "voltage.h" #include "powerdomain.h"
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 2/11 ARM: OMAP: expose control.h to mach area
Quoted 5 lines · Eduardo Valentin
This patch exposes the definitions under
control.hto drivers outside the machine code.Signed-off-by Eduardo Valentin <[email protected]>---
After second thought, this complete header movement needs to avoided. Drivers should not anyway include something like <mach/control.h>
May be split the control.h header file data into ..
- defines used by mach-omap2/* files which can remain in "control.h" in existing location.
- common functions/defines used across drivers/*, mach-omap2/*, plat-omap/*, should
go to include/linux/omap_control.h
- Driver specific defines like thermal, usb etc, should go to respective drivers file.
What do you think ?
Regards
santosh
RFC PATCH 2/11 ARM: OMAP: expose control.h to mach area
Hello,
Quoted 5 lines · Santosh
Quoted 3 lines · Eduardo Valentin
This patch exposes the definitions under
control.hto drivers outside the machine code.
Quoted 8 lines
Quoted 2 lines
Signed-off-by Eduardo Valentin <[email protected]>---
After second thought, this complete header movement needs to avoided. Drivers should not anyway include something like <
mach/control.h>May be split the
control.hheader file data into ..
- defines used by mach-omap2/* files which can remain in "control.h" in existing location.
OK..
Quoted 3 lines
- common functions/defines used across
drivers/*, mach-omap2/*, plat-omap/*, should
go toinclude/linux/omap_control.h
Right..
Quoted 2 lines
- Driver specific defines like thermal, usb etc, should go to respective drivers file.
Indeed.
Quoted 2 lines
What do you think ?
I think we are in line. And I believe I saw a similar comment by Benoit in other email thread.
Having a better thinking of this, it makes sense to have the definition specific to drivers in the driver scope only, as they are going to be used only there anyway.
I will drop this patch off and update the remaining changes accordingly (drop the change in control.h for thermal specific and move it to omap_bandgap.h).
Quoted 3 lines
Regards
santosh
Signature · 1 line
Eduardo Valentin
Tony Lindgren
maintainerRFC PATCH 2/11 ARM: OMAP: expose control.h to mach area
Quoted 37 lines · Valentin, Eduardo
Hello,
Quoted 5 lines · Santosh
Quoted 3 lines · Eduardo Valentin
This patch exposes the definitions under
control.hto drivers outside the machine code.Quoted 8 lines
Quoted 2 lines
Signed-off-by Eduardo Valentin <[email protected]>---
After second thought, this complete header movement needs to avoided. Drivers should not anyway include something like <
mach/control.h>May be split the
control.hheader file data into ..
- defines used by mach-omap2/* files which can remain in "control.h" in existing location.OK..
Quoted 3 lines
- common functions/defines used across
drivers/*, mach-omap2/*, plat-omap/*, should
go toinclude/linux/omap_control.hRight..
Quoted 2 lines
- Driver specific defines like thermal, usb etc, should go to respective drivers file.
Indeed.
Quoted 2 lines
What do you think ?
I think we are in line. And I believe I saw a similar comment by Benoit in other email thread.
Quoted 7 lines
Having a better thinking of this, it makes sense to have the definition specific to drivers in the driver scope only, as they are going to be used only there anyway.
I will drop this patch off and update the remaining changes accordingly (drop the change in
control.hfor thermal specific and move it toomap_bandgap.h).
Yes good, we should not expose these to the other drivers, that will lead into misuse of these defines from various other drivers that we may not notice until it's too late.
Regards,
Tony
RFC PATCH 3/11 arm: omap: device: create a device for system control module
In reply to Eduardo ValentinFrom: Kishon Vijay Abraham I <[email protected]>
Extracts the device data from hwmod database and create a platform device using omap device build.
The device build is done during postcore_initcall.
--- arch/arm/mach-omap2/devices.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/devices.c +26 -0
@@ -40,6 +40,32 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +static int omap_init_control (void ) +{ +struct omap_hwmod *oh; +struct platform_device *pdev; +const char *oh_name, *name; + + oh_name ="ctrl_module_core" ; + name ="omap-control-core" ; + + oh =omap_hwmod_lookup (oh_name); +if (!oh) { +pr_err ("Could not lookup hwmod for %s\n" , oh_name); +return PTR_ERR (oh); + } + + pdev =omap_device_build (name,-1 , oh,NULL ,0 ,NULL ,0 , true); +if (IS_ERR (pdev)) { +pr_err ("Could not build omap_device for %s %s\n" , + name, oh_name); +return PTR_ERR (pdev); + } + +return 0 ; +} +postcore_initcall (omap_init_control); +static int __init omap3_l3_init (void ) {struct omap_hwmod *oh;
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 3/11 arm: omap: device: create a device for system control module
Quoted 6 lines · Eduardo Valentin
From: Kishon Vijay Abraham I<[email protected]>
Extracts the device data from hwmod database and create a platform device using omap device build.
The device build is done during
postcore_initcall.
Do you still need that since you are supporting only DT? The device will be built automatically in the DT case.
Regards,
Benoit
Quoted 44 lines
Signed-off-by Kishon Vijay Abraham I<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>--- arch/arm/mach-omap2/devices.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +26
-0@@ -40,6 +40,32 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +static int omap_init_control (void ) +{ +struct omap_hwmod *oh; +struct platform_device *pdev; +const char *oh_name, *name; + + oh_name ="ctrl_module_core" ; + name ="omap-control-core" ; + + oh =omap_hwmod_lookup (oh_name); +if (!oh) { +pr_err ("Could not lookup hwmod for %s\n" , oh_name); +return PTR_ERR (oh); + } + + pdev =omap_device_build (name,-1 , oh,NULL ,0 ,NULL ,0 , true); +if (IS_ERR (pdev)) { +pr_err ("Could not build omap_device for %s %s\n" , + name, oh_name); +return PTR_ERR (pdev); + } + +return 0 ; +} +postcore_initcall (omap_init_control); +static int __init omap3_l3_init (void ) {struct omap_hwmod *oh;
RFC PATCH 3/11 arm: omap: device: create a device for system control module
Quoted 10 lines · Cousson Benoit
Quoted 6 lines · Eduardo Valentin
From: Kishon Vijay Abraham I<[email protected]>
Extracts the device data from hwmod database and create a platform device using omap device build.
The device build is done during
postcore_initcall.Do you still need that since you are supporting only DT? The device will be built automatically in the DT case.
In fact this is not needed for DT only probing. Dropping this one.
Quoted 49 lines
Regards,
BenoitQuoted 44 lines
Signed-off-by Kishon Vijay Abraham I<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>--- arch/arm/mach-omap2/devices.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +26
-0@@ -40,6 +40,32 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +static int omap_init_control (void ) +{ +struct omap_hwmod *oh; +struct platform_device *pdev; +const char *oh_name, *name; + + oh_name ="ctrl_module_core" ; + name ="omap-control-core" ; + + oh =omap_hwmod_lookup (oh_name); +if (!oh) { +pr_err ("Could not lookup hwmod for %s\n" , oh_name); +return PTR_ERR (oh); + } + + pdev =omap_device_build (name,-1 , oh,NULL ,0 ,NULL ,0 , true); +if (IS_ERR (pdev)) { +pr_err ("Could not build omap_device for %s %s\n" , + name, oh_name); +return PTR_ERR (pdev); + } + +return 0 ; +} +postcore_initcall (omap_init_control); +static int __init omap3_l3_init (void ) {struct omap_hwmod *oh;
RFC PATCH 3/11 arm: omap: device: create a device for system control module
Hi.
Quoted 11 lines · Eduardo Valentin
Quoted 9 lines · Cousson Benoit
Quoted 6 lines · Eduardo Valentin
From: Kishon Vijay Abraham I<[email protected]>
Extracts the device data from hwmod database and create a platform device using omap device build.
The device build is done during
postcore_initcall.Do you still need that since you are supporting only DT? The device will be built automatically in the DT case.
In fact this is not needed for DT only probing. Dropping this one.
Yes, platform device(struct platform_device) will be built automatically, but omap device(struct omap_device) will not be built. Also when omap device is allocated(omap_device_alloc) hwmod_clocks are registered, but in case of ctrl_module_core device - no new clock are registered. So, is it fine to drop omap device and skip omap_device_build() call?
BR,
Konstantin Baydarov.
Quoted 47 lines
Quoted 47 lines
Regards,
BenoitQuoted 43 lines
Signed-off-by Kishon Vijay Abraham I<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>--- arch/arm/mach-omap2/devices.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +26
-0@@ -40,6 +40,32 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +static int omap_init_control (void ) +{ +struct omap_hwmod *oh; +struct platform_device *pdev; +const char *oh_name, *name; + + oh_name ="ctrl_module_core" ; + name ="omap-control-core" ; + + oh =omap_hwmod_lookup (oh_name); +if (!oh) { +pr_err ("Could not lookup hwmod for %s\n" , oh_name); +return PTR_ERR (oh); + } + + pdev =omap_device_build (name,-1 , oh,NULL ,0 ,NULL ,0 , true); +if (IS_ERR (pdev)) { +pr_err ("Could not build omap_device for %s %s\n" , + name, oh_name); +return PTR_ERR (pdev); + } + +return 0 ; +} +postcore_initcall (omap_init_control); +static int __init omap3_l3_init (void ) {struct omap_hwmod *oh;
RFC PATCH 3/11 arm: omap: device: create a device for system control module
Hello Konstantin,
Sorry for the delayed reply.
Quoted 7 lines · Konstantin Baydarov
?Hi.
Quoted 4 lines · Eduardo Valentin
Quoted 3 lines · Cousson Benoit
Quoted 2 lines · Eduardo Valentin
From: Kishon Vijay Abraham I<[email protected]>
Quoted 8 lines
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
Extracts the device data from hwmod database and create a platform device using omap device build.
The device build is done during
postcore_initcall.Do you still need that since you are supporting only DT? The device will be built automatically in the DT case.
In fact this is not needed for DT only probing. Dropping this one.
Yes, platform
device(struct platform_device)will be built automatically, but omapdevice(struct omap_device)will not be built.
The platform_device will be built as well as the omap_device. There are hooks at the platform_device creation that will proceed with the omap_device deployment. Please check:arch/arm/plat-omap/omap_device.c: _omap_device_notifier_call and omap_device_build_from_dt
Quoted 2 lines
Also when omap device is
allocated(omap_device_alloc)hwmod_clocksare registered, but in case ofctrl_module_coredevice - no new clock are registered. So, is it fine to drop omap device and skipomap_device_build()call?
As explained above, when booting with DT, you will get both, pdev and omap_dev.
Quoted 3 lines
?BR,
? ?Konstantin Baydarov.
All best,
Eduardo
Quoted 49 lines
Quoted 48 lines
Quoted 48 lines
Regards,
BenoitQuoted 43 lines
Signed-off-by Kishon Vijay Abraham I<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>---
?arch/arm/mach-omap2/devices.c | ? 26 ++++++++++++++++++++++++++ ?1 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +0
-0@@ -40,6 +40,32 @@?#define
L3_MODULES_MAX_LEN12
?#defineL3_MODULES3arch/arm/mach-omap2/devices.c +26
-0+static int omap_init_control (void ) +{ + ? struct omap_hwmod ? ? ? ? ? ? ? *oh; + ? struct platform_device ? ? ? ? ?*pdev; + ? const char ? ? ? ? ? ? ? ? ? ? ?*oh_name, *name; + + ? oh_name = "ctrl_module_core"; + ? name = "omap-control-core"; + + ? oh = omap_hwmod_lookup(oh_name); + ? if (!oh) { + ? ? ? ? ? pr_err("Could not lookup hwmod for %s\n", oh_name); + ? ? ? ? ? return PTR_ERR(oh); + ? } + + ? pdev = omap_device_build(name, -1, oh, NULL, 0, NULL, 0, true); + ? if (IS_ERR(pdev)) { + ? ? ? ? ? pr_err("Could not build omap_device for %s %s\n", + ? ? ? ? ? ? ? ? ?name, oh_name); + ? ? ? ? ? return PTR_ERR(pdev); + ? } + + ? return 0; +} +postcore_initcall (omap_init_control); +?static int
__initomap3_l3_init(void)
?{
? ? structomap_hwmod*oh;
Signature · 1 line
Eduardo Valentin
RFC PATCH 3/11 arm: omap: device: create a device for system control module
In reply to Eduardo ValentinHi.
Quoted 27 lines · Eduardo Valentin
From: Kishon Vijay Abraham I <[email protected]>
Extracts the device data from hwmod database and create a platform device using omap device build.
The device build is done during
postcore_initcall.Signed-off-by Kishon Vijay Abraham I <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>--- arch/arm/mach-omap2/devices.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +6
-0@@ -40,6 +40,32 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +static int omap_init_control (void ) +{ +struct omap_hwmod *oh; +struct platform_device *pdev; +const char *oh_name, *name; +
arch/arm/mach-omap2/devices.c line 58
Quoted 10 lines
arch/arm/mach-omap2/devices.c +10
-0+ oh_name ="ctrl_module_core" ; + name ="omap-control-core" ; + + oh =omap_hwmod_lookup (oh_name); +if (!oh) { +pr_err ("Could not lookup hwmod for %s\n" , oh_name); +return PTR_ERR (oh); + } + + pdev =omap_device_build (name,-1 , oh,NULL ,0 ,NULL ,0 , true);
I noticed that control module omap device is created and configured according to following idle flags:
static struct omap_hwmod_class_sysconfig omap44xx_ctrl_module_sysc = {
.rev_offs = 0x0000,
.sysc_offs = 0x0010,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
SIDLE_SMART_WKUP),
.sysc_fields = &omap_hwmod_sysc_type2,
};
IIUC, ".idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | SIDLE_SMART_WKUP)" means that CONTROL_GEN_CORE idlemode will be set to
"0x2,0x3: Clock is automatically gated when there is no access to the Control Module through L4-interconnect". See CONTROL_GEN_CORE_SYSCONFIG register.
So IIUC theoretically CONTROL_GEN_CORE module clock can be automatically gated. Recalling that CONTROL_GEN_CORE module has an THERMAL_ALERT interrupt that is used by the bandgap driver, I'm wondering if the THERMAL_ALERT interrupt will be fired when CONTROL_GEN_CORE module clock is gated? Probably bandgap driver should set CONTROL_GEN_CORE idle mode to SIDLE_NO, to prevent loosing THERMAL_ALERT interrupt?
BR,
Konstantin Baydarov.
Quoted 13 lines
arch/arm/mach-omap2/devices.c +10
-0+if (IS_ERR (pdev)) { +pr_err ("Could not build omap_device for %s %s\n" , + name, oh_name); +return PTR_ERR (pdev); + } + +return 0 ; +} +postcore_initcall (omap_init_control); +static int __init omap3_l3_init (void ) {struct omap_hwmod *oh;
RFC PATCH 4/11 OMAP: Add early device for system control module
In reply to Eduardo ValentinThis is a way to add an early device for system control module. the code is also requesting for driver registration and probing. Done at early_initcall because at that time, ioremapping is possible.
--- arch/arm/mach-omap2/devices.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/devices.c +29 -0
@@ -40,6 +40,35 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +static struct resource control_resources[] = { + [0 ] = { + .start =0x4a002000 , + .end =0x4a0027ff , + .flags =IORESOURCE_MEM , + }, +}; +static struct platform_device control_device = { + .name ="omap-control-core" , + .id =0 , + .resource = control_resources, + .num_resources =ARRAY_SIZE (control_resources), +}; + +static struct platform_device *early_devices[]__initdata = { + &control_device, +}; + +static int __init plat_early_device_setup (void ) +{ +early_platform_add_devices (early_devices, +ARRAY_SIZE (early_devices)); +early_platform_driver_register_all ("early_omap_control" ); +early_platform_driver_probe ("early_omap_control" ,1 , false); + +return 0 ; +} +early_initcall (plat_early_device_setup); +static int omap_init_control (void ) {struct omap_hwmod *oh;
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 4/11 OMAP: Add early device for system control module
Hi , Eduardo.
Quoted 31 lines · Eduardo Valentin
This is a way to add an early device for system control module. the code is also requesting for driver registration and probing. Done at
early_initcallbecause at that time, ioremapping is possible.Signed-off-by Eduardo Valentin <[email protected]>--- arch/arm/mach-omap2/devices.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +14
-0@@ -40,6 +40,35 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +static struct resource control_resources[] = { + [0 ] = { + .start =0x4a002000 , + .end =0x4a0027ff , + .flags =IORESOURCE_MEM , + }, +}; +static struct platform_device control_device = { + .name ="omap-control-core" , + .id =0 , + .resource = control_resources, + .num_resources =ARRAY_SIZE (control_resources), +}; +
arch/arm/mach-omap2/devices.c line 66
Quoted 10 lines
arch/arm/mach-omap2/devices.c +10
-0+static struct platform_device *early_devices[]__initdata = { + &control_device, +}; + +static int __init plat_early_device_setup (void ) +{ +early_platform_add_devices (early_devices, +ARRAY_SIZE (early_devices)); +early_platform_driver_register_all ("early_omap_control" ); +early_platform_driver_probe ("early_omap_control" ,1 , false);
I checked out git://gitorious.org/omap-thermal/omap-thermal.git omap_scm_dev.
Looks like that calling devm_kzalloc() and platform_get_resource() from early_initcall is too early. I get following backtrace (probably the backtrace is kernel config dependent):
...
[ 0.198455] [<c00193b4>] (unwind_backtrace+0x0/0xe0) from [<c02b2a10>] (do_raw_spin_lock+0x20/0x134) [ 0.207977] [<c02b2a10>] (do_raw_spin_lock+0x20/0x134) from [<c05df068>] (_raw_spin_lock_irqsave+0x58/0x64) [ 0.218109] [<c05df068>] (_raw_spin_lock_irqsave+0x58/0x64) from [<c02f03bc>] (devres_add+0x18/0x38) [ 0.227600] [<c02f03bc>] (devres_add+0x18/0x38) from [<c02f07d0>] (devm_kzalloc+0x50/0x5c) [ 0.236206] [<c02f07d0>] (devm_kzalloc+0x50/0x5c) from [<c05c73a4>] (omap_control_probe+0x20/0xe4) [ 0.245544] [<c05c73a4>] (omap_control_probe+0x20/0xe4) from [<c07b3178>] (early_platform_driver_probe+0x1ac/0x23c) [ 0.256378] [<c07b3178>] (early_platform_driver_probe+0x1ac/0x23c) from [<c0798030>] (plat_early_device_setup+0x2c/0x3c) [ 0.267700] [<c0798030>] (plat_early_device_setup+0x2c/0x3c) from [<c078f8c4>] (do_one_initcall+0x90/0x164) [ 0.277801] [<c078f8c4>] (do_one_initcall+0x90/0x164) from [<c078f9ec>] (kernel_init+0x54/0x1a4) [ 0.286956] [<c078f9ec>] (kernel_init+0x54/0x1a4) from [<c0013818>] (kernel_thread_exit+0x0/0x8) [ 0.296203] ------------[ cut here ]------------ [ 0.301086] WARNING: at include/linux/kref.h:41 kobject_get+0x24/0x48() [ 0.308044] [<c00193b4>] (unwind_backtrace+0x0/0xe0) from [<c00394a4>] (warn_slowpath_common+0x48/0x60) [ 0.317871] [<c00394a4>] (warn_slowpath_common+0x48/0x60) from [<c0039574>] (warn_slowpath_null+0x18/0x1c) [ 0.327941] [<c0039574>] (warn_slowpath_null+0x18/0x1c) from [<c02a59b4>] (kobject_get+0x24/0x48) [ 0.337219] [<c02a59b4>] (kobject_get+0x24/0x48) from [<c02eb588>] (get_device+0x14/0x1c) [ 0.345764] [<c02eb588>] (get_device+0x14/0x1c) from [<c02eb66c>] (device_add+0xc4/0x594) [ 0.354370] [<c02eb66c>] (device_add+0xc4/0x594) from [<c03eeab4>] (of_platform_device_create_pdata+0x5c/0x7c) [ 0.364807] [<c03eeab4>] (of_platform_device_create_pdata+0x5c/0x7c) from [<c03eec94>] (of_platform_bus_create+0x1c0/0x258) [ 0.376403] [<c03eec94>] (of_platform_bus_create+0x1c0/0x258) from [<c03eee4c>] (of_platform_populate+0x5c/0x88) [ 0.387023] [<c03eee4c>] (of_platform_populate+0x5c/0x88) from [<c07b3178>] (early_platform_driver_probe+0x1ac/0x23c) [ 0.398101] [<c07b3178>] (early_platform_driver_probe+0x1ac/0x23c) from [<c0798030>] (plat_early_device_setup+0x2c/0x3c) [ 0.409423] [<c0798030>] (plat_early_device_setup+0x2c/0x3c) from [<c078f8c4>] (do_one_initcall+0x90/0x164) [ 0.419586] [<c078f8c4>] (do_one_initcall+0x90/0x164) from [<c078f9ec>] (kernel_init+0x54/0x1a4) [ 0.428771] [<c078f9ec>] (kernel_init+0x54/0x1a4) from [<c0013818>] (kernel_thread_exit+0x0/0x8) [ 0.437957] ---[ end trace da227214a82491b7 ]--
...
BR,
Konstantin Baydarov.
Quoted 8 lines
arch/arm/mach-omap2/devices.c +5
-0+ +return 0 ; +} +early_initcall (plat_early_device_setup); +static int omap_init_control (void ) {struct omap_hwmod *oh;
RFC PATCH 4/11 OMAP: Add early device for system control module
Hello,
Quoted 6 lines · Konstantin Baydarov
?Hi , Eduardo.
Quoted 3 lines · Eduardo Valentin
This is a way to add an early device for system control module. the code is also requesting for driver registration and probing. Done at
early_initcallbecause at that time, ioremapping is possible.
OK. Which debug config you have?
In any case, that can be solved by not requesting the resource and passing the address area by other means.
Quoted 82 lines
Quoted 28 lines
Signed-off-by Eduardo Valentin <[email protected]>---
?arch/arm/mach-omap2/devices.c | ? 29 +++++++++++++++++++++++++++++ ?1 files changed, 29 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +0
-0@@ -40,6 +40,35 @@?#define
L3_MODULES_MAX_LEN12
?#defineL3_MODULES3arch/arm/mach-omap2/devices.c +14
-0+static struct resource control_resources[] = { + ? ? [0] = { + ? ? ? ? ? ? .start ?= 0x4a002000, + ? ? ? ? ? ? .end ? ?= 0x4a0027ff, + ? ? ? ? ? ? .flags ?= IORESOURCE_MEM, + ? ? }, +}; +static struct platform_device control_device = { + ? ? .name ? ? ? ? ? = "omap-control-core", + ? ? .id ? ? ? ? ? ? = 0, + ? ? .resource ? ? ? = control_resources, + ? ? .num_resources ?= ARRAY_SIZE(control_resources), +}; +arch/arm/mach-omap2/devices.c
Quoted 10 lines
arch/arm/mach-omap2/devices.c +10
-0+static struct platform_device *early_devices[]__initdata = { + ? ? &control_device, +}; + +static int __init plat_early_device_setup (void ) +{ + ? ? early_platform_add_devices(early_devices, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ARRAY_SIZE(early_devices)); + ? ? early_platform_driver_register_all("early_omap_control"); + ? ? early_platform_driver_probe("early_omap_control", 1, false);I checked out
git://gitorious.org/omap-thermal/omap-thermal.gitomap_scm_dev.
Looks like that callingdevm_kzalloc()andplatform_get_resource()fromearly_initcallis too early.
I get following backtrace (probably the backtrace is kernel config dependent):
...
[ ? ?0.198455] [<c00193b4>] (unwind_backtrace+0x0/0xe0) from [<c02b2a10>] (do_raw_spin_lock+0x20/0x134)
[ ? ?0.207977] [<c02b2a10>] (do_raw_spin_lock+0x20/0x134) from [<c05df068>] (_raw_spin_lock_irqsave+0x58/0x64) [ ? ?0.218109] [<c05df068>] (_raw_spin_lock_irqsave+0x58/0x64) from [<c02f03bc>] (devres_add+0x18/0x38)
[ ? ?0.227600] [<c02f03bc>] (devres_add+0x18/0x38) from [<c02f07d0>] (devm_kzalloc+0x50/0x5c)
[ ? ?0.236206] [<c02f07d0>] (devm_kzalloc+0x50/0x5c) from [<c05c73a4>] (omap_control_probe+0x20/0xe4)
[ ? ?0.245544] [<c05c73a4>] (omap_control_probe+0x20/0xe4) from [<c07b3178>] (early_platform_driver_probe+0x1ac/0x23c) [ ? ?0.256378] [<c07b3178>] (early_platform_driver_probe+0x1ac/0x23c) from [<c0798030>] (plat_early_device_setup+0x2c/0x3c) [ ? ?0.267700] [<c0798030>] (plat_early_device_setup+0x2c/0x3c) from [<c078f8c4>] (do_one_initcall+0x90/0x164) [ ? ?0.277801] [<c078f8c4>] (do_one_initcall+0x90/0x164) from [<c078f9ec>] (kernel_init+0x54/0x1a4)
[ ? ?0.286956] [<c078f9ec>] (kernel_init+0x54/0x1a4) from [<c0013818>] (kernel_thread_exit+0x0/0x8)
[ ? ?0.296203] ------------[ cut here ]------------
[ ? ?0.301086] WARNING: atinclude/linux/kref.h:41kobject_get+0x24/0x48()
[ ? ?0.308044] [<c00193b4>] (unwind_backtrace+0x0/0xe0) from [<c00394a4>] (warn_slowpath_common+0x48/0x60) [ ? ?0.317871] [<c00394a4>] (warn_slowpath_common+0x48/0x60) from [<c0039574>] (warn_slowpath_null+0x18/0x1c) [ ? ?0.327941] [<c0039574>] (warn_slowpath_null+0x18/0x1c) from [<c02a59b4>] (kobject_get+0x24/0x48)
[ ? ?0.337219] [<c02a59b4>] (kobject_get+0x24/0x48) from [<c02eb588>] (get_device+0x14/0x1c)
[ ? ?0.345764] [<c02eb588>] (get_device+0x14/0x1c) from [<c02eb66c>] (device_add+0xc4/0x594)
[ ? ?0.354370] [<c02eb66c>] (device_add+0xc4/0x594) from [<c03eeab4>] (of_platform_device_create_pdata+0x5c/0x7c) [ ? ?0.364807] [<c03eeab4>] (of_platform_device_create_pdata+0x5c/0x7c) from [<c03eec94>] (of_platform_bus_create+0x1c0/0x258) [ ? ?0.376403] [<c03eec94>] (of_platform_bus_create+0x1c0/0x258) from [<c03eee4c>] (of_platform_populate+0x5c/0x88) [ ? ?0.387023] [<c03eee4c>] (of_platform_populate+0x5c/0x88) from [<c07b3178>] (early_platform_driver_probe+0x1ac/0x23c) [ ? ?0.398101] [<c07b3178>] (early_platform_driver_probe+0x1ac/0x23c) from [<c0798030>] (plat_early_device_setup+0x2c/0x3c) [ ? ?0.409423] [<c0798030>] (plat_early_device_setup+0x2c/0x3c) from [<c078f8c4>] (do_one_initcall+0x90/0x164) [ ? ?0.419586] [<c078f8c4>] (do_one_initcall+0x90/0x164) from [<c078f9ec>] (kernel_init+0x54/0x1a4)
[ ? ?0.428771] [<c078f9ec>] (kernel_init+0x54/0x1a4) from [<c0013818>] (kernel_thread_exit+0x0/0x8)
[ ? ?0.437957] ---[ end traceda227214a82491b7]--
...?BR,
? ?Konstantin Baydarov.Quoted 8 lines
arch/arm/mach-omap2/devices.c +5
-0+ + ? ? return 0; +} +early_initcall (plat_early_device_setup); +?static int
omap_init_control(void)
?{
? ? ? structomap_hwmod? ? ? ? ? ? ? *oh;
Signature · 1 line
Eduardo Valentin
RFC PATCH 4/11 OMAP: Add early device for system control module
In reply to Eduardo ValentinHi.
Quoted 14 lines · Eduardo Valentin
This is a way to add an early device for system control module. the code is also requesting for driver registration and probing. Done at
early_initcallbecause at that time, ioremapping is possible.Signed-off-by Eduardo Valentin <[email protected]>--- arch/arm/mach-omap2/devices.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +0
-0
arch/arm/mach-omap2/devices.c line 49
Quoted 10 lines
arch/arm/mach-omap2/devices.c +7
-0@@ -40,6 +40,35 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +static struct resource control_resources[] = { + [0 ] = { + .start =0x4a002000 , + .end =0x4a0027ff , + .flags =IORESOURCE_MEM , + }, +};
Init control module platform device resources from device tree instead of hard-coding them.
Prevent control module driver registering itself second time after it has already been registered by early_platform_driver_register_all().
arch/arm/boot/dts/omap4.dtsi +3 -0
@@ -275,7 +275,10 @@ ctrl_module_core: ctrl_module_core at 4a002000 { compatible = "ti,omap4-control"; + #address-cells = <1>; + #size-cells = <1>; ti,hwmods = "ctrl_module_core"; + reg = <0x4a002000 0x1000>; bandgap { compatible = "ti,omap4460-bandgap"; interrupts = <0 126 4>; /* talert */
arch/arm/mach-omap2/devices.c +61 -0
87 lines not on this page · raw message
drivers/mfd/omap-control-core.c +4 -0
@@ -194,6 +194,10 @@ static struct platform_driver omap_contrstatic int __init omap_control_init (void ) { +/* Check is early driver probe is done */ +if (!omap_control_module) +return 0 ; +return platform_driver_register (&omap_control_driver); }postcore_initcall_sync (omap_control_init);
RFC PATCH 4/11 OMAP: Add early device for system control module
In reply to Eduardo ValentinQuoted 14 lines · Eduardo Valentin
This is a way to add an early device for system control module. the code is also requesting for driver registration and probing. Done at
early_initcallbecause at that time, ioremapping is possible.Signed-off-by Eduardo Valentin<[email protected]>--- arch/arm/mach-omap2/devices.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +0
-0
arch/arm/mach-omap2/devices.c line 49
Quoted 10 lines
arch/arm/mach-omap2/devices.c +7
-0@@ -40,6 +40,35 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +static struct resource control_resources[] = { + [0 ] = { + .start =0x4a002000 , + .end =0x4a0027ff , + .flags =IORESOURCE_MEM , + }, +};
I guess you should be able to do use DT to build the early device as well. It will avoid hard coding some physical address inside the devices.
Regards,
Benoit
Quoted 25 lines
arch/arm/mach-omap2/devices.c +22
-0+static struct platform_device control_device = { + .name ="omap-control-core" , + .id =0 , + .resource = control_resources, + .num_resources =ARRAY_SIZE (control_resources), +}; + +static struct platform_device *early_devices[]__initdata = { + &control_device, +}; + +static int __init plat_early_device_setup (void ) +{ +early_platform_add_devices (early_devices, +ARRAY_SIZE (early_devices)); +early_platform_driver_register_all ("early_omap_control" ); +early_platform_driver_probe ("early_omap_control" ,1 , false); + +return 0 ; +} +early_initcall (plat_early_device_setup); +static int omap_init_control (void ) {struct omap_hwmod *oh;
RFC PATCH 4/11 OMAP: Add early device for system control module
In reply to Eduardo ValentinQuoted 46 lines · Eduardo Valentin
This is a way to add an early device for system control module. the code is also requesting for driver registration and probing. Done at
early_initcallbecause at that time, ioremapping is possible.Signed-off-by Eduardo Valentin <[email protected]>---
?arch/arm/mach-omap2/devices.c | ? 29 +++++++++++++++++++++++++++++ ?1 files changed, 29 insertions(+), 0 deletions(-)arch/arm/mach-omap2/devices.c +0
-0@@ -40,6 +40,35 @@?#define
L3_MODULES_MAX_LEN12
?#defineL3_MODULES3arch/arm/mach-omap2/devices.c +29
-0+static struct resource control_resources[] = { + ? ? ? [0] = { + ? ? ? ? ? ? ? .start ?= 0x4a002000, + ? ? ? ? ? ? ? .end ? ?= 0x4a0027ff, + ? ? ? ? ? ? ? .flags ?= IORESOURCE_MEM, + ? ? ? }, +}; +static struct platform_device control_device = { + ? ? ? .name ? ? ? ? ? = "omap-control-core", + ? ? ? .id ? ? ? ? ? ? = 0, + ? ? ? .resource ? ? ? = control_resources, + ? ? ? .num_resources ?= ARRAY_SIZE(control_resources), +}; + +static struct platform_device *early_devices[]__initdata = { + ? ? ? &control_device, +}; + +static int __init plat_early_device_setup (void ) +{ + ? ? ? early_platform_add_devices(early_devices, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ARRAY_SIZE(early_devices)); + ? ? ? early_platform_driver_register_all("early_omap_control"); + ? ? ? early_platform_driver_probe("early_omap_control", 1, false); + + ? ? ? return 0; +} +early_initcall (plat_early_device_setup); +
Quoted 3 lines
?static int
omap_init_control(void)
?{
? ? ? ?structomap_hwmod? ? ? ? ? ? ? *oh;
Nice !!
Apart from fix from Konstantin and Benoit's DT comment, patch looks fine to me.
Regards
Santosh
RFC PATCH 5/11 mfd: omap: control: core system control driver
In reply to Eduardo ValentinThis patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
In this patch, the children defined are for:
. USB-phy pin control
. Bangap temperature sensor
Device driver is probed with postcore_initcall. However, as some of the APIs exposed by this driver may be needed in very early init phase, an early init class is also available: "early_omap_control".
--- .../devicetree/bindings/mfd/omap_control.txt | 44 ++++ arch/arm/mach-omap2/Kconfig | 1 + arch/arm/plat-omap/Kconfig | 3 + drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 1 + drivers/mfd/omap-control-core.c | 211 ++++++++++++++++++++ include/linux/mfd/omap_control.h | 69 +++++++ 7 files changed, 338 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/mfd/omap_control.txt create mode 100644 drivers/mfd/omap-control-core.c create mode 100644 include/linux/mfd/omap_control.h
Documentation/devicetree/bindings/mfd/omap_control.txt new file +44 -0
@@ -0,0 +1,44 @@ +* Texas Instrument OMAP System Control Module (SCM) bindings + +The control module allows software control of various static modes supported by +the device. The control module controls the settings of various device modules +through register configuration and internal signals. It also controls the pad +configuration, pin functional multiplexing, and the routing of internal signals +(such as PRCM signals or DMA requests) to output pins configured for hardware +observability. + +Required properties: +- compatible : Should be: + - "ti,omap3-control" for OMAP3 support + - "ti,omap4-control" for OMAP4 support + - "ti,omap5-control" for OMAP5 support + +OMAP specific properties: +- ti,hwmods: Name of the hwmod associated to the control module: + Should be "ctrl_module_core"; + +Sub-nodes: +- bandgap : contains the bandgap node + + The bindings details of individual bandgap device can be found in: + Documentation/devicetree/bindings/thermal/omap_bandgap.txt + +- usb : contains the usb phy pin control node + + The only required property for this child is: + - compatible = "ti,omap4-control-usb"; + +Examples: + +ctrl_module_core: ctrl_module_core at 4a002000 { + compatible = "ti,omap4-control"; + ti,hwmods = "ctrl_module_core"; + bandgap { + compatible = "ti,omap4460-bandgap"; + interrupts = <0 126 4>; /* talert */ + ti,tshut-gpio = <86>; /* tshut */ + }; + usb { + compatible = "ti,omap4-usb-phy"; + }; +};
arch/arm/mach-omap2/Kconfig +1 -0
@@ -52,6 +52,7 @@ config ARCH_OMAP4 select PL310_ERRATA_727915 select ARM_ERRATA_720789 select ARCH_HAS_OPP + select ARCH_HAS_CONTROL_MODULE select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PM
arch/arm/plat-omap/Kconfig +3 -0
@@ -5,6 +5,9 @@ menu "TI OMAP Common Features" config ARCH_OMAP_OTG bool +config ARCH_HAS_CONTROL_MODULE + bool + choice prompt "OMAP System Type" default ARCH_OMAP2PLUS
drivers/mfd/Kconfig +9 -0
@@ -795,6 +795,15 @@ config MFD_WL1273_CORE driver connects the radio-wl1273 V4L2 module and the wl1273 audio codec. +config MFD_OMAP_CONTROL + bool "Texas Instruments OMAP System control module" + depends on ARCH_HAS_CONTROL_MODULE + help + This is the core driver for system control module. This driver + is responsible for creating the control module mfd child, + like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic + change for off mode. + config MFD_OMAP_USB_HOST bool "Support OMAP USBHS core driver" depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
drivers/mfd/Makefile +1 -0
@@ -106,6 +106,7 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
drivers/mfd/omap-control-core.c new file +211 -0
211 lines not on this page · raw message
include/linux/mfd/omap_control.h new file +69 -0
69 lines not on this page · raw message
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 5/11 mfd: omap: control: core system control driver
Quoted 172 lines · Eduardo Valentin
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
In this patch, the children defined are for:
. USB-phy pin control
. Bangap temperature sensorDevice driver is probed with
postcore_initcall. However, as some of the APIs exposed by this driver may be needed in very early init phase, an early init class is also available: "early_omap_control".Signed-off-by J Keerthy<[email protected]>Signed-off-by Kishon Vijay Abraham I<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>--- .../devicetree/bindings/mfd/omap_control.txt | 44 ++++ arch/arm/mach-omap2/Kconfig | 1 + arch/arm/plat-omap/Kconfig | 3 + drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 1 + drivers/mfd/omap-control-core.c | 211 ++++++++++++++++++++ include/linux/mfd/omap_control.h | 69 +++++++ 7 files changed, 338 insertions(+), 0 deletions(-)create mode 100644
Documentation/devicetree/bindings/mfd/omap_control.txtcreate mode 100644drivers/mfd/omap-control-core.c
create mode 100644include/linux/mfd/omap_control.hDocumentation/devicetree/bindings/mfd/omap_control.txt new file +44
-0@@ -0,0 +1,44 @@ +* Texas Instrument OMAP System Control Module (SCM) bindings + +The control module allows software control of various static modes supported by +the device. The control module controls the settings of various device modules +through register configuration and internal signals. It also controls the pad +configuration, pin functional multiplexing, and the routing of internal signals +(such as PRCM signals or DMA requests) to output pins configured for hardware +observability. + +Required properties: +- compatible : Should be: + - "ti,omap3-control" for OMAP3 support + - "ti,omap4-control" for OMAP4 support + - "ti,omap5-control" for OMAP5 support + +OMAP specific properties: +- ti,hwmods: Name of the hwmod associated to the control module: + Should be "ctrl_module_core"; + +Sub-nodes: +- bandgap : contains the bandgap node + + The bindings details of individual bandgap device can be found in: + Documentation/devicetree/bindings/thermal/omap_bandgap.txt + +- usb : contains the usb phy pin control node + + The only required property for this child is: + - compatible = "ti,omap4-control-usb"; + +Examples: + +ctrl_module_core: ctrl_module_core at 4a002000 { + compatible = "ti,omap4-control"; + ti,hwmods = "ctrl_module_core"; + bandgap { + compatible = "ti,omap4460-bandgap"; + interrupts =<0 126 4>; /* talert */ + ti,tshut-gpio =<86>; /* tshut */ + }; + usb { + compatible = "ti,omap4-usb-phy"; + }; +};arch/arm/mach-omap2/Kconfig +1
-0@@ -52,6 +52,7 @@ config ARCH_OMAP4 select PL310_ERRATA_727915 select ARM_ERRATA_720789 select ARCH_HAS_OPP + select ARCH_HAS_CONTROL_MODULE select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PMarch/arm/plat-omap/Kconfig +3
-0@@ -5,6 +5,9 @@ menu "TI OMAP Common Features" config ARCH_OMAP_OTG bool +config ARCH_HAS_CONTROL_MODULE + bool + choice prompt "OMAP System Type" default ARCH_OMAP2PLUSdrivers/mfd/Kconfig +9
-0@@ -795,6 +795,15 @@ config MFD_WL1273_CORE driver connects the radio-wl1273 V4L2 module and the wl1273 audio codec. +config MFD_OMAP_CONTROL + bool "Texas Instruments OMAP System control module" + depends on ARCH_HAS_CONTROL_MODULE + help + This is the core driver for system control module. This driver + is responsible for creating the control module mfd child, + like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic + change for off mode. + config MFD_OMAP_USB_HOST bool "Support OMAP USBHS core driver" depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3drivers/mfd/Makefile +1
-0@@ -106,6 +106,7 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.odrivers/mfd/omap-control-core.c new file +24
-0@@ -0,0 +1,211 @@ +/* +* OMAP system control module driver file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contacts: +* Based on original code written by: +* J Keerthy<[email protected]> +* Moiz Sonasath<[email protected]> +* MFD clean up and re-factoring: +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* 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 <linux/module.h> +#include <linux/export.h>
drivers/mfd/omap-control-core.c line 34
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/mfd/core.h> +#include <linux/mfd/omap_control.h> + +static struct omap_control *omap_control_module;
Mmm, we can have up to 4 control module instances in OMAP4.
Well, I'm not sure it worth considering them as separate devices. Is that your plan as well?
But since they all have different base address, it will be trick to handle them with only a single entry.
Quoted 40 lines
drivers/mfd/omap-control-core.c new file +40
-0+ +/** +* omap_control_readl: Read a single omap control module register. +* +* @dev: device to read from. +* @reg: register to read. +* @val: output with register value. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_readl (struct device *dev,u32 reg,u32 *val) +{ +struct omap_control *omap_control =dev_get_drvdata (dev); + +if (!omap_control) +return -EINVAL ; + + *val =readl (omap_control->base + reg); + +return 0 ; +} +EXPORT_SYMBOL_GPL (omap_control_readl); + +/** +* omap_control_writel: Write a single omap control module register. +* +* @dev: device to read from. +* @val: value to write. +* @reg: register to write to. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_writel (struct device *dev,u32 val,u32 reg) +{ +struct omap_control *omap_control =dev_get_drvdata (dev); +unsigned long flags; + +if (!omap_control) +return -EINVAL ; +
drivers/mfd/omap-control-core.c line 84
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+spin_lock_irqsave (&omap_control->reg_lock, flags); +writel (val, omap_control->base + reg); +spin_unlock_irqrestore (&omap_control->reg_lock, flags); + +return 0 ; +} +EXPORT_SYMBOL_GPL (omap_control_writel); + +/** +* omap_control_get: returns the control module device pinter
typo
Quoted 4 lines
drivers/mfd/omap-control-core.c new file +4
-0+* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/
drivers/mfd/omap-control-core.c line 98
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+struct device *omap_control_get (void ) +{ +unsigned long flags; + +if (!omap_control_module) +return ERR_PTR (-ENODEV ); + +spin_lock_irqsave (&omap_control_module->reg_lock, flags); + omap_control_module->use_count++; +spin_unlock_irqrestore (&omap_control_module->reg_lock, flags);
Don't we do have some better way to increment atomically a variable in Linux.
Quoted 29 lines
drivers/mfd/omap-control-core.c new file +29
-0+ +return omap_control_module->dev; +} +EXPORT_SYMBOL_GPL (omap_control_get); + +/** +* omap_control_put: returns the control module device pinter +* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +void omap_control_put (struct device *dev) +{ +struct omap_control *omap_control =dev_get_drvdata (dev); +unsigned long flags; + +if (!omap_control) +return ; + +spin_lock_irqsave (&omap_control->reg_lock, flags); + omap_control->use_count--; +spin_unlock_irqrestore (&omap_control_module->reg_lock, flags); +} +EXPORT_SYMBOL_GPL (omap_control_put); + +static const struct of_device_id of_omap_control_match[] = { + { .compatible ="ti,omap3-control" , }, + { .compatible ="ti,omap4-control" , }, + { .compatible ="ti,omap5-control" , },
drivers/mfd/omap-control-core.c line 137
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+ { }, +}; + +static int __devinit omap_control_probe (struct platform_device *pdev) +{ +struct resource *res; +void __iomem *base; +struct device *dev =&pdev->dev; +struct device_node *np = dev->of_node; +struct omap_control *omap_control;
Maybe omap_control_data instead? At least if this is drvdata only. If this is supposed to be the *handle* to the control module instance, it should be fine.
Quoted 105 lines
drivers/mfd/omap-control-core.c new file +74
-0+ + omap_control =devm_kzalloc (dev,sizeof (*omap_control),GFP_KERNEL ); +if (!omap_control) { +dev_err (dev,"not enough memory for omap_control\n" ); +return -ENOMEM ; + } + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!res) { +dev_err (dev,"missing memory base resource\n" ); +return -EINVAL ; + } + + base =devm_request_and_ioremap (dev, res); +if (!base) { +dev_err (dev,"ioremap failed\n" ); +return -EADDRNOTAVAIL ; + } + + omap_control->base = base; + omap_control->dev = dev; +spin_lock_init (&omap_control->reg_lock); + +platform_set_drvdata (pdev, omap_control); + omap_control_module = omap_control; + +return of_platform_populate (np, of_omap_control_match,NULL , dev); +} + +static int __devexit omap_control_remove(struct platform_device *pdev) +{ +struct omap_control *omap_control =platform_get_drvdata (pdev); + +spin_lock (&omap_control->reg_lock); +if (omap_control->use_count>0 ) { +spin_unlock (&omap_control->reg_lock); +dev_err (&pdev->dev,"device removed while still being used\n" ); +return -EBUSY ; + } +spin_unlock (&omap_control->reg_lock); + +iounmap (omap_control->base); +platform_set_drvdata (pdev,NULL ); + +return 0 ; +} + +static struct platform_driver omap_control_driver = { + .probe = omap_control_probe, + .remove =__devexit_p (omap_control_remove), + .driver = { + .name ="omap-control-core" , + .owner =THIS_MODULE , + .of_match_table = of_omap_control_match, + }, +}; + +static int __init omap_control_init (void ) +{ +return platform_driver_register (&omap_control_driver); +} +postcore_initcall_sync (omap_control_init); + +static void __exit omap_control_exit(void) +{ +platform_driver_unregister (&omap_control_driver); +} +module_exit (omap_control_exit); +early_platform_init ("early_omap_control" ,&omap_control_driver); + +MODULE_DESCRIPTION ("OMAP system control module driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_ALIAS ("platform:omap-control-core" ); +MODULE_AUTHOR ("Texas Instruments Inc." );include/linux/mfd/omap_control.h new file +25
-0@@ -0,0 +1,69 @@ +/* +* OMAP system control module header file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contact: +* J Keerthy<[email protected]> +* Moiz Sonasath<[email protected]> +* Abraham, Kishon Vijay<[email protected]> +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* 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 __DRIVERS_OMAP_CONTROL_H +#define __DRIVERS_OMAP_CONTROL_H + +#include <linux/err.h>
include/linux/mfd/omap_control.h line 35
Quoted 10 lines
include/linux/mfd/omap_control.h new file +10
-0+ +/** +* struct system control module - scm device structure +* @dev: device pointer +* @base: Base of the temp I/O +* @reg_lock: protect omap_control structure +* @use_count: track API users +*/ +struct omap_control { +struct device *dev;
Do you really need the dev?
You API is device based and not omap_control based, so it should not be needed.
I guess we should be consistent here. We can store the devices and used a device based API or store the omap_control and thus expose a omap_control API.
Regards,
Benoit
RFC PATCH 5/11 mfd: omap: control: core system control driver
Hello,
Quoted 186 lines · Cousson Benoit
Quoted 172 lines · Eduardo Valentin
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
In this patch, the children defined are for:
. USB-phy pin control
. Bangap temperature sensorDevice driver is probed with
postcore_initcall. However, as some of the APIs exposed by this driver may be needed in very early init phase, an early init class is also available: "early_omap_control".Signed-off-by J Keerthy<[email protected]>Signed-off-by Kishon Vijay Abraham I<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>--- .../devicetree/bindings/mfd/omap_control.txt | 44 ++++ arch/arm/mach-omap2/Kconfig | 1 + arch/arm/plat-omap/Kconfig | 3 + drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 1 + drivers/mfd/omap-control-core.c | 211 ++++++++++++++++++++ include/linux/mfd/omap_control.h | 69 +++++++ 7 files changed, 338 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/mfd/omap_control.txt create mode 100644 drivers/mfd/omap-control-core.c create mode 100644 include/linux/mfd/omap_control.hDocumentation/devicetree/bindings/mfd/omap_control.txt new file +44
-0@@ -0,0 +1,44 @@ +* Texas Instrument OMAP System Control Module (SCM) bindings + +The control module allows software control of various static modes supported by +the device. The control module controls the settings of various device modules +through register configuration and internal signals. It also controls the pad +configuration, pin functional multiplexing, and the routing of internal signals +(such as PRCM signals or DMA requests) to output pins configured for hardware +observability. + +Required properties: +- compatible : Should be: + - "ti,omap3-control" for OMAP3 support + - "ti,omap4-control" for OMAP4 support + - "ti,omap5-control" for OMAP5 support + +OMAP specific properties: +- ti,hwmods: Name of the hwmod associated to the control module: + Should be "ctrl_module_core"; + +Sub-nodes: +- bandgap : contains the bandgap node + + The bindings details of individual bandgap device can be found in: + Documentation/devicetree/bindings/thermal/omap_bandgap.txt + +- usb : contains the usb phy pin control node + + The only required property for this child is: + - compatible = "ti,omap4-control-usb"; + +Examples: + +ctrl_module_core: ctrl_module_core at 4a002000 { + compatible = "ti,omap4-control"; + ti,hwmods = "ctrl_module_core"; + bandgap { + compatible = "ti,omap4460-bandgap"; + interrupts =<0 126 4>; /* talert */ + ti,tshut-gpio =<86>; /* tshut */ + }; + usb { + compatible = "ti,omap4-usb-phy"; + }; +};arch/arm/mach-omap2/Kconfig +1
-0@@ -52,6 +52,7 @@ config ARCH_OMAP4 select PL310_ERRATA_727915 select ARM_ERRATA_720789 select ARCH_HAS_OPP + select ARCH_HAS_CONTROL_MODULE select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PMarch/arm/plat-omap/Kconfig +3
-0@@ -5,6 +5,9 @@ menu "TI OMAP Common Features" config ARCH_OMAP_OTG bool +config ARCH_HAS_CONTROL_MODULE + bool + choice prompt "OMAP System Type" default ARCH_OMAP2PLUSdrivers/mfd/Kconfig +9
-0@@ -795,6 +795,15 @@ config MFD_WL1273_CORE driver connects the radio-wl1273 V4L2 module and the wl1273 audio codec. +config MFD_OMAP_CONTROL + bool "Texas Instruments OMAP System control module" + depends on ARCH_HAS_CONTROL_MODULE + help + This is the core driver for system control module. This driver + is responsible for creating the control module mfd child, + like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic + change for off mode. + config MFD_OMAP_USB_HOST bool "Support OMAP USBHS core driver" depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3drivers/mfd/Makefile +1
-0@@ -106,6 +106,7 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.odrivers/mfd/omap-control-core.c new file +24
-0@@ -0,0 +1,211 @@ +/* +* OMAP system control module driver file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contacts: +* Based on original code written by: +* J Keerthy<[email protected]> +* Moiz Sonasath<[email protected]> +* MFD clean up and re-factoring: +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* 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 <linux/module.h> +#include <linux/export.h> drivers/mfd/omap-control-core.c line 34
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/mfd/core.h> +#include <linux/mfd/omap_control.h> + +static struct omap_control *omap_control_module;Mmm, we can have up to 4 control module instances in OMAP4.
Quoted 2 lines
Well, I'm not sure it worth considering them as separate devices. Is that your plan as well?
At least for now I was focusing on the ctrl_module_core ...
Quoted 3 lines
But since they all have different base address, it will be trick to handle them with only a single entry.
Indeed. We can always add the support latter on.
I am not sure what would be the best way to handle those instances though, and how they are going to expose APIs. Would need to have an instance bound to API set?
Quoted 45 lines
Quoted 45 lines
drivers/mfd/omap-control-core.c new file +44
-0+ +/** +* omap_control_readl: Read a single omap control module register. +* +* @dev: device to read from. +* @reg: register to read. +* @val: output with register value. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_readl (struct device *dev,u32 reg,u32 *val) +{ +struct omap_control *omap_control =dev_get_drvdata (dev); + +if (!omap_control) +return -EINVAL ; + + *val =readl (omap_control->base + reg); + +return 0 ; +} +EXPORT_SYMBOL_GPL (omap_control_readl); + +/** +* omap_control_writel: Write a single omap control module register. +* +* @dev: device to read from. +* @val: value to write. +* @reg: register to write to. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_writel (struct device *dev,u32 val,u32 reg) +{ +struct omap_control *omap_control =dev_get_drvdata (dev); +unsigned long flags; + +if (!omap_control) +return -EINVAL ; + +spin_lock_irqsave (&omap_control->reg_lock, flags); +writel (val, omap_control->base + reg); +spin_unlock_irqrestore (&omap_control->reg_lock, flags); +
Quoted 8 lines
drivers/mfd/omap-control-core.c line 84
Quoted 6 lines
drivers/mfd/omap-control-core.c new file +6
-0+return 0 ; +} +EXPORT_SYMBOL_GPL (omap_control_writel); + +/** +* omap_control_get: returns the control module device pinter typo
K
Quoted 10 lines
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +9
-0+* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +struct device *omap_control_get (void ) +{ +unsigned long flags; + +if (!omap_control_module)
Quoted 8 lines
drivers/mfd/omap-control-core.c line 98
Quoted 5 lines
drivers/mfd/omap-control-core.c new file +5
-0+return ERR_PTR (-ENODEV ); + +spin_lock_irqsave (&omap_control_module->reg_lock, flags); + omap_control_module->use_count++; +spin_unlock_irqrestore (&omap_control_module->reg_lock, flags);Don't we do have some better way to increment atomically a variable in Linux.
Yeah we have, atomic API. In general I think the SCM/bangap/phy APIs need to be revisited WRT locking, in general.
Quoted 36 lines
Quoted 36 lines
drivers/mfd/omap-control-core.c new file +35
-0+ +return omap_control_module->dev; +} +EXPORT_SYMBOL_GPL (omap_control_get); + +/** +* omap_control_put: returns the control module device pinter +* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +void omap_control_put (struct device *dev) +{ +struct omap_control *omap_control =dev_get_drvdata (dev); +unsigned long flags; + +if (!omap_control) +return ; + +spin_lock_irqsave (&omap_control->reg_lock, flags); + omap_control->use_count--; +spin_unlock_irqrestore (&omap_control_module->reg_lock, flags); +} +EXPORT_SYMBOL_GPL (omap_control_put); + +static const struct of_device_id of_omap_control_match[] = { + { .compatible ="ti,omap3-control" , }, + { .compatible ="ti,omap4-control" , }, + { .compatible ="ti,omap5-control" , }, + { }, +}; + +static int __devinit omap_control_probe (struct platform_device *pdev) +{ +struct resource *res;
Quoted 8 lines
drivers/mfd/omap-control-core.c line 137
Quoted 4 lines
drivers/mfd/omap-control-core.c new file +4
-0+void __iomem *base; +struct device *dev =&pdev->dev; +struct device_node *np = dev->of_node; +struct omap_control *omap_control;Maybe
omap_control_datainstead? At least if this is drvdata only. If this is supposed to be the *handle* to the control module instance, it should be fine.
That's suppose to be the phandle :-)
Quoted 121 lines
Quoted 106 lines
drivers/mfd/omap-control-core.c new file +74
-0+ + omap_control =devm_kzalloc (dev,sizeof (*omap_control),GFP_KERNEL ); +if (!omap_control) { +dev_err (dev,"not enough memory for omap_control\n" ); +return -ENOMEM ; + } + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!res) { +dev_err (dev,"missing memory base resource\n" ); +return -EINVAL ; + } + + base =devm_request_and_ioremap (dev, res); +if (!base) { +dev_err (dev,"ioremap failed\n" ); +return -EADDRNOTAVAIL ; + } + + omap_control->base = base; + omap_control->dev = dev; +spin_lock_init (&omap_control->reg_lock); + +platform_set_drvdata (pdev, omap_control); + omap_control_module = omap_control; + +return of_platform_populate (np, of_omap_control_match,NULL , dev); +} + +static int __devexit omap_control_remove(struct platform_device *pdev) +{ +struct omap_control *omap_control =platform_get_drvdata (pdev); + +spin_lock (&omap_control->reg_lock); +if (omap_control->use_count>0 ) { +spin_unlock (&omap_control->reg_lock); +dev_err (&pdev->dev,"device removed while still being used\n" ); +return -EBUSY ; + } +spin_unlock (&omap_control->reg_lock); + +iounmap (omap_control->base); +platform_set_drvdata (pdev,NULL ); + +return 0 ; +} + +static struct platform_driver omap_control_driver = { + .probe = omap_control_probe, + .remove =__devexit_p (omap_control_remove), + .driver = { + .name ="omap-control-core" , + .owner =THIS_MODULE , + .of_match_table = of_omap_control_match, + }, +}; + +static int __init omap_control_init (void ) +{ +return platform_driver_register (&omap_control_driver); +} +postcore_initcall_sync (omap_control_init); + +static void __exit omap_control_exit(void) +{ +platform_driver_unregister (&omap_control_driver); +} +module_exit (omap_control_exit); +early_platform_init ("early_omap_control" ,&omap_control_driver); + +MODULE_DESCRIPTION ("OMAP system control module driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_ALIAS ("platform:omap-control-core" ); +MODULE_AUTHOR ("Texas Instruments Inc." );include/linux/mfd/omap_control.h new file +25
-0@@ -0,0 +1,69 @@ +/* +* OMAP system control module header file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contact: +* J Keerthy<[email protected]> +* Moiz Sonasath<[email protected]> +* Abraham, Kishon Vijay<[email protected]> +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* 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 __DRIVERS_OMAP_CONTROL_H +#define __DRIVERS_OMAP_CONTROL_H + +#include <linux/err.h> include/linux/mfd/omap_control.h line 35
Quoted 10 lines
include/linux/mfd/omap_control.h new file +10
-0+ +/** +* struct system control module - scm device structure +* @dev: device pointer +* @base: Base of the temp I/O +* @reg_lock: protect omap_control structure +* @use_count: track API users +*/ +struct omap_control { +struct device *dev;Do you really need the dev?
You API is device based and notomap_controlbased, so it should not be needed.
Quoted 3 lines
I guess we should be consistent here. We can store the devices and used a device based API or store the
omap_controland thus expose aomap_controlAPI.
Yeah, this API structure is left over of the previous driver.
The omap_control_get returns the SCM device reference and the users of SCM use it as parameter for the SCM APIs.
We need to have in mind that, for SCM, the users are:
a. Its children (USB phy, BG, etc)
b. Non children users (mach code)
The refcounting and the locking needs to take care of both I'd say. The struct dev was just a way to pass the SCM phandle.
Quoted 3 lines
Regards,
Benoit
RFC PATCH 5/11 mfd: omap: control: core system control driver
Quoted 189 lines · Eduardo Valentin
Hello,
Quoted 186 lines · Cousson Benoit
Quoted 172 lines · Eduardo Valentin
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
In this patch, the children defined are for:
. USB-phy pin control
. Bangap temperature sensorDevice driver is probed with
postcore_initcall. However, as some of the APIs exposed by this driver may be needed in very early init phase, an early init class is also available: "early_omap_control".Signed-off-by J Keerthy<[email protected]>Signed-off-by Kishon Vijay Abraham I<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>--- .../devicetree/bindings/mfd/omap_control.txt | 44 ++++ arch/arm/mach-omap2/Kconfig | 1 + arch/arm/plat-omap/Kconfig | 3 + drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 1 + drivers/mfd/omap-control-core.c | 211 ++++++++++++++++++++ include/linux/mfd/omap_control.h | 69 +++++++ 7 files changed, 338 insertions(+), 0 deletions(-)create mode 100644
Documentation/devicetree/bindings/mfd/omap_control.txtcreate mode 100644drivers/mfd/omap-control-core.c
create mode 100644include/linux/mfd/omap_control.hDocumentation/devicetree/bindings/mfd/omap_control.txt new file +44
-0@@ -0,0 +1,44 @@ +* Texas Instrument OMAP System Control Module (SCM) bindings + +The control module allows software control of various static modes supported by +the device. The control module controls the settings of various device modules +through register configuration and internal signals. It also controls the pad +configuration, pin functional multiplexing, and the routing of internal signals +(such as PRCM signals or DMA requests) to output pins configured for hardware +observability. + +Required properties: +- compatible : Should be: + - "ti,omap3-control" for OMAP3 support + - "ti,omap4-control" for OMAP4 support + - "ti,omap5-control" for OMAP5 support + +OMAP specific properties: +- ti,hwmods: Name of the hwmod associated to the control module: + Should be "ctrl_module_core"; + +Sub-nodes: +- bandgap : contains the bandgap node + + The bindings details of individual bandgap device can be found in: + Documentation/devicetree/bindings/thermal/omap_bandgap.txt + +- usb : contains the usb phy pin control node + + The only required property for this child is: + - compatible = "ti,omap4-control-usb"; + +Examples: + +ctrl_module_core: ctrl_module_core at 4a002000 { + compatible = "ti,omap4-control"; + ti,hwmods = "ctrl_module_core"; + bandgap { + compatible = "ti,omap4460-bandgap"; + interrupts =<0 126 4>; /* talert */ + ti,tshut-gpio =<86>; /* tshut */ + }; + usb { + compatible = "ti,omap4-usb-phy"; + }; +};arch/arm/mach-omap2/Kconfig +1
-0@@ -52,6 +52,7 @@ config ARCH_OMAP4 select PL310_ERRATA_727915 select ARM_ERRATA_720789 select ARCH_HAS_OPP + select ARCH_HAS_CONTROL_MODULE select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PMarch/arm/plat-omap/Kconfig +3
-0@@ -5,6 +5,9 @@ menu "TI OMAP Common Features" config ARCH_OMAP_OTG bool +config ARCH_HAS_CONTROL_MODULE + bool + choice prompt "OMAP System Type" default ARCH_OMAP2PLUSdrivers/mfd/Kconfig +9
-0@@ -795,6 +795,15 @@ config MFD_WL1273_CORE driver connects the radio-wl1273 V4L2 module and the wl1273 audio codec. +config MFD_OMAP_CONTROL + bool "Texas Instruments OMAP System control module" + depends on ARCH_HAS_CONTROL_MODULE + help + This is the core driver for system control module. This driver + is responsible for creating the control module mfd child, + like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic + change for off mode. + config MFD_OMAP_USB_HOST bool "Support OMAP USBHS core driver" depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3drivers/mfd/Makefile +1
-0@@ -106,6 +106,7 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.odrivers/mfd/omap-control-core.c new file +24
-0@@ -0,0 +1,211 @@ +/* +* OMAP system control module driver file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contacts: +* Based on original code written by: +* J Keerthy<[email protected]> +* Moiz Sonasath<[email protected]> +* MFD clean up and re-factoring: +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* 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 <linux/module.h> +#include <linux/export.h> drivers/mfd/omap-control-core.c line 34
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/mfd/core.h> +#include <linux/mfd/omap_control.h> + +static struct omap_control *omap_control_module;Mmm, we can have up to 4 control module instances in OMAP4.
Quoted 4 lines
Quoted 2 lines
Well, I'm not sure it worth considering them as separate devices. Is that your plan as well?
At least for now I was focusing on the
ctrl_module_core...
OK, that's a good start already :-)
Quoted 8 lines
Quoted 2 lines
But since they all have different base address, it will be trick to handle them with only a single entry.
Indeed. We can always add the support latter on.
I am not sure what would be the best way to handle those instances though, and how they are going to expose APIs. Would need to have an instance bound to API set?
We should not go to that path I guess. We should have an API at children level independent of the underlying control module partitioning.
Regards,
Benoit
Quoted 264 lines
Quoted 44 lines
Quoted 44 lines
drivers/mfd/omap-control-core.c new file +44
-0+ +/** +* omap_control_readl: Read a single omap control module register. +* +* @dev: device to read from. +* @reg: register to read. +* @val: output with register value. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_readl (struct device *dev,u32 reg,u32 *val) +{ +struct omap_control *omap_control =dev_get_drvdata (dev); + +if (!omap_control) +return -EINVAL ; + + *val =readl (omap_control->base + reg); + +return 0 ; +} +EXPORT_SYMBOL_GPL (omap_control_readl); + +/** +* omap_control_writel: Write a single omap control module register. +* +* @dev: device to read from. +* @val: value to write. +* @reg: register to write to. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_writel (struct device *dev,u32 val,u32 reg) +{ +struct omap_control *omap_control =dev_get_drvdata (dev); +unsigned long flags; + +if (!omap_control) +return -EINVAL ; + +spin_lock_irqsave (&omap_control->reg_lock, flags); +writel (val, omap_control->base + reg); +spin_unlock_irqrestore (&omap_control->reg_lock, flags); +Quoted 8 lines
drivers/mfd/omap-control-core.c line 84
Quoted 6 lines
drivers/mfd/omap-control-core.c new file +6
-0+return 0 ; +} +EXPORT_SYMBOL_GPL (omap_control_writel); + +/** +* omap_control_get: returns the control module device pinter typo
K
Quoted 10 lines
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +9
-0+* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +struct device *omap_control_get (void ) +{ +unsigned long flags; + +if (!omap_control_module)Quoted 8 lines
drivers/mfd/omap-control-core.c line 98
Quoted 5 lines
drivers/mfd/omap-control-core.c new file +5
-0+return ERR_PTR (-ENODEV ); + +spin_lock_irqsave (&omap_control_module->reg_lock, flags); + omap_control_module->use_count++; +spin_unlock_irqrestore (&omap_control_module->reg_lock, flags);Don't we do have some better way to increment atomically a variable in Linux.
Yeah we have, atomic API. In general I think the SCM/bangap/phy APIs need to be revisited WRT locking, in general.
Quoted 36 lines
Quoted 36 lines
drivers/mfd/omap-control-core.c new file +35
-0+ +return omap_control_module->dev; +} +EXPORT_SYMBOL_GPL (omap_control_get); + +/** +* omap_control_put: returns the control module device pinter +* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +void omap_control_put (struct device *dev) +{ +struct omap_control *omap_control =dev_get_drvdata (dev); +unsigned long flags; + +if (!omap_control) +return ; + +spin_lock_irqsave (&omap_control->reg_lock, flags); + omap_control->use_count--; +spin_unlock_irqrestore (&omap_control_module->reg_lock, flags); +} +EXPORT_SYMBOL_GPL (omap_control_put); + +static const struct of_device_id of_omap_control_match[] = { + { .compatible ="ti,omap3-control" , }, + { .compatible ="ti,omap4-control" , }, + { .compatible ="ti,omap5-control" , }, + { }, +}; + +static int __devinit omap_control_probe (struct platform_device *pdev) +{ +struct resource *res;Quoted 8 lines
drivers/mfd/omap-control-core.c line 137
Quoted 4 lines
drivers/mfd/omap-control-core.c new file +4
-0+void __iomem *base; +struct device *dev =&pdev->dev; +struct device_node *np = dev->of_node; +struct omap_control *omap_control;Maybe
omap_control_datainstead? At least if this is drvdata only. If this is supposed to be the *handle* to the control module instance, it should be fine.That's suppose to be the phandle :-)
Quoted 121 lines
Quoted 106 lines
drivers/mfd/omap-control-core.c new file +74
-0+ + omap_control =devm_kzalloc (dev,sizeof (*omap_control),GFP_KERNEL ); +if (!omap_control) { +dev_err (dev,"not enough memory for omap_control\n" ); +return -ENOMEM ; + } + + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!res) { +dev_err (dev,"missing memory base resource\n" ); +return -EINVAL ; + } + + base =devm_request_and_ioremap (dev, res); +if (!base) { +dev_err (dev,"ioremap failed\n" ); +return -EADDRNOTAVAIL ; + } + + omap_control->base = base; + omap_control->dev = dev; +spin_lock_init (&omap_control->reg_lock); + +platform_set_drvdata (pdev, omap_control); + omap_control_module = omap_control; + +return of_platform_populate (np, of_omap_control_match,NULL , dev); +} + +static int __devexit omap_control_remove(struct platform_device *pdev) +{ +struct omap_control *omap_control =platform_get_drvdata (pdev); + +spin_lock (&omap_control->reg_lock); +if (omap_control->use_count>0 ) { +spin_unlock (&omap_control->reg_lock); +dev_err (&pdev->dev,"device removed while still being used\n" ); +return -EBUSY ; + } +spin_unlock (&omap_control->reg_lock); + +iounmap (omap_control->base); +platform_set_drvdata (pdev,NULL ); + +return 0 ; +} + +static struct platform_driver omap_control_driver = { + .probe = omap_control_probe, + .remove =__devexit_p (omap_control_remove), + .driver = { + .name ="omap-control-core" , + .owner =THIS_MODULE , + .of_match_table = of_omap_control_match, + }, +}; + +static int __init omap_control_init (void ) +{ +return platform_driver_register (&omap_control_driver); +} +postcore_initcall_sync (omap_control_init); + +static void __exit omap_control_exit(void) +{ +platform_driver_unregister (&omap_control_driver); +} +module_exit (omap_control_exit); +early_platform_init ("early_omap_control" ,&omap_control_driver); + +MODULE_DESCRIPTION ("OMAP system control module driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_ALIAS ("platform:omap-control-core" ); +MODULE_AUTHOR ("Texas Instruments Inc." );include/linux/mfd/omap_control.h new file +25
-0@@ -0,0 +1,69 @@ +/* +* OMAP system control module header file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contact: +* J Keerthy<[email protected]> +* Moiz Sonasath<[email protected]> +* Abraham, Kishon Vijay<[email protected]> +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* 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 __DRIVERS_OMAP_CONTROL_H +#define __DRIVERS_OMAP_CONTROL_H + +#include <linux/err.h> include/linux/mfd/omap_control.h line 35
Quoted 10 lines
include/linux/mfd/omap_control.h new file +10
-0+ +/** +* struct system control module - scm device structure +* @dev: device pointer +* @base: Base of the temp I/O +* @reg_lock: protect omap_control structure +* @use_count: track API users +*/ +struct omap_control { +struct device *dev;Do you really need the dev?
You API is device based and notomap_controlbased, so it should not be needed.Quoted 3 lines
I guess we should be consistent here. We can store the devices and used a device based API or store the
omap_controland thus expose aomap_controlAPI.Yeah, this API structure is left over of the previous driver.
The
omap_control_getreturns the SCM device reference and the users of SCM use it as parameter for the SCM APIs.We need to have in mind that, for SCM, the users are:
a. Its children (USB phy, BG, etc)
b. Non children users (mach code)The refcounting and the locking needs to take care of both I'd say. The struct dev was just a way to pass the SCM phandle.
Quoted 3 lines
Regards,
Benoit
Tony Lindgren
maintainerRFC PATCH 5/11 mfd: omap: control: core system control driver
Quoted 16 lines · Cousson, Benoit
Quoted 7 lines · Eduardo Valentin
Quoted 5 lines
Mmm, we can have up to 4 control module instances in OMAP4.
Well, I'm not sure it worth considering them as separate devices. Is that your plan as well?
At least for now I was focusing on the
ctrl_module_core...OK, that's a good start already :-)
Quoted 5 lines
Quoted 2 lines
But since they all have different base address, it will be trick to handle them with only a single entry.
Indeed. We can always add the support latter on.
Quoted 7 lines
Quoted 3 lines
I am not sure what would be the best way to handle those instances though, and how they are going to expose APIs. Would need to have an instance bound to API set?
We should not go to that path I guess. We should have an API at children level independent of the underlying control module partitioning.
These should be separate driver instances for the control modules.
And then the ioremapped area should ignore at least the padconf registers so drivers/pinctrl/pinctrl-simple can handle those. There should not be any dependencies to the SCM driver from pinctrl-simple, the core SCM driver can manage the clocks and trigger the save of padconf regs.
Also we should allow MMC driver handle the MMC specific registers and USB driver(s) handle the USB specific registers if possible. Those should not live under drivers/mfd unless there are some dependencies other than trying to ioremap the whole SCM module instead of ioremapping in each driver.
We can have a static map for the SCM, so ioremapping each driver individually should not be an issue.
Regards,
Tony
RFC PATCH 5/11 mfd: omap: control: core system control driver
Quoted 33 lines · Tony Lindgren
Quoted 16 lines · Cousson, Benoit
Quoted 7 lines · Eduardo Valentin
Quoted 5 lines
Mmm, we can have up to 4 control module instances in OMAP4.
Well, I'm not sure it worth considering them as separate devices. Is that your plan as well?
At least for now I was focusing on the
ctrl_module_core...OK, that's a good start already :-)
Quoted 5 lines
Quoted 2 lines
But since they all have different base address, it will be trick to handle them with only a single entry.
Indeed. We can always add the support latter on.
Quoted 7 lines
Quoted 3 lines
I am not sure what would be the best way to handle those instances though, and how they are going to expose APIs. Would need to have an instance bound to API set?
We should not go to that path I guess. We should have an API at children level independent of the underlying control module partitioning.
These should be separate driver instances for the control modules.
And then the ioremapped area should ignore at least the padconf registers so
drivers/pinctrl/pinctrl-simplecan handle those. There should not be any dependencies to the SCM driver from pinctrl-simple, the core SCM driver can manage the clocks and trigger the save of padconf regs.
Quoted 9 lines
Also we should allow MMC driver handle the MMC specific registers and USB driver(s) handle the USB specific registers if possible. Those should not live under
drivers/mfdunless there are some dependencies other than trying to ioremap the whole SCM module instead of ioremapping in each driver.We can have a static map for the SCM, so ioremapping each driver individually should not be an issue.
This sounds a good idea. With this we may not even need a core control module drivers if all the individual drivers take care of the registers they care. Mapping shouldn't be a problem as you mentioned.
Regards
Santosh
RFC PATCH 5/11 mfd: omap: control: core system control driver
Quoted 40 lines · Santosh
Quoted 39 lines · Tony Lindgren
Quoted 16 lines · Cousson, Benoit
Quoted 7 lines · Eduardo Valentin
Quoted 5 lines
Mmm, we can have up to 4 control module instances in OMAP4.
Well, I'm not sure it worth considering them as separate devices. Is that your plan as well?
At least for now I was focusing on the
ctrl_module_core...OK, that's a good start already :-)
Quoted 5 lines
Quoted 2 lines
But since they all have different base address, it will be trick to handle them with only a single entry.
Indeed. We can always add the support latter on.
Quoted 7 lines
Quoted 3 lines
I am not sure what would be the best way to handle those instances though, and how they are going to expose APIs. Would need to have an instance bound to API set?
We should not go to that path I guess. We should have an API at children level independent of the underlying control module partitioning.
These should be separate driver instances for the control modules.
And then the ioremapped area should ignore at least the padconf registers so
drivers/pinctrl/pinctrl-simplecan handle those. There should not be any dependencies to the SCM driver from pinctrl-simple, the core SCM driver can manage the clocks and trigger the save of padconf regs.Also we should allow MMC driver handle the MMC specific registers and USB driver(s) handle the USB specific registers if possible. Those should not live under
drivers/mfdunless there are some dependencies other than trying to ioremap the whole SCM module instead of ioremapping in each driver.
Quoted 6 lines
Quoted 3 lines
We can have a static map for the SCM, so ioremapping each driver individually should not be an issue.
This sounds a good idea. With this we may not even need a core control module drivers if all the individual drivers take care of the registers they care. Mapping shouldn't be a problem as you mentioned.
We should keep the MFD for PM / OCP single port correctness. Other than that it will be mostly useless, indeed.
Regards,
Benoit
RFC PATCH 5/11 mfd: omap: control: core system control driver
Hello,
Quoted 35 lines · Cousson Benoit
Quoted 34 lines · Santosh
Quoted 33 lines · Tony Lindgren
Quoted 16 lines · Cousson, Benoit
Quoted 7 lines · Eduardo Valentin
Quoted 5 lines
Mmm, we can have up to 4 control module instances in OMAP4.
Well, I'm not sure it worth considering them as separate devices. Is that your plan as well?
At least for now I was focusing on the
ctrl_module_core...OK, that's a good start already :-)
Quoted 5 lines
Quoted 2 lines
But since they all have different base address, it will be trick to handle them with only a single entry.
Indeed. We can always add the support latter on.
Quoted 7 lines
Quoted 3 lines
I am not sure what would be the best way to handle those instances though, and how they are going to expose APIs. Would need to have an instance bound to API set?
We should not go to that path I guess. We should have an API at children level independent of the underlying control module partitioning.
These should be separate driver instances for the control modules.
And then the ioremapped area should ignore at least the padconf registers so
drivers/pinctrl/pinctrl-simplecan handle those. There should not be any dependencies to the SCM driver from pinctrl-simple, the core SCM driver can manage the clocks and trigger the save of padconf regs.
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Also we should allow MMC driver handle the MMC specific registers and USB driver(s) handle the USB specific registers if possible. Those should not live under
drivers/mfdunless there are some dependencies other than trying to ioremap the whole SCM module instead of ioremapping in each driver.We can have a static map for the SCM, so ioremapping each driver individually should not be an issue.
Within this series I kept the original MFD setup in the original driver found in the TI Android tree. But in fact, I agree with Tony here.
In general, ideally it would be good if we could setup this driver family, having for each driver their respective resources; a separated individual io area, IRQs, locking, APIs, etc.
But, the issue is to avoid having hard coded io areas in the code, and move them to auto generated data, DT/hwmod.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
This sounds a good idea. With this we may not even need a core control module drivers if all the individual drivers take care of the registers they care. Mapping shouldn't be a problem as you mentioned.
We should keep the MFD for PM / OCP single port correctness. Other than that it will be mostly useless, indeed.
Then, I guess the idea of having 1 static mapping for the MFD core, either in DT or hwmod, is to maintain the single OCP port we have today for SCM.
But, Benoit, IIRC, from our previous discussions, we won't have the io area for children autogenerated anyway, as they don't have any OCP. I suppose this applies also for clock data?
If children data won't be autogenerated, assuming we are relying on the autogenerated data, it means that SCM core area is the boundary that will be ioremapped and protected. But then we still have a flaw because children can still stomp between each other. Not to mention non-children users and the pin ctrl simple.
That said, if we want to have these io areas properly assigned to their drivers, we either have children area autogenerated, in DT / hwmod. Or we have them in the code.
Assuming you still want to have the MFD core, for matching w/ the OCP single port, it would still need to have the resources for its children in the driver code.
Or we hack them in the DT entries. Like I already did in this series for the thermal IRQ :-)
Quoted 4 lines
Regards,
Benoit
RFC PATCH 5/11 mfd: omap: control: core system control driver
In reply to Tony LindgrenHi, Tony.
Quoted 27 lines · Tony Lindgren
Quoted 10 lines · Cousson, Benoit
Quoted 5 lines · Eduardo Valentin
Quoted 4 lines
Mmm, we can have up to 4 control module instances in OMAP4.
Well, I'm not sure it worth considering them as separate devices. Is that your plan as well?
At least for now I was focusing on the
ctrl_module_core...OK, that's a good start already :-)
Quoted 2 lines
Quoted 2 lines
But since they all have different base address, it will be trick to handle them with only a single entry.
Quoted 8 lines
Quoted 5 lines
Indeed. We can always add the support latter on.
I am not sure what would be the best way to handle those instances though, and how they are going to expose APIs. Would need to have an instance bound to API set?
We should not go to that path I guess. We should have an API at children level independent of the underlying control module partitioning.
These should be separate driver instances for the control modules.
And then the ioremapped area should ignore at least the padconf registers so
drivers/pinctrl/pinctrl-simplecan handle those. There should not be any dependencies to the SCM driver from pinctrl-simple, the core SCM driver can manage the clocks and trigger the save of padconf regs.
Quoted 8 lines
Also we should allow MMC driver handle the MMC specific registers and USB driver(s) handle the USB specific registers if possible. Those should not live under
drivers/mfdunless there are some dependencies other than trying to ioremap the whole SCM module instead of ioremapping in each driver.We can have a static map for the SCM, so ioremapping each driver individually should not be an issue.
Actually SCM registers window is mapped statically. Mapping is defined in omap44xx_io_desc[] in arch/arm/mach-omap2/io.c:
...
.virtual = L4_44XX_VIRT,
.pfn = __phys_to_pfn(L4_44XX_PHYS),
.length = L4_44XX_SIZE,
.type = MT_DEVICE,...
So ioremap() always returns same virtual address (0xfc002000).
BR,
Konstantin Baydarov.
Quoted 9 lines
Regards,
Tony
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Tony Lindgren
maintainerRFC PATCH 5/11 mfd: omap: control: core system control driver
Quoted 7 lines · Konstantin Baydarov
Quoted 3 lines · Tony Lindgren
We can have a static map for the SCM, so ioremapping each driver individually should not be an issue.
Actually SCM registers window is mapped statically. Mapping is defined in omap44xx_io_desc[] in
arch/arm/mach-omap2/io.c:...
Quoted 8 lines
.virtual = L4_44XX_VIRT, .pfn = __phys_to_pfn(L4_44XX_PHYS), .length = L4_44XX_SIZE, .type = MT_DEVICE,...
So
ioremap()always returns same virtual address (0xfc002000).
Hmm I guess you mean L4_44XX_VIRT + offset. Otherwise drivers would not work at all.. Or else I don't follow you.
Regards,
Tony
RFC PATCH 5/11 mfd: omap: control: core system control driver
Quoted 14 lines · Tony Lindgren
Quoted 13 lines · Konstantin Baydarov
Quoted 2 lines · Tony Lindgren
We can have a static map for the SCM, so ioremapping each driver individually should not be an issue.
Actually SCM registers window is mapped statically. Mapping is defined in omap44xx_io_desc[] in
arch/arm/mach-omap2/io.c:...
.virtual = L4_44XX_VIRT, .pfn = __phys_to_pfn(L4_44XX_PHYS), .length = L4_44XX_SIZE, .type = MT_DEVICE,...
Quoted 3 lines
Quoted 1 line
So
ioremap()always returns same virtual address (0xfc002000).Hmm I guess you mean
L4_44XX_VIRT+ offset. Otherwise drivers would not work at all.. Or else I don't follow you.
Right. I mean when 0x4A00 2000(scm base) is remapped in scm driver, ioremap() always returns same virtual address (0xfc002000).
Quoted 7 lines
Regards,
Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
RFC PATCH 5/11 mfd: omap: control: core system control driver
In reply to Eduardo ValentinQuoted 22 lines · Eduardo Valentin
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
In this patch, the children defined are for:
. USB-phy pin control
. Bangap temperature sensorDevice driver is probed with
postcore_initcall. However, as some of the APIs exposed by this driver may be needed in very early init phase, an early init class is also available: "early_omap_control".Signed-off-by J Keerthy <[email protected]>Signed-off-by Kishon Vijay Abraham I <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>---
[..]
arch/arm/plat-omap/Kconfig menu "TI OMAP Common Features" · line 10
Quoted 11 lines
arch/arm/plat-omap/Kconfig +0
-0@@ -5,6 +5,9 @@ menu "TI OMAP Common Features"?config
ARCH_OMAP_OTG
? ? ? ?boolarch/arm/plat-omap/Kconfig +3
-0+config ARCH_HAS_CONTROL_MODULE + ? ? ? bool +
Thanks for getting rid of OMAP CONFIG here.
Quoted 88 lines
?choice
? ? ? ?prompt "OMAP System Type"
? ? ? ?defaultARCH_OMAP2PLUSdrivers/mfd/Kconfig +0
-0@@ -795,6 +795,15 @@ config MFD_WL1273_CORE? ? ? ? ?driver connects the radio-wl1273 V4L2 module and the wl1273 ? ? ? ? ?audio codec.
drivers/mfd/Kconfig +9
-0+config MFD_OMAP_CONTROL + ? ? ? bool "Texas Instruments OMAP System control module" + ? ? ? depends on ARCH_HAS_CONTROL_MODULE + ? ? ? help + ? ? ? ? This is the core driver for system control module. This driver + ? ? ? ? is responsible for creating the control module mfd child, + ? ? ? ? like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic + ? ? ? ? change for off mode. +?config
MFD_OMAP_USB_HOST
? ? ? ?bool "Support OMAP USBHS core driver"
? ? ? ?depends onUSB_EHCI_HCD_OMAP||USB_OHCI_HCD_OMAP3drivers/mfd/Makefile +0
-0@@ -106,6 +106,7 @@ obj-$(CONFIG_MFD_TPS6586X) ?+= tps6586x.o?obj-$(CONFIG_MFD_VX855) ? ? ? ? ? ? ? ?+= vx855.o ?obj-$(CONFIG_MFD_WL1273_CORE) ?+= wl1273-core.o ?obj-$(CONFIG_MFD_CS5535) ? ? ? += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o ?obj-$(CONFIG_MFD_OMAP_USB_HOST) ? ? ? ?+= omap-usb-host.o ?obj-$(CONFIG_MFD_PM8921_CORE) ?+= pm8921-core.o ?obj-$(CONFIG_MFD_PM8XXX_IRQ) ? += pm8xxx-irq.o
drivers/mfd/omap-control-core.c new file +47
-0@@ -0,0 +1,211 @@ +/* +* OMAP system control module driver file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contacts: +* Based on original code written by: +* ? ?J Keerthy <[email protected]> +* ? ?Moiz Sonasath <[email protected]> +* MFD clean up and re-factoring: +* ? ?Eduardo Valentin <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* 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 <linux/module.h> +#include <linux/export.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/mfd/core.h> +#include <linux/mfd/omap_control.h> + +static struct omap_control *omap_control_module; + +/** +* omap_control_readl: Read a single omap control module register. +* +* @dev: device to read from. +* @reg: register to read. +* @val: output with register value. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_readl (struct device *dev,u32 reg,u32 *val) +{ + ? ? ? struct omap_control *omap_control = dev_get_drvdata(dev);
drivers/mfd/omap-control-core.c line 57
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+ + ? ? ? if (!omap_control) + ? ? ? ? ? ? ? return -EINVAL; + + ? ? ? *val = readl(omap_control->base + reg); + + ? ? ? return 0; +} +EXPORT_SYMBOL_GPL (omap_control_readl); +
I might have missed in the last scan, but can you let function return the register value.
I am guessing, you did this for error case handling. You might want to stick to read API semantic and just have WARN_ON() to take care of error case.
Quoted 99 lines
drivers/mfd/omap-control-core.c new file +99
-0+/** +* omap_control_writel: Write a single omap control module register. +* +* @dev: device to read from. +* @val: value to write. +* @reg: register to write to. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_writel (struct device *dev,u32 val,u32 reg) +{ + ? ? ? struct omap_control *omap_control = dev_get_drvdata(dev); + ? ? ? unsigned long flags; + + ? ? ? if (!omap_control) + ? ? ? ? ? ? ? return -EINVAL; + + ? ? ? spin_lock_irqsave(&omap_control->reg_lock, flags); + ? ? ? writel(val, omap_control->base + reg); + ? ? ? spin_unlock_irqrestore(&omap_control->reg_lock, flags); + + ? ? ? return 0; +} +EXPORT_SYMBOL_GPL (omap_control_writel); + +/** +* omap_control_get: returns the control module device pinter +* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +struct device *omap_control_get (void ) +{ + ? ? ? unsigned long flags; + + ? ? ? if (!omap_control_module) + ? ? ? ? ? ? ? return ERR_PTR(-ENODEV); + + ? ? ? spin_lock_irqsave(&omap_control_module->reg_lock, flags); + ? ? ? omap_control_module->use_count++; + ? ? ? spin_unlock_irqrestore(&omap_control_module->reg_lock, flags); + + ? ? ? return omap_control_module->dev; +} +EXPORT_SYMBOL_GPL (omap_control_get); + +/** +* omap_control_put: returns the control module device pinter +* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +void omap_control_put (struct device *dev) +{ + ? ? ? struct omap_control *omap_control = dev_get_drvdata(dev); + ? ? ? unsigned long flags; + + ? ? ? if (!omap_control) + ? ? ? ? ? ? ? return; + + ? ? ? spin_lock_irqsave(&omap_control->reg_lock, flags); + ? ? ? omap_control->use_count--; + ? ? ? spin_unlock_irqrestore(&omap_control_module->reg_lock, flags); +} +EXPORT_SYMBOL_GPL (omap_control_put); + +static const struct of_device_id of_omap_control_match[] = { + ? ? ? { .compatible = "ti,omap3-control", }, + ? ? ? { .compatible = "ti,omap4-control", }, + ? ? ? { .compatible = "ti,omap5-control", }, + ? ? ? { }, +}; + +static int __devinit omap_control_probe (struct platform_device *pdev) +{ + ? ? ? struct resource *res; + ? ? ? void __iomem *base; + ? ? ? struct device *dev = &pdev->dev; + ? ? ? struct device_node *np = dev->of_node; + ? ? ? struct omap_control *omap_control; + + ? ? ? omap_control = devm_kzalloc(dev, sizeof(*omap_control), GFP_KERNEL); + ? ? ? if (!omap_control) { + ? ? ? ? ? ? ? dev_err(dev, "not enough memory for omap_control\n"); + ? ? ? ? ? ? ? return -ENOMEM; + ? ? ? } + + ? ? ? res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ? ? ? if (!res) { + ? ? ? ? ? ? ? dev_err(dev, "missing memory base resource\n"); + ? ? ? ? ? ? ? return -EINVAL; + ? ? ? } + + ? ? ? base = devm_request_and_ioremap(dev, res); + ? ? ? if (!base) { + ? ? ? ? ? ? ? dev_err(dev, "ioremap failed\n"); + ? ? ? ? ? ? ? return -EADDRNOTAVAIL; + ? ? ? } +
drivers/mfd/omap-control-core.c line 166
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+ ? ? ? omap_control->base = base; + ? ? ? omap_control->dev = dev; + ? ? ? spin_lock_init(&omap_control->reg_lock); + + ? ? ? platform_set_drvdata(pdev, omap_control); + ? ? ? omap_control_module = omap_control; + + ? ? ? return of_platform_populate(np, of_omap_control_match, NULL, dev); +} +
Will the probe get called on multiple devices and race ?
drivers/mfd/omap-control-core.c line 178
Quoted 12 lines
drivers/mfd/omap-control-core.c new file +12
-0+static int __devexit omap_control_remove(struct platform_device *pdev) +{ + ? ? ? struct omap_control *omap_control = platform_get_drvdata(pdev); + + ? ? ? spin_lock(&omap_control->reg_lock); + ? ? ? if (omap_control->use_count > 0) { + ? ? ? ? ? ? ? spin_unlock(&omap_control->reg_lock); + ? ? ? ? ? ? ? dev_err(&pdev->dev, "device removed while still being used\n"); + ? ? ? ? ? ? ? return -EBUSY; + ? ? ? } + ? ? ? spin_unlock(&omap_control->reg_lock); +
Do you really need above lock where you are just doing the register read. smp_rmb(), should be enough, I guess.
Regards
Santosh
RFC PATCH 5/11 mfd: omap: control: core system control driver
Hello,
Quoted 34 lines · Santosh
Quoted 22 lines · Eduardo Valentin
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
In this patch, the children defined are for:
. USB-phy pin control
. Bangap temperature sensorDevice driver is probed with
postcore_initcall. However, as some of the APIs exposed by this driver may be needed in very early init phase, an early init class is also available: "early_omap_control".Signed-off-by J Keerthy <[email protected]>Signed-off-by Kishon Vijay Abraham I <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>---
[..]
Quoted 8 lines
arch/arm/plat-omap/Kconfig +0
-0@@ -5,6 +5,9 @@ menu "TI OMAP Common Features"?config
ARCH_OMAP_OTG
? ? ? ?bool
Quoted 4 lines
arch/arm/plat-omap/Kconfig menu "TI OMAP Common Features" · line 10
Quoted 3 lines
arch/arm/plat-omap/Kconfig +3
-0+config ARCH_HAS_CONTROL_MODULE + ? ? ? bool +Thanks for getting rid of OMAP CONFIG here.
OK. ARCH_HAS_CONTROL_MODULE is a bit too generic though..
Quoted 93 lines
Quoted 93 lines
?choice
? ? ? ?prompt "OMAP System Type"
? ? ? ?defaultARCH_OMAP2PLUSdrivers/mfd/Kconfig +0
-0@@ -795,6 +795,15 @@ config MFD_WL1273_CORE? ? ? ? ?driver connects the radio-wl1273 V4L2 module and the wl1273 ? ? ? ? ?audio codec.
drivers/mfd/Kconfig +9
-0+config MFD_OMAP_CONTROL + ? ? ? bool "Texas Instruments OMAP System control module" + ? ? ? depends on ARCH_HAS_CONTROL_MODULE + ? ? ? help + ? ? ? ? This is the core driver for system control module. This driver + ? ? ? ? is responsible for creating the control module mfd child, + ? ? ? ? like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic + ? ? ? ? change for off mode. +?config
MFD_OMAP_USB_HOST
? ? ? ?bool "Support OMAP USBHS core driver"
? ? ? ?depends onUSB_EHCI_HCD_OMAP||USB_OHCI_HCD_OMAP3drivers/mfd/Makefile +0
-0@@ -106,6 +106,7 @@ obj-$(CONFIG_MFD_TPS6586X) ?+= tps6586x.o?obj-$(CONFIG_MFD_VX855) ? ? ? ? ? ? ? ?+= vx855.o ?obj-$(CONFIG_MFD_WL1273_CORE) ?+= wl1273-core.o ?obj-$(CONFIG_MFD_CS5535) ? ? ? += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o ?obj-$(CONFIG_MFD_OMAP_USB_HOST) ? ? ? ?+= omap-usb-host.o ?obj-$(CONFIG_MFD_PM8921_CORE) ?+= pm8921-core.o ?obj-$(CONFIG_MFD_PM8XXX_IRQ) ? += pm8xxx-irq.o
drivers/mfd/omap-control-core.c new file +51
-0@@ -0,0 +1,211 @@ +/* +* OMAP system control module driver file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contacts: +* Based on original code written by: +* ? ?J Keerthy <[email protected]> +* ? ?Moiz Sonasath <[email protected]> +* MFD clean up and re-factoring: +* ? ?Eduardo Valentin <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* 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 <linux/module.h> +#include <linux/export.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/mfd/core.h> +#include <linux/mfd/omap_control.h> + +static struct omap_control *omap_control_module; + +/** +* omap_control_readl: Read a single omap control module register. +* +* @dev: device to read from. +* @reg: register to read. +* @val: output with register value. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_readl (struct device *dev,u32 reg,u32 *val) +{ + ? ? ? struct omap_control *omap_control = dev_get_drvdata(dev); + + ? ? ? if (!omap_control) + ? ? ? ? ? ? ? return -EINVAL; +
Quoted 8 lines
drivers/mfd/omap-control-core.c line 57
Quoted 6 lines
drivers/mfd/omap-control-core.c new file +6
-0+ ? ? ? *val = readl(omap_control->base + reg); + + ? ? ? return 0; +} +EXPORT_SYMBOL_GPL (omap_control_readl); +I might have missed in the last scan, but can you let function return the register value.
Why?
Quoted 4 lines
I am guessing, you did this for error case handling. You might want to stick to read API semantic and just have
WARN_ON()to take care of error case.
Yeah, that was for error handling and to do not confuse register values with error values.
Quoted 104 lines
Quoted 104 lines
drivers/mfd/omap-control-core.c new file +103
-0+/** +* omap_control_writel: Write a single omap control module register. +* +* @dev: device to read from. +* @val: value to write. +* @reg: register to write to. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_writel (struct device *dev,u32 val,u32 reg) +{ + ? ? ? struct omap_control *omap_control = dev_get_drvdata(dev); + ? ? ? unsigned long flags; + + ? ? ? if (!omap_control) + ? ? ? ? ? ? ? return -EINVAL; + + ? ? ? spin_lock_irqsave(&omap_control->reg_lock, flags); + ? ? ? writel(val, omap_control->base + reg); + ? ? ? spin_unlock_irqrestore(&omap_control->reg_lock, flags); + + ? ? ? return 0; +} +EXPORT_SYMBOL_GPL (omap_control_writel); + +/** +* omap_control_get: returns the control module device pinter +* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +struct device *omap_control_get (void ) +{ + ? ? ? unsigned long flags; + + ? ? ? if (!omap_control_module) + ? ? ? ? ? ? ? return ERR_PTR(-ENODEV); + + ? ? ? spin_lock_irqsave(&omap_control_module->reg_lock, flags); + ? ? ? omap_control_module->use_count++; + ? ? ? spin_unlock_irqrestore(&omap_control_module->reg_lock, flags); + + ? ? ? return omap_control_module->dev; +} +EXPORT_SYMBOL_GPL (omap_control_get); + +/** +* omap_control_put: returns the control module device pinter +* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +void omap_control_put (struct device *dev) +{ + ? ? ? struct omap_control *omap_control = dev_get_drvdata(dev); + ? ? ? unsigned long flags; + + ? ? ? if (!omap_control) + ? ? ? ? ? ? ? return; + + ? ? ? spin_lock_irqsave(&omap_control->reg_lock, flags); + ? ? ? omap_control->use_count--; + ? ? ? spin_unlock_irqrestore(&omap_control_module->reg_lock, flags); +} +EXPORT_SYMBOL_GPL (omap_control_put); + +static const struct of_device_id of_omap_control_match[] = { + ? ? ? { .compatible = "ti,omap3-control", }, + ? ? ? { .compatible = "ti,omap4-control", }, + ? ? ? { .compatible = "ti,omap5-control", }, + ? ? ? { }, +}; + +static int __devinit omap_control_probe (struct platform_device *pdev) +{ + ? ? ? struct resource *res; + ? ? ? void __iomem *base; + ? ? ? struct device *dev = &pdev->dev; + ? ? ? struct device_node *np = dev->of_node; + ? ? ? struct omap_control *omap_control; + + ? ? ? omap_control = devm_kzalloc(dev, sizeof(*omap_control), GFP_KERNEL); + ? ? ? if (!omap_control) { + ? ? ? ? ? ? ? dev_err(dev, "not enough memory for omap_control\n"); + ? ? ? ? ? ? ? return -ENOMEM; + ? ? ? } + + ? ? ? res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ? ? ? if (!res) { + ? ? ? ? ? ? ? dev_err(dev, "missing memory base resource\n"); + ? ? ? ? ? ? ? return -EINVAL; + ? ? ? } + + ? ? ? base = devm_request_and_ioremap(dev, res); + ? ? ? if (!base) { + ? ? ? ? ? ? ? dev_err(dev, "ioremap failed\n"); + ? ? ? ? ? ? ? return -EADDRNOTAVAIL; + ? ? ? } + + ? ? ? omap_control->base = base; + ? ? ? omap_control->dev = dev; + ? ? ? spin_lock_init(&omap_control->reg_lock); +
Quoted 8 lines
drivers/mfd/omap-control-core.c line 57
Quoted 6 lines
drivers/mfd/omap-control-core.c new file +6
-0+ ? ? ? platform_set_drvdata(pdev, omap_control); + ? ? ? omap_control_module = omap_control; + + ? ? ? return of_platform_populate(np, of_omap_control_match, NULL, dev); +} +Will the probe get called on multiple devices and race ?
It depends. If we decide to have an early device for scm, then the probe will be called more than once. If not, then only once.
Quoted 15 lines
drivers/mfd/omap-control-core.c line 178
Quoted 13 lines
drivers/mfd/omap-control-core.c new file +12
-0+static int __devexit omap_control_remove(struct platform_device *pdev) +{ + ? ? ? struct omap_control *omap_control = platform_get_drvdata(pdev); + + ? ? ? spin_lock(&omap_control->reg_lock); + ? ? ? if (omap_control->use_count > 0) { + ? ? ? ? ? ? ? spin_unlock(&omap_control->reg_lock); + ? ? ? ? ? ? ? dev_err(&pdev->dev, "device removed while still being used\n"); + ? ? ? ? ? ? ? return -EBUSY; + ? ? ? } + ? ? ? spin_unlock(&omap_control->reg_lock); +Do you really need above lock where you are just doing the register read.
smp_rmb(), should be enough, I guess.
It is locking the use counter not a register..
Quoted 3 lines
Regards
Santosh
RFC PATCH 5/11 mfd: omap: control: core system control driver
Quoted 146 lines · Eduardo Valentin
Hello,
Quoted 34 lines · Santosh
Quoted 22 lines · Eduardo Valentin
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
In this patch, the children defined are for:
. USB-phy pin control
. Bangap temperature sensorDevice driver is probed with
postcore_initcall. However, as some of the APIs exposed by this driver may be needed in very early init phase, an early init class is also available: "early_omap_control".Signed-off-by J Keerthy <[email protected]>Signed-off-by Kishon Vijay Abraham I <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>---
[..]
Quoted 8 lines
arch/arm/plat-omap/Kconfig +0
-0@@ -5,6 +5,9 @@ menu "TI OMAP Common Features"?config
ARCH_OMAP_OTG
? ? ? ?boolQuoted 4 lines
arch/arm/plat-omap/Kconfig menu "TI OMAP Common Features" · line 10
Quoted 3 lines
arch/arm/plat-omap/Kconfig +3
-0+config ARCH_HAS_CONTROL_MODULE + ? ? ? bool +Thanks for getting rid of OMAP CONFIG here.
OK.
ARCH_HAS_CONTROL_MODULEis a bit too generic though..Quoted 93 lines
Quoted 93 lines
?choice
? ? ? ?prompt "OMAP System Type"
? ? ? ?defaultARCH_OMAP2PLUSdrivers/mfd/Kconfig +0
-0@@ -795,6 +795,15 @@ config MFD_WL1273_CORE? ? ? ? ?driver connects the radio-wl1273 V4L2 module and the wl1273 ? ? ? ? ?audio codec.
drivers/mfd/Kconfig +9
-0+config MFD_OMAP_CONTROL + ? ? ? bool "Texas Instruments OMAP System control module" + ? ? ? depends on ARCH_HAS_CONTROL_MODULE + ? ? ? help + ? ? ? ? This is the core driver for system control module. This driver + ? ? ? ? is responsible for creating the control module mfd child, + ? ? ? ? like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic + ? ? ? ? change for off mode. +?config
MFD_OMAP_USB_HOST
? ? ? ?bool "Support OMAP USBHS core driver"
? ? ? ?depends onUSB_EHCI_HCD_OMAP||USB_OHCI_HCD_OMAP3drivers/mfd/Makefile +0
-0@@ -106,6 +106,7 @@ obj-$(CONFIG_MFD_TPS6586X) ?+= tps6586x.o?obj-$(CONFIG_MFD_VX855) ? ? ? ? ? ? ? ?+= vx855.o ?obj-$(CONFIG_MFD_WL1273_CORE) ?+= wl1273-core.o ?obj-$(CONFIG_MFD_CS5535) ? ? ? += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o ?obj-$(CONFIG_MFD_OMAP_USB_HOST) ? ? ? ?+= omap-usb-host.o ?obj-$(CONFIG_MFD_PM8921_CORE) ?+= pm8921-core.o ?obj-$(CONFIG_MFD_PM8XXX_IRQ) ? += pm8xxx-irq.o
drivers/mfd/omap-control-core.c new file +51
-0@@ -0,0 +1,211 @@ +/* +* OMAP system control module driver file +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Contacts: +* Based on original code written by: +* ? ?J Keerthy <[email protected]> +* ? ?Moiz Sonasath <[email protected]> +* MFD clean up and re-factoring: +* ? ?Eduardo Valentin <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* 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 <linux/module.h> +#include <linux/export.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/mfd/core.h> +#include <linux/mfd/omap_control.h> + +static struct omap_control *omap_control_module; + +/** +* omap_control_readl: Read a single omap control module register. +* +* @dev: device to read from. +* @reg: register to read. +* @val: output with register value. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_readl (struct device *dev,u32 reg,u32 *val) +{ + ? ? ? struct omap_control *omap_control = dev_get_drvdata(dev); + + ? ? ? if (!omap_control) + ? ? ? ? ? ? ? return -EINVAL; +Quoted 8 lines
drivers/mfd/omap-control-core.c line 57
Quoted 6 lines
drivers/mfd/omap-control-core.c new file +6
-0+ ? ? ? *val = readl(omap_control->base + reg); + + ? ? ? return 0; +} +EXPORT_SYMBOL_GPL (omap_control_readl); +I might have missed in the last scan, but can you let function return the register value.
Quoted 2 lines
Why?
Because thats how typical read 1 value kind of functions look like..
Quoted 8 lines
Quoted 4 lines
I am guessing, you did this for error case handling. You might want to stick to read API semantic and just have
WARN_ON()to take care of error case.Yeah, that was for error handling and to do not confuse register values with error values.
No strong opinion if you like it that way but it just appeared odd to me from a caller perspective.
Quoted 113 lines
Quoted 104 lines
Quoted 104 lines
drivers/mfd/omap-control-core.c new file +103
-0+/** +* omap_control_writel: Write a single omap control module register. +* +* @dev: device to read from. +* @val: value to write. +* @reg: register to write to. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_writel (struct device *dev,u32 val,u32 reg) +{ + ? ? ? struct omap_control *omap_control = dev_get_drvdata(dev); + ? ? ? unsigned long flags; + + ? ? ? if (!omap_control) + ? ? ? ? ? ? ? return -EINVAL; + + ? ? ? spin_lock_irqsave(&omap_control->reg_lock, flags); + ? ? ? writel(val, omap_control->base + reg); + ? ? ? spin_unlock_irqrestore(&omap_control->reg_lock, flags); + + ? ? ? return 0; +} +EXPORT_SYMBOL_GPL (omap_control_writel); + +/** +* omap_control_get: returns the control module device pinter +* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +struct device *omap_control_get (void ) +{ + ? ? ? unsigned long flags; + + ? ? ? if (!omap_control_module) + ? ? ? ? ? ? ? return ERR_PTR(-ENODEV); + + ? ? ? spin_lock_irqsave(&omap_control_module->reg_lock, flags); + ? ? ? omap_control_module->use_count++; + ? ? ? spin_unlock_irqrestore(&omap_control_module->reg_lock, flags); + + ? ? ? return omap_control_module->dev; +} +EXPORT_SYMBOL_GPL (omap_control_get); + +/** +* omap_control_put: returns the control module device pinter +* +* The modules which has to use control module API's to read or write should +* call this API to get the control module device pointer. +*/ +void omap_control_put (struct device *dev) +{ + ? ? ? struct omap_control *omap_control = dev_get_drvdata(dev); + ? ? ? unsigned long flags; + + ? ? ? if (!omap_control) + ? ? ? ? ? ? ? return; + + ? ? ? spin_lock_irqsave(&omap_control->reg_lock, flags); + ? ? ? omap_control->use_count--; + ? ? ? spin_unlock_irqrestore(&omap_control_module->reg_lock, flags); +} +EXPORT_SYMBOL_GPL (omap_control_put); + +static const struct of_device_id of_omap_control_match[] = { + ? ? ? { .compatible = "ti,omap3-control", }, + ? ? ? { .compatible = "ti,omap4-control", }, + ? ? ? { .compatible = "ti,omap5-control", }, + ? ? ? { }, +}; + +static int __devinit omap_control_probe (struct platform_device *pdev) +{ + ? ? ? struct resource *res; + ? ? ? void __iomem *base; + ? ? ? struct device *dev = &pdev->dev; + ? ? ? struct device_node *np = dev->of_node; + ? ? ? struct omap_control *omap_control; + + ? ? ? omap_control = devm_kzalloc(dev, sizeof(*omap_control), GFP_KERNEL); + ? ? ? if (!omap_control) { + ? ? ? ? ? ? ? dev_err(dev, "not enough memory for omap_control\n"); + ? ? ? ? ? ? ? return -ENOMEM; + ? ? ? } + + ? ? ? res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ? ? ? if (!res) { + ? ? ? ? ? ? ? dev_err(dev, "missing memory base resource\n"); + ? ? ? ? ? ? ? return -EINVAL; + ? ? ? } + + ? ? ? base = devm_request_and_ioremap(dev, res); + ? ? ? if (!base) { + ? ? ? ? ? ? ? dev_err(dev, "ioremap failed\n"); + ? ? ? ? ? ? ? return -EADDRNOTAVAIL; + ? ? ? } + + ? ? ? omap_control->base = base; + ? ? ? omap_control->dev = dev; + ? ? ? spin_lock_init(&omap_control->reg_lock); +Quoted 8 lines
drivers/mfd/omap-control-core.c line 57
Quoted 6 lines
drivers/mfd/omap-control-core.c new file +6
-0+ ? ? ? platform_set_drvdata(pdev, omap_control); + ? ? ? omap_control_module = omap_control; + + ? ? ? return of_platform_populate(np, of_omap_control_match, NULL, dev); +} +Will the probe get called on multiple devices and race ?
Quoted 3 lines
It depends. If we decide to have an early device for scm, then the probe will be called more than once. If not, then only once.
OK. But in either case it won't race so that's fine.
Quoted 16 lines
Quoted 15 lines
drivers/mfd/omap-control-core.c line 178
Quoted 13 lines
drivers/mfd/omap-control-core.c new file +12
-0+static int __devexit omap_control_remove(struct platform_device *pdev) +{ + ? ? ? struct omap_control *omap_control = platform_get_drvdata(pdev); + + ? ? ? spin_lock(&omap_control->reg_lock); + ? ? ? if (omap_control->use_count > 0) { + ? ? ? ? ? ? ? spin_unlock(&omap_control->reg_lock); + ? ? ? ? ? ? ? dev_err(&pdev->dev, "device removed while still being used\n"); + ? ? ? ? ? ? ? return -EBUSY; + ? ? ? } + ? ? ? spin_unlock(&omap_control->reg_lock); +Do you really need above lock where you are just doing the register read.
smp_rmb(), should be enough, I guess.
Quoted 2 lines
It is locking the use counter not a register..
Yes I know. But is just read and you can do away and hence you can avoid the lock.
Regards
Santosh
RFC PATCH 5/11 mfd: omap: control: core system control driver
Quoted 1 line · Santosh
On Mon, May 28, 2012 at 5:12 PM, Eduardo Valentin
[...]
Quoted 25 lines
Quoted 25 lines
Quoted 24 lines
Quoted 12 lines
drivers/mfd/omap-control-core.c new file +12
-0+/** +* omap_control_readl: Read a single omap control module register. +* +* @dev: device to read from. +* @reg: register to read. +* @val: output with register value. +* +* returns 0 on success or -EINVAL in case struct device is invalid. +*/ +int omap_control_readl (struct device *dev,u32 reg,u32 *val) +{ +struct omap_control *omap_control =dev_get_drvdata (dev);drivers/mfd/omap-control-core.c line 57
Quoted 10 lines
drivers/mfd/omap-control-core.c new file +10
-0+ +if (!omap_control) +return -EINVAL ; + + *val =readl (omap_control->base + reg); + +return 0 ; +} +EXPORT_SYMBOL_GPL (omap_control_readl); +I might have missed in the last scan, but can you let function return the register value.
Quoted 4 lines
Quoted 2 lines
Why?
Because thats how typical read 1 value kind of functions look like..
Yeah, I tend to agree with Santosh here as well. I'm expecting such API to return the value.
Moreover the error handling in that case is really an exception and thus a WARM is enough since it should never ever happen except if there is a bug during the probe. And in that case, it should already fail at probe time.
Quoted 9 lines
Quoted 7 lines
Quoted 3 lines
I am guessing, you did this for error case handling. You might want to stick to read API semantic and just have
WARN_ON()to take care of error case.Yeah, that was for error handling and to do not confuse register values with error values.
No strong opinion if you like it that way but it just appeared odd to me from a caller perspective.
Yep, I do agree.
Benoit
RFC PATCH 6/11 OMAP2+: use control module mfd driver in omap_type
In reply to Eduardo ValentinOMAP system control module can be probed early, then omap_type is safe to use its APIs.
TODO: add support for other omap versions
--- arch/arm/mach-omap2/id.c | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/id.c +15 -1
@@ -18,6 +18,7 @@#include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/mfd/omap_control.h> #include <asm/cputype.h>
@@ -40,8 +41,14 @@ EXPORT_SYMBOL(omap_rev);int omap_type (void ) { +struct device *scm; +int ret =0 ;u32 val =0 ; + scm =omap_control_get (); +if (IS_ERR_OR_NULL (scm)) +return 0 ; +if (cpu_is_omap24xx ()) { val =omap_ctrl_readl (OMAP24XX_CONTROL_STATUS ); }else if (cpu_is_am33xx ()) {
@@ -49,16 +56,23 @@ int omap_type(void) }else if (cpu_is_omap34xx ()) { val =omap_ctrl_readl (OMAP343X_CONTROL_STATUS ); }else if (cpu_is_omap44xx ()) { - val =omap_ctrl_readl (OMAP4_CTRL_MODULE_CORE_STATUS ); + ret =omap_control_readl (scm,OMAP4_CTRL_MODULE_CORE_STATUS , + &val); }else {pr_err ("Cannot detect omap type!\n" ); goto out; } +if (ret) { +pr_err ("problem while fetching omap type\n" ); + goto out; + } + val &=OMAP2_DEVICETYPE_MASK ; val >>=8 ; out: +omap_control_put (scm);return val; }EXPORT_SYMBOL (omap_type);
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 6/11 OMAP2+: use control module mfd driver in omap_type
Hi Eduardo,
Quoted 25 lines · Eduardo Valentin
OMAP system control module can be probed early, then
omap_typeis safe to use its APIs.TODO: add support for other omap versions
Signed-off-by Eduardo Valentin<[email protected]>--- arch/arm/mach-omap2/id.c | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletions(-)arch/arm/mach-omap2/id.c +1
-0@@ -18,6 +18,7 @@#include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/mfd/omap_control.h> #include <asm/cputype.h> @@ -40,8 +41,14 @@ EXPORT_SYMBOL(omap_rev);int omap_type (void )
arch/arm/mach-omap2/id.c EXPORT_SYMBOL(omap_rev); · line 52
Quoted 10 lines
arch/arm/mach-omap2/id.c +6
-0{ +struct device *scm; +int ret =0 ;u32 val =0 ; + scm =omap_control_get (); +if (IS_ERR_OR_NULL (scm)) +return 0 ; +if (cpu_is_omap24xx ()) {
OK, not really related to that patch, but the previous cpu_is_omap24xx makes me think of that :-)
What about the omap<X>_check_revision used by cpu_is_XXX?
This call is the very first one to require the control module access in order to get the ID_CODE inside the control module.
So far it still use that ugly hard coded phys -> virtual address macro that is sued for that.
arch/arm/mach-omap2/id.c int omap_type(void) · line 60
Quoted 9 lines
arch/arm/mach-omap2/id.c +2
-1val =omap_ctrl_readl (OMAP24XX_CONTROL_STATUS ); }else if (cpu_is_am33xx ()) {@@ -49,16 +56,23 @@ int omap_type(void) }else if (cpu_is_omap34xx ()) { val =omap_ctrl_readl (OMAP343X_CONTROL_STATUS ); }else if (cpu_is_omap44xx ()) { - val =omap_ctrl_readl (OMAP4_CTRL_MODULE_CORE_STATUS ); + ret =omap_control_readl (scm,OMAP4_CTRL_MODULE_CORE_STATUS , + &val);
I guess you should get rid of these cpu_is_omap44xx and store the omap_type somewhere to avoid further access to the control module since there are a couple of places that use that API.
Not necessarily in this patch for sure, but something that might be done in this series.
Regards,
Benoit
RFC PATCH 6/11 OMAP2+: use control module mfd driver in omap_type
Quoted 45 lines · Benoit
Hi Eduardo,
Quoted 26 lines · Eduardo Valentin
OMAP system control module can be probed early, then
omap_typeis safe to use its APIs.TODO: add support for other omap versions
Signed-off-by Eduardo Valentin<[email protected]>---
?arch/arm/mach-omap2/id.c | ? 16 +++++++++++++++- ?1 files changed, 15 insertions(+), 1 deletions(-)arch/arm/mach-omap2/id.c +0
-0@@ -18,6 +18,7 @@?#include<linux/kernel.h>
?#include<linux/init.h>
?#include<linux/io.h>
+#include<linux/mfd/omap_control.h>?#include<asm/cputype.h>
arch/arm/mach-omap2/id.c +0
-0@@ -40,8 +41,14 @@ EXPORT_SYMBOL(omap_rev); ?int omap_type(void)arch/arm/mach-omap2/id.c EXPORT_SYMBOL(omap_rev); · line 52
Quoted 10 lines
arch/arm/mach-omap2/id.c +6
-0?{ + ? ? ? struct device *scm; + ? ? ? int ret = 0; ? ? ? ?u32 val = 0; + ? ? ? scm = omap_control_get(); + ? ? ? if (IS_ERR_OR_NULL(scm)) + ? ? ? ? ? ? ? return 0; + ? ? ? ?if (cpu_is_omap24xx()) {OK, not really related to that patch, but the previous
cpu_is_omap24xxmakes me think of that :-)
Quoted 8 lines
What about the omap<X>_check_revision used by
cpu_is_XXX?This call is the very first one to require the control module access in order to get the
ID_CODEinside the control module.So far it still use that ugly hard coded phys -> virtual address macro that is sued for that.
Agree with Benoits comment. One way to deal with this is, store the register offset with init and then just use it here.
That way you can get rid of all cpu_is_XXXX() from this function.
Regards
Santosh
RFC PATCH 6/11 OMAP2+: use control module mfd driver in omap_type
Hello,
Quoted 51 lines · Santosh
Quoted 50 lines · Benoit
Hi Eduardo,
Quoted 26 lines · Eduardo Valentin
OMAP system control module can be probed early, then
omap_typeis safe to use its APIs.TODO: add support for other omap versions
Signed-off-by Eduardo Valentin<[email protected]>---
?arch/arm/mach-omap2/id.c | ? 16 +++++++++++++++- ?1 files changed, 15 insertions(+), 1 deletions(-)arch/arm/mach-omap2/id.c +0
-0@@ -18,6 +18,7 @@?#include<linux/kernel.h>
?#include<linux/init.h>
?#include<linux/io.h>
+#include<linux/mfd/omap_control.h>?#include<asm/cputype.h>
arch/arm/mach-omap2/id.c +0
-0@@ -40,8 +41,14 @@ EXPORT_SYMBOL(omap_rev); ?int omap_type(void)arch/arm/mach-omap2/id.c EXPORT_SYMBOL(omap_rev); · line 52
Quoted 10 lines
arch/arm/mach-omap2/id.c +6
-0?{ + ? ? ? struct device *scm; + ? ? ? int ret = 0; ? ? ? ?u32 val = 0; + ? ? ? scm = omap_control_get(); + ? ? ? if (IS_ERR_OR_NULL(scm)) + ? ? ? ? ? ? ? return 0; + ? ? ? ?if (cpu_is_omap24xx()) {OK, not really related to that patch, but the previous
cpu_is_omap24xxmakes me think of that :-)What about the omap<X>_check_revision used by
cpu_is_XXX?This call is the very first one to require the control module access in order to get the
ID_CODEinside the control module.
Quoted 7 lines
Quoted 3 lines
So far it still use that ugly hard coded phys -> virtual address macro that is sued for that.
Agree with Benoits comment. One way to deal with this is, store the register offset with init and then just use it here.
That way you can get rid of all
cpu_is_XXXX()from this function.
I see. I need to check how this storing would look like. Probably we can do the storing when the early device gets probed.
Quoted 3 lines
Regards
Santosh
Tony Lindgren
maintainerRFC PATCH 6/11 OMAP2+: use control module mfd driver in omap_type
Quoted 14 lines · Eduardo Valentin
Quoted 13 lines · Santosh
Quoted 12 lines · Benoit
OK, not really related to that patch, but the previous
cpu_is_omap24xxmakes me think of that :-)What about the omap<X>_check_revision used by
cpu_is_XXX?This call is the very first one to require the control module access in order to get the
ID_CODEinside the control module.So far it still use that ugly hard coded phys -> virtual address macro that is sued for that.
Quoted 7 lines
Quoted 4 lines
Agree with Benoits comment. One way to deal with this is, store the register offset with init and then just use it here.
That way you can get rid of all
cpu_is_XXXX()from this function.I see. I need to check how this storing would look like. Probably we can do the storing when the early device gets probed.
As this needs to be initialized very early I'd rather avoid dependencies to drivers for this. Maybe that register can be read and saved when the device gets built? It's ioremapped anyways at that point.
That is assuming we don't need to export it to drivers or constantly read it..
Tony
RFC PATCH 7/11 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
In reply to Eduardo ValentinCreated a new platform driver for the platform device created by the control module mfd core, wrt usb. This driver has API's to power on/off the phy and the API's to write to musb mailbox.
(p.s. the mailbox for musb in omap4 is present in system control module)
--- drivers/usb/otg/Kconfig | 13 ++++ drivers/usb/otg/Makefile | 1 + drivers/usb/otg/omap4-usb-phy.c | 130 +++++++++++++++++++++++++++++++++++++ include/linux/usb/omap4_usb_phy.h | 53 +++++++++++++++ 4 files changed, 197 insertions(+), 0 deletions(-) create mode 100644 drivers/usb/otg/omap4-usb-phy.c create mode 100644 include/linux/usb/omap4_usb_phy.h
drivers/usb/otg/Kconfig +13 -0
@@ -78,6 +78,19 @@ config TWL6030_USB are hooked to this driver through platform_data structure. The definition of internal PHY APIs are in the mach-omap2 layer. +config OMAP4_USB_PHY + tristate "Texas Instruments OMAP4+ USB pin control driver" + depends on MFD_OMAP_CONTROL + help + If you say yes here you get support for the Texas Instruments + OMAP4+ USB pin control driver. The register set is part of system + control module. + + USB phy in OMAP configures control module register for powering on + the phy, configuring VBUSVALID, AVALID, IDDIG and SESSEND. For + performing the above mentioned configuration, API's are added in + by this children of the control module driver. + config NOP_USB_XCEIV tristate "NOP USB Transceiver Driver" select USB_OTG_UTILS
drivers/usb/otg/Makefile +1 -0
@@ -13,6 +13,7 @@ obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o +obj-$(CONFIG_OMAP4_USB_PHY) += omap4-usb-phy.o obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o obj-$(CONFIG_USB_ULPI) += ulpi.o obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o
drivers/usb/otg/omap4-usb-phy.c new file +130 -0
130 lines not on this page · raw message
include/linux/usb/omap4_usb_phy.h new file +53 -0
53 lines not on this page · raw message
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 7/11 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
Hi Edurardo,
A few doubts,
Quoted 88 lines · Eduardo Valentin
Created a new platform driver for the platform device created by the control module mfd core, wrt usb. This driver has API's to power on/off the phy and the API's to write to musb mailbox.
(p.s. the mailbox for musb in omap4 is present in system control module)
[kishon at ti.com: wrote the original API's related to USB functions]Signed-off-by Kishon Vijay Abraham I <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>---
?drivers/usb/otg/Kconfig ? ? ? ? ? | ? 13 ++++ ?drivers/usb/otg/Makefile ? ? ? ? ?| ? ?1 + ?drivers/usb/otg/omap4-usb-phy.c ? | ?130 +++++++++++++++++++++++++++++++++++++ ?include/linux/usb/omap4_usb_phy.h | ? 53 +++++++++++++++?4 files changed, 197 insertions(+), 0 deletions(-) ?create mode 100644
drivers/usb/otg/omap4-usb-phy.c?create mode 100644include/linux/usb/omap4_usb_phy.hdrivers/usb/otg/Kconfig +0
-0@@ -78,6 +78,19 @@ config TWL6030_USB? ? ? ? ?are hooked to this driver through
platform_datastructure. ? ? ? ? ?The definition of internal PHY APIs are in the mach-omap2 layer.drivers/usb/otg/Kconfig +13
-0+config OMAP4_USB_PHY + ? ? ? tristate "Texas Instruments OMAP4+ USB pin control driver" + ? ? ? depends on MFD_OMAP_CONTROL + ? ? ? help + ? ? ? ? If you say yes here you get support for the Texas Instruments + ? ? ? ? OMAP4+ USB pin control driver. The register set is part of system + ? ? ? ? control module. + + ? ? ? ? USB phy in OMAP configures control module register for powering on + ? ? ? ? the phy, configuring VBUSVALID, AVALID, IDDIG and SESSEND. For + ? ? ? ? performing the above mentioned configuration, API's are added in + ? ? ? ? by this children of the control module driver. +?config
NOP_USB_XCEIV
? ? ? ?tristate "NOP USB Transceiver Driver"
? ? ? ?selectUSB_OTG_UTILSdrivers/usb/otg/Makefile +0
-0@@ -13,6 +13,7 @@ obj-$(CONFIG_USB_GPIO_VBUS) ? += gpio_vbus.o?obj-$(CONFIG_ISP1301_OMAP) ? ? += isp1301_omap.o ?obj-$(CONFIG_TWL4030_USB) ? ? ?+= twl4030-usb.o ?obj-$(CONFIG_TWL6030_USB) ? ? ?+= twl6030-usb.o +obj-$(CONFIG_OMAP4_USB_PHY) ? ?+= omap4-usb-phy.o ?obj-$(CONFIG_NOP_USB_XCEIV) ? ?+= nop-usb-xceiv.o ?obj-$(CONFIG_USB_ULPI) ? ? ? ? += ulpi.o ?obj-$(CONFIG_USB_ULPI_VIEWPORT) ? ? ? ?+= ulpi_viewport.o
drivers/usb/otg/omap4-usb-phy.c new file +27
-0@@ -0,0 +1,130 @@ +/* +* OMAP4 system control module driver, USB control children +* +* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ +* +* Contact: +* ? ?Kishon Vijay Abraham I <[email protected]> +* ? ?Eduardo Valentin <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include <linux/module.h> +#include <linux/init.h>
drivers/usb/otg/omap4-usb-phy.c line 37
Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10
-0+#include <linux/delay.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/mfd/omap_control.h> +#include <linux/usb/omap4_usb_phy.h> + +/** +* omap4_usb_phy_power - power on/off the phy using control module reg +* @dev: struct device * +* @on: 0 or 1, based on powering on or off the PHY
Could it be bool ?
Quoted 5 lines
drivers/usb/otg/omap4-usb-phy.c new file +5
-0+* +* omap_usb2 can call this API to power on or off the PHY. +*/ +int omap4_usb_phy_power (struct device *dev,int on) +{
drivers/usb/otg/omap4-usb-phy.c line 52
Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10
-0+ ? ? ? u32 val; + ? ? ? int ret; + + ? ? ? if (on) { + ? ? ? ? ? ? ? ret = omap_control_readl(dev, CONTROL_DEV_CONF, &val); + ? ? ? ? ? ? ? if (!ret && (val & PHY_PD)) { + ? ? ? ? ? ? ? ? ? ? ? ret = omap_control_writel(dev, ~PHY_PD, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CONTROL_DEV_CONF); + ? ? ? ? ? ? ? ? ? ? ? /* XXX: add proper documentation for this delay */ + ? ? ? ? ? ? ? ? ? ? ? mdelay(200);
Also does it have to be a busy one?
RFC PATCH 7/11 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
In reply to Eduardo ValentinQuoted 10 lines · Eduardo Valentin
Created a new platform driver for the platform device created by the control module mfd core, wrt usb. This driver has API's to power on/off the phy and the API's to write to musb mailbox.
(p.s. the mailbox for musb in omap4 is present in system control module)
[kishon at ti.com: wrote the original API's related to USB functions]Signed-off-by Kishon Vijay Abraham I<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>
...
Quoted 6 lines
drivers/usb/otg/omap4-usb-phy.c new file +6
-0+/** +* omap4_usb_phy_mailbox - write to usb otg mailbox +* @dev: struct device * +* @val: the value to be written to the mailbox +* +* On detection of a device (ID pin is grounded), the phy should call this API
drivers/usb/otg/omap4-usb-phy.c line 77
Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10
-0+* to set AVALID, VBUSVALID and ID pin is grounded. +* +* When OMAP is connected to a host (OMAP in device mode), the phy should call +* this API to set AVALID, VBUSVALID and ID pin in high impedance. +* +* The phy should call this API, if OMAP is disconnected from host or device. +*/ +int omap4_usb_phy_mailbox (struct device *dev,u32 val) +{ +return omap_control_writel (dev, val,CONTROL_USBOTGHS_CONTROL );
Mmm, I'm missing something. The device for usb_phy mailbox cannot be the same than the device for the scm...
drivers/usb/otg/omap4-usb-phy.c line 85
Quoted 8 lines
drivers/usb/otg/omap4-usb-phy.c new file +8
-0+} +EXPORT_SYMBOL_GPL (omap4_usb_phy_mailbox); + +static int __devinit omap_usb_phy_probe (struct platform_device *pdev) +{ +struct omap_control *omap_control; + + omap_control =dev_get_drvdata (pdev->dev.parent);
Directly accessing your parent device data does not looks very nice to me. Maybe that's only me, but I'll never try to sneak into my parents stuff :-)
You previously exposed an API to get/put the control module device, so I guess you should use it from the probe.
drivers/usb/otg/omap4-usb-phy.c line 90
Quoted 5 lines
drivers/usb/otg/omap4-usb-phy.c new file +5
-0+ +if (!omap_control) { +dev_err (&pdev->dev,"no omap_control in our parent\n" ); +return -EINVAL ; + }
BTW, where is the omap_control struct used?
I'm not sure to understand how the user is supposed to call that API?
Regards,
Benoit
Tony Lindgren
maintainerRFC PATCH 7/11 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
In reply to Eduardo ValentinQuoted 10 lines · Eduardo Valentin
drivers/usb/otg/omap4-usb-phy.c new file +10
-0+int omap4_usb_phy_power (struct device *dev,int on) +{ +u32 val; +int ret; + +if (on) { + ret =omap_control_readl (dev,CONTROL_DEV_CONF , &val); +if (!ret && (val &PHY_PD )) { + ret =omap_control_writel (dev, ~PHY_PD , +CONTROL_DEV_CONF );
drivers/usb/otg/omap4-usb-phy.c line 60
Quoted 10 lines
drivers/usb/otg/omap4-usb-phy.c new file +10
-0+/* XXX: add proper documentation for this delay */ +mdelay (200 ); + } + }else { + ret =omap_control_writel (dev,PHY_PD ,CONTROL_DEV_CONF ); + } + +return ret; +} +EXPORT_SYMBOL_GPL (omap4_usb_phy_power);
I'm not quite convinced that we should export omap_control_read/write to drivers. If there's a clear register area this USB phy driver can manage, then ioremaping it separately makes sense. If it's just one register, then exporting something like omap_control_usb_phy_set() might be better for ensuring that drivers don't mess up things for other drivers.
Regards,
Tony
Tony Lindgren
maintainerRFC PATCH 7/11 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
Quoted 20 lines · Tony Lindgren
Quoted 19 lines · Eduardo Valentin
drivers/usb/otg/omap4-usb-phy.c new file +19
-0+int omap4_usb_phy_power (struct device *dev,int on) +{ +u32 val; +int ret; + +if (on) { + ret =omap_control_readl (dev,CONTROL_DEV_CONF , &val); +if (!ret && (val &PHY_PD )) { + ret =omap_control_writel (dev, ~PHY_PD , +CONTROL_DEV_CONF ); +/* XXX: add proper documentation for this delay */ +mdelay (200 ); + } + }else { + ret =omap_control_writel (dev,PHY_PD ,CONTROL_DEV_CONF ); + } + +return ret; +}
Quoted 8 lines
Quoted 1 line
+EXPORT_SYMBOL_GPL(omap4_usb_phy_power);
I'm not quite convinced that we should export omap_control_read/write to drivers. If there's a clear register area this USB phy driver can manage, then ioremaping it separately makes sense. If it's just one register, then exporting something like
omap_control_usb_phy_set()might be better for ensuring that drivers don't mess up things for other drivers.
After chatting with Benoit a bit we came to the conclusion that the clock and powerdomain state needs to be managed for the children by the SCM core driver so the children can't be completely independent.
But rather than exporting omap_control_read/write, maybe you can register the usb/bandgap whatever children with SCM core driver, then have the runtime PM calls from children be passthrough calls to the parent?
Maybe Kevin has some better ideas here?
Regards,
Tony
RFC PATCH 7/11 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
Quoted 34 lines · Tony Lindgren
Quoted 20 lines · Tony Lindgren
Quoted 19 lines · Eduardo Valentin
drivers/usb/otg/omap4-usb-phy.c new file +19
-0+int omap4_usb_phy_power (struct device *dev,int on) +{ +u32 val; +int ret; + +if (on) { + ret =omap_control_readl (dev,CONTROL_DEV_CONF , &val); +if (!ret && (val &PHY_PD )) { + ret =omap_control_writel (dev, ~PHY_PD , +CONTROL_DEV_CONF ); +/* XXX: add proper documentation for this delay */ +mdelay (200 ); + } + }else { + ret =omap_control_writel (dev,PHY_PD ,CONTROL_DEV_CONF ); + } + +return ret; +}Quoted 8 lines
Quoted 1 line
+EXPORT_SYMBOL_GPL(omap4_usb_phy_power);
I'm not quite convinced that we should export omap_control_read/write to drivers. If there's a clear register area this USB phy driver can manage, then ioremaping it separately makes sense. If it's just one register, then exporting something like
omap_control_usb_phy_set()might be better for ensuring that drivers don't mess up things for other drivers.After chatting with Benoit a bit we came to the conclusion that the clock and powerdomain state needs to be managed for the children by the SCM core driver so the children can't be completely independent.
Quoted 6 lines
But rather than exporting omap_control_read/write, maybe you can register the usb/bandgap whatever children with SCM core driver, then have the runtime PM calls from children be passthrough calls to the parent?
Maybe Kevin has some better ideas here?
Handling this with parent/child relationships is the way to go for runtime PM.
In MFD, are all sub-devices always children of the core device in the LDM? If so, it seems relatively easy to handle. If the parent/child relationships are modeled correctly in the LDM, then the children do not have to know anything about their parent, the runtime PM core will handle this (parent will not be runtime suspended until all the children are.)
Kevin
Tony Lindgren
maintainerRFC PATCH 7/11 mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
Quoted 43 lines · Kevin Hilman
Quoted 34 lines · Tony Lindgren
Quoted 20 lines · Tony Lindgren
Quoted 19 lines · Eduardo Valentin
drivers/usb/otg/omap4-usb-phy.c new file +19
-0+int omap4_usb_phy_power (struct device *dev,int on) +{ +u32 val; +int ret; + +if (on) { + ret =omap_control_readl (dev,CONTROL_DEV_CONF , &val); +if (!ret && (val &PHY_PD )) { + ret =omap_control_writel (dev, ~PHY_PD , +CONTROL_DEV_CONF ); +/* XXX: add proper documentation for this delay */ +mdelay (200 ); + } + }else { + ret =omap_control_writel (dev,PHY_PD ,CONTROL_DEV_CONF ); + } + +return ret; +}Quoted 8 lines
Quoted 1 line
+EXPORT_SYMBOL_GPL(omap4_usb_phy_power);
I'm not quite convinced that we should export omap_control_read/write to drivers. If there's a clear register area this USB phy driver can manage, then ioremaping it separately makes sense. If it's just one register, then exporting something like
omap_control_usb_phy_set()might be better for ensuring that drivers don't mess up things for other drivers.After chatting with Benoit a bit we came to the conclusion that the clock and powerdomain state needs to be managed for the children by the SCM core driver so the children can't be completely independent.
Quoted 6 lines
But rather than exporting omap_control_read/write, maybe you can register the usb/bandgap whatever children with SCM core driver, then have the runtime PM calls from children be passthrough calls to the parent?
Maybe Kevin has some better ideas here?
Quoted 8 lines
Handling this with parent/child relationships is the way to go for runtime PM.
In MFD, are all sub-devices always children of the core device in the LDM? If so, it seems relatively easy to handle. If the parent/child relationships are modeled correctly in the LDM, then the children do not have to know anything about their parent, the runtime PM core will handle this (parent will not be runtime suspended until all the children are.)
OK, so the parent-child relationship is there for DT case, but how do we set it for non-DT case? Call something like this from children:
omap_scm_register(dev, OMAP_SCM_USB_PHY) that then does device_move?
Tony
RFC PATCH 8/11 ARM: OMAP4+: Adding the temperature sensor register set bit fields
In reply to Eduardo ValentinOMAP4460 specific temperature sensor register bit fields are added. Existing OMAP4 entries are renamed to OMAP4430.
--- arch/arm/mach-omap2/include/mach/control.h | 116 ++++++++++++++++++++++++++++ 1 files changed, 116 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/include/mach/control.h +116 -0
@@ -230,6 +230,122 @@/* OMAP44xx control McBSP padconf */ #define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP 0x061c +/* TEMP_SENSOR OMAP4430 */ +#define OMAP4430_BGAP_TEMPSOFF_SHIFT 12 +#define OMAP4430_BGAP_TEMPSOFF_MASK (1 << 12) +#define OMAP4430_BGAP_TSHUT_SHIFT 11 +#define OMAP4430_BGAP_TSHUT_MASK (1 << 11) +#define OMAP4430_BGAP_TEMP_SENSOR_CONTCONV_SHIFT 10 +#define OMAP4430_BGAP_TEMP_SENSOR_CONTCONV_MASK (1 << 10) +#define OMAP4430_BGAP_TEMP_SENSOR_SOC_SHIFT 9 +#define OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK (1 << 9) +#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 8 +#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 8) +#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff << 0) + +/* TEMP_SENSOR OMAP4460 */ +#define OMAP4460_BGAP_TEMPSOFF_SHIFT 13 +#define OMAP4460_BGAP_TEMPSOFF_MASK (1 << 13) +#define OMAP4460_BGAP_TEMP_SENSOR_SOC_SHIFT 11 +#define OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK (1 << 11) +#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 +#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 10) +#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) + +/* BANDGAP_CTRL */ +#define OMAP4460_SINGLE_MODE_SHIFT 31 +#define OMAP4460_SINGLE_MODE_MASK (1 << 31) +#define OMAP4460_MASK_HOT_SHIFT 1 +#define OMAP4460_MASK_HOT_MASK (1 << 1) +#define OMAP4460_MASK_COLD_SHIFT 0 +#define OMAP4460_MASK_COLD_MASK (1 << 0) + +/* BANDGAP_COUNTER */ +#define OMAP4460_COUNTER_SHIFT 0 +#define OMAP4460_COUNTER_MASK (0xffffff << 0) + +/* BANDGAP_THRESHOLD */ +#define OMAP4460_T_HOT_SHIFT 16 +#define OMAP4460_T_HOT_MASK (0x3ff << 16) +#define OMAP4460_T_COLD_SHIFT 0 +#define OMAP4460_T_COLD_MASK (0x3ff << 0) + +/* TSHUT_THRESHOLD */ +#define OMAP4460_TSHUT_HOT_SHIFT 16 +#define OMAP4460_TSHUT_HOT_MASK (0x3ff << 16) +#define OMAP4460_TSHUT_COLD_SHIFT 0 +#define OMAP4460_TSHUT_COLD_MASK (0x3ff << 0) + +/* BANDGAP_STATUS */ +#define OMAP4460_CLEAN_STOP_SHIFT 3 +#define OMAP4460_CLEAN_STOP_MASK (1 << 3) +#define OMAP4460_BGAP_ALERT_SHIFT 2 +#define OMAP4460_BGAP_ALERT_MASK (1 << 2) +#define OMAP4460_HOT_FLAG_SHIFT 1 +#define OMAP4460_HOT_FLAG_MASK (1 << 1) +#define OMAP4460_COLD_FLAG_SHIFT 0 +#define OMAP4460_COLD_FLAG_MASK (1 << 0) + +/* TEMP_SENSOR OMAP5430 */ +#define OMAP5430_BGAP_TEMP_SENSOR_SOC_SHIFT 12 +#define OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK (1 << 12) +#define OMAP5430_BGAP_TEMPSOFF_SHIFT 11 +#define OMAP5430_BGAP_TEMPSOFF_MASK (1 << 11) +#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 +#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 10) +#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0) + +/* BANDGAP_CTRL */ +#define OMAP5430_MASK_HOT_CORE_SHIFT 5 +#define OMAP5430_MASK_HOT_CORE_MASK (1 << 5) +#define OMAP5430_MASK_COLD_CORE_SHIFT 4 +#define OMAP5430_MASK_COLD_CORE_MASK (1 << 4) +#define OMAP5430_MASK_HOT_MM_SHIFT 3 +#define OMAP5430_MASK_HOT_MM_MASK (1 << 3) +#define OMAP5430_MASK_COLD_MM_SHIFT 2 +#define OMAP5430_MASK_COLD_MM_MASK (1 << 2) +#define OMAP5430_MASK_HOT_MPU_SHIFT 1 +#define OMAP5430_MASK_HOT_MPU_MASK (1 << 1) +#define OMAP5430_MASK_COLD_MPU_SHIFT 0 +#define OMAP5430_MASK_COLD_MPU_MASK (1 << 0) + +/* BANDGAP_COUNTER */ +#define OMAP5430_REPEAT_MODE_SHIFT 31 +#define OMAP5430_REPEAT_MODE_MASK (1 << 31) +#define OMAP5430_COUNTER_SHIFT 0 +#define OMAP5430_COUNTER_MASK (0xffffff << 0) + +/* BANDGAP_THRESHOLD */ +#define OMAP5430_T_HOT_SHIFT 16 +#define OMAP5430_T_HOT_MASK (0x3ff << 16) +#define OMAP5430_T_COLD_SHIFT 0 +#define OMAP5430_T_COLD_MASK (0x3ff << 0) + +/* TSHUT_THRESHOLD */ +#define OMAP5430_TSHUT_HOT_SHIFT 16 +#define OMAP5430_TSHUT_HOT_MASK (0x3ff << 16) +#define OMAP5430_TSHUT_COLD_SHIFT 0 +#define OMAP5430_TSHUT_COLD_MASK (0x3ff << 0) + +/* BANDGAP_STATUS */ +#define OMAP5430_BGAP_ALERT_SHIFT 31 +#define OMAP5430_BGAP_ALERT_MASK (1 << 31) +#define OMAP5430_HOT_CORE_FLAG_SHIFT 5 +#define OMAP5430_HOT_CORE_FLAG_MASK (1 << 5) +#define OMAP5430_COLD_CORE_FLAG_SHIFT 4 +#define OMAP5430_COLD_CORE_FLAG_MASK (1 << 4) +#define OMAP5430_HOT_MM_FLAG_SHIFT 3 +#define OMAP5430_HOT_MM_FLAG_MASK (1 << 3) +#define OMAP5430_COLD_MM_FLAG_SHIFT 2 +#define OMAP5430_COLD_MM_FLAG_MASK (1 << 2) +#define OMAP5430_HOT_MPU_FLAG_SHIFT 1 +#define OMAP5430_HOT_MPU_FLAG_MASK (1 << 1) +#define OMAP5430_COLD_MPU_FLAG_SHIFT 0 +#define OMAP5430_COLD_MPU_FLAG_MASK (1 << 0) +/* AM35XX only CONTROL_GENERAL register offsets */ #define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 8/11 ARM: OMAP4+: Adding the temperature sensor register set bit fields
Quoted 7 lines · Eduardo Valentin
OMAP4460 specific temperature sensor register bit fields are added. Existing OMAP4 entries are renamed to OMAP4430.
Signed-off-by Keerthy<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>--- arch/arm/mach-omap2/include/mach/control.h | 116 ++++++++++++++++++++++++++++
Now that we do have a dedicated driver for the bandgap, I guess it will be better to put these defines inside the driver directly.
Benoit
Quoted 129 lines
1 files changed, 116 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/control.h +116
-0@@ -230,6 +230,122 @@/* OMAP44xx control McBSP padconf */ #define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP 0x061c +/* TEMP_SENSOR OMAP4430 */ +#define OMAP4430_BGAP_TEMPSOFF_SHIFT 12 +#define OMAP4430_BGAP_TEMPSOFF_MASK (1<< 12) +#define OMAP4430_BGAP_TSHUT_SHIFT 11 +#define OMAP4430_BGAP_TSHUT_MASK (1<< 11) +#define OMAP4430_BGAP_TEMP_SENSOR_CONTCONV_SHIFT 10 +#define OMAP4430_BGAP_TEMP_SENSOR_CONTCONV_MASK (1<< 10) +#define OMAP4430_BGAP_TEMP_SENSOR_SOC_SHIFT 9 +#define OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK (1<< 9) +#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 8 +#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK (1<< 8) +#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff<< 0) + +/* TEMP_SENSOR OMAP4460 */ +#define OMAP4460_BGAP_TEMPSOFF_SHIFT 13 +#define OMAP4460_BGAP_TEMPSOFF_MASK (1<< 13) +#define OMAP4460_BGAP_TEMP_SENSOR_SOC_SHIFT 11 +#define OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK (1<< 11) +#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 +#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK (1<< 10) +#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff<< 0) + +/* BANDGAP_CTRL */ +#define OMAP4460_SINGLE_MODE_SHIFT 31 +#define OMAP4460_SINGLE_MODE_MASK (1<< 31) +#define OMAP4460_MASK_HOT_SHIFT 1 +#define OMAP4460_MASK_HOT_MASK (1<< 1) +#define OMAP4460_MASK_COLD_SHIFT 0 +#define OMAP4460_MASK_COLD_MASK (1<< 0) + +/* BANDGAP_COUNTER */ +#define OMAP4460_COUNTER_SHIFT 0 +#define OMAP4460_COUNTER_MASK (0xffffff<< 0) + +/* BANDGAP_THRESHOLD */ +#define OMAP4460_T_HOT_SHIFT 16 +#define OMAP4460_T_HOT_MASK (0x3ff<< 16) +#define OMAP4460_T_COLD_SHIFT 0 +#define OMAP4460_T_COLD_MASK (0x3ff<< 0) + +/* TSHUT_THRESHOLD */ +#define OMAP4460_TSHUT_HOT_SHIFT 16 +#define OMAP4460_TSHUT_HOT_MASK (0x3ff<< 16) +#define OMAP4460_TSHUT_COLD_SHIFT 0 +#define OMAP4460_TSHUT_COLD_MASK (0x3ff<< 0) + +/* BANDGAP_STATUS */ +#define OMAP4460_CLEAN_STOP_SHIFT 3 +#define OMAP4460_CLEAN_STOP_MASK (1<< 3) +#define OMAP4460_BGAP_ALERT_SHIFT 2 +#define OMAP4460_BGAP_ALERT_MASK (1<< 2) +#define OMAP4460_HOT_FLAG_SHIFT 1 +#define OMAP4460_HOT_FLAG_MASK (1<< 1) +#define OMAP4460_COLD_FLAG_SHIFT 0 +#define OMAP4460_COLD_FLAG_MASK (1<< 0) + +/* TEMP_SENSOR OMAP5430 */ +#define OMAP5430_BGAP_TEMP_SENSOR_SOC_SHIFT 12 +#define OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK (1<< 12) +#define OMAP5430_BGAP_TEMPSOFF_SHIFT 11 +#define OMAP5430_BGAP_TEMPSOFF_MASK (1<< 11) +#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 +#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK (1<< 10) +#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff<< 0) + +/* BANDGAP_CTRL */ +#define OMAP5430_MASK_HOT_CORE_SHIFT 5 +#define OMAP5430_MASK_HOT_CORE_MASK (1<< 5) +#define OMAP5430_MASK_COLD_CORE_SHIFT 4 +#define OMAP5430_MASK_COLD_CORE_MASK (1<< 4) +#define OMAP5430_MASK_HOT_MM_SHIFT 3 +#define OMAP5430_MASK_HOT_MM_MASK (1<< 3) +#define OMAP5430_MASK_COLD_MM_SHIFT 2 +#define OMAP5430_MASK_COLD_MM_MASK (1<< 2) +#define OMAP5430_MASK_HOT_MPU_SHIFT 1 +#define OMAP5430_MASK_HOT_MPU_MASK (1<< 1) +#define OMAP5430_MASK_COLD_MPU_SHIFT 0 +#define OMAP5430_MASK_COLD_MPU_MASK (1<< 0) + +/* BANDGAP_COUNTER */ +#define OMAP5430_REPEAT_MODE_SHIFT 31 +#define OMAP5430_REPEAT_MODE_MASK (1<< 31) +#define OMAP5430_COUNTER_SHIFT 0 +#define OMAP5430_COUNTER_MASK (0xffffff<< 0) + +/* BANDGAP_THRESHOLD */ +#define OMAP5430_T_HOT_SHIFT 16 +#define OMAP5430_T_HOT_MASK (0x3ff<< 16) +#define OMAP5430_T_COLD_SHIFT 0 +#define OMAP5430_T_COLD_MASK (0x3ff<< 0) + +/* TSHUT_THRESHOLD */ +#define OMAP5430_TSHUT_HOT_SHIFT 16 +#define OMAP5430_TSHUT_HOT_MASK (0x3ff<< 16) +#define OMAP5430_TSHUT_COLD_SHIFT 0 +#define OMAP5430_TSHUT_COLD_MASK (0x3ff<< 0) + +/* BANDGAP_STATUS */ +#define OMAP5430_BGAP_ALERT_SHIFT 31 +#define OMAP5430_BGAP_ALERT_MASK (1<< 31) +#define OMAP5430_HOT_CORE_FLAG_SHIFT 5 +#define OMAP5430_HOT_CORE_FLAG_MASK (1<< 5) +#define OMAP5430_COLD_CORE_FLAG_SHIFT 4 +#define OMAP5430_COLD_CORE_FLAG_MASK (1<< 4) +#define OMAP5430_HOT_MM_FLAG_SHIFT 3 +#define OMAP5430_HOT_MM_FLAG_MASK (1<< 3) +#define OMAP5430_COLD_MM_FLAG_SHIFT 2 +#define OMAP5430_COLD_MM_FLAG_MASK (1<< 2) +#define OMAP5430_HOT_MPU_FLAG_SHIFT 1 +#define OMAP5430_HOT_MPU_FLAG_MASK (1<< 1) +#define OMAP5430_COLD_MPU_FLAG_SHIFT 0 +#define OMAP5430_COLD_MPU_FLAG_MASK (1<< 0) +/* AM35XX only CONTROL_GENERAL register offsets */ #define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
RFC PATCH 8/11 ARM: OMAP4+: Adding the temperature sensor register set bit fields
Quoted 11 lines · Cousson Benoit
Quoted 7 lines · Eduardo Valentin
OMAP4460 specific temperature sensor register bit fields are added. Existing OMAP4 entries are renamed to OMAP4430.
Signed-off-by Keerthy<[email protected]>Signed-off-by Eduardo Valentin<[email protected]>--- arch/arm/mach-omap2/include/mach/control.h | 116 ++++++++++++++++++++++++++++Now that we do have a dedicated driver for the bandgap, I guess it will be better to put these defines inside the driver directly.
Agreed
Quoted 133 lines
Benoit
Quoted 129 lines
1 files changed, 116 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/control.h +116
-0@@ -230,6 +230,122 @@/* OMAP44xx control McBSP padconf */ #define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP 0x061c +/* TEMP_SENSOR OMAP4430 */ +#define OMAP4430_BGAP_TEMPSOFF_SHIFT 12 +#define OMAP4430_BGAP_TEMPSOFF_MASK (1<< 12) +#define OMAP4430_BGAP_TSHUT_SHIFT 11 +#define OMAP4430_BGAP_TSHUT_MASK (1<< 11) +#define OMAP4430_BGAP_TEMP_SENSOR_CONTCONV_SHIFT 10 +#define OMAP4430_BGAP_TEMP_SENSOR_CONTCONV_MASK (1<< 10) +#define OMAP4430_BGAP_TEMP_SENSOR_SOC_SHIFT 9 +#define OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK (1<< 9) +#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 8 +#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK (1<< 8) +#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff<< 0) + +/* TEMP_SENSOR OMAP4460 */ +#define OMAP4460_BGAP_TEMPSOFF_SHIFT 13 +#define OMAP4460_BGAP_TEMPSOFF_MASK (1<< 13) +#define OMAP4460_BGAP_TEMP_SENSOR_SOC_SHIFT 11 +#define OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK (1<< 11) +#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 +#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK (1<< 10) +#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff<< 0) + +/* BANDGAP_CTRL */ +#define OMAP4460_SINGLE_MODE_SHIFT 31 +#define OMAP4460_SINGLE_MODE_MASK (1<< 31) +#define OMAP4460_MASK_HOT_SHIFT 1 +#define OMAP4460_MASK_HOT_MASK (1<< 1) +#define OMAP4460_MASK_COLD_SHIFT 0 +#define OMAP4460_MASK_COLD_MASK (1<< 0) + +/* BANDGAP_COUNTER */ +#define OMAP4460_COUNTER_SHIFT 0 +#define OMAP4460_COUNTER_MASK (0xffffff<< 0) + +/* BANDGAP_THRESHOLD */ +#define OMAP4460_T_HOT_SHIFT 16 +#define OMAP4460_T_HOT_MASK (0x3ff<< 16) +#define OMAP4460_T_COLD_SHIFT 0 +#define OMAP4460_T_COLD_MASK (0x3ff<< 0) + +/* TSHUT_THRESHOLD */ +#define OMAP4460_TSHUT_HOT_SHIFT 16 +#define OMAP4460_TSHUT_HOT_MASK (0x3ff<< 16) +#define OMAP4460_TSHUT_COLD_SHIFT 0 +#define OMAP4460_TSHUT_COLD_MASK (0x3ff<< 0) + +/* BANDGAP_STATUS */ +#define OMAP4460_CLEAN_STOP_SHIFT 3 +#define OMAP4460_CLEAN_STOP_MASK (1<< 3) +#define OMAP4460_BGAP_ALERT_SHIFT 2 +#define OMAP4460_BGAP_ALERT_MASK (1<< 2) +#define OMAP4460_HOT_FLAG_SHIFT 1 +#define OMAP4460_HOT_FLAG_MASK (1<< 1) +#define OMAP4460_COLD_FLAG_SHIFT 0 +#define OMAP4460_COLD_FLAG_MASK (1<< 0) + +/* TEMP_SENSOR OMAP5430 */ +#define OMAP5430_BGAP_TEMP_SENSOR_SOC_SHIFT 12 +#define OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK (1<< 12) +#define OMAP5430_BGAP_TEMPSOFF_SHIFT 11 +#define OMAP5430_BGAP_TEMPSOFF_MASK (1<< 11) +#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_SHIFT 10 +#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK (1<< 10) +#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0 +#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff<< 0) + +/* BANDGAP_CTRL */ +#define OMAP5430_MASK_HOT_CORE_SHIFT 5 +#define OMAP5430_MASK_HOT_CORE_MASK (1<< 5) +#define OMAP5430_MASK_COLD_CORE_SHIFT 4 +#define OMAP5430_MASK_COLD_CORE_MASK (1<< 4) +#define OMAP5430_MASK_HOT_MM_SHIFT 3 +#define OMAP5430_MASK_HOT_MM_MASK (1<< 3) +#define OMAP5430_MASK_COLD_MM_SHIFT 2 +#define OMAP5430_MASK_COLD_MM_MASK (1<< 2) +#define OMAP5430_MASK_HOT_MPU_SHIFT 1 +#define OMAP5430_MASK_HOT_MPU_MASK (1<< 1) +#define OMAP5430_MASK_COLD_MPU_SHIFT 0 +#define OMAP5430_MASK_COLD_MPU_MASK (1<< 0) + +/* BANDGAP_COUNTER */ +#define OMAP5430_REPEAT_MODE_SHIFT 31 +#define OMAP5430_REPEAT_MODE_MASK (1<< 31) +#define OMAP5430_COUNTER_SHIFT 0 +#define OMAP5430_COUNTER_MASK (0xffffff<< 0) + +/* BANDGAP_THRESHOLD */ +#define OMAP5430_T_HOT_SHIFT 16 +#define OMAP5430_T_HOT_MASK (0x3ff<< 16) +#define OMAP5430_T_COLD_SHIFT 0 +#define OMAP5430_T_COLD_MASK (0x3ff<< 0) + +/* TSHUT_THRESHOLD */ +#define OMAP5430_TSHUT_HOT_SHIFT 16 +#define OMAP5430_TSHUT_HOT_MASK (0x3ff<< 16) +#define OMAP5430_TSHUT_COLD_SHIFT 0 +#define OMAP5430_TSHUT_COLD_MASK (0x3ff<< 0) + +/* BANDGAP_STATUS */ +#define OMAP5430_BGAP_ALERT_SHIFT 31 +#define OMAP5430_BGAP_ALERT_MASK (1<< 31) +#define OMAP5430_HOT_CORE_FLAG_SHIFT 5 +#define OMAP5430_HOT_CORE_FLAG_MASK (1<< 5) +#define OMAP5430_COLD_CORE_FLAG_SHIFT 4 +#define OMAP5430_COLD_CORE_FLAG_MASK (1<< 4) +#define OMAP5430_HOT_MM_FLAG_SHIFT 3 +#define OMAP5430_HOT_MM_FLAG_MASK (1<< 3) +#define OMAP5430_COLD_MM_FLAG_SHIFT 2 +#define OMAP5430_COLD_MM_FLAG_MASK (1<< 2) +#define OMAP5430_HOT_MPU_FLAG_SHIFT 1 +#define OMAP5430_HOT_MPU_FLAG_MASK (1<< 1) +#define OMAP5430_COLD_MPU_FLAG_SHIFT 0 +#define OMAP5430_COLD_MPU_FLAG_MASK (1<< 0) +/* AM35XX only CONTROL_GENERAL register offsets */ #define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
RFC PATCH 8/11 ARM: OMAP4+: Adding the temperature sensor register set bit fields
In reply to Eduardo ValentinQuoted 6 lines · Eduardo Valentin
OMAP4460 specific temperature sensor register bit fields are added. Existing OMAP4 entries are renamed to OMAP4430.
Signed-off-by Keerthy <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>---
Once you split the header, as mentioned in earlier comment, you can move those defines in driver file directly.
Regards
Santsoh
RFC PATCH 8/11 ARM: OMAP4+: Adding the temperature sensor register set bit fields
Quoted 10 lines · Santosh
Quoted 6 lines · Eduardo Valentin
OMAP4460 specific temperature sensor register bit fields are added. Existing OMAP4 entries are renamed to OMAP4430.
Signed-off-by Keerthy <[email protected]>Signed-off-by Eduardo Valentin <[email protected]>---
Once you split the header, as mentioned in earlier comment, you can move those defines in driver file directly.
Agreed, this patch is gonna be dropped and the definition will be part of patch introducing the bandgap driver
Quoted 3 lines
Regards
Santsoh
RFC PATCH 9/11 ARM: OMAP4+: thermal: introduce bandgap temperature sensor
In reply to Eduardo ValentinIn the System Control Module, OMAP supplies a voltage reference and a temperature sensor feature that are gathered in the band gap voltage and temperature sensor (VBGAPTS) module. The band gap provides current and voltage reference for its internal circuits and other analog IP blocks. The analog-to-digital converter (ADC) produces an output value that is proportional to the silicon temperature.
This patch provides a platform driver which expose this feature. It is moduled as a MFD child of the System Control Module core MFD driver.
This driver provides only APIs to access the device properties, like temperature, thresholds and update rate.
--- .../devicetree/bindings/thermal/omap_bandgap.txt | 27 + drivers/thermal/Kconfig | 13 + drivers/thermal/Makefile | 4 +- drivers/thermal/omap-bandgap.c | 1601 ++++++++++++++++++++ drivers/thermal/omap-bandgap.h | 63 + 5 files changed, 1707 insertions(+), 1 deletions(-) create mode 100644 Documentation/devicetree/bindings/thermal/omap_bandgap.txt create mode 100644 drivers/thermal/omap-bandgap.c create mode 100644 drivers/thermal/omap-bandgap.h
Documentation/devicetree/bindings/thermal/omap_bandgap.txt new file +27 -0
@@ -0,0 +1,27 @@ +* Texas Instrument OMAP SCM bandgap bindings + +In the System Control Module, OMAP supplies a voltage reference +and a temperature sensor feature that are gathered in the band +gap voltage and temperature sensor (VBGAPTS) module. The band +gap provides current and voltage reference for its internal +circuits and other analog IP blocks. The analog-to-digital +converter (ADC) produces an output value that is proportional +to the silicon temperature. + +Required properties: +- compatible : Should be: + - "ti,omap4460-control-bandgap" : for OMAP4460 bandgap + - "ti,omap5430-control-bandgap" : for OMAP5430 bandgap +- interrupts : this entry should indicate which interrupt line +the talert signal is routed to; +Specific: +- ti,tshut-gpio : this entry should be used to inform which GPIO +line the tshut signal is routed to; + +Example: + +bandgap { + compatible = "ti,omap4460-control-bandgap"; + interrupts = <0 126 4>; /* talert */ + ti,tshut-gpio = <86>; +};
drivers/thermal/Kconfig +13 -0
@@ -26,3 +26,16 @@ config SPEAR_THERMAL help Enable this to plug the SPEAr thermal sensor driver into the Linux thermal framework + +config OMAP_BANDGAP + tristate "Texas Instruments OMAP4+ temperature sensor driver" + depends on THERMAL + depends on MFD_OMAP_CONTROL + help + If you say yes here you get support for the Texas Instruments + OMAP4460+ on die bandgap temperature sensor support. The register + set is part of system control module. + + This includes alert interrupts generation and also the TSHUT + support. +
drivers/thermal/Makefile +3 -1
@@ -3,4 +3,6 @@ # obj-$(CONFIG_THERMAL) += thermal_sys.o -obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o +obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o +obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal.o +omap-thermal-y := omap-bandgap.o
drivers/thermal/omap-bandgap.c new file +1601 -0
1,601 lines not on this page · raw message
drivers/thermal/omap-bandgap.h new file +63 -0
63 lines not on this page · raw message
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 9/11 ARM: OMAP4+: thermal: introduce bandgap temperature sensor
Quoted 366 lines · Eduardo Valentin
In the System Control Module, OMAP supplies a voltage reference and a temperature sensor feature that are gathered in the band gap voltage and temperature sensor (VBGAPTS) module. The band gap provides current and voltage reference for its internal circuits and other analog IP blocks. The analog-to-digital converter (ADC) produces an output value that is proportional to the silicon temperature.
This patch provides a platform driver which expose this feature. It is moduled as a MFD child of the System Control Module core MFD driver.
This driver provides only APIs to access the device properties, like temperature, thresholds and update rate.
Signed-off-by Eduardo Valentin<[email protected]>Signed-off-by Keerthy<[email protected]>--- .../devicetree/bindings/thermal/omap_bandgap.txt | 27 + drivers/thermal/Kconfig | 13 + drivers/thermal/Makefile | 4 +- drivers/thermal/omap-bandgap.c | 1601 ++++++++++++++++++++ drivers/thermal/omap-bandgap.h | 63 + 5 files changed, 1707 insertions(+), 1 deletions(-)create mode 100644
Documentation/devicetree/bindings/thermal/omap_bandgap.txtcreate mode 100644drivers/thermal/omap-bandgap.c
create mode 100644drivers/thermal/omap-bandgap.hDocumentation/devicetree/bindings/thermal/omap_bandgap.txt new file +27
-0@@ -0,0 +1,27 @@ +* Texas Instrument OMAP SCM bandgap bindings + +In the System Control Module, OMAP supplies a voltage reference +and a temperature sensor feature that are gathered in the band +gap voltage and temperature sensor (VBGAPTS) module. The band +gap provides current and voltage reference for its internal +circuits and other analog IP blocks. The analog-to-digital +converter (ADC) produces an output value that is proportional +to the silicon temperature. + +Required properties: +- compatible : Should be: + - "ti,omap4460-control-bandgap" : for OMAP4460 bandgap + - "ti,omap5430-control-bandgap" : for OMAP5430 bandgap +- interrupts : this entry should indicate which interrupt line +the talert signal is routed to; +Specific: +- ti,tshut-gpio : this entry should be used to inform which GPIO +line the tshut signal is routed to; + +Example: + +bandgap { + compatible = "ti,omap4460-control-bandgap"; + interrupts =<0 126 4>; /* talert */ + ti,tshut-gpio =<86>; +};drivers/thermal/Kconfig +13
-0@@ -26,3 +26,16 @@ config SPEAR_THERMAL help Enable this to plug the SPEAr thermal sensor driver into the Linux thermal framework + +config OMAP_BANDGAP + tristate "Texas Instruments OMAP4+ temperature sensor driver" + depends on THERMAL + depends on MFD_OMAP_CONTROL + help + If you say yes here you get support for the Texas Instruments + OMAP4460+ on die bandgap temperature sensor support. The register + set is part of system control module. + + This includes alert interrupts generation and also the TSHUT + support. +drivers/thermal/Makefile +3
-1@@ -3,4 +3,6 @@ # obj-$(CONFIG_THERMAL) += thermal_sys.o -obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o +obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o +obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal.o +omap-thermal-y := omap-bandgap.odrivers/thermal/omap-bandgap.c new file +265
-0@@ -0,0 +1,1601 @@ +/* +* OMAP4 Bandgap temperature sensor driver +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Author: J Keerthy<[email protected]> +* Author: Moiz Sonasath<[email protected]> +* Couple of fixes, DT and MFD adaptation: +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include <linux/module.h> +#include <linux/export.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/types.h> +#include <linux/mutex.h> +#include <linux/reboot.h> +#include <linux/of_platform.h> +#include <linux/of_irq.h> +#include <linux/mfd/omap_control.h> + +#include <mach/control.h> + +#include "omap-bandgap.h" + +/* Offsets from the base of temperature sensor registers */ + +#define OMAP4460_TEMP_SENSOR_CTRL_OFFSET 0x32C +#define OMAP4460_BGAP_CTRL_OFFSET 0x378 +#define OMAP4460_BGAP_COUNTER_OFFSET 0x37C +#define OMAP4460_BGAP_THRESHOLD_OFFSET 0x380 +#define OMAP4460_BGAP_TSHUT_OFFSET 0x384 +#define OMAP4460_BGAP_STATUS_OFFSET 0x388 +#define OMAP4460_FUSE_OPP_BGAP 0x260 + +#define OMAP5430_TEMP_SENSOR_MPU_OFFSET 0x32C +#define OMAP5430_BGAP_CTRL_OFFSET 0x380 +#define OMAP5430_BGAP_COUNTER_MPU_OFFSET 0x39C +#define OMAP5430_BGAP_THRESHOLD_MPU_OFFSET 0x384 +#define OMAP5430_BGAP_TSHUT_MPU_OFFSET 0x390 +#define OMAP5430_BGAP_STATUS_OFFSET 0x3A8 +#define OMAP5430_FUSE_OPP_BGAP_MPU 0x1E4 + +#define OMAP5430_TEMP_SENSOR_GPU_OFFSET 0x330 +#define OMAP5430_BGAP_COUNTER_GPU_OFFSET 0x3A0 +#define OMAP5430_BGAP_THRESHOLD_GPU_OFFSET 0x388 +#define OMAP5430_BGAP_TSHUT_GPU_OFFSET 0x394 +#define OMAP5430_FUSE_OPP_BGAP_GPU 0x1E0 + +#define OMAP5430_TEMP_SENSOR_CORE_OFFSET 0x334 +#define OMAP5430_BGAP_COUNTER_CORE_OFFSET 0x3A4 +#define OMAP5430_BGAP_THRESHOLD_CORE_OFFSET 0x38C +#define OMAP5430_BGAP_TSHUT_CORE_OFFSET 0x398 +#define OMAP5430_FUSE_OPP_BGAP_CORE 0x1E8 + +#define OMAP4460_TSHUT_HOT 900/* 122 deg C */ +#define OMAP4460_TSHUT_COLD 895/* 100 deg C */ +#define OMAP4460_T_HOT 800/* 73 deg C */ +#define OMAP4460_T_COLD 795/* 71 deg C */ +#define OMAP4460_MAX_FREQ 1500000 +#define OMAP4460_MIN_FREQ 1000000 +#define OMAP4460_MIN_TEMP -40000 +#define OMAP4460_MAX_TEMP 123000 +#define OMAP4460_HYST_VAL 5000 +#define OMAP4460_ADC_START_VALUE 530 +#define OMAP4460_ADC_END_VALUE 932 + +#define OMAP5430_MPU_TSHUT_HOT 915 +#define OMAP5430_MPU_TSHUT_COLD 900 +#define OMAP5430_MPU_T_HOT 800 +#define OMAP5430_MPU_T_COLD 795 +#define OMAP5430_MPU_MAX_FREQ 1500000 +#define OMAP5430_MPU_MIN_FREQ 1000000 +#define OMAP5430_MPU_MIN_TEMP -40000 +#define OMAP5430_MPU_MAX_TEMP 125000 +#define OMAP5430_MPU_HYST_VAL 5000 +#define OMAP5430_ADC_START_VALUE 532 +#define OMAP5430_ADC_END_VALUE 934 + +#define OMAP5430_GPU_TSHUT_HOT 915 +#define OMAP5430_GPU_TSHUT_COLD 900 +#define OMAP5430_GPU_T_HOT 800 +#define OMAP5430_GPU_T_COLD 795 +#define OMAP5430_GPU_MAX_FREQ 1500000 +#define OMAP5430_GPU_MIN_FREQ 1000000 +#define OMAP5430_GPU_MIN_TEMP -40000 +#define OMAP5430_GPU_MAX_TEMP 125000 +#define OMAP5430_GPU_HYST_VAL 5000 + +#define OMAP5430_CORE_TSHUT_HOT 915 +#define OMAP5430_CORE_TSHUT_COLD 900 +#define OMAP5430_CORE_T_HOT 800 +#define OMAP5430_CORE_T_COLD 795 +#define OMAP5430_CORE_MAX_FREQ 1500000 +#define OMAP5430_CORE_MIN_FREQ 1000000 +#define OMAP5430_CORE_MIN_TEMP -40000 +#define OMAP5430_CORE_MAX_TEMP 125000 +#define OMAP5430_CORE_HYST_VAL 5000 + +/** +* The register offsets and bit fields might change across +* OMAP versions hence populating them in this structure. +*/ + +struct temp_sensor_registers { +u32 temp_sensor_ctrl; +u32 bgap_tempsoff_mask; +u32 bgap_soc_mask; +u32 bgap_eocz_mask; +u32 bgap_dtemp_mask; + +u32 bgap_mask_ctrl; +u32 mask_hot_mask; +u32 mask_cold_mask; + +u32 bgap_mode_ctrl; +u32 mode_ctrl_mask; + +u32 bgap_counter; +u32 counter_mask; + +u32 bgap_threshold; +u32 threshold_thot_mask; +u32 threshold_tcold_mask; + +u32 tshut_threshold; +u32 tshut_hot_mask; +u32 tshut_cold_mask; + +u32 bgap_status; +u32 status_clean_stop_mask; +u32 status_bgap_alert_mask; +u32 status_hot_mask; +u32 status_cold_mask; + +u32 bgap_efuse; +}; + +/** +* The thresholds and limits for temperature sensors. +*/ +struct temp_sensor_data { +u32 tshut_hot; +u32 tshut_cold; +u32 t_hot; +u32 t_cold; +u32 min_freq; +u32 max_freq; +int max_temp; +int min_temp; +int hyst_val; +u32 adc_start_val; +u32 adc_end_val; +u32 update_int1; +u32 update_int2; +}; + +/** +* struct temp_sensor_regval - temperature sensor register values +* @bg_mode_ctrl: temp sensor control register value +* @bg_ctrl: bandgap ctrl register value +* @bg_counter: bandgap counter value +* @bg_threshold: bandgap threshold register value +* @tshut_threshold: bandgap tshut register value +*/ +struct temp_sensor_regval { +u32 bg_mode_ctrl; +u32 bg_ctrl; +u32 bg_counter; +u32 bg_threshold; +u32 tshut_threshold; +}; + +/** +* struct omap_temp_sensor - bandgap temperature sensor platform data +* @ts_data: pointer to struct with thresholds, limits of temperature sensor +* @registers: pointer to the list of register offsets and bitfields +* @regval: temperature sensor register values +* @domain: the name of the domain where the sensor is located +*/ +struct omap_temp_sensor { +struct temp_sensor_data *ts_data; +struct temp_sensor_registers *registers; +struct temp_sensor_regval *regval; +char *domain; +}; + +/** +* struct omap_bandgap_data - bandgap platform data structure +* @has_talert: indicates if the chip has talert output line +* @has_tshut: indicates if the chip has tshut output line +* @conv_table: Pointer to adc to temperature conversion table +* @fclock_name: clock name of the functional clock +* @div_ck_nme: clock name of the clock divisor +* @sensor_count: count of temperature sensor device in scm +* @sensors: array of sensors present in this bandgap instance +* @expose_sensor: callback to export sensor to thermal API +*/ +struct omap_bandgap_data { +bool has_talert; +bool has_tshut; +const int *conv_table; +char *fclock_name; +char *div_ck_name; +int sensor_count; +int (*report_temperature)(struct omap_bandgap *bg_ptr,int id); +int (*expose_sensor)(struct omap_bandgap *bg_ptr,int id,char *domain); + +/* this needs to be at the end */ +struct omap_temp_sensor sensors[]; +}; + +/* TODO: provide data structures for 4430 */ + +/* +* OMAP4460 has one instance of thermal sensor for MPU +* need to describe the individual bit fields +*/ +static struct temp_sensor_registers +omap4460_mpu_temp_sensor_registers = { + .temp_sensor_ctrl =OMAP4460_TEMP_SENSOR_CTRL_OFFSET , + .bgap_tempsoff_mask =OMAP4460_BGAP_TEMPSOFF_MASK , + .bgap_soc_mask =OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK , + .bgap_eocz_mask =OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK , + .bgap_dtemp_mask =OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK , + + .bgap_mask_ctrl =OMAP4460_BGAP_CTRL_OFFSET , + .mask_hot_mask =OMAP4460_MASK_HOT_MASK , + .mask_cold_mask =OMAP4460_MASK_COLD_MASK , + + .bgap_mode_ctrl =OMAP4460_BGAP_CTRL_OFFSET , + .mode_ctrl_mask =OMAP4460_SINGLE_MODE_MASK , + + .bgap_counter =OMAP4460_BGAP_COUNTER_OFFSET , + .counter_mask =OMAP4460_COUNTER_MASK , + + .bgap_threshold =OMAP4460_BGAP_THRESHOLD_OFFSET , + .threshold_thot_mask =OMAP4460_T_HOT_MASK , + .threshold_tcold_mask =OMAP4460_T_COLD_MASK , + + .tshut_threshold =OMAP4460_BGAP_TSHUT_OFFSET , + .tshut_hot_mask =OMAP4460_TSHUT_HOT_MASK , + .tshut_cold_mask =OMAP4460_TSHUT_COLD_MASK , + + .bgap_status =OMAP4460_BGAP_STATUS_OFFSET ,
drivers/thermal/omap-bandgap.c line 275
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ .status_clean_stop_mask = OMAP4460_CLEAN_STOP_MASK, + .status_bgap_alert_mask = OMAP4460_BGAP_ALERT_MASK, + .status_hot_mask = OMAP4460_HOT_FLAG_MASK, + .status_cold_mask = OMAP4460_COLD_FLAG_MASK, + + .bgap_efuse = OMAP4460_FUSE_OPP_BGAP, +}; + +/* +* OMAP4460 has one instance of thermal sensor for MPU
Bad copy paste.
Quoted 31 lines
drivers/thermal/omap-bandgap.c new file +31
-0+* need to describe the individual bit fields +*/ +static struct temp_sensor_registers +omap5430_mpu_temp_sensor_registers = { + .temp_sensor_ctrl =OMAP5430_TEMP_SENSOR_MPU_OFFSET , + .bgap_tempsoff_mask =OMAP5430_BGAP_TEMPSOFF_MASK , + .bgap_soc_mask =OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK , + .bgap_eocz_mask =OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK , + .bgap_dtemp_mask =OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK , + + .bgap_mask_ctrl =OMAP5430_BGAP_CTRL_OFFSET , + .mask_hot_mask =OMAP5430_MASK_HOT_MPU_MASK , + .mask_cold_mask =OMAP5430_MASK_COLD_MPU_MASK , + + .bgap_mode_ctrl =OMAP5430_BGAP_COUNTER_MPU_OFFSET , + .mode_ctrl_mask =OMAP5430_REPEAT_MODE_MASK , + + .bgap_counter =OMAP5430_BGAP_COUNTER_MPU_OFFSET , + .counter_mask =OMAP5430_COUNTER_MASK , + + .bgap_threshold =OMAP5430_BGAP_THRESHOLD_MPU_OFFSET , + .threshold_thot_mask =OMAP5430_T_HOT_MASK , + .threshold_tcold_mask =OMAP5430_T_COLD_MASK , + + .tshut_threshold =OMAP5430_BGAP_TSHUT_MPU_OFFSET , + .tshut_hot_mask =OMAP5430_TSHUT_HOT_MASK , + .tshut_cold_mask =OMAP5430_TSHUT_COLD_MASK , + + .bgap_status =OMAP5430_BGAP_STATUS_OFFSET , + .status_clean_stop_mask =0x0 , + .status_bgap_alert_mask =OMAP5430_BGAP_ALERT_MASK ,
drivers/thermal/omap-bandgap.c line 316
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ .status_hot_mask = OMAP5430_HOT_MPU_FLAG_MASK, + .status_cold_mask = OMAP5430_COLD_MPU_FLAG_MASK, + + .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_MPU, +}; + +/* +* OMAP4460 has one instance of thermal sensor for MPU +* need to describe the individual bit fields +*/
Ditto
Quoted 29 lines
drivers/thermal/omap-bandgap.c new file +29
-0+static struct temp_sensor_registers +omap5430_gpu_temp_sensor_registers = { + .temp_sensor_ctrl =OMAP5430_TEMP_SENSOR_GPU_OFFSET , + .bgap_tempsoff_mask =OMAP5430_BGAP_TEMPSOFF_MASK , + .bgap_soc_mask =OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK , + .bgap_eocz_mask =OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK , + .bgap_dtemp_mask =OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK , + + .bgap_mask_ctrl =OMAP5430_BGAP_CTRL_OFFSET , + .mask_hot_mask =OMAP5430_MASK_HOT_MM_MASK , + .mask_cold_mask =OMAP5430_MASK_COLD_MM_MASK , + + .bgap_mode_ctrl =OMAP5430_BGAP_COUNTER_GPU_OFFSET , + .mode_ctrl_mask =OMAP5430_REPEAT_MODE_MASK , + + .bgap_counter =OMAP5430_BGAP_COUNTER_GPU_OFFSET , + .counter_mask =OMAP5430_COUNTER_MASK , + + .bgap_threshold =OMAP5430_BGAP_THRESHOLD_GPU_OFFSET , + .threshold_thot_mask =OMAP5430_T_HOT_MASK , + .threshold_tcold_mask =OMAP5430_T_COLD_MASK , + + .tshut_threshold =OMAP5430_BGAP_TSHUT_GPU_OFFSET , + .tshut_hot_mask =OMAP5430_TSHUT_HOT_MASK , + .tshut_cold_mask =OMAP5430_TSHUT_COLD_MASK , + + .bgap_status =OMAP5430_BGAP_STATUS_OFFSET , + .status_clean_stop_mask =0x0 , + .status_bgap_alert_mask =OMAP5430_BGAP_ALERT_MASK ,
drivers/thermal/omap-bandgap.c line 355
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ .status_hot_mask = OMAP5430_HOT_MM_FLAG_MASK, + .status_cold_mask = OMAP5430_COLD_MM_FLAG_MASK, + + .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_GPU, +}; + +/* +* OMAP4460 has one instance of thermal sensor for MPU +* need to describe the individual bit fields +*/
Ditto
Quoted 215 lines
drivers/thermal/omap-bandgap.c new file +215
-0+static struct temp_sensor_registers +omap5430_core_temp_sensor_registers = { + .temp_sensor_ctrl =OMAP5430_TEMP_SENSOR_CORE_OFFSET , + .bgap_tempsoff_mask =OMAP5430_BGAP_TEMPSOFF_MASK , + .bgap_soc_mask =OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK , + .bgap_eocz_mask =OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK , + .bgap_dtemp_mask =OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK , + + .bgap_mask_ctrl =OMAP5430_BGAP_CTRL_OFFSET , + .mask_hot_mask =OMAP5430_MASK_HOT_CORE_MASK , + .mask_cold_mask =OMAP5430_MASK_COLD_CORE_MASK , + + .bgap_mode_ctrl =OMAP5430_BGAP_COUNTER_CORE_OFFSET , + .mode_ctrl_mask =OMAP5430_REPEAT_MODE_MASK , + + .bgap_counter =OMAP5430_BGAP_COUNTER_CORE_OFFSET , + .counter_mask =OMAP5430_COUNTER_MASK , + + .bgap_threshold =OMAP5430_BGAP_THRESHOLD_CORE_OFFSET , + .threshold_thot_mask =OMAP5430_T_HOT_MASK , + .threshold_tcold_mask =OMAP5430_T_COLD_MASK , + + .tshut_threshold =OMAP5430_BGAP_TSHUT_CORE_OFFSET , + .tshut_hot_mask =OMAP5430_TSHUT_HOT_MASK , + .tshut_cold_mask =OMAP5430_TSHUT_COLD_MASK , + + .bgap_status =OMAP5430_BGAP_STATUS_OFFSET , + .status_clean_stop_mask =0x0 , + .status_bgap_alert_mask =OMAP5430_BGAP_ALERT_MASK , + .status_hot_mask =OMAP5430_HOT_CORE_FLAG_MASK , + .status_cold_mask =OMAP5430_COLD_CORE_FLAG_MASK , + + .bgap_efuse =OMAP5430_FUSE_OPP_BGAP_CORE , +}; + +/* Thresholds and limits for OMAP4460 MPU temperature sensor */ +static struct temp_sensor_data omap4460_mpu_temp_sensor_data = { + .tshut_hot =OMAP4460_TSHUT_HOT , + .tshut_cold =OMAP4460_TSHUT_COLD , + .t_hot =OMAP4460_T_HOT , + .t_cold =OMAP4460_T_COLD , + .min_freq =OMAP4460_MIN_FREQ , + .max_freq =OMAP4460_MAX_FREQ , + .max_temp =OMAP4460_MAX_TEMP , + .min_temp =OMAP4460_MIN_TEMP , + .hyst_val =OMAP4460_HYST_VAL , + .adc_start_val =OMAP4460_ADC_START_VALUE , + .adc_end_val =OMAP4460_ADC_END_VALUE , + .update_int1 =1000 , + .update_int2 =2000 , +}; + +/* Thresholds and limits for OMAP5430 MPU temperature sensor */ +static struct temp_sensor_data omap5430_mpu_temp_sensor_data = { + .tshut_hot =OMAP5430_MPU_TSHUT_HOT , + .tshut_cold =OMAP5430_MPU_TSHUT_COLD , + .t_hot =OMAP5430_MPU_T_HOT , + .t_cold =OMAP5430_MPU_T_COLD , + .min_freq =OMAP5430_MPU_MIN_FREQ , + .max_freq =OMAP5430_MPU_MAX_FREQ , + .max_temp =OMAP5430_MPU_MAX_TEMP , + .min_temp =OMAP5430_MPU_MIN_TEMP , + .hyst_val =OMAP5430_MPU_HYST_VAL , + .adc_start_val =OMAP5430_ADC_START_VALUE , + .adc_end_val =OMAP5430_ADC_END_VALUE , + .update_int1 =1000 , + .update_int2 =2000 , +}; + +/* Thresholds and limits for OMAP5430 GPU temperature sensor */ +static struct temp_sensor_data omap5430_gpu_temp_sensor_data = { + .tshut_hot =OMAP5430_GPU_TSHUT_HOT , + .tshut_cold =OMAP5430_GPU_TSHUT_COLD , + .t_hot =OMAP5430_GPU_T_HOT , + .t_cold =OMAP5430_GPU_T_COLD , + .min_freq =OMAP5430_GPU_MIN_FREQ , + .max_freq =OMAP5430_GPU_MAX_FREQ , + .max_temp =OMAP5430_GPU_MAX_TEMP , + .min_temp =OMAP5430_GPU_MIN_TEMP , + .hyst_val =OMAP5430_GPU_HYST_VAL , + .adc_start_val =OMAP5430_ADC_START_VALUE , + .adc_end_val =OMAP5430_ADC_END_VALUE , + .update_int1 =1000 , + .update_int2 =2000 , +}; + +/* Thresholds and limits for OMAP5430 CORE temperature sensor */ +static struct temp_sensor_data omap5430_core_temp_sensor_data = { + .tshut_hot =OMAP5430_CORE_TSHUT_HOT , + .tshut_cold =OMAP5430_CORE_TSHUT_COLD , + .t_hot =OMAP5430_CORE_T_HOT , + .t_cold =OMAP5430_CORE_T_COLD , + .min_freq =OMAP5430_CORE_MIN_FREQ , + .max_freq =OMAP5430_CORE_MAX_FREQ , + .max_temp =OMAP5430_CORE_MAX_TEMP , + .min_temp =OMAP5430_CORE_MIN_TEMP , + .hyst_val =OMAP5430_CORE_HYST_VAL , + .adc_start_val =OMAP5430_ADC_START_VALUE , + .adc_end_val =OMAP5430_ADC_END_VALUE , + .update_int1 =1000 , + .update_int2 =2000 , +}; + +/* +* Temperature values in milli degree celsius +* ADC code values from 530 to 923 +*/ +static const int +omap4460_adc_to_temp[OMAP4460_ADC_END_VALUE -OMAP4460_ADC_START_VALUE +1 ] = { +-40000 ,-40000 ,-40000 ,-40000 ,-39800 ,-39400 ,-39000 ,-38600 ,-38200 , +-37800 ,-37300 ,-36800 ,-36400 ,-36000 ,-35600 ,-35200 ,-34800 , +-34300 ,-33800 ,-33400 ,-33000 ,-32600 ,-32200 ,-31800 ,-31300 , +-30800 ,-30400 ,-30000 ,-29600 ,-29200 ,-28700 ,-28200 ,-27800 , +-27400 ,-27000 ,-26600 ,-26200 ,-25700 ,-25200 ,-24800 ,-24400 , +-24000 ,-23600 ,-23200 ,-22700 ,-22200 ,-21800 ,-21400 ,-21000 , +-20600 ,-20200 ,-19700 ,-19200 ,-18800 ,-18400 ,-18000 ,-17600 , +-17200 ,-16700 ,-16200 ,-15800 ,-15400 ,-15000 ,-14600 ,-14200 , +-13700 ,-13200 ,-12800 ,-12400 ,-12000 ,-11600 ,-11200 ,-10700 , +-10200 ,-9800 ,-9400 ,-9000 ,-8600 ,-8200 ,-7700 ,-7200 ,-6800 , +-6400 ,-6000 ,-5600 ,-5200 ,-4800 ,-4300 ,-3800 ,-3400 ,-3000 , +-2600 ,-2200 ,-1800 ,-1300 ,-800 ,-400 ,0 ,400 ,800 ,1200 ,1600 , +2100 ,2600 ,3000 ,3400 ,3800 ,4200 ,4600 ,5100 ,5600 ,6000 ,6400 , +6800 ,7200 ,7600 ,8000 ,8500 ,9000 ,9400 ,9800 ,10200 ,10600 ,11000 , +11400 ,11900 ,12400 ,12800 ,13200 ,13600 ,14000 ,14400 ,14800 , +15300 ,15800 ,16200 ,16600 ,17000 ,17400 ,17800 ,18200 ,18700 , +19200 ,19600 ,20000 ,20400 ,20800 ,21200 ,21600 ,22100 ,22600 , +23000 ,23400 ,23800 ,24200 ,24600 ,25000 ,25400 ,25900 ,26400 , +26800 ,27200 ,27600 ,28000 ,28400 ,28800 ,29300 ,29800 ,30200 , +30600 ,31000 ,31400 ,31800 ,32200 ,32600 ,33100 ,33600 ,34000 , +34400 ,34800 ,35200 ,35600 ,36000 ,36400 ,36800 ,37300 ,37800 , +38200 ,38600 ,39000 ,39400 ,39800 ,40200 ,40600 ,41100 ,41600 , +42000 ,42400 ,42800 ,43200 ,43600 ,44000 ,44400 ,44800 ,45300 , +45800 ,46200 ,46600 ,47000 ,47400 ,47800 ,48200 ,48600 ,49000 , +49500 ,50000 ,50400 ,50800 ,51200 ,51600 ,52000 ,52400 ,52800 , +53200 ,53700 ,54200 ,54600 ,55000 ,55400 ,55800 ,56200 ,56600 , +57000 ,57400 ,57800 ,58200 ,58700 ,59200 ,59600 ,60000 ,60400 , +60800 ,61200 ,61600 ,62000 ,62400 ,62800 ,63300 ,63800 ,64200 , +64600 ,65000 ,65400 ,65800 ,66200 ,66600 ,67000 ,67400 ,67800 , +68200 ,68700 ,69200 ,69600 ,70000 ,70400 ,70800 ,71200 ,71600 , +72000 ,72400 ,72800 ,73200 ,73600 ,74100 ,74600 ,75000 ,75400 , +75800 ,76200 ,76600 ,77000 ,77400 ,77800 ,78200 ,78600 ,79000 , +79400 ,79800 ,80300 ,80800 ,81200 ,81600 ,82000 ,82400 ,82800 , +83200 ,83600 ,84000 ,84400 ,84800 ,85200 ,85600 ,86000 ,86400 , +86800 ,87300 ,87800 ,88200 ,88600 ,89000 ,89400 ,89800 ,90200 , +90600 ,91000 ,91400 ,91800 ,92200 ,92600 ,93000 ,93400 ,93800 , +94200 ,94600 ,95000 ,95500 ,96000 ,96400 ,96800 ,97200 ,97600 , +98000 ,98400 ,98800 ,99200 ,99600 ,100000 ,100400 ,100800 ,101200 , +101600 ,102000 ,102400 ,102800 ,103200 ,103600 ,104000 ,104400 , +104800 ,105200 ,105600 ,106100 ,106600 ,107000 ,107400 ,107800 , +108200 ,108600 ,109000 ,109400 ,109800 ,110200 ,110600 ,111000 , +111400 ,111800 ,112200 ,112600 ,113000 ,113400 ,113800 ,114200 , +114600 ,115000 ,115400 ,115800 ,116200 ,116600 ,117000 ,117400 , +117800 ,118200 ,118600 ,119000 ,119400 ,119800 ,120200 ,120600 , +121000 ,121400 ,121800 ,122200 ,122600 ,123000 ,123400 ,123800 ,124200 , +124600 ,124900 ,125000 ,125000 ,125000 ,125000 +}; + +static const int +omap5430_adc_to_temp[OMAP5430_ADC_END_VALUE -OMAP5430_ADC_START_VALUE +1 ] = { +-40000 ,-40000 ,-40000 ,-40000 ,-39800 ,-39400 ,-39000 ,-38600 , +-38200 ,-37800 ,-37300 ,-36800 , +-36400 ,-36000 ,-35600 ,-35200 ,-34800 ,-34300 ,-33800 ,-33400 ,-33000 , +-32600 , +-32200 ,-31800 ,-31300 ,-30800 ,-30400 ,-30000 ,-29600 ,-29200 ,-28700 , +-28200 ,-27800 ,-27400 ,-27000 ,-26600 ,-26200 ,-25700 ,-25200 ,-24800 , +-24400 ,-24000 ,-23600 ,-23200 ,-22700 ,-22200 ,-21800 ,-21400 ,-21000 , +-20600 ,-20200 ,-19700 ,-19200 ,-9300 ,-18400 ,-18000 ,-17600 ,-17200 , +-16700 ,-16200 ,-15800 ,-15400 ,-15000 ,-14600 ,-14200 ,-13700 ,-13200 , +-12800 ,-12400 ,-12000 ,-11600 ,-11200 ,-10700 ,-10200 ,-9800 ,-9400 , +-9000 , +-8600 ,-8200 ,-7700 ,-7200 ,-6800 ,-6400 ,-6000 ,-5600 ,-5200 ,-4800 , +-4300 , +-3800 ,-3400 ,-3000 ,-2600 ,-2200 ,-1800 ,-1300 ,-800 ,-400 ,0 ,400 , +800 , +1200 ,1600 ,2100 ,2600 ,3000 ,3400 ,3800 ,4200 ,4600 ,5100 ,5600 ,6000 , +6400 ,6800 ,7200 ,7600 ,8000 ,8500 ,9000 ,9400 ,9800 ,10200 ,10800 , +11100 , +11400 ,11900 ,12400 ,12800 ,13200 ,13600 ,14000 ,14400 ,14800 ,15300 , +15800 , +16200 ,16600 ,17000 ,17400 ,17800 ,18200 ,18700 ,19200 ,19600 ,20000 , +20400 , +20800 ,21200 ,21600 ,22100 ,22600 ,23000 ,23400 ,23800 ,24200 ,24600 , +25000 , +25400 ,25900 ,26400 ,26800 ,27200 ,27600 ,28000 ,28400 ,28800 ,29300 , +29800 , +30200 ,30600 ,31000 ,31400 ,31800 ,32200 ,32600 ,33100 ,33600 ,34000 , +34400 , +34800 ,35200 ,35600 ,36000 ,36400 ,36800 ,37300 ,37800 ,38200 ,38600 , +39000 , +39400 ,39800 ,40200 ,40600 ,41100 ,41600 ,42000 ,42400 ,42800 ,43200 , +43600 , +44000 ,44400 ,44800 ,45300 ,45800 ,46200 ,46600 ,47000 ,47400 ,47800 , +48200 , +48600 ,49000 ,49500 ,50000 ,50400 ,50800 ,51200 ,51600 ,52000 ,52400 , +52800 , +53200 ,53700 ,54200 ,54600 ,55000 ,55400 ,55800 ,56200 ,56600 ,57000 , +57400 , +57800 ,58200 ,58700 ,59200 ,59600 ,60000 ,60400 ,60800 ,61200 ,61600 , +62000 , +62400 ,62800 ,63300 ,63800 ,64200 ,64600 ,65000 ,65400 ,65800 ,66200 , +66600 , +67000 ,67400 ,67800 ,68200 ,68700 ,69200 ,69600 ,70000 ,70400 ,70800 , +71200 , +71600 ,72000 ,72400 ,72800 ,73200 ,73600 ,74100 ,74600 ,75000 ,75400 , +75800 , +76200 ,76600 ,77000 ,77400 ,77800 ,78200 ,78600 ,79000 ,79400 ,79800 , +80300 , +80800 ,81200 ,81600 ,82000 ,82400 ,82800 ,83200 ,83600 ,84000 ,84400 , +84800 , +85200 ,85600 ,86000 ,86400 ,86800 ,87300 ,87800 ,88200 ,88600 ,89000 , +89400 , +89800 ,90200 ,90600 ,91000 ,91400 ,91800 ,92200 ,92600 ,93000 ,93400 , +93800 , +94200 ,94600 ,95000 ,95500 ,96000 ,96400 ,96800 ,97200 ,97600 ,98000 , +98400 ,
drivers/thermal/omap-bandgap.c line 580
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+98800 ,99200 ,99600 ,100000 ,100400 ,100800 ,101200 ,101600 ,102000 , +102400 , +102800 ,103200 ,103600 ,104000 ,104400 ,104800 ,105200 ,105600 ,106100 , +106600 ,107000 ,107400 ,107800 ,108200 ,108600 ,109000 ,109400 ,109800 , +110200 ,110600 ,111000 ,111400 ,111800 ,112200 ,112600 ,113000 ,113400 , +113800 ,114200 ,114600 ,115000 ,115400 ,115800 ,116200 ,116600 ,117000 , +117400 ,117800 ,118200 ,118600 ,119000 ,119400 ,119800 ,120200 ,120600 , +121000 ,121400 ,121800 ,122200 ,122600 ,123000 ,123400 ,123800 ,124200 , + 124600, 124900, 125000, 125000, 125000, 125000, +};
It might be good to store the per SoC data in dedicated files or at least put some #ifdef around to avoid wasting memory for a non-multi OMAP boot.
Quoted 603 lines
drivers/thermal/omap-bandgap.c new file +603
-0+ +static irqreturn_t talert_irq_handler (int irq,void *data) +{ +struct omap_bandgap *bg_ptr = data; +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 t_hot =0 , t_cold =0 , temp, ctrl; +int i, r; + + bg_ptr = data; +/* Read the status of t_hot */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { + tsr = bg_ptr->pdata->sensors[i].registers; + r =omap_control_readl (cdev, tsr->bgap_status,&t_hot); + t_hot&= tsr->status_hot_mask; + +/* Read the status of t_cold */ + r |=omap_control_readl (cdev, tsr->bgap_status,&t_cold); + t_cold&= tsr->status_cold_mask; + +if (!t_cold&& !t_hot) +continue ; + + r |=omap_control_readl (cdev, tsr->bgap_mask_ctrl,&ctrl); +/* +* One TALERT interrupt: Two sources +* If the interrupt is due to t_hot then mask t_hot and +* and unmask t_cold else mask t_cold and unmask t_hot +*/ +if (t_hot) { + ctrl&= ~tsr->mask_hot_mask; + ctrl |= tsr->mask_cold_mask; + }else if (t_cold) { + ctrl&= ~tsr->mask_cold_mask; + ctrl |= tsr->mask_hot_mask; + } + + r |=omap_control_writel (cdev, ctrl, tsr->bgap_mask_ctrl); + +if (r) { +dev_err (bg_ptr->dev,"failed to ack talert interrupt\n" ); +return IRQ_NONE ; + } + +/* read temperature */ + r =omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= tsr->bgap_dtemp_mask; + +/* report temperature to whom may concern */ +if (bg_ptr->pdata->report_temperature) + bg_ptr->pdata->report_temperature (bg_ptr, i); + } + +return IRQ_HANDLED ; +} + +static irqreturn_t omap_bandgap_tshut_irq_handler (int irq,void *data) +{ +orderly_poweroff (true); + +return IRQ_HANDLED ; +} + +static +int adc_to_temp_conversion (struct omap_bandgap *bg_ptr,int id,int adc_val, +int *t) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; + +/* look up for temperature in the table and return the temperature */ +if (adc_val< ts_data->adc_start_val || adc_val> ts_data->adc_end_val) +return -ERANGE ; + + *t = bg_ptr->conv_table[adc_val - ts_data->adc_start_val]; + +return 0 ; +} + +static int temp_to_adc_conversion (long temp,struct omap_bandgap *bg_ptr,int i, +int *adc) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[i].ts_data; +int high, low, mid; + + low =0 ; + high = ts_data->adc_end_val - ts_data->adc_start_val; + mid = (high + low) /2 ; + +if (temp< bg_ptr->conv_table[high] || temp> bg_ptr->conv_table[high]) +return -EINVAL ; + +while (low< high) { +if (temp< bg_ptr->conv_table[mid]) + high = mid -1 ; +else + low = mid +1 ; + mid = (low + high) /2 ; + } + + *adc = ts_data->adc_start_val + low; + +return 0 ; +} + +static int temp_sensor_unmask_interrupts (struct omap_bandgap *bg_ptr,int id, +u32 t_hot,u32 t_cold) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp, reg_val; +int err; + +/* Read the current on die temperature */ + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= tsr->bgap_dtemp_mask; + + err |=omap_control_readl (cdev, tsr->bgap_mask_ctrl,®_val); +if (temp< t_hot) + reg_val |= tsr->mask_hot_mask; +else + reg_val&= ~tsr->mask_hot_mask; + +if (t_cold< temp) + reg_val |= tsr->mask_cold_mask; +else + reg_val&= ~tsr->mask_cold_mask; + err |=omap_control_writel (cdev, reg_val, tsr->bgap_mask_ctrl); + +if (err) { +dev_err (bg_ptr->dev,"failed to unmask interrupts\n" ); +return -EIO ; + } + +return 0 ; +} + +static +int add_hyst (int adc_val,int hyst_val,struct omap_bandgap *bg_ptr,int i, +u32 *sum) +{ +int temp, ret; + + ret =adc_to_temp_conversion (bg_ptr, i, adc_val,&temp); +if (ret<0 ) +return ret; + + temp += hyst_val; + +return temp_to_adc_conversion (temp, bg_ptr, i, sum); +} + +static +int temp_sensor_configure_thot (struct omap_bandgap *bg_ptr,int id,int t_hot) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 thresh_val, reg_val; +int cold, err; + + tsr = bg_ptr->pdata->sensors[id].registers; + +/* obtain the T cold value */ + err =omap_control_readl (cdev, tsr->bgap_threshold,&thresh_val); + cold = (thresh_val& tsr->threshold_tcold_mask)>> +__ffs (tsr->threshold_tcold_mask); +if (t_hot<= cold) { +/* change the t_cold to t_hot - 5000 millidegrees */ + err |=add_hyst (t_hot, -ts_data->hyst_val, bg_ptr, id,&cold); +/* write the new t_cold value */ + reg_val = thresh_val& (~tsr->threshold_tcold_mask); + reg_val |= cold<<__ffs (tsr->threshold_tcold_mask); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + thresh_val = reg_val; + } + +/* write the new t_hot value */ + reg_val = thresh_val& ~tsr->threshold_thot_mask; + reg_val |= (t_hot<<__ffs (tsr->threshold_thot_mask)); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram thot threshold\n" ); +return -EIO ; + } + +return temp_sensor_unmask_interrupts (bg_ptr, id, t_hot, cold); +} + +static +int temp_sensor_init_talert_thresholds (struct omap_bandgap *bg_ptr,int id, +int t_hot,int t_cold) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 reg_val, thresh_val; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->bgap_threshold,&thresh_val); + +/* write the new t_cold value */ + reg_val = thresh_val& ~tsr->threshold_tcold_mask; + reg_val |= (t_cold<<__ffs (tsr->threshold_tcold_mask)); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tcold threshold\n" ); +return -EIO ; + } + + err =omap_control_readl (cdev, tsr->bgap_threshold,&thresh_val); + +/* write the new t_hot value */ + reg_val = thresh_val& ~tsr->threshold_thot_mask; + reg_val |= (t_hot<<__ffs (tsr->threshold_thot_mask)); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram thot threshold\n" ); +return -EIO ; + } + + err =omap_control_readl (cdev, tsr->bgap_mask_ctrl,®_val); + reg_val |= tsr->mask_hot_mask; + reg_val |= tsr->mask_cold_mask; + err |=omap_control_writel (cdev, reg_val, tsr->bgap_mask_ctrl); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram thot threshold\n" ); +return -EIO ; + } + +return err; +} + +static +int temp_sensor_configure_tcold (struct omap_bandgap *bg_ptr,int id, +int t_cold) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 thresh_val, reg_val; +int hot, err; + + tsr = bg_ptr->pdata->sensors[id].registers; +/* obtain the T cold value */ + err =omap_control_readl (cdev, tsr->bgap_threshold,&thresh_val); + hot = (thresh_val& tsr->threshold_thot_mask)>> +__ffs (tsr->threshold_thot_mask); + +if (t_cold>= hot) { +/* change the t_hot to t_cold + 5000 millidegrees */ + err |=add_hyst (t_cold, ts_data->hyst_val, bg_ptr, id,&hot); +/* write the new t_hot value */ + reg_val = thresh_val& (~tsr->threshold_thot_mask); + reg_val |= hot<<__ffs (tsr->threshold_thot_mask); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + thresh_val = reg_val; + } + +/* write the new t_cold value */ + reg_val = thresh_val& ~tsr->threshold_tcold_mask; + reg_val |= (t_cold<<__ffs (tsr->threshold_tcold_mask)); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tcold threshold\n" ); +return -EIO ; + } + +return temp_sensor_unmask_interrupts (bg_ptr, id, hot, t_cold); +} + +static int temp_sensor_configure_tshut_hot (struct omap_bandgap *bg_ptr, +int id,int tshut_hot) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 reg_val; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->tshut_threshold,®_val); + reg_val&= ~tsr->tshut_hot_mask; + reg_val |= tshut_hot<<__ffs (tsr->tshut_hot_mask); + err |=omap_control_writel (cdev, reg_val, tsr->tshut_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tshut thot\n" ); +return -EIO ; + } + +return 0 ; +} + +static int temp_sensor_configure_tshut_cold (struct omap_bandgap *bg_ptr, +int id,int tshut_cold) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 reg_val; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->tshut_threshold,®_val); + reg_val&= ~tsr->tshut_cold_mask; + reg_val |= tshut_cold<<__ffs (tsr->tshut_cold_mask); + err |=omap_control_writel (cdev, reg_val, tsr->tshut_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tshut tcold\n" ); +return -EIO ; + } + +return 0 ; +} + +static int configure_temp_sensor_counter (struct omap_bandgap *bg_ptr,int id, +u32 counter) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 val; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->bgap_counter,&val); + val&= ~tsr->counter_mask; + val |= counter<<__ffs (tsr->counter_mask); + err |=omap_control_writel (cdev, val, tsr->bgap_counter); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tshut tcold\n" ); +return -EIO ; + } + +return 0 ; +} + +/* Exposed APIs */ +/** +* omap_bandgap_read_thot() - reads sensor current thot +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @thot - resulting current thot value +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_read_thot (struct omap_bandgap *bg_ptr,int id, +int *thot) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + ret =omap_control_readl (cdev, tsr->bgap_threshold,&temp); + temp = (temp& tsr->threshold_thot_mask)>> +__ffs (tsr->threshold_thot_mask); + ret |=adc_to_temp_conversion (bg_ptr, id, temp,&temp); +if (ret) { +dev_err (bg_ptr->dev,"failed to read thot\n" ); +return -EIO ; + } + + *thot = temp; + +return 0 ; +} + +/** +* omap_bandgap_write_thot() - sets sensor current thot +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @val - desired thot value +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_write_thot (struct omap_bandgap *bg_ptr,int id,int val) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; +struct temp_sensor_registers *tsr; +u32 t_hot; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + +if (val< ts_data->min_temp + ts_data->hyst_val) +return -EINVAL ; + ret =temp_to_adc_conversion (val, bg_ptr, id,&t_hot); +if (ret<0 ) +return ret; + +mutex_lock (&bg_ptr->bg_mutex); +temp_sensor_configure_thot (bg_ptr, id, t_hot); +mutex_unlock (&bg_ptr->bg_mutex); + +return 0 ; +} + +/** +* omap_bandgap_read_tcold() - reads sensor current tcold +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @tcold - resulting current tcold value +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_read_tcold (struct omap_bandgap *bg_ptr,int id, +int *tcold) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + ret =omap_control_readl (cdev, tsr->bgap_threshold,&temp); + temp = (temp& tsr->threshold_tcold_mask) + >>__ffs (tsr->threshold_tcold_mask); + ret |=adc_to_temp_conversion (bg_ptr, id, temp,&temp); +if (ret) +return -EIO ; + + *tcold = temp; + +return 0 ; +} + +/** +* omap_bandgap_write_tcold() - sets the sensor tcold +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @val - desired tcold value +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_write_tcold (struct omap_bandgap *bg_ptr,int id,int val) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; +struct temp_sensor_registers *tsr; +u32 t_cold; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; +if (val> ts_data->max_temp + ts_data->hyst_val) +return -EINVAL ; + + ret =temp_to_adc_conversion (val, bg_ptr, id,&t_cold); +if (ret<0 ) +return ret; + +mutex_lock (&bg_ptr->bg_mutex); +temp_sensor_configure_tcold (bg_ptr, id, t_cold); +mutex_unlock (&bg_ptr->bg_mutex); + +return 0 ; +} + +/** +* omap_bandgap_read_update_interval() - read the sensor update interval +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @interval - resulting update interval in miliseconds +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_read_update_interval (struct omap_bandgap *bg_ptr,int id, +int *interval) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 time; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + ret =omap_control_readl (cdev, tsr->bgap_counter,&time); +if (ret) +return ret; + time = (time& tsr->counter_mask)>>__ffs (tsr->counter_mask); + time = time *1000 / bg_ptr->clk_rate; + + *interval = time; + +return 0 ; +} + +/** +* omap_bandgap_write_update_interval() - set the update interval +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @interval - desired update interval in miliseconds +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_write_update_interval (struct omap_bandgap *bg_ptr, +int id,u32 interval) +{ + interval = interval * bg_ptr->clk_rate /1000 ; +mutex_lock (&bg_ptr->bg_mutex); +configure_temp_sensor_counter (bg_ptr, id, interval); +mutex_unlock (&bg_ptr->bg_mutex); + +return 0 ; +} + +/** +* omap_bandgap_read_temperature() - report current temperature +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @temperature - resulting temperature +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_read_temperature (struct omap_bandgap *bg_ptr,int id, +int *temperature) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + ret =omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= tsr->bgap_dtemp_mask; + + ret |=adc_to_temp_conversion (bg_ptr, id, temp,&temp); +if (ret) +return -EIO ; + + *temperature = temp; + +return 0 ; +} + +/** +* enable_continuous_mode() - One time enabling of continuous conversion mode +* @bg_ptr - pointer to scm instance +*/ +static int enable_continuous_mode (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +int i, r; +u32 val; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { + tsr = bg_ptr->pdata->sensors[i].registers; + r =omap_control_readl (cdev, tsr->bgap_mode_ctrl,&val); + val |=1 <<__ffs (tsr->mode_ctrl_mask); + r |=omap_control_writel (cdev, val, tsr->bgap_mode_ctrl); +if (r) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return r ? -EIO :0 ; +} + +static int omap_bandgap_tshut_init (struct omap_bandgap *bg_ptr, +struct platform_device *pdev) +{ +int gpio_nr = bg_ptr->tshut_gpio; +int status; + +/* Request for gpio_86 line */ + status =gpio_request (gpio_nr,"tshut" ); +if (status<0 ) { +dev_err (bg_ptr->dev, +"Could not request for TSHUT GPIO:%i\n" ,86 ); +return status; + } + status =gpio_direction_input (gpio_nr); +if (status) { +dev_err (bg_ptr->dev, +"Cannot set input TSHUT GPIO %d\n" , gpio_nr); +return status; + } + + status =request_irq (gpio_to_irq (gpio_nr), + omap_bandgap_tshut_irq_handler, +IRQF_TRIGGER_RISING ,"tshut" , +NULL ); +if (status) { +gpio_free (gpio_nr); +dev_err (bg_ptr->dev,"request irq failed for TSHUT" ); + } + +return 0 ; +} + +static int omap_bandgap_talert_init (struct omap_bandgap *bg_ptr, +struct platform_device *pdev) +{ +int ret; + + bg_ptr->irq =platform_get_irq (pdev,0 ); +if (bg_ptr->irq<0 ) { +dev_err (&pdev->dev,"get_irq failed\n" ); +return bg_ptr->irq; + } + ret =request_threaded_irq (bg_ptr->irq,NULL , + talert_irq_handler, +IRQF_TRIGGER_HIGH |IRQF_ONESHOT , +"talert" , bg_ptr); +if (ret) { +dev_err (&pdev->dev,"Request threaded irq failed.\n" ); +return ret;
drivers/thermal/omap-bandgap.c line 1193
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ } + +return 0 ; +} + +static const struct omap_bandgap_data omap4460_data = { + .has_talert = true, + .has_tshut = true, + .fclock_name ="bandgap_ts_fclk" , + .div_ck_name ="div_ts_ck" ,
None of these clock data should be there ideally. You should ensure that the proper device alias will be there using clkdev entries.
Except that with DT, it will not work without the clock DT binding :-(
I think Rob posted a latest update based on CCF... but for the moment we are stuck :-(
Quoted 25 lines
drivers/thermal/omap-bandgap.c new file +25
-0+ .conv_table = omap4460_adc_to_temp, + .sensors = { + { + .registers =&omap4460_mpu_temp_sensor_registers, + .ts_data =&omap4460_mpu_temp_sensor_data, + .domain = "cpu", + }, + }, + .sensor_count = 1, +}; + +static const struct omap_bandgap_data omap5430_data = { + .has_talert = true, + .has_tshut = true, + .fclock_name ="ts_clk_div_ck" , + .div_ck_name ="ts_clk_div_ck" , + .conv_table = omap5430_adc_to_temp, + .sensors = { + { + .registers =&omap5430_mpu_temp_sensor_registers, + .ts_data =&omap5430_mpu_temp_sensor_data, + .domain ="cpu" , + }, + { + .registers =&omap5430_gpu_temp_sensor_registers,
drivers/thermal/omap-bandgap.c line 1228
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ .ts_data =&omap5430_gpu_temp_sensor_data, + .domain = "gpu", + }, + { + .registers =&omap5430_core_temp_sensor_registers, + .ts_data =&omap5430_core_temp_sensor_data, + .domain = "core", + }, + }, + .sensor_count = 3,
It can probably be replaced by a sizeof.
drivers/thermal/omap-bandgap.c line 1238
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+}; + +static const struct of_device_id of_omap_bandgap_match[] = { +/* +* TODO: Add support to 4430 +* { .compatible = "ti,omap4430-bandgap", .data = , }, +*/ + { + .compatible ="ti,omap4460-bandgap" , + .data = (void *)&omap4460_data,
No need to cast toward a void *.
Quoted 4 lines
drivers/thermal/omap-bandgap.c new file +4
-0+ }, + { + .compatible = "ti,omap5430-bandgap", + .data = (void *)&omap5430_data,
drivers/thermal/omap-bandgap.c line 1252
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ }, +/* Sentinel */ + { }, +}; + +static struct omap_bandgap *omap_bandgap_build (struct platform_device *pdev) +{ +struct device_node *node = pdev->dev.of_node; +const struct of_device_id *of_id; +struct omap_bandgap *bg_ptr;
bg_ptr is not a super name.
drivers/thermal/omap-bandgap.c line 1259
Quoted 7 lines
drivers/thermal/omap-bandgap.c new file +7
-0+u32 prop; + +/* just for the sake */ +if (!node) { +dev_err (&pdev->dev,"no platform information available\n" ); +return ERR_PTR (-EINVAL ); + }
Not needed, just do the of_match_device here directly.
drivers/thermal/omap-bandgap.c line 1270
Quoted 11 lines
drivers/thermal/omap-bandgap.c new file +11
-0+ + bg_ptr =devm_kzalloc (&pdev->dev,sizeof (struct omap_bandgap ), +GFP_KERNEL ); +if (!bg_ptr) { +dev_err (&pdev->dev,"Unable to allocate mem for driver ref\n" ); +return ERR_PTR (-ENOMEM ); + } + + of_id =of_match_device (of_omap_bandgap_match,&pdev->dev); +if (of_id) + bg_ptr->pdata = of_id->data;
Nit: This is not really pdata anymore, so you should maybe remove the "p" to avoid confusion.
Quoted 26 lines
drivers/thermal/omap-bandgap.c new file +26
-0+ +if (bg_ptr->pdata->has_tshut) { +if (of_property_read_u32 (node,"ti,tshut-gpio" ,&prop)<0 ) { +dev_err (&pdev->dev,"missing tshut gpio in device tree\n" ); +return ERR_PTR (-EINVAL ); + } + bg_ptr->tshut_gpio = prop; +if (!gpio_is_valid (bg_ptr->tshut_gpio)) { +dev_err (&pdev->dev,"invalid gpio for tshut (%d)\n" , + bg_ptr->tshut_gpio); +return ERR_PTR (-EINVAL ); + } + } + +return bg_ptr; +} + +static +int __devinit omap_bandgap_probe (struct platform_device *pdev) +{ +struct device *cdev = pdev->dev.parent; +struct omap_bandgap *bg_ptr; +int clk_rate, ret =0 , i; + +if (!cdev) { +dev_err (&pdev->dev,"no omap control ref in our parent\n" );
drivers/thermal/omap-bandgap.c line 1306
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+return -EINVAL ; + } + + bg_ptr =omap_bandgap_build (pdev); +if (IS_ERR_OR_NULL (bg_ptr)) { +dev_err (&pdev->dev,"failed to fetch platform data\n" ); +return PTR_ERR (bg_ptr); + } + +if (bg_ptr->pdata->has_talert) {
Nit2: Yeah, in fact instead of pdata, "conf" or "settings" seems to be more representative of what this structure really contain.
Quoted 7 lines
drivers/thermal/omap-bandgap.c new file +7
-0+ ret =omap_bandgap_talert_init (bg_ptr, pdev); +if (ret) { +dev_err (&pdev->dev,"failed to initialize Talert IRQ\n" ); +return ret; + } + } +
drivers/thermal/omap-bandgap.c line 1323
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+if (bg_ptr->pdata->has_tshut) { + ret =omap_bandgap_tshut_init (bg_ptr, pdev); +if (ret) { +dev_err (&pdev->dev, +"failed to initialize system tshut IRQ\n" ); + goto free_talert; + } + } + + bg_ptr->fclock =clk_get (NULL , bg_ptr->pdata->fclock_name);
That's not good to get a clock without using the local dev alias. But because of lack of clock DT binding yet, I'm not sure we have the choice.
Quoted 43 lines
drivers/thermal/omap-bandgap.c new file +43
-0+ ret =IS_ERR_OR_NULL (bg_ptr->fclock); +if (ret) { +dev_err (&pdev->dev,"failed to request fclock reference\n" ); + goto free_irqs; + } + + bg_ptr->div_clk =clk_get (NULL , bg_ptr->pdata->div_ck_name); + ret =IS_ERR_OR_NULL (bg_ptr->div_clk); +if (ret) { +dev_err (&pdev->dev, +"failed to request div_ts_ck clock ref\n" ); + goto free_irqs; + } + + bg_ptr->conv_table = bg_ptr->pdata->conv_table; +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +u32 val; + + tsr = bg_ptr->pdata->sensors[i].registers; +/* +* check if the efuse has a non-zero value if not +* it is an untrimmed sample and the temperatures +* may not be accurate +*/ + ret =omap_control_readl (cdev, tsr->bgap_efuse,&val); +if (ret || !val) +dev_info (&pdev->dev, +"Non-trimmed BGAP, Temp not accurate\n" ); + } + + clk_rate =clk_round_rate (bg_ptr->div_clk, + bg_ptr->pdata->sensors[0 ].ts_data->max_freq); +if (clk_rate< bg_ptr->pdata->sensors[0 ].ts_data->min_freq || + clk_rate ==0xffffffff ) { + ret = -ENODEV ; + goto put_clks; + } + + ret =clk_set_rate (bg_ptr->div_clk, clk_rate); +if (ret) { +dev_err (&pdev->dev,"Cannot set clock rate\n" ); + goto put_clks;
drivers/thermal/omap-bandgap.c line 1376
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ } + + bg_ptr->clk_rate = clk_rate; +clk_enable (bg_ptr->fclock); + +mutex_init (&bg_ptr->bg_mutex); + bg_ptr->dev =&pdev->dev; +platform_set_drvdata (pdev, bg_ptr); + +/* 1 clk cycle */
What does that mean exactly?
Regards,
Benoit
Quoted 294 lines
drivers/thermal/omap-bandgap.c new file +225
-0+for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) +configure_temp_sensor_counter (bg_ptr, i,1 ); + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_data *ts_data; + + ts_data = bg_ptr->pdata->sensors[i].ts_data; + +temp_sensor_init_talert_thresholds (bg_ptr, i, + ts_data->t_hot, + ts_data->t_cold); +temp_sensor_configure_tshut_hot (bg_ptr, i, + ts_data->tshut_hot); +temp_sensor_configure_tshut_cold (bg_ptr, i, + ts_data->tshut_cold); + } + +enable_continuous_mode (bg_ptr); + +/* Set .250 seconds time as default counter */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) +configure_temp_sensor_counter (bg_ptr, i, + bg_ptr->clk_rate /4 ); + +/* Every thing is good? Then expose the sensors */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +char *domain; + + domain = bg_ptr->pdata->sensors[i].domain; +if (bg_ptr->pdata->expose_sensor) + bg_ptr->pdata->expose_sensor (bg_ptr, i, domain); + } + +return 0 ; + +put_clks: +clk_disable (bg_ptr->fclock); +clk_put (bg_ptr->fclock); +clk_put (bg_ptr->div_clk); +free_irqs: +free_irq (gpio_to_irq (bg_ptr->tshut_gpio),NULL ); +gpio_free (bg_ptr->tshut_gpio); +free_talert: +free_irq (bg_ptr->irq, bg_ptr); + +return ret; +} + +static +int __devexit omap_bandgap_remove(struct platform_device *pdev) +{ +struct omap_bandgap *bg_ptr =platform_get_drvdata (pdev); + +clk_disable (bg_ptr->fclock); +clk_put (bg_ptr->fclock); +clk_put (bg_ptr->div_clk); +free_irq (bg_ptr->irq, bg_ptr); +free_irq (gpio_to_irq (bg_ptr->tshut_gpio),NULL ); +gpio_free (bg_ptr->tshut_gpio); + +return 0 ; +} + +#ifdef CONFIG_PM +static int omap_bandgap_save_ctxt (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +int err =0 ; +int i; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +struct temp_sensor_regval *rval; + + rval = bg_ptr->pdata->sensors[i].regval; + tsr = bg_ptr->pdata->sensors[i].registers; + + err =omap_control_readl (cdev, tsr->bgap_mode_ctrl, + &rval->bg_mode_ctrl); + err |=omap_control_readl (cdev, tsr->bgap_mask_ctrl, + &rval->bg_ctrl); + err |=omap_control_readl (cdev, tsr->bgap_counter, + &rval->bg_counter); + err |=omap_control_readl (cdev, tsr->bgap_threshold, + &rval->bg_threshold); + err |=omap_control_readl (cdev, tsr->tshut_threshold, + &rval->tshut_threshold); + +if (err) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return err ? -EIO :0 ; +} + +static int +omap_bandgap_force_single_read (struct omap_bandgap *bg_ptr,int id) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp =0 , counter =1000 ; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; +/* Select single conversion mode */ + err =omap_control_readl (cdev, tsr->bgap_mode_ctrl,&temp); + temp&= ~(1 <<__ffs (tsr->mode_ctrl_mask)); +omap_control_writel (cdev, temp, tsr->bgap_mode_ctrl); + +/* Start of Conversion = 1 */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp |=1 <<__ffs (tsr->bgap_soc_mask); +omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); +/* Wait until DTEMP is updated */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= (tsr->bgap_dtemp_mask); +while ((temp ==0 )&& --counter) { + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= (tsr->bgap_dtemp_mask); + } +/* Start of Conversion = 0 */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= ~(1 <<__ffs (tsr->bgap_soc_mask)); + err |=omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); + +return err ? -EIO :0 ; +} + +static int omap_bandgap_restore_ctxt (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +int i, err =0 ; +u32 temp =0 ; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +struct temp_sensor_regval *rval; +u32 val; + + rval = bg_ptr->pdata->sensors[i].regval; + tsr = bg_ptr->pdata->sensors[i].registers; + + err =omap_control_readl (cdev, tsr->bgap_counter,&val); +if (val ==0 ) { + err |=omap_control_writel (cdev, rval->bg_threshold, + tsr->bgap_threshold); + err |=omap_control_writel (cdev, rval->tshut_threshold, + tsr->tshut_threshold); +/* Force immediate temperature measurement and update +* of the DTEMP field +*/ +omap_bandgap_force_single_read (bg_ptr, i); + err |=omap_control_writel (cdev, rval->bg_counter, + tsr->bgap_counter); + err |=omap_control_writel (cdev, rval->bg_mode_ctrl, + tsr->bgap_mode_ctrl); + err |=omap_control_writel (cdev, rval->bg_ctrl, + tsr->bgap_mask_ctrl); + }else { + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl, + &temp); + temp&= (tsr->bgap_dtemp_mask); +if (temp ==0 ) { +omap_bandgap_force_single_read (bg_ptr, i); + err |=omap_control_readl (cdev, + tsr->bgap_mask_ctrl, + &temp); + temp |=1 <<__ffs (tsr->mode_ctrl_mask); + err |=omap_control_writel (cdev, temp, + tsr->bgap_mask_ctrl); + } + } +if (err) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return err ? -EIO :0 ; +} + +static int omap_bandgap_suspend (struct device *dev) +{ +struct omap_bandgap *bg_ptr =dev_get_drvdata (dev); +int err; + + err =omap_bandgap_save_ctxt (bg_ptr); +clk_disable (bg_ptr->fclock); + +return err; +} + +static int omap_bandgap_resume (struct device *dev) +{ +struct omap_bandgap *bg_ptr =dev_get_drvdata (dev); + +clk_enable (bg_ptr->fclock); + +return omap_bandgap_restore_ctxt (bg_ptr); +} +static const struct dev_pm_ops omap_bandgap_dev_pm_ops = { +SET_SYSTEM_SLEEP_PM_OPS (omap_bandgap_suspend, + omap_bandgap_resume) +}; + +#define DEV_PM_OPS (&omap_bandgap_dev_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif + +static struct platform_driver omap_bandgap_sensor_driver = { + .probe = omap_bandgap_probe, + .remove = omap_bandgap_remove, + .driver = { + .name ="omap-bandgap" , + .pm =DEV_PM_OPS , + .of_match_table = of_omap_bandgap_match, + }, +}; + +module_platform_driver (omap_bandgap_sensor_driver); +early_platform_init ("early_omap_temperature" ,&omap_bandgap_sensor_driver); + +MODULE_DESCRIPTION ("OMAP4+ bandgap temperature sensor driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_ALIAS ("platform:omap-bandgap" ); +MODULE_AUTHOR ("Texas Instrument Inc." );drivers/thermal/omap-bandgap.h new file +63
-0@@ -0,0 +1,63 @@ +/* +* OMAP4 Bandgap temperature sensor driver +* +* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +* Contact: +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ +#ifndef __OMAP_BANDGAP_H +#define __OMAP_BANDGAP_H + +struct omap_bandgap_data ; + +/** +* struct omap_bandgap - bandgap device structure +* @dev: device pointer +* @pdata: platform data with sensor data +* @fclock: pointer to functional clock of temperature sensor +* @div_clk: pointer to parent clock of temperature sensor fclk +* @conv_table: Pointer to adc to temperature conversion table +* @bg_mutex: Mutex for sysfs, irq and PM +* @irq: MPU Irq number for thermal alert +* @tshut_gpio: GPIO where Tshut signal is routed +* @clk_rate: Holds current clock rate +*/ +struct omap_bandgap { +struct device *dev; +const struct omap_bandgap_data *pdata; +struct clk *fclock; +struct clk *div_clk; +const int *conv_table; +struct mutex bg_mutex;/* Mutex for irq and PM */ +int irq; +int tshut_gpio; +u32 clk_rate; +}; + +int omap_bandgap_read_thot (struct omap_bandgap *bg_ptr,int id,int *thot); +int omap_bandgap_write_thot (struct omap_bandgap *bg_ptr,int id,int val); +int omap_bandgap_read_tcold (struct omap_bandgap *bg_ptr,int id,int *tcold); +int omap_bandgap_write_tcold (struct omap_bandgap *bg_ptr,int id,int val); +int omap_bandgap_read_update_interval (struct omap_bandgap *bg_ptr,int id, +int *interval); +int omap_bandgap_write_update_interval (struct omap_bandgap *bg_ptr,int id, +u32 interval); +int omap_bandgap_read_temperature (struct omap_bandgap *bg_ptr,int id, +int *temperature); + +#endif
RFC PATCH 9/11 ARM: OMAP4+: thermal: introduce bandgap temperature sensor
Quoted 687 lines · Cousson Benoit
Quoted 366 lines · Eduardo Valentin
In the System Control Module, OMAP supplies a voltage reference and a temperature sensor feature that are gathered in the band gap voltage and temperature sensor (VBGAPTS) module. The band gap provides current and voltage reference for its internal circuits and other analog IP blocks. The analog-to-digital converter (ADC) produces an output value that is proportional to the silicon temperature.
This patch provides a platform driver which expose this feature. It is moduled as a MFD child of the System Control Module core MFD driver.
This driver provides only APIs to access the device properties, like temperature, thresholds and update rate.
Signed-off-by Eduardo Valentin<[email protected]>Signed-off-by Keerthy<[email protected]>--- .../devicetree/bindings/thermal/omap_bandgap.txt | 27 + drivers/thermal/Kconfig | 13 + drivers/thermal/Makefile | 4 +- drivers/thermal/omap-bandgap.c | 1601 ++++++++++++++++++++ drivers/thermal/omap-bandgap.h | 63 + 5 files changed, 1707 insertions(+), 1 deletions(-) create mode 100644 Documentation/devicetree/bindings/thermal/omap_bandgap.txt create mode 100644 drivers/thermal/omap-bandgap.c create mode 100644 drivers/thermal/omap-bandgap.hDocumentation/devicetree/bindings/thermal/omap_bandgap.txt new file +27
-0@@ -0,0 +1,27 @@ +* Texas Instrument OMAP SCM bandgap bindings + +In the System Control Module, OMAP supplies a voltage reference +and a temperature sensor feature that are gathered in the band +gap voltage and temperature sensor (VBGAPTS) module. The band +gap provides current and voltage reference for its internal +circuits and other analog IP blocks. The analog-to-digital +converter (ADC) produces an output value that is proportional +to the silicon temperature. + +Required properties: +- compatible : Should be: + - "ti,omap4460-control-bandgap" : for OMAP4460 bandgap + - "ti,omap5430-control-bandgap" : for OMAP5430 bandgap +- interrupts : this entry should indicate which interrupt line +the talert signal is routed to; +Specific: +- ti,tshut-gpio : this entry should be used to inform which GPIO +line the tshut signal is routed to; + +Example: + +bandgap { + compatible = "ti,omap4460-control-bandgap"; + interrupts =<0 126 4>; /* talert */ + ti,tshut-gpio =<86>; +};drivers/thermal/Kconfig +13
-0@@ -26,3 +26,16 @@ config SPEAR_THERMAL help Enable this to plug the SPEAr thermal sensor driver into the Linux thermal framework + +config OMAP_BANDGAP + tristate "Texas Instruments OMAP4+ temperature sensor driver" + depends on THERMAL + depends on MFD_OMAP_CONTROL + help + If you say yes here you get support for the Texas Instruments + OMAP4460+ on die bandgap temperature sensor support. The register + set is part of system control module. + + This includes alert interrupts generation and also the TSHUT + support. +drivers/thermal/Makefile +3
-1@@ -3,4 +3,6 @@ # obj-$(CONFIG_THERMAL) += thermal_sys.o -obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o +obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o +obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal.o +omap-thermal-y := omap-bandgap.odrivers/thermal/omap-bandgap.c new file +265
-0@@ -0,0 +1,1601 @@ +/* +* OMAP4 Bandgap temperature sensor driver +* +* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ +* Author: J Keerthy<[email protected]> +* Author: Moiz Sonasath<[email protected]> +* Couple of fixes, DT and MFD adaptation: +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include <linux/module.h> +#include <linux/export.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/types.h> +#include <linux/mutex.h> +#include <linux/reboot.h> +#include <linux/of_platform.h> +#include <linux/of_irq.h> +#include <linux/mfd/omap_control.h> + +#include <mach/control.h> + +#include "omap-bandgap.h" + +/* Offsets from the base of temperature sensor registers */ + +#define OMAP4460_TEMP_SENSOR_CTRL_OFFSET 0x32C +#define OMAP4460_BGAP_CTRL_OFFSET 0x378 +#define OMAP4460_BGAP_COUNTER_OFFSET 0x37C +#define OMAP4460_BGAP_THRESHOLD_OFFSET 0x380 +#define OMAP4460_BGAP_TSHUT_OFFSET 0x384 +#define OMAP4460_BGAP_STATUS_OFFSET 0x388 +#define OMAP4460_FUSE_OPP_BGAP 0x260 + +#define OMAP5430_TEMP_SENSOR_MPU_OFFSET 0x32C +#define OMAP5430_BGAP_CTRL_OFFSET 0x380 +#define OMAP5430_BGAP_COUNTER_MPU_OFFSET 0x39C +#define OMAP5430_BGAP_THRESHOLD_MPU_OFFSET 0x384 +#define OMAP5430_BGAP_TSHUT_MPU_OFFSET 0x390 +#define OMAP5430_BGAP_STATUS_OFFSET 0x3A8 +#define OMAP5430_FUSE_OPP_BGAP_MPU 0x1E4 + +#define OMAP5430_TEMP_SENSOR_GPU_OFFSET 0x330 +#define OMAP5430_BGAP_COUNTER_GPU_OFFSET 0x3A0 +#define OMAP5430_BGAP_THRESHOLD_GPU_OFFSET 0x388 +#define OMAP5430_BGAP_TSHUT_GPU_OFFSET 0x394 +#define OMAP5430_FUSE_OPP_BGAP_GPU 0x1E0 + +#define OMAP5430_TEMP_SENSOR_CORE_OFFSET 0x334 +#define OMAP5430_BGAP_COUNTER_CORE_OFFSET 0x3A4 +#define OMAP5430_BGAP_THRESHOLD_CORE_OFFSET 0x38C +#define OMAP5430_BGAP_TSHUT_CORE_OFFSET 0x398 +#define OMAP5430_FUSE_OPP_BGAP_CORE 0x1E8 + +#define OMAP4460_TSHUT_HOT 900/* 122 deg C */ +#define OMAP4460_TSHUT_COLD 895/* 100 deg C */ +#define OMAP4460_T_HOT 800/* 73 deg C */ +#define OMAP4460_T_COLD 795/* 71 deg C */ +#define OMAP4460_MAX_FREQ 1500000 +#define OMAP4460_MIN_FREQ 1000000 +#define OMAP4460_MIN_TEMP -40000 +#define OMAP4460_MAX_TEMP 123000 +#define OMAP4460_HYST_VAL 5000 +#define OMAP4460_ADC_START_VALUE 530 +#define OMAP4460_ADC_END_VALUE 932 + +#define OMAP5430_MPU_TSHUT_HOT 915 +#define OMAP5430_MPU_TSHUT_COLD 900 +#define OMAP5430_MPU_T_HOT 800 +#define OMAP5430_MPU_T_COLD 795 +#define OMAP5430_MPU_MAX_FREQ 1500000 +#define OMAP5430_MPU_MIN_FREQ 1000000 +#define OMAP5430_MPU_MIN_TEMP -40000 +#define OMAP5430_MPU_MAX_TEMP 125000 +#define OMAP5430_MPU_HYST_VAL 5000 +#define OMAP5430_ADC_START_VALUE 532 +#define OMAP5430_ADC_END_VALUE 934 + +#define OMAP5430_GPU_TSHUT_HOT 915 +#define OMAP5430_GPU_TSHUT_COLD 900 +#define OMAP5430_GPU_T_HOT 800 +#define OMAP5430_GPU_T_COLD 795 +#define OMAP5430_GPU_MAX_FREQ 1500000 +#define OMAP5430_GPU_MIN_FREQ 1000000 +#define OMAP5430_GPU_MIN_TEMP -40000 +#define OMAP5430_GPU_MAX_TEMP 125000 +#define OMAP5430_GPU_HYST_VAL 5000 + +#define OMAP5430_CORE_TSHUT_HOT 915 +#define OMAP5430_CORE_TSHUT_COLD 900 +#define OMAP5430_CORE_T_HOT 800 +#define OMAP5430_CORE_T_COLD 795 +#define OMAP5430_CORE_MAX_FREQ 1500000 +#define OMAP5430_CORE_MIN_FREQ 1000000 +#define OMAP5430_CORE_MIN_TEMP -40000 +#define OMAP5430_CORE_MAX_TEMP 125000 +#define OMAP5430_CORE_HYST_VAL 5000 + +/** +* The register offsets and bit fields might change across +* OMAP versions hence populating them in this structure. +*/ + +struct temp_sensor_registers { +u32 temp_sensor_ctrl; +u32 bgap_tempsoff_mask; +u32 bgap_soc_mask; +u32 bgap_eocz_mask; +u32 bgap_dtemp_mask; + +u32 bgap_mask_ctrl; +u32 mask_hot_mask; +u32 mask_cold_mask; + +u32 bgap_mode_ctrl; +u32 mode_ctrl_mask; + +u32 bgap_counter; +u32 counter_mask; + +u32 bgap_threshold; +u32 threshold_thot_mask; +u32 threshold_tcold_mask; + +u32 tshut_threshold; +u32 tshut_hot_mask; +u32 tshut_cold_mask; + +u32 bgap_status; +u32 status_clean_stop_mask; +u32 status_bgap_alert_mask; +u32 status_hot_mask; +u32 status_cold_mask; + +u32 bgap_efuse; +}; + +/** +* The thresholds and limits for temperature sensors. +*/ +struct temp_sensor_data { +u32 tshut_hot; +u32 tshut_cold; +u32 t_hot; +u32 t_cold; +u32 min_freq; +u32 max_freq; +int max_temp; +int min_temp; +int hyst_val; +u32 adc_start_val; +u32 adc_end_val; +u32 update_int1; +u32 update_int2; +}; + +/** +* struct temp_sensor_regval - temperature sensor register values +* @bg_mode_ctrl: temp sensor control register value +* @bg_ctrl: bandgap ctrl register value +* @bg_counter: bandgap counter value +* @bg_threshold: bandgap threshold register value +* @tshut_threshold: bandgap tshut register value +*/ +struct temp_sensor_regval { +u32 bg_mode_ctrl; +u32 bg_ctrl; +u32 bg_counter; +u32 bg_threshold; +u32 tshut_threshold; +}; + +/** +* struct omap_temp_sensor - bandgap temperature sensor platform data +* @ts_data: pointer to struct with thresholds, limits of temperature sensor +* @registers: pointer to the list of register offsets and bitfields +* @regval: temperature sensor register values +* @domain: the name of the domain where the sensor is located +*/ +struct omap_temp_sensor { +struct temp_sensor_data *ts_data; +struct temp_sensor_registers *registers; +struct temp_sensor_regval *regval; +char *domain; +}; + +/** +* struct omap_bandgap_data - bandgap platform data structure +* @has_talert: indicates if the chip has talert output line +* @has_tshut: indicates if the chip has tshut output line +* @conv_table: Pointer to adc to temperature conversion table +* @fclock_name: clock name of the functional clock +* @div_ck_nme: clock name of the clock divisor +* @sensor_count: count of temperature sensor device in scm +* @sensors: array of sensors present in this bandgap instance +* @expose_sensor: callback to export sensor to thermal API +*/ +struct omap_bandgap_data { +bool has_talert; +bool has_tshut; +const int *conv_table; +char *fclock_name; +char *div_ck_name; +int sensor_count; +int (*report_temperature)(struct omap_bandgap *bg_ptr,int id); +int (*expose_sensor)(struct omap_bandgap *bg_ptr,int id,char *domain); + +/* this needs to be at the end */ +struct omap_temp_sensor sensors[]; +}; + +/* TODO: provide data structures for 4430 */ + +/* +* OMAP4460 has one instance of thermal sensor for MPU +* need to describe the individual bit fields +*/ +static struct temp_sensor_registers +omap4460_mpu_temp_sensor_registers = { + .temp_sensor_ctrl =OMAP4460_TEMP_SENSOR_CTRL_OFFSET , + .bgap_tempsoff_mask =OMAP4460_BGAP_TEMPSOFF_MASK , + .bgap_soc_mask =OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK , + .bgap_eocz_mask =OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK , + .bgap_dtemp_mask =OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK , + + .bgap_mask_ctrl =OMAP4460_BGAP_CTRL_OFFSET , + .mask_hot_mask =OMAP4460_MASK_HOT_MASK , + .mask_cold_mask =OMAP4460_MASK_COLD_MASK , + + .bgap_mode_ctrl =OMAP4460_BGAP_CTRL_OFFSET , + .mode_ctrl_mask =OMAP4460_SINGLE_MODE_MASK , + + .bgap_counter =OMAP4460_BGAP_COUNTER_OFFSET , + .counter_mask =OMAP4460_COUNTER_MASK , + + .bgap_threshold =OMAP4460_BGAP_THRESHOLD_OFFSET , + .threshold_thot_mask =OMAP4460_T_HOT_MASK , + .threshold_tcold_mask =OMAP4460_T_COLD_MASK , + + .tshut_threshold =OMAP4460_BGAP_TSHUT_OFFSET , + .tshut_hot_mask =OMAP4460_TSHUT_HOT_MASK , + .tshut_cold_mask =OMAP4460_TSHUT_COLD_MASK , + + .bgap_status =OMAP4460_BGAP_STATUS_OFFSET ,drivers/thermal/omap-bandgap.c line 275
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ .status_clean_stop_mask = OMAP4460_CLEAN_STOP_MASK, + .status_bgap_alert_mask = OMAP4460_BGAP_ALERT_MASK, + .status_hot_mask = OMAP4460_HOT_FLAG_MASK, + .status_cold_mask = OMAP4460_COLD_FLAG_MASK, + + .bgap_efuse = OMAP4460_FUSE_OPP_BGAP, +}; + +/* +* OMAP4460 has one instance of thermal sensor for MPU Bad copy paste.
Quoted 31 lines
drivers/thermal/omap-bandgap.c new file +31
-0+* need to describe the individual bit fields +*/ +static struct temp_sensor_registers +omap5430_mpu_temp_sensor_registers = { + .temp_sensor_ctrl =OMAP5430_TEMP_SENSOR_MPU_OFFSET , + .bgap_tempsoff_mask =OMAP5430_BGAP_TEMPSOFF_MASK , + .bgap_soc_mask =OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK , + .bgap_eocz_mask =OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK , + .bgap_dtemp_mask =OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK , + + .bgap_mask_ctrl =OMAP5430_BGAP_CTRL_OFFSET , + .mask_hot_mask =OMAP5430_MASK_HOT_MPU_MASK , + .mask_cold_mask =OMAP5430_MASK_COLD_MPU_MASK , + + .bgap_mode_ctrl =OMAP5430_BGAP_COUNTER_MPU_OFFSET , + .mode_ctrl_mask =OMAP5430_REPEAT_MODE_MASK , + + .bgap_counter =OMAP5430_BGAP_COUNTER_MPU_OFFSET , + .counter_mask =OMAP5430_COUNTER_MASK , + + .bgap_threshold =OMAP5430_BGAP_THRESHOLD_MPU_OFFSET , + .threshold_thot_mask =OMAP5430_T_HOT_MASK , + .threshold_tcold_mask =OMAP5430_T_COLD_MASK , + + .tshut_threshold =OMAP5430_BGAP_TSHUT_MPU_OFFSET , + .tshut_hot_mask =OMAP5430_TSHUT_HOT_MASK , + .tshut_cold_mask =OMAP5430_TSHUT_COLD_MASK , + + .bgap_status =OMAP5430_BGAP_STATUS_OFFSET , + .status_clean_stop_mask =0x0 , + .status_bgap_alert_mask =OMAP5430_BGAP_ALERT_MASK ,drivers/thermal/omap-bandgap.c line 316
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ .status_hot_mask = OMAP5430_HOT_MPU_FLAG_MASK, + .status_cold_mask = OMAP5430_COLD_MPU_FLAG_MASK, + + .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_MPU, +}; + +/* +* OMAP4460 has one instance of thermal sensor for MPU +* need to describe the individual bit fields +*/ Ditto
Quoted 29 lines
drivers/thermal/omap-bandgap.c new file +29
-0+static struct temp_sensor_registers +omap5430_gpu_temp_sensor_registers = { + .temp_sensor_ctrl =OMAP5430_TEMP_SENSOR_GPU_OFFSET , + .bgap_tempsoff_mask =OMAP5430_BGAP_TEMPSOFF_MASK , + .bgap_soc_mask =OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK , + .bgap_eocz_mask =OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK , + .bgap_dtemp_mask =OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK , + + .bgap_mask_ctrl =OMAP5430_BGAP_CTRL_OFFSET , + .mask_hot_mask =OMAP5430_MASK_HOT_MM_MASK , + .mask_cold_mask =OMAP5430_MASK_COLD_MM_MASK , + + .bgap_mode_ctrl =OMAP5430_BGAP_COUNTER_GPU_OFFSET , + .mode_ctrl_mask =OMAP5430_REPEAT_MODE_MASK , + + .bgap_counter =OMAP5430_BGAP_COUNTER_GPU_OFFSET , + .counter_mask =OMAP5430_COUNTER_MASK , + + .bgap_threshold =OMAP5430_BGAP_THRESHOLD_GPU_OFFSET , + .threshold_thot_mask =OMAP5430_T_HOT_MASK , + .threshold_tcold_mask =OMAP5430_T_COLD_MASK , + + .tshut_threshold =OMAP5430_BGAP_TSHUT_GPU_OFFSET , + .tshut_hot_mask =OMAP5430_TSHUT_HOT_MASK , + .tshut_cold_mask =OMAP5430_TSHUT_COLD_MASK , + + .bgap_status =OMAP5430_BGAP_STATUS_OFFSET , + .status_clean_stop_mask =0x0 , + .status_bgap_alert_mask =OMAP5430_BGAP_ALERT_MASK ,drivers/thermal/omap-bandgap.c line 355
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ .status_hot_mask = OMAP5430_HOT_MM_FLAG_MASK, + .status_cold_mask = OMAP5430_COLD_MM_FLAG_MASK, + + .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_GPU, +}; + +/* +* OMAP4460 has one instance of thermal sensor for MPU +* need to describe the individual bit fields +*/ Ditto
Quoted 221 lines
drivers/thermal/omap-bandgap.c new file +221
-0+static struct temp_sensor_registers +omap5430_core_temp_sensor_registers = { + .temp_sensor_ctrl =OMAP5430_TEMP_SENSOR_CORE_OFFSET , + .bgap_tempsoff_mask =OMAP5430_BGAP_TEMPSOFF_MASK , + .bgap_soc_mask =OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK , + .bgap_eocz_mask =OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK , + .bgap_dtemp_mask =OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK , + + .bgap_mask_ctrl =OMAP5430_BGAP_CTRL_OFFSET , + .mask_hot_mask =OMAP5430_MASK_HOT_CORE_MASK , + .mask_cold_mask =OMAP5430_MASK_COLD_CORE_MASK , + + .bgap_mode_ctrl =OMAP5430_BGAP_COUNTER_CORE_OFFSET , + .mode_ctrl_mask =OMAP5430_REPEAT_MODE_MASK , + + .bgap_counter =OMAP5430_BGAP_COUNTER_CORE_OFFSET , + .counter_mask =OMAP5430_COUNTER_MASK , + + .bgap_threshold =OMAP5430_BGAP_THRESHOLD_CORE_OFFSET , + .threshold_thot_mask =OMAP5430_T_HOT_MASK , + .threshold_tcold_mask =OMAP5430_T_COLD_MASK , + + .tshut_threshold =OMAP5430_BGAP_TSHUT_CORE_OFFSET , + .tshut_hot_mask =OMAP5430_TSHUT_HOT_MASK , + .tshut_cold_mask =OMAP5430_TSHUT_COLD_MASK , + + .bgap_status =OMAP5430_BGAP_STATUS_OFFSET , + .status_clean_stop_mask =0x0 , + .status_bgap_alert_mask =OMAP5430_BGAP_ALERT_MASK , + .status_hot_mask =OMAP5430_HOT_CORE_FLAG_MASK , + .status_cold_mask =OMAP5430_COLD_CORE_FLAG_MASK , + + .bgap_efuse =OMAP5430_FUSE_OPP_BGAP_CORE , +}; + +/* Thresholds and limits for OMAP4460 MPU temperature sensor */ +static struct temp_sensor_data omap4460_mpu_temp_sensor_data = { + .tshut_hot =OMAP4460_TSHUT_HOT , + .tshut_cold =OMAP4460_TSHUT_COLD , + .t_hot =OMAP4460_T_HOT , + .t_cold =OMAP4460_T_COLD , + .min_freq =OMAP4460_MIN_FREQ , + .max_freq =OMAP4460_MAX_FREQ , + .max_temp =OMAP4460_MAX_TEMP , + .min_temp =OMAP4460_MIN_TEMP , + .hyst_val =OMAP4460_HYST_VAL , + .adc_start_val =OMAP4460_ADC_START_VALUE , + .adc_end_val =OMAP4460_ADC_END_VALUE , + .update_int1 =1000 , + .update_int2 =2000 , +}; + +/* Thresholds and limits for OMAP5430 MPU temperature sensor */ +static struct temp_sensor_data omap5430_mpu_temp_sensor_data = { + .tshut_hot =OMAP5430_MPU_TSHUT_HOT , + .tshut_cold =OMAP5430_MPU_TSHUT_COLD , + .t_hot =OMAP5430_MPU_T_HOT , + .t_cold =OMAP5430_MPU_T_COLD , + .min_freq =OMAP5430_MPU_MIN_FREQ , + .max_freq =OMAP5430_MPU_MAX_FREQ , + .max_temp =OMAP5430_MPU_MAX_TEMP , + .min_temp =OMAP5430_MPU_MIN_TEMP , + .hyst_val =OMAP5430_MPU_HYST_VAL , + .adc_start_val =OMAP5430_ADC_START_VALUE , + .adc_end_val =OMAP5430_ADC_END_VALUE , + .update_int1 =1000 , + .update_int2 =2000 , +}; + +/* Thresholds and limits for OMAP5430 GPU temperature sensor */ +static struct temp_sensor_data omap5430_gpu_temp_sensor_data = { + .tshut_hot =OMAP5430_GPU_TSHUT_HOT , + .tshut_cold =OMAP5430_GPU_TSHUT_COLD , + .t_hot =OMAP5430_GPU_T_HOT , + .t_cold =OMAP5430_GPU_T_COLD , + .min_freq =OMAP5430_GPU_MIN_FREQ , + .max_freq =OMAP5430_GPU_MAX_FREQ , + .max_temp =OMAP5430_GPU_MAX_TEMP , + .min_temp =OMAP5430_GPU_MIN_TEMP , + .hyst_val =OMAP5430_GPU_HYST_VAL , + .adc_start_val =OMAP5430_ADC_START_VALUE , + .adc_end_val =OMAP5430_ADC_END_VALUE , + .update_int1 =1000 , + .update_int2 =2000 , +}; + +/* Thresholds and limits for OMAP5430 CORE temperature sensor */ +static struct temp_sensor_data omap5430_core_temp_sensor_data = { + .tshut_hot =OMAP5430_CORE_TSHUT_HOT , + .tshut_cold =OMAP5430_CORE_TSHUT_COLD , + .t_hot =OMAP5430_CORE_T_HOT , + .t_cold =OMAP5430_CORE_T_COLD , + .min_freq =OMAP5430_CORE_MIN_FREQ , + .max_freq =OMAP5430_CORE_MAX_FREQ , + .max_temp =OMAP5430_CORE_MAX_TEMP , + .min_temp =OMAP5430_CORE_MIN_TEMP , + .hyst_val =OMAP5430_CORE_HYST_VAL , + .adc_start_val =OMAP5430_ADC_START_VALUE , + .adc_end_val =OMAP5430_ADC_END_VALUE , + .update_int1 =1000 , + .update_int2 =2000 , +}; + +/* +* Temperature values in milli degree celsius +* ADC code values from 530 to 923 +*/ +static const int +omap4460_adc_to_temp[OMAP4460_ADC_END_VALUE -OMAP4460_ADC_START_VALUE +1 ] = { +-40000 ,-40000 ,-40000 ,-40000 ,-39800 ,-39400 ,-39000 ,-38600 ,-38200 , +-37800 ,-37300 ,-36800 ,-36400 ,-36000 ,-35600 ,-35200 ,-34800 , +-34300 ,-33800 ,-33400 ,-33000 ,-32600 ,-32200 ,-31800 ,-31300 , +-30800 ,-30400 ,-30000 ,-29600 ,-29200 ,-28700 ,-28200 ,-27800 , +-27400 ,-27000 ,-26600 ,-26200 ,-25700 ,-25200 ,-24800 ,-24400 , +-24000 ,-23600 ,-23200 ,-22700 ,-22200 ,-21800 ,-21400 ,-21000 , +-20600 ,-20200 ,-19700 ,-19200 ,-18800 ,-18400 ,-18000 ,-17600 , +-17200 ,-16700 ,-16200 ,-15800 ,-15400 ,-15000 ,-14600 ,-14200 , +-13700 ,-13200 ,-12800 ,-12400 ,-12000 ,-11600 ,-11200 ,-10700 , +-10200 ,-9800 ,-9400 ,-9000 ,-8600 ,-8200 ,-7700 ,-7200 ,-6800 , +-6400 ,-6000 ,-5600 ,-5200 ,-4800 ,-4300 ,-3800 ,-3400 ,-3000 , +-2600 ,-2200 ,-1800 ,-1300 ,-800 ,-400 ,0 ,400 ,800 ,1200 ,1600 , +2100 ,2600 ,3000 ,3400 ,3800 ,4200 ,4600 ,5100 ,5600 ,6000 ,6400 , +6800 ,7200 ,7600 ,8000 ,8500 ,9000 ,9400 ,9800 ,10200 ,10600 ,11000 , +11400 ,11900 ,12400 ,12800 ,13200 ,13600 ,14000 ,14400 ,14800 , +15300 ,15800 ,16200 ,16600 ,17000 ,17400 ,17800 ,18200 ,18700 , +19200 ,19600 ,20000 ,20400 ,20800 ,21200 ,21600 ,22100 ,22600 , +23000 ,23400 ,23800 ,24200 ,24600 ,25000 ,25400 ,25900 ,26400 , +26800 ,27200 ,27600 ,28000 ,28400 ,28800 ,29300 ,29800 ,30200 , +30600 ,31000 ,31400 ,31800 ,32200 ,32600 ,33100 ,33600 ,34000 , +34400 ,34800 ,35200 ,35600 ,36000 ,36400 ,36800 ,37300 ,37800 , +38200 ,38600 ,39000 ,39400 ,39800 ,40200 ,40600 ,41100 ,41600 , +42000 ,42400 ,42800 ,43200 ,43600 ,44000 ,44400 ,44800 ,45300 , +45800 ,46200 ,46600 ,47000 ,47400 ,47800 ,48200 ,48600 ,49000 , +49500 ,50000 ,50400 ,50800 ,51200 ,51600 ,52000 ,52400 ,52800 , +53200 ,53700 ,54200 ,54600 ,55000 ,55400 ,55800 ,56200 ,56600 , +57000 ,57400 ,57800 ,58200 ,58700 ,59200 ,59600 ,60000 ,60400 , +60800 ,61200 ,61600 ,62000 ,62400 ,62800 ,63300 ,63800 ,64200 , +64600 ,65000 ,65400 ,65800 ,66200 ,66600 ,67000 ,67400 ,67800 , +68200 ,68700 ,69200 ,69600 ,70000 ,70400 ,70800 ,71200 ,71600 , +72000 ,72400 ,72800 ,73200 ,73600 ,74100 ,74600 ,75000 ,75400 , +75800 ,76200 ,76600 ,77000 ,77400 ,77800 ,78200 ,78600 ,79000 , +79400 ,79800 ,80300 ,80800 ,81200 ,81600 ,82000 ,82400 ,82800 , +83200 ,83600 ,84000 ,84400 ,84800 ,85200 ,85600 ,86000 ,86400 , +86800 ,87300 ,87800 ,88200 ,88600 ,89000 ,89400 ,89800 ,90200 , +90600 ,91000 ,91400 ,91800 ,92200 ,92600 ,93000 ,93400 ,93800 , +94200 ,94600 ,95000 ,95500 ,96000 ,96400 ,96800 ,97200 ,97600 , +98000 ,98400 ,98800 ,99200 ,99600 ,100000 ,100400 ,100800 ,101200 , +101600 ,102000 ,102400 ,102800 ,103200 ,103600 ,104000 ,104400 , +104800 ,105200 ,105600 ,106100 ,106600 ,107000 ,107400 ,107800 , +108200 ,108600 ,109000 ,109400 ,109800 ,110200 ,110600 ,111000 , +111400 ,111800 ,112200 ,112600 ,113000 ,113400 ,113800 ,114200 , +114600 ,115000 ,115400 ,115800 ,116200 ,116600 ,117000 ,117400 , +117800 ,118200 ,118600 ,119000 ,119400 ,119800 ,120200 ,120600 , +121000 ,121400 ,121800 ,122200 ,122600 ,123000 ,123400 ,123800 ,124200 , +124600 ,124900 ,125000 ,125000 ,125000 ,125000 +}; + +static const int +omap5430_adc_to_temp[OMAP5430_ADC_END_VALUE -OMAP5430_ADC_START_VALUE +1 ] = { +-40000 ,-40000 ,-40000 ,-40000 ,-39800 ,-39400 ,-39000 ,-38600 , +-38200 ,-37800 ,-37300 ,-36800 , +-36400 ,-36000 ,-35600 ,-35200 ,-34800 ,-34300 ,-33800 ,-33400 ,-33000 , +-32600 , +-32200 ,-31800 ,-31300 ,-30800 ,-30400 ,-30000 ,-29600 ,-29200 ,-28700 , +-28200 ,-27800 ,-27400 ,-27000 ,-26600 ,-26200 ,-25700 ,-25200 ,-24800 , +-24400 ,-24000 ,-23600 ,-23200 ,-22700 ,-22200 ,-21800 ,-21400 ,-21000 , +-20600 ,-20200 ,-19700 ,-19200 ,-9300 ,-18400 ,-18000 ,-17600 ,-17200 , +-16700 ,-16200 ,-15800 ,-15400 ,-15000 ,-14600 ,-14200 ,-13700 ,-13200 , +-12800 ,-12400 ,-12000 ,-11600 ,-11200 ,-10700 ,-10200 ,-9800 ,-9400 , +-9000 , +-8600 ,-8200 ,-7700 ,-7200 ,-6800 ,-6400 ,-6000 ,-5600 ,-5200 ,-4800 , +-4300 , +-3800 ,-3400 ,-3000 ,-2600 ,-2200 ,-1800 ,-1300 ,-800 ,-400 ,0 ,400 , +800 , +1200 ,1600 ,2100 ,2600 ,3000 ,3400 ,3800 ,4200 ,4600 ,5100 ,5600 ,6000 , +6400 ,6800 ,7200 ,7600 ,8000 ,8500 ,9000 ,9400 ,9800 ,10200 ,10800 , +11100 , +11400 ,11900 ,12400 ,12800 ,13200 ,13600 ,14000 ,14400 ,14800 ,15300 , +15800 , +16200 ,16600 ,17000 ,17400 ,17800 ,18200 ,18700 ,19200 ,19600 ,20000 , +20400 , +20800 ,21200 ,21600 ,22100 ,22600 ,23000 ,23400 ,23800 ,24200 ,24600 , +25000 , +25400 ,25900 ,26400 ,26800 ,27200 ,27600 ,28000 ,28400 ,28800 ,29300 , +29800 , +30200 ,30600 ,31000 ,31400 ,31800 ,32200 ,32600 ,33100 ,33600 ,34000 , +34400 , +34800 ,35200 ,35600 ,36000 ,36400 ,36800 ,37300 ,37800 ,38200 ,38600 , +39000 , +39400 ,39800 ,40200 ,40600 ,41100 ,41600 ,42000 ,42400 ,42800 ,43200 , +43600 , +44000 ,44400 ,44800 ,45300 ,45800 ,46200 ,46600 ,47000 ,47400 ,47800 , +48200 , +48600 ,49000 ,49500 ,50000 ,50400 ,50800 ,51200 ,51600 ,52000 ,52400 , +52800 , +53200 ,53700 ,54200 ,54600 ,55000 ,55400 ,55800 ,56200 ,56600 ,57000 , +57400 , +57800 ,58200 ,58700 ,59200 ,59600 ,60000 ,60400 ,60800 ,61200 ,61600 , +62000 , +62400 ,62800 ,63300 ,63800 ,64200 ,64600 ,65000 ,65400 ,65800 ,66200 , +66600 , +67000 ,67400 ,67800 ,68200 ,68700 ,69200 ,69600 ,70000 ,70400 ,70800 , +71200 , +71600 ,72000 ,72400 ,72800 ,73200 ,73600 ,74100 ,74600 ,75000 ,75400 , +75800 , +76200 ,76600 ,77000 ,77400 ,77800 ,78200 ,78600 ,79000 ,79400 ,79800 , +80300 , +80800 ,81200 ,81600 ,82000 ,82400 ,82800 ,83200 ,83600 ,84000 ,84400 , +84800 , +85200 ,85600 ,86000 ,86400 ,86800 ,87300 ,87800 ,88200 ,88600 ,89000 , +89400 , +89800 ,90200 ,90600 ,91000 ,91400 ,91800 ,92200 ,92600 ,93000 ,93400 , +93800 , +94200 ,94600 ,95000 ,95500 ,96000 ,96400 ,96800 ,97200 ,97600 ,98000 , +98400 , +98800 ,99200 ,99600 ,100000 ,100400 ,100800 ,101200 ,101600 ,102000 , +102400 , +102800 ,103200 ,103600 ,104000 ,104400 ,104800 ,105200 ,105600 ,106100 , +106600 ,107000 ,107400 ,107800 ,108200 ,108600 ,109000 ,109400 ,109800 , +110200 ,110600 ,111000 ,111400 ,111800 ,112200 ,112600 ,113000 ,113400 , +113800 ,114200 ,114600 ,115000 ,115400 ,115800 ,116200 ,116600 ,117000 ,
Quoted 8 lines
drivers/thermal/omap-bandgap.c line 580
Quoted 4 lines
drivers/thermal/omap-bandgap.c new file +4
-0+117400 ,117800 ,118200 ,118600 ,119000 ,119400 ,119800 ,120200 ,120600 , +121000 ,121400 ,121800 ,122200 ,122600 ,123000 ,123400 ,123800 ,124200 , + 124600, 124900, 125000, 125000, 125000, 125000, +};It might be good to store the per SoC data in dedicated files or at least put some #ifdef around to avoid wasting memory for a non-multi OMAP boot.
Indeed, I was rewriting this stuff with that in mind when I saw your comment :-)
Idea is to move all this arch dependent data structures to specific files. Here at omap-bandgap.c we would have essentially the pdriver and the local functions and APIs. The omapX-thermal.c would contain the specific data structures and the functions related to the thermal zones, and possibly the policy specifics for each case. Something like:
drivers/thermal/
|- omap-bandgap.c: Bandgap platform driver specific functions and APIs (CONFIG_OMAP_BANDGAP) |- omap-bandgap.h: Common data structure definition and defines |- omap4-thermal.c: OMAP4xx data structures needed by the bandgap driver and the thermal zone definitions (CONFIG_OMAP4_THERMAL) |- omap5-thermal.c: OMAP54xx data structures needed by the bandgap driver and the thermal zone definitions (CONFIG_OMAP5_THERMAL) |- omap-thermal.ko: Module binary. It would contain the support depending on what has been selected at compile time
Quoted 1 line
filename: omap-thermal.ko
author: Texas Instrument Inc. alias: platform:omap-bandgap license: GPL v2 description: OMAP4+ bandgap temperature sensor driver srcversion: 937A9F9230A5025A0E9A268 alias: of:N*T*Cti,omap4460-bandgap* alias: of:N*T*Cti,omap5430-bandgap* depends: intree: Y vermagic: 3.4.0-rc6-12199-g3e31a0c-dirty SMP preempt mod_unload modversions ARMv7 p2v8
There is gonna happen some ifdefery in omap-bandgap.[c,h] in order to compose the match_id table based on what has been selected for compilation, but I at least don't see any other way around.
Quoted 1,131 lines
Quoted 603 lines
drivers/thermal/omap-bandgap.c new file +603
-0+ +static irqreturn_t talert_irq_handler (int irq,void *data) +{ +struct omap_bandgap *bg_ptr = data; +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 t_hot =0 , t_cold =0 , temp, ctrl; +int i, r; + + bg_ptr = data; +/* Read the status of t_hot */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { + tsr = bg_ptr->pdata->sensors[i].registers; + r =omap_control_readl (cdev, tsr->bgap_status,&t_hot); + t_hot&= tsr->status_hot_mask; + +/* Read the status of t_cold */ + r |=omap_control_readl (cdev, tsr->bgap_status,&t_cold); + t_cold&= tsr->status_cold_mask; + +if (!t_cold&& !t_hot) +continue ; + + r |=omap_control_readl (cdev, tsr->bgap_mask_ctrl,&ctrl); +/* +* One TALERT interrupt: Two sources +* If the interrupt is due to t_hot then mask t_hot and +* and unmask t_cold else mask t_cold and unmask t_hot +*/ +if (t_hot) { + ctrl&= ~tsr->mask_hot_mask; + ctrl |= tsr->mask_cold_mask; + }else if (t_cold) { + ctrl&= ~tsr->mask_cold_mask; + ctrl |= tsr->mask_hot_mask; + } + + r |=omap_control_writel (cdev, ctrl, tsr->bgap_mask_ctrl); + +if (r) { +dev_err (bg_ptr->dev,"failed to ack talert interrupt\n" ); +return IRQ_NONE ; + } + +/* read temperature */ + r =omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= tsr->bgap_dtemp_mask; + +/* report temperature to whom may concern */ +if (bg_ptr->pdata->report_temperature) + bg_ptr->pdata->report_temperature (bg_ptr, i); + } + +return IRQ_HANDLED ; +} + +static irqreturn_t omap_bandgap_tshut_irq_handler (int irq,void *data) +{ +orderly_poweroff (true); + +return IRQ_HANDLED ; +} + +static +int adc_to_temp_conversion (struct omap_bandgap *bg_ptr,int id,int adc_val, +int *t) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; + +/* look up for temperature in the table and return the temperature */ +if (adc_val< ts_data->adc_start_val || adc_val> ts_data->adc_end_val) +return -ERANGE ; + + *t = bg_ptr->conv_table[adc_val - ts_data->adc_start_val]; + +return 0 ; +} + +static int temp_to_adc_conversion (long temp,struct omap_bandgap *bg_ptr,int i, +int *adc) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[i].ts_data; +int high, low, mid; + + low =0 ; + high = ts_data->adc_end_val - ts_data->adc_start_val; + mid = (high + low) /2 ; + +if (temp< bg_ptr->conv_table[high] || temp> bg_ptr->conv_table[high]) +return -EINVAL ; + +while (low< high) { +if (temp< bg_ptr->conv_table[mid]) + high = mid -1 ; +else + low = mid +1 ; + mid = (low + high) /2 ; + } + + *adc = ts_data->adc_start_val + low; + +return 0 ; +} + +static int temp_sensor_unmask_interrupts (struct omap_bandgap *bg_ptr,int id, +u32 t_hot,u32 t_cold) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp, reg_val; +int err; + +/* Read the current on die temperature */ + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= tsr->bgap_dtemp_mask; + + err |=omap_control_readl (cdev, tsr->bgap_mask_ctrl,®_val); +if (temp< t_hot) + reg_val |= tsr->mask_hot_mask; +else + reg_val&= ~tsr->mask_hot_mask; + +if (t_cold< temp) + reg_val |= tsr->mask_cold_mask; +else + reg_val&= ~tsr->mask_cold_mask; + err |=omap_control_writel (cdev, reg_val, tsr->bgap_mask_ctrl); + +if (err) { +dev_err (bg_ptr->dev,"failed to unmask interrupts\n" ); +return -EIO ; + } + +return 0 ; +} + +static +int add_hyst (int adc_val,int hyst_val,struct omap_bandgap *bg_ptr,int i, +u32 *sum) +{ +int temp, ret; + + ret =adc_to_temp_conversion (bg_ptr, i, adc_val,&temp); +if (ret<0 ) +return ret; + + temp += hyst_val; + +return temp_to_adc_conversion (temp, bg_ptr, i, sum); +} + +static +int temp_sensor_configure_thot (struct omap_bandgap *bg_ptr,int id,int t_hot) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 thresh_val, reg_val; +int cold, err; + + tsr = bg_ptr->pdata->sensors[id].registers; + +/* obtain the T cold value */ + err =omap_control_readl (cdev, tsr->bgap_threshold,&thresh_val); + cold = (thresh_val& tsr->threshold_tcold_mask)>> +__ffs (tsr->threshold_tcold_mask); +if (t_hot<= cold) { +/* change the t_cold to t_hot - 5000 millidegrees */ + err |=add_hyst (t_hot, -ts_data->hyst_val, bg_ptr, id,&cold); +/* write the new t_cold value */ + reg_val = thresh_val& (~tsr->threshold_tcold_mask); + reg_val |= cold<<__ffs (tsr->threshold_tcold_mask); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + thresh_val = reg_val; + } + +/* write the new t_hot value */ + reg_val = thresh_val& ~tsr->threshold_thot_mask; + reg_val |= (t_hot<<__ffs (tsr->threshold_thot_mask)); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram thot threshold\n" ); +return -EIO ; + } + +return temp_sensor_unmask_interrupts (bg_ptr, id, t_hot, cold); +} + +static +int temp_sensor_init_talert_thresholds (struct omap_bandgap *bg_ptr,int id, +int t_hot,int t_cold) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 reg_val, thresh_val; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->bgap_threshold,&thresh_val); + +/* write the new t_cold value */ + reg_val = thresh_val& ~tsr->threshold_tcold_mask; + reg_val |= (t_cold<<__ffs (tsr->threshold_tcold_mask)); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tcold threshold\n" ); +return -EIO ; + } + + err =omap_control_readl (cdev, tsr->bgap_threshold,&thresh_val); + +/* write the new t_hot value */ + reg_val = thresh_val& ~tsr->threshold_thot_mask; + reg_val |= (t_hot<<__ffs (tsr->threshold_thot_mask)); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram thot threshold\n" ); +return -EIO ; + } + + err =omap_control_readl (cdev, tsr->bgap_mask_ctrl,®_val); + reg_val |= tsr->mask_hot_mask; + reg_val |= tsr->mask_cold_mask; + err |=omap_control_writel (cdev, reg_val, tsr->bgap_mask_ctrl); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram thot threshold\n" ); +return -EIO ; + } + +return err; +} + +static +int temp_sensor_configure_tcold (struct omap_bandgap *bg_ptr,int id, +int t_cold) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 thresh_val, reg_val; +int hot, err; + + tsr = bg_ptr->pdata->sensors[id].registers; +/* obtain the T cold value */ + err =omap_control_readl (cdev, tsr->bgap_threshold,&thresh_val); + hot = (thresh_val& tsr->threshold_thot_mask)>> +__ffs (tsr->threshold_thot_mask); + +if (t_cold>= hot) { +/* change the t_hot to t_cold + 5000 millidegrees */ + err |=add_hyst (t_cold, ts_data->hyst_val, bg_ptr, id,&hot); +/* write the new t_hot value */ + reg_val = thresh_val& (~tsr->threshold_thot_mask); + reg_val |= hot<<__ffs (tsr->threshold_thot_mask); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + thresh_val = reg_val; + } + +/* write the new t_cold value */ + reg_val = thresh_val& ~tsr->threshold_tcold_mask; + reg_val |= (t_cold<<__ffs (tsr->threshold_tcold_mask)); + err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tcold threshold\n" ); +return -EIO ; + } + +return temp_sensor_unmask_interrupts (bg_ptr, id, hot, t_cold); +} + +static int temp_sensor_configure_tshut_hot (struct omap_bandgap *bg_ptr, +int id,int tshut_hot) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 reg_val; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->tshut_threshold,®_val); + reg_val&= ~tsr->tshut_hot_mask; + reg_val |= tshut_hot<<__ffs (tsr->tshut_hot_mask); + err |=omap_control_writel (cdev, reg_val, tsr->tshut_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tshut thot\n" ); +return -EIO ; + } + +return 0 ; +} + +static int temp_sensor_configure_tshut_cold (struct omap_bandgap *bg_ptr, +int id,int tshut_cold) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 reg_val; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->tshut_threshold,®_val); + reg_val&= ~tsr->tshut_cold_mask; + reg_val |= tshut_cold<<__ffs (tsr->tshut_cold_mask); + err |=omap_control_writel (cdev, reg_val, tsr->tshut_threshold); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tshut tcold\n" ); +return -EIO ; + } + +return 0 ; +} + +static int configure_temp_sensor_counter (struct omap_bandgap *bg_ptr,int id, +u32 counter) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 val; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; + err =omap_control_readl (cdev, tsr->bgap_counter,&val); + val&= ~tsr->counter_mask; + val |= counter<<__ffs (tsr->counter_mask); + err |=omap_control_writel (cdev, val, tsr->bgap_counter); +if (err) { +dev_err (bg_ptr->dev,"failed to reprogram tshut tcold\n" ); +return -EIO ; + } + +return 0 ; +} + +/* Exposed APIs */ +/** +* omap_bandgap_read_thot() - reads sensor current thot +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @thot - resulting current thot value +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_read_thot (struct omap_bandgap *bg_ptr,int id, +int *thot) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + ret =omap_control_readl (cdev, tsr->bgap_threshold,&temp); + temp = (temp& tsr->threshold_thot_mask)>> +__ffs (tsr->threshold_thot_mask); + ret |=adc_to_temp_conversion (bg_ptr, id, temp,&temp); +if (ret) { +dev_err (bg_ptr->dev,"failed to read thot\n" ); +return -EIO ; + } + + *thot = temp; + +return 0 ; +} + +/** +* omap_bandgap_write_thot() - sets sensor current thot +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @val - desired thot value +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_write_thot (struct omap_bandgap *bg_ptr,int id,int val) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; +struct temp_sensor_registers *tsr; +u32 t_hot; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + +if (val< ts_data->min_temp + ts_data->hyst_val) +return -EINVAL ; + ret =temp_to_adc_conversion (val, bg_ptr, id,&t_hot); +if (ret<0 ) +return ret; + +mutex_lock (&bg_ptr->bg_mutex); +temp_sensor_configure_thot (bg_ptr, id, t_hot); +mutex_unlock (&bg_ptr->bg_mutex); + +return 0 ; +} + +/** +* omap_bandgap_read_tcold() - reads sensor current tcold +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @tcold - resulting current tcold value +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_read_tcold (struct omap_bandgap *bg_ptr,int id, +int *tcold) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + ret =omap_control_readl (cdev, tsr->bgap_threshold,&temp); + temp = (temp& tsr->threshold_tcold_mask) + >>__ffs (tsr->threshold_tcold_mask); + ret |=adc_to_temp_conversion (bg_ptr, id, temp,&temp); +if (ret) +return -EIO ; + + *tcold = temp; + +return 0 ; +} + +/** +* omap_bandgap_write_tcold() - sets the sensor tcold +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @val - desired tcold value +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_write_tcold (struct omap_bandgap *bg_ptr,int id,int val) +{ +struct temp_sensor_data *ts_data = bg_ptr->pdata->sensors[id].ts_data; +struct temp_sensor_registers *tsr; +u32 t_cold; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; +if (val> ts_data->max_temp + ts_data->hyst_val) +return -EINVAL ; + + ret =temp_to_adc_conversion (val, bg_ptr, id,&t_cold); +if (ret<0 ) +return ret; + +mutex_lock (&bg_ptr->bg_mutex); +temp_sensor_configure_tcold (bg_ptr, id, t_cold); +mutex_unlock (&bg_ptr->bg_mutex); + +return 0 ; +} + +/** +* omap_bandgap_read_update_interval() - read the sensor update interval +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @interval - resulting update interval in miliseconds +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_read_update_interval (struct omap_bandgap *bg_ptr,int id, +int *interval) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 time; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + ret =omap_control_readl (cdev, tsr->bgap_counter,&time); +if (ret) +return ret; + time = (time& tsr->counter_mask)>>__ffs (tsr->counter_mask); + time = time *1000 / bg_ptr->clk_rate; + + *interval = time; + +return 0 ; +} + +/** +* omap_bandgap_write_update_interval() - set the update interval +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @interval - desired update interval in miliseconds +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_write_update_interval (struct omap_bandgap *bg_ptr, +int id,u32 interval) +{ + interval = interval * bg_ptr->clk_rate /1000 ; +mutex_lock (&bg_ptr->bg_mutex); +configure_temp_sensor_counter (bg_ptr, id, interval); +mutex_unlock (&bg_ptr->bg_mutex); + +return 0 ; +} + +/** +* omap_bandgap_read_temperature() - report current temperature +* @bg_ptr - pointer to bandgap instance +* @id - sensor id +* @temperature - resulting temperature +* +* returns 0 on success or the proper error code +*/ +int omap_bandgap_read_temperature (struct omap_bandgap *bg_ptr,int id, +int *temperature) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp; +int ret; + + tsr = bg_ptr->pdata->sensors[id].registers; + ret =omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= tsr->bgap_dtemp_mask; + + ret |=adc_to_temp_conversion (bg_ptr, id, temp,&temp); +if (ret) +return -EIO ; + + *temperature = temp; + +return 0 ; +} + +/** +* enable_continuous_mode() - One time enabling of continuous conversion mode +* @bg_ptr - pointer to scm instance +*/ +static int enable_continuous_mode (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +int i, r; +u32 val; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { + tsr = bg_ptr->pdata->sensors[i].registers; + r =omap_control_readl (cdev, tsr->bgap_mode_ctrl,&val); + val |=1 <<__ffs (tsr->mode_ctrl_mask); + r |=omap_control_writel (cdev, val, tsr->bgap_mode_ctrl); +if (r) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return r ? -EIO :0 ; +} + +static int omap_bandgap_tshut_init (struct omap_bandgap *bg_ptr, +struct platform_device *pdev) +{ +int gpio_nr = bg_ptr->tshut_gpio; +int status; + +/* Request for gpio_86 line */ + status =gpio_request (gpio_nr,"tshut" ); +if (status<0 ) { +dev_err (bg_ptr->dev, +"Could not request for TSHUT GPIO:%i\n" ,86 ); +return status; + } + status =gpio_direction_input (gpio_nr); +if (status) { +dev_err (bg_ptr->dev, +"Cannot set input TSHUT GPIO %d\n" , gpio_nr); +return status; + } + + status =request_irq (gpio_to_irq (gpio_nr), + omap_bandgap_tshut_irq_handler, +IRQF_TRIGGER_RISING ,"tshut" , +NULL ); +if (status) { +gpio_free (gpio_nr); +dev_err (bg_ptr->dev,"request irq failed for TSHUT" ); + } + +return 0 ; +} + +static int omap_bandgap_talert_init (struct omap_bandgap *bg_ptr, +struct platform_device *pdev) +{ +int ret; + + bg_ptr->irq =platform_get_irq (pdev,0 ); +if (bg_ptr->irq<0 ) { +dev_err (&pdev->dev,"get_irq failed\n" ); +return bg_ptr->irq; + } + ret =request_threaded_irq (bg_ptr->irq,NULL , + talert_irq_handler, +IRQF_TRIGGER_HIGH |IRQF_ONESHOT , +"talert" , bg_ptr); +if (ret) { +dev_err (&pdev->dev,"Request threaded irq failed.\n" ); +return ret;drivers/thermal/omap-bandgap.c line 1193
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ } + +return 0 ; +} + +static const struct omap_bandgap_data omap4460_data = { + .has_talert = true, + .has_tshut = true, + .fclock_name ="bandgap_ts_fclk" , + .div_ck_name ="div_ts_ck" ,None of these clock data should be there ideally. You should ensure that the proper device alias will be there using clkdev entries.
Except that with DT, it will not work without the clock DT binding :-(
I think Rob posted a latest update based on CCF... but for the moment we are stuck :-(
Quoted 25 lines
drivers/thermal/omap-bandgap.c new file +25
-0+ .conv_table = omap4460_adc_to_temp, + .sensors = { + { + .registers =&omap4460_mpu_temp_sensor_registers, + .ts_data =&omap4460_mpu_temp_sensor_data, + .domain = "cpu", + }, + }, + .sensor_count = 1, +}; + +static const struct omap_bandgap_data omap5430_data = { + .has_talert = true, + .has_tshut = true, + .fclock_name ="ts_clk_div_ck" , + .div_ck_name ="ts_clk_div_ck" , + .conv_table = omap5430_adc_to_temp, + .sensors = { + { + .registers =&omap5430_mpu_temp_sensor_registers, + .ts_data =&omap5430_mpu_temp_sensor_data, + .domain ="cpu" , + }, + { + .registers =&omap5430_gpu_temp_sensor_registers,drivers/thermal/omap-bandgap.c line 1228
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ .ts_data =&omap5430_gpu_temp_sensor_data, + .domain = "gpu", + }, + { + .registers =&omap5430_core_temp_sensor_registers, + .ts_data =&omap5430_core_temp_sensor_data, + .domain = "core", + }, + }, + .sensor_count = 3,It can probably be replaced by a sizeof.
drivers/thermal/omap-bandgap.c line 1238
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+}; + +static const struct of_device_id of_omap_bandgap_match[] = { +/* +* TODO: Add support to 4430 +* { .compatible = "ti,omap4430-bandgap", .data = , }, +*/ + { + .compatible ="ti,omap4460-bandgap" , + .data = (void *)&omap4460_data,No need to cast toward a void *.
Quoted 4 lines
drivers/thermal/omap-bandgap.c new file +4
-0+ }, + { + .compatible = "ti,omap5430-bandgap", + .data = (void *)&omap5430_data,drivers/thermal/omap-bandgap.c line 1252
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ }, +/* Sentinel */ + { }, +}; + +static struct omap_bandgap *omap_bandgap_build (struct platform_device *pdev) +{ +struct device_node *node = pdev->dev.of_node; +const struct of_device_id *of_id; +struct omap_bandgap *bg_ptr;
bg_ptris not a super name.drivers/thermal/omap-bandgap.c line 1259
Quoted 7 lines
drivers/thermal/omap-bandgap.c new file +7
-0+u32 prop; + +/* just for the sake */ +if (!node) { +dev_err (&pdev->dev,"no platform information available\n" ); +return ERR_PTR (-EINVAL ); + }Not needed, just do the
of_match_devicehere directly.drivers/thermal/omap-bandgap.c line 1270
Quoted 11 lines
drivers/thermal/omap-bandgap.c new file +11
-0+ + bg_ptr =devm_kzalloc (&pdev->dev,sizeof (struct omap_bandgap ), +GFP_KERNEL ); +if (!bg_ptr) { +dev_err (&pdev->dev,"Unable to allocate mem for driver ref\n" ); +return ERR_PTR (-ENOMEM ); + } + + of_id =of_match_device (of_omap_bandgap_match,&pdev->dev); +if (of_id) + bg_ptr->pdata = of_id->data;Nit: This is not really pdata anymore, so you should maybe remove the "p" to avoid confusion.
Quoted 26 lines
drivers/thermal/omap-bandgap.c new file +26
-0+ +if (bg_ptr->pdata->has_tshut) { +if (of_property_read_u32 (node,"ti,tshut-gpio" ,&prop)<0 ) { +dev_err (&pdev->dev,"missing tshut gpio in device tree\n" ); +return ERR_PTR (-EINVAL ); + } + bg_ptr->tshut_gpio = prop; +if (!gpio_is_valid (bg_ptr->tshut_gpio)) { +dev_err (&pdev->dev,"invalid gpio for tshut (%d)\n" , + bg_ptr->tshut_gpio); +return ERR_PTR (-EINVAL ); + } + } + +return bg_ptr; +} + +static +int __devinit omap_bandgap_probe (struct platform_device *pdev) +{ +struct device *cdev = pdev->dev.parent; +struct omap_bandgap *bg_ptr; +int clk_rate, ret =0 , i; + +if (!cdev) { +dev_err (&pdev->dev,"no omap control ref in our parent\n" );drivers/thermal/omap-bandgap.c line 1306
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+return -EINVAL ; + } + + bg_ptr =omap_bandgap_build (pdev); +if (IS_ERR_OR_NULL (bg_ptr)) { +dev_err (&pdev->dev,"failed to fetch platform data\n" ); +return PTR_ERR (bg_ptr); + } + +if (bg_ptr->pdata->has_talert) {Nit2: Yeah, in fact instead of pdata, "conf" or "settings" seems to be more representative of what this structure really contain.
Quoted 7 lines
drivers/thermal/omap-bandgap.c new file +7
-0+ ret =omap_bandgap_talert_init (bg_ptr, pdev); +if (ret) { +dev_err (&pdev->dev,"failed to initialize Talert IRQ\n" ); +return ret; + } + } +drivers/thermal/omap-bandgap.c line 1323
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+if (bg_ptr->pdata->has_tshut) { + ret =omap_bandgap_tshut_init (bg_ptr, pdev); +if (ret) { +dev_err (&pdev->dev, +"failed to initialize system tshut IRQ\n" ); + goto free_talert; + } + } + + bg_ptr->fclock =clk_get (NULL , bg_ptr->pdata->fclock_name);That's not good to get a clock without using the local dev alias. But because of lack of clock DT binding yet, I'm not sure we have the choice.
Quoted 43 lines
drivers/thermal/omap-bandgap.c new file +43
-0+ ret =IS_ERR_OR_NULL (bg_ptr->fclock); +if (ret) { +dev_err (&pdev->dev,"failed to request fclock reference\n" ); + goto free_irqs; + } + + bg_ptr->div_clk =clk_get (NULL , bg_ptr->pdata->div_ck_name); + ret =IS_ERR_OR_NULL (bg_ptr->div_clk); +if (ret) { +dev_err (&pdev->dev, +"failed to request div_ts_ck clock ref\n" ); + goto free_irqs; + } + + bg_ptr->conv_table = bg_ptr->pdata->conv_table; +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +u32 val; + + tsr = bg_ptr->pdata->sensors[i].registers; +/* +* check if the efuse has a non-zero value if not +* it is an untrimmed sample and the temperatures +* may not be accurate +*/ + ret =omap_control_readl (cdev, tsr->bgap_efuse,&val); +if (ret || !val) +dev_info (&pdev->dev, +"Non-trimmed BGAP, Temp not accurate\n" ); + } + + clk_rate =clk_round_rate (bg_ptr->div_clk, + bg_ptr->pdata->sensors[0 ].ts_data->max_freq); +if (clk_rate< bg_ptr->pdata->sensors[0 ].ts_data->min_freq || + clk_rate ==0xffffffff ) { + ret = -ENODEV ; + goto put_clks; + } + + ret =clk_set_rate (bg_ptr->div_clk, clk_rate); +if (ret) { +dev_err (&pdev->dev,"Cannot set clock rate\n" ); + goto put_clks;drivers/thermal/omap-bandgap.c line 1376
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ } + + bg_ptr->clk_rate = clk_rate; +clk_enable (bg_ptr->fclock); + +mutex_init (&bg_ptr->bg_mutex); + bg_ptr->dev =&pdev->dev; +platform_set_drvdata (pdev, bg_ptr); + +/* 1 clk cycle */ What does that mean exactly?
Regards,
BenoitQuoted 294 lines
drivers/thermal/omap-bandgap.c new file +225
-0+for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) +configure_temp_sensor_counter (bg_ptr, i,1 ); + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_data *ts_data; + + ts_data = bg_ptr->pdata->sensors[i].ts_data; + +temp_sensor_init_talert_thresholds (bg_ptr, i, + ts_data->t_hot, + ts_data->t_cold); +temp_sensor_configure_tshut_hot (bg_ptr, i, + ts_data->tshut_hot); +temp_sensor_configure_tshut_cold (bg_ptr, i, + ts_data->tshut_cold); + } + +enable_continuous_mode (bg_ptr); + +/* Set .250 seconds time as default counter */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) +configure_temp_sensor_counter (bg_ptr, i, + bg_ptr->clk_rate /4 ); + +/* Every thing is good? Then expose the sensors */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +char *domain; + + domain = bg_ptr->pdata->sensors[i].domain; +if (bg_ptr->pdata->expose_sensor) + bg_ptr->pdata->expose_sensor (bg_ptr, i, domain); + } + +return 0 ; + +put_clks: +clk_disable (bg_ptr->fclock); +clk_put (bg_ptr->fclock); +clk_put (bg_ptr->div_clk); +free_irqs: +free_irq (gpio_to_irq (bg_ptr->tshut_gpio),NULL ); +gpio_free (bg_ptr->tshut_gpio); +free_talert: +free_irq (bg_ptr->irq, bg_ptr); + +return ret; +} + +static +int __devexit omap_bandgap_remove(struct platform_device *pdev) +{ +struct omap_bandgap *bg_ptr =platform_get_drvdata (pdev); + +clk_disable (bg_ptr->fclock); +clk_put (bg_ptr->fclock); +clk_put (bg_ptr->div_clk); +free_irq (bg_ptr->irq, bg_ptr); +free_irq (gpio_to_irq (bg_ptr->tshut_gpio),NULL ); +gpio_free (bg_ptr->tshut_gpio); + +return 0 ; +} + +#ifdef CONFIG_PM +static int omap_bandgap_save_ctxt (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +int err =0 ; +int i; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +struct temp_sensor_regval *rval; + + rval = bg_ptr->pdata->sensors[i].regval; + tsr = bg_ptr->pdata->sensors[i].registers; + + err =omap_control_readl (cdev, tsr->bgap_mode_ctrl, + &rval->bg_mode_ctrl); + err |=omap_control_readl (cdev, tsr->bgap_mask_ctrl, + &rval->bg_ctrl); + err |=omap_control_readl (cdev, tsr->bgap_counter, + &rval->bg_counter); + err |=omap_control_readl (cdev, tsr->bgap_threshold, + &rval->bg_threshold); + err |=omap_control_readl (cdev, tsr->tshut_threshold, + &rval->tshut_threshold); + +if (err) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return err ? -EIO :0 ; +} + +static int +omap_bandgap_force_single_read (struct omap_bandgap *bg_ptr,int id) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp =0 , counter =1000 ; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; +/* Select single conversion mode */ + err =omap_control_readl (cdev, tsr->bgap_mode_ctrl,&temp); + temp&= ~(1 <<__ffs (tsr->mode_ctrl_mask)); +omap_control_writel (cdev, temp, tsr->bgap_mode_ctrl); + +/* Start of Conversion = 1 */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp |=1 <<__ffs (tsr->bgap_soc_mask); +omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); +/* Wait until DTEMP is updated */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= (tsr->bgap_dtemp_mask); +while ((temp ==0 )&& --counter) { + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= (tsr->bgap_dtemp_mask); + } +/* Start of Conversion = 0 */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= ~(1 <<__ffs (tsr->bgap_soc_mask)); + err |=omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); + +return err ? -EIO :0 ; +} + +static int omap_bandgap_restore_ctxt (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +int i, err =0 ; +u32 temp =0 ; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +struct temp_sensor_regval *rval; +u32 val; + + rval = bg_ptr->pdata->sensors[i].regval; + tsr = bg_ptr->pdata->sensors[i].registers; + + err =omap_control_readl (cdev, tsr->bgap_counter,&val); +if (val ==0 ) { + err |=omap_control_writel (cdev, rval->bg_threshold, + tsr->bgap_threshold); + err |=omap_control_writel (cdev, rval->tshut_threshold, + tsr->tshut_threshold); +/* Force immediate temperature measurement and update +* of the DTEMP field +*/ +omap_bandgap_force_single_read (bg_ptr, i); + err |=omap_control_writel (cdev, rval->bg_counter, + tsr->bgap_counter); + err |=omap_control_writel (cdev, rval->bg_mode_ctrl, + tsr->bgap_mode_ctrl); + err |=omap_control_writel (cdev, rval->bg_ctrl, + tsr->bgap_mask_ctrl); + }else { + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl, + &temp); + temp&= (tsr->bgap_dtemp_mask); +if (temp ==0 ) { +omap_bandgap_force_single_read (bg_ptr, i); + err |=omap_control_readl (cdev, + tsr->bgap_mask_ctrl, + &temp); + temp |=1 <<__ffs (tsr->mode_ctrl_mask); + err |=omap_control_writel (cdev, temp, + tsr->bgap_mask_ctrl); + } + } +if (err) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return err ? -EIO :0 ; +} + +static int omap_bandgap_suspend (struct device *dev) +{ +struct omap_bandgap *bg_ptr =dev_get_drvdata (dev); +int err; + + err =omap_bandgap_save_ctxt (bg_ptr); +clk_disable (bg_ptr->fclock); + +return err; +} + +static int omap_bandgap_resume (struct device *dev) +{ +struct omap_bandgap *bg_ptr =dev_get_drvdata (dev); + +clk_enable (bg_ptr->fclock); + +return omap_bandgap_restore_ctxt (bg_ptr); +} +static const struct dev_pm_ops omap_bandgap_dev_pm_ops = { +SET_SYSTEM_SLEEP_PM_OPS (omap_bandgap_suspend, + omap_bandgap_resume) +}; + +#define DEV_PM_OPS (&omap_bandgap_dev_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif + +static struct platform_driver omap_bandgap_sensor_driver = { + .probe = omap_bandgap_probe, + .remove = omap_bandgap_remove, + .driver = { + .name ="omap-bandgap" , + .pm =DEV_PM_OPS , + .of_match_table = of_omap_bandgap_match, + }, +}; + +module_platform_driver (omap_bandgap_sensor_driver); +early_platform_init ("early_omap_temperature" ,&omap_bandgap_sensor_driver); + +MODULE_DESCRIPTION ("OMAP4+ bandgap temperature sensor driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_ALIAS ("platform:omap-bandgap" ); +MODULE_AUTHOR ("Texas Instrument Inc." );drivers/thermal/omap-bandgap.h new file +63
-0@@ -0,0 +1,63 @@ +/* +* OMAP4 Bandgap temperature sensor driver +* +* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +* Contact: +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ +#ifndef __OMAP_BANDGAP_H +#define __OMAP_BANDGAP_H + +struct omap_bandgap_data ; + +/** +* struct omap_bandgap - bandgap device structure +* @dev: device pointer +* @pdata: platform data with sensor data +* @fclock: pointer to functional clock of temperature sensor +* @div_clk: pointer to parent clock of temperature sensor fclk +* @conv_table: Pointer to adc to temperature conversion table +* @bg_mutex: Mutex for sysfs, irq and PM +* @irq: MPU Irq number for thermal alert +* @tshut_gpio: GPIO where Tshut signal is routed +* @clk_rate: Holds current clock rate +*/ +struct omap_bandgap { +struct device *dev; +const struct omap_bandgap_data *pdata; +struct clk *fclock; +struct clk *div_clk; +const int *conv_table; +struct mutex bg_mutex;/* Mutex for irq and PM */ +int irq; +int tshut_gpio; +u32 clk_rate; +}; + +int omap_bandgap_read_thot (struct omap_bandgap *bg_ptr,int id,int *thot); +int omap_bandgap_write_thot (struct omap_bandgap *bg_ptr,int id,int val); +int omap_bandgap_read_tcold (struct omap_bandgap *bg_ptr,int id,int *tcold); +int omap_bandgap_write_tcold (struct omap_bandgap *bg_ptr,int id,int val); +int omap_bandgap_read_update_interval (struct omap_bandgap *bg_ptr,int id, +int *interval); +int omap_bandgap_write_update_interval (struct omap_bandgap *bg_ptr,int id, +u32 interval); +int omap_bandgap_read_temperature (struct omap_bandgap *bg_ptr,int id, +int *temperature); + +#endif
RFC PATCH 9/11 ARM: OMAP4+: thermal: introduce bandgap temperature sensor
In reply to Cousson, BenoitHello again,
Quoted 1 line · Cousson Benoit
On 5/25/2012 10:25 AM, Eduardo Valentin wrote:
<big cut>
Quoted 9 lines
drivers/thermal/omap-bandgap.c line 1193
Quoted 6 lines
drivers/thermal/omap-bandgap.c new file +6
-0+ +static const struct omap_bandgap_data omap4460_data = { + .has_talert = true, + .has_tshut = true, + .fclock_name ="bandgap_ts_fclk" , + .div_ck_name ="div_ts_ck" ,None of these clock data should be there ideally. You should ensure that the proper device alias will be there using clkdev entries.
In fact, it is a shame that it would be needed to have this entries there :-(
Quoted 5 lines
Except that with DT, it will not work without the clock DT binding :-(
I think Rob posted a latest update based on CCF... but for the moment we are stuck :-(
OK. But would it work for BG as well as it seams to be a special case?
Quoted 30 lines
Quoted 30 lines
drivers/thermal/omap-bandgap.c new file +29
-0+ .conv_table = omap4460_adc_to_temp, + .sensors = { + { + .registers =&omap4460_mpu_temp_sensor_registers, + .ts_data =&omap4460_mpu_temp_sensor_data, + .domain = "cpu", + }, + }, + .sensor_count = 1, +}; + +static const struct omap_bandgap_data omap5430_data = { + .has_talert = true, + .has_tshut = true, + .fclock_name ="ts_clk_div_ck" , + .div_ck_name ="ts_clk_div_ck" , + .conv_table = omap5430_adc_to_temp, + .sensors = { + { + .registers =&omap5430_mpu_temp_sensor_registers, + .ts_data =&omap5430_mpu_temp_sensor_data, + .domain ="cpu" , + }, + { + .registers =&omap5430_gpu_temp_sensor_registers, + .ts_data =&omap5430_gpu_temp_sensor_data, + .domain ="gpu" , + }, + {
Quoted 8 lines
drivers/thermal/omap-bandgap.c line 1228
Quoted 6 lines
drivers/thermal/omap-bandgap.c new file +6
-0+ .registers =&omap5430_core_temp_sensor_registers, + .ts_data =&omap5430_core_temp_sensor_data, + .domain = "core", + }, + }, + .sensor_count = 3,It can probably be replaced by a sizeof.
ARRAY_SIZE prob, will check.
Quoted 13 lines
drivers/thermal/omap-bandgap.c line 1238
Quoted 11 lines
drivers/thermal/omap-bandgap.c new file +10
-0+}; + +static const struct of_device_id of_omap_bandgap_match[] = { +/* +* TODO: Add support to 4430 +* { .compatible = "ti,omap4430-bandgap", .data = , }, +*/ + { + .compatible ="ti,omap4460-bandgap" , + .data = (void *)&omap4460_data,No need to cast toward a void *.
In this case, there is a need, because the omap4460_data is const but the .data field isn't. So I need to force it.
Quoted 17 lines
Quoted 5 lines
drivers/thermal/omap-bandgap.c new file +4
-0+ }, + { + .compatible = "ti,omap5430-bandgap", + .data = (void *)&omap5430_data,drivers/thermal/omap-bandgap.c line 1252
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ }, +/* Sentinel */ + { }, +}; + +static struct omap_bandgap *omap_bandgap_build (struct platform_device *pdev) +{ +struct device_node *node = pdev->dev.of_node; +const struct of_device_id *of_id; +struct omap_bandgap *bg_ptr;
bg_ptris not a super name.
Got a better name? Just don't want a long one to avoid code bending at 80th column...
Quoted 10 lines
drivers/thermal/omap-bandgap.c line 1259
Quoted 8 lines
drivers/thermal/omap-bandgap.c new file +7
-0+u32 prop; + +/* just for the sake */ +if (!node) { +dev_err (&pdev->dev,"no platform information available\n" ); +return ERR_PTR (-EINVAL ); + }Not needed, just do the
of_match_devicehere directly.
Indeed...
Quoted 15 lines
drivers/thermal/omap-bandgap.c line 1270
Quoted 12 lines
drivers/thermal/omap-bandgap.c new file +11
-0+ + bg_ptr =devm_kzalloc (&pdev->dev,sizeof (struct omap_bandgap ), +GFP_KERNEL ); +if (!bg_ptr) { +dev_err (&pdev->dev,"Unable to allocate mem for driver ref\n" ); +return ERR_PTR (-ENOMEM ); + } + + of_id =of_match_device (of_omap_bandgap_match,&pdev->dev); +if (of_id) + bg_ptr->pdata = of_id->data;Nit: This is not really pdata anymore, so you should maybe remove the "p" to avoid confusion.
OK...
Quoted 32 lines
Quoted 32 lines
drivers/thermal/omap-bandgap.c new file +31
-0+ +if (bg_ptr->pdata->has_tshut) { +if (of_property_read_u32 (node,"ti,tshut-gpio" ,&prop)<0 ) { +dev_err (&pdev->dev,"missing tshut gpio in device tree\n" ); +return ERR_PTR (-EINVAL ); + } + bg_ptr->tshut_gpio = prop; +if (!gpio_is_valid (bg_ptr->tshut_gpio)) { +dev_err (&pdev->dev,"invalid gpio for tshut (%d)\n" , + bg_ptr->tshut_gpio); +return ERR_PTR (-EINVAL ); + } + } + +return bg_ptr; +} + +static +int __devinit omap_bandgap_probe (struct platform_device *pdev) +{ +struct device *cdev = pdev->dev.parent; +struct omap_bandgap *bg_ptr; +int clk_rate, ret =0 , i; + +if (!cdev) { +dev_err (&pdev->dev,"no omap control ref in our parent\n" ); +return -EINVAL ; + } + + bg_ptr =omap_bandgap_build (pdev); +if (IS_ERR_OR_NULL (bg_ptr)) {
Quoted 8 lines
drivers/thermal/omap-bandgap.c line 1306
Quoted 5 lines
drivers/thermal/omap-bandgap.c new file +5
-0+dev_err (&pdev->dev,"failed to fetch platform data\n" ); +return PTR_ERR (bg_ptr); + } + +if (bg_ptr->pdata->has_talert) {Nit2: Yeah, in fact instead of pdata, "conf" or "settings" seems to be more representative of what this structure really contain.
conf looks good to me.
Quoted 14 lines
Quoted 14 lines
drivers/thermal/omap-bandgap.c new file +13
-0+ ret =omap_bandgap_talert_init (bg_ptr, pdev); +if (ret) { +dev_err (&pdev->dev,"failed to initialize Talert IRQ\n" ); +return ret; + } + } + +if (bg_ptr->pdata->has_tshut) { + ret =omap_bandgap_tshut_init (bg_ptr, pdev); +if (ret) { +dev_err (&pdev->dev, +"failed to initialize system tshut IRQ\n" ); + goto free_talert;
Quoted 8 lines
drivers/thermal/omap-bandgap.c line 1323
Quoted 4 lines
drivers/thermal/omap-bandgap.c new file +4
-0+ } + } + + bg_ptr->fclock =clk_get (NULL , bg_ptr->pdata->fclock_name);That's not good to get a clock without using the local dev alias. But because of lack of clock DT binding yet, I'm not sure we have the choice.
In fact I didn't touch the clk data on purpose and left the clock handling as is. On my side I didn't know how the clock struct would look like with DT, so, I didn't mess with it.
Do you have a reference to check the work in progress for clock DT ?
Quoted 48 lines
Quoted 48 lines
drivers/thermal/omap-bandgap.c new file +47
-0+ ret =IS_ERR_OR_NULL (bg_ptr->fclock); +if (ret) { +dev_err (&pdev->dev,"failed to request fclock reference\n" ); + goto free_irqs; + } + + bg_ptr->div_clk =clk_get (NULL , bg_ptr->pdata->div_ck_name); + ret =IS_ERR_OR_NULL (bg_ptr->div_clk); +if (ret) { +dev_err (&pdev->dev, +"failed to request div_ts_ck clock ref\n" ); + goto free_irqs; + } + + bg_ptr->conv_table = bg_ptr->pdata->conv_table; +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +u32 val; + + tsr = bg_ptr->pdata->sensors[i].registers; +/* +* check if the efuse has a non-zero value if not +* it is an untrimmed sample and the temperatures +* may not be accurate +*/ + ret =omap_control_readl (cdev, tsr->bgap_efuse,&val); +if (ret || !val) +dev_info (&pdev->dev, +"Non-trimmed BGAP, Temp not accurate\n" ); + } + + clk_rate =clk_round_rate (bg_ptr->div_clk, + bg_ptr->pdata->sensors[0 ].ts_data->max_freq); +if (clk_rate< bg_ptr->pdata->sensors[0 ].ts_data->min_freq || + clk_rate ==0xffffffff ) { + ret = -ENODEV ; + goto put_clks; + } + + ret =clk_set_rate (bg_ptr->div_clk, clk_rate); +if (ret) { +dev_err (&pdev->dev,"Cannot set clock rate\n" ); + goto put_clks; + } + + bg_ptr->clk_rate = clk_rate; +clk_enable (bg_ptr->fclock);
Quoted 8 lines
drivers/thermal/omap-bandgap.c line 1376
Quoted 6 lines
drivers/thermal/omap-bandgap.c new file +6
-0+ +mutex_init (&bg_ptr->bg_mutex); + bg_ptr->dev =&pdev->dev; +platform_set_drvdata (pdev, bg_ptr); + +/* 1 clk cycle */ What does that mean exactly?
That's indeed a good question. I guess by default we configure the bandgap to wait only 1 cycle before it goes to the next read round, if in continuous mode.
That should get overwritten when we have, for instance, some policy initialized and changing the update rate based on the temperature level that the sensor is.
These decisions would go under omapXX-thermal.c, BTW. Check my reply on your suggestion for data structure split.
Quoted 290 lines
Regards,
BenoitQuoted 286 lines
drivers/thermal/omap-bandgap.c new file +225
-0+for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) +configure_temp_sensor_counter (bg_ptr, i,1 ); + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_data *ts_data; + + ts_data = bg_ptr->pdata->sensors[i].ts_data; + +temp_sensor_init_talert_thresholds (bg_ptr, i, + ts_data->t_hot, + ts_data->t_cold); +temp_sensor_configure_tshut_hot (bg_ptr, i, + ts_data->tshut_hot); +temp_sensor_configure_tshut_cold (bg_ptr, i, + ts_data->tshut_cold); + } + +enable_continuous_mode (bg_ptr); + +/* Set .250 seconds time as default counter */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) +configure_temp_sensor_counter (bg_ptr, i, + bg_ptr->clk_rate /4 ); + +/* Every thing is good? Then expose the sensors */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +char *domain; + + domain = bg_ptr->pdata->sensors[i].domain; +if (bg_ptr->pdata->expose_sensor) + bg_ptr->pdata->expose_sensor (bg_ptr, i, domain); + } + +return 0 ; + +put_clks: +clk_disable (bg_ptr->fclock); +clk_put (bg_ptr->fclock); +clk_put (bg_ptr->div_clk); +free_irqs: +free_irq (gpio_to_irq (bg_ptr->tshut_gpio),NULL ); +gpio_free (bg_ptr->tshut_gpio); +free_talert: +free_irq (bg_ptr->irq, bg_ptr); + +return ret; +} + +static +int __devexit omap_bandgap_remove(struct platform_device *pdev) +{ +struct omap_bandgap *bg_ptr =platform_get_drvdata (pdev); + +clk_disable (bg_ptr->fclock); +clk_put (bg_ptr->fclock); +clk_put (bg_ptr->div_clk); +free_irq (bg_ptr->irq, bg_ptr); +free_irq (gpio_to_irq (bg_ptr->tshut_gpio),NULL ); +gpio_free (bg_ptr->tshut_gpio); + +return 0 ; +} + +#ifdef CONFIG_PM +static int omap_bandgap_save_ctxt (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +int err =0 ; +int i; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +struct temp_sensor_regval *rval; + + rval = bg_ptr->pdata->sensors[i].regval; + tsr = bg_ptr->pdata->sensors[i].registers; + + err =omap_control_readl (cdev, tsr->bgap_mode_ctrl, + &rval->bg_mode_ctrl); + err |=omap_control_readl (cdev, tsr->bgap_mask_ctrl, + &rval->bg_ctrl); + err |=omap_control_readl (cdev, tsr->bgap_counter, + &rval->bg_counter); + err |=omap_control_readl (cdev, tsr->bgap_threshold, + &rval->bg_threshold); + err |=omap_control_readl (cdev, tsr->tshut_threshold, + &rval->tshut_threshold); + +if (err) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return err ? -EIO :0 ; +} + +static int +omap_bandgap_force_single_read (struct omap_bandgap *bg_ptr,int id) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp =0 , counter =1000 ; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; +/* Select single conversion mode */ + err =omap_control_readl (cdev, tsr->bgap_mode_ctrl,&temp); + temp&= ~(1 <<__ffs (tsr->mode_ctrl_mask)); +omap_control_writel (cdev, temp, tsr->bgap_mode_ctrl); + +/* Start of Conversion = 1 */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp |=1 <<__ffs (tsr->bgap_soc_mask); +omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); +/* Wait until DTEMP is updated */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= (tsr->bgap_dtemp_mask); +while ((temp ==0 )&& --counter) { + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= (tsr->bgap_dtemp_mask); + } +/* Start of Conversion = 0 */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= ~(1 <<__ffs (tsr->bgap_soc_mask)); + err |=omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); + +return err ? -EIO :0 ; +} + +static int omap_bandgap_restore_ctxt (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +int i, err =0 ; +u32 temp =0 ; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +struct temp_sensor_regval *rval; +u32 val; + + rval = bg_ptr->pdata->sensors[i].regval; + tsr = bg_ptr->pdata->sensors[i].registers; + + err =omap_control_readl (cdev, tsr->bgap_counter,&val); +if (val ==0 ) { + err |=omap_control_writel (cdev, rval->bg_threshold, + tsr->bgap_threshold); + err |=omap_control_writel (cdev, rval->tshut_threshold, + tsr->tshut_threshold); +/* Force immediate temperature measurement and update +* of the DTEMP field +*/ +omap_bandgap_force_single_read (bg_ptr, i); + err |=omap_control_writel (cdev, rval->bg_counter, + tsr->bgap_counter); + err |=omap_control_writel (cdev, rval->bg_mode_ctrl, + tsr->bgap_mode_ctrl); + err |=omap_control_writel (cdev, rval->bg_ctrl, + tsr->bgap_mask_ctrl); + }else { + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl, + &temp); + temp&= (tsr->bgap_dtemp_mask); +if (temp ==0 ) { +omap_bandgap_force_single_read (bg_ptr, i); + err |=omap_control_readl (cdev, + tsr->bgap_mask_ctrl, + &temp); + temp |=1 <<__ffs (tsr->mode_ctrl_mask); + err |=omap_control_writel (cdev, temp, + tsr->bgap_mask_ctrl); + } + } +if (err) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return err ? -EIO :0 ; +} + +static int omap_bandgap_suspend (struct device *dev) +{ +struct omap_bandgap *bg_ptr =dev_get_drvdata (dev); +int err; + + err =omap_bandgap_save_ctxt (bg_ptr); +clk_disable (bg_ptr->fclock); + +return err; +} + +static int omap_bandgap_resume (struct device *dev) +{ +struct omap_bandgap *bg_ptr =dev_get_drvdata (dev); + +clk_enable (bg_ptr->fclock); + +return omap_bandgap_restore_ctxt (bg_ptr); +} +static const struct dev_pm_ops omap_bandgap_dev_pm_ops = { +SET_SYSTEM_SLEEP_PM_OPS (omap_bandgap_suspend, + omap_bandgap_resume) +}; + +#define DEV_PM_OPS (&omap_bandgap_dev_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif + +static struct platform_driver omap_bandgap_sensor_driver = { + .probe = omap_bandgap_probe, + .remove = omap_bandgap_remove, + .driver = { + .name ="omap-bandgap" , + .pm =DEV_PM_OPS , + .of_match_table = of_omap_bandgap_match, + }, +}; + +module_platform_driver (omap_bandgap_sensor_driver); +early_platform_init ("early_omap_temperature" ,&omap_bandgap_sensor_driver); + +MODULE_DESCRIPTION ("OMAP4+ bandgap temperature sensor driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_ALIAS ("platform:omap-bandgap" ); +MODULE_AUTHOR ("Texas Instrument Inc." );drivers/thermal/omap-bandgap.h new file +55
-0@@ -0,0 +1,63 @@ +/* +* OMAP4 Bandgap temperature sensor driver +* +* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +* Contact: +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ +#ifndef __OMAP_BANDGAP_H +#define __OMAP_BANDGAP_H + +struct omap_bandgap_data ; + +/** +* struct omap_bandgap - bandgap device structure +* @dev: device pointer +* @pdata: platform data with sensor data +* @fclock: pointer to functional clock of temperature sensor +* @div_clk: pointer to parent clock of temperature sensor fclk +* @conv_table: Pointer to adc to temperature conversion table +* @bg_mutex: Mutex for sysfs, irq and PM +* @irq: MPU Irq number for thermal alert +* @tshut_gpio: GPIO where Tshut signal is routed +* @clk_rate: Holds current clock rate +*/ +struct omap_bandgap { +struct device *dev; +const struct omap_bandgap_data *pdata; +struct clk *fclock; +struct clk *div_clk; +const int *conv_table; +struct mutex bg_mutex;/* Mutex for irq and PM */ +int irq; +int tshut_gpio; +u32 clk_rate; +}; + +int omap_bandgap_read_thot (struct omap_bandgap *bg_ptr,int id,int *thot); +int omap_bandgap_write_thot (struct omap_bandgap *bg_ptr,int id,int val); +int omap_bandgap_read_tcold (struct omap_bandgap *bg_ptr,int id,int *tcold); +int omap_bandgap_write_tcold (struct omap_bandgap *bg_ptr,int id,int val);
Quoted 9 lines
drivers/thermal/omap-bandgap.h line 63
Quoted 8 lines
drivers/thermal/omap-bandgap.h new file +8
-0+int omap_bandgap_read_update_interval (struct omap_bandgap *bg_ptr,int id, +int *interval); +int omap_bandgap_write_update_interval (struct omap_bandgap *bg_ptr,int id, +u32 interval); +int omap_bandgap_read_temperature (struct omap_bandgap *bg_ptr,int id, +int *temperature); + +#endif
---
Eduardo
RFC PATCH 9/11 ARM: OMAP4+: thermal: introduce bandgap temperature sensor
Quoted 66 lines · Eduardo Valentin
Hello again,
Quoted 1 line · Cousson Benoit
On 5/25/2012 10:25 AM, Eduardo Valentin wrote:
<big cut>
Quoted 9 lines
drivers/thermal/omap-bandgap.c line 1193
Quoted 6 lines
drivers/thermal/omap-bandgap.c new file +6
-0+ +static const struct omap_bandgap_data omap4460_data = { + .has_talert = true, + .has_tshut = true, + .fclock_name ="bandgap_ts_fclk" , + .div_ck_name ="div_ts_ck" ,None of these clock data should be there ideally. You should ensure that the proper device alias will be there using clkdev entries.
In fact, it is a shame that it would be needed to have this entries there :-(
Quoted 5 lines
Except that with DT, it will not work without the clock DT binding :-(
I think Rob posted a latest update based on CCF... but for the moment we are stuck :-(
OK. But would it work for BG as well as it seams to be a special case?
Quoted 30 lines
Quoted 30 lines
drivers/thermal/omap-bandgap.c new file +29
-0+ .conv_table = omap4460_adc_to_temp, + .sensors = { + { + .registers =&omap4460_mpu_temp_sensor_registers, + .ts_data =&omap4460_mpu_temp_sensor_data, + .domain = "cpu", + }, + }, + .sensor_count = 1, +}; + +static const struct omap_bandgap_data omap5430_data = { + .has_talert = true, + .has_tshut = true, + .fclock_name ="ts_clk_div_ck" , + .div_ck_name ="ts_clk_div_ck" , + .conv_table = omap5430_adc_to_temp, + .sensors = { + { + .registers =&omap5430_mpu_temp_sensor_registers, + .ts_data =&omap5430_mpu_temp_sensor_data, + .domain ="cpu" , + }, + { + .registers =&omap5430_gpu_temp_sensor_registers, + .ts_data =&omap5430_gpu_temp_sensor_data, + .domain ="gpu" , + }, + {Quoted 8 lines
drivers/thermal/omap-bandgap.c line 1228
Quoted 6 lines
drivers/thermal/omap-bandgap.c new file +6
-0+ .registers =&omap5430_core_temp_sensor_registers, + .ts_data =&omap5430_core_temp_sensor_data, + .domain = "core", + }, + }, + .sensor_count = 3,It can probably be replaced by a sizeof.
Quoted 1 line
ARRAY_SIZEprob, will check.
Ah, yes, that's one... I was looking for it for forgot the name :-)
Quoted 33 lines
Quoted 4 lines
Quoted 4 lines
drivers/thermal/omap-bandgap.c new file +4
-0+}; + +static const struct of_device_id of_omap_bandgap_match[] = { +/* Quoted 8 lines
drivers/thermal/omap-bandgap.c line 1238
Quoted 6 lines
drivers/thermal/omap-bandgap.c new file +6
-0+* TODO: Add support to 4430 +* { .compatible = "ti,omap4430-bandgap", .data = , }, +*/ + { + .compatible = "ti,omap4460-bandgap", + .data = (void *)&omap4460_data,No need to cast toward a void *.
In this case, there is a need, because the
omap4460_datais const but the .data field isn't. So I need to force it.Quoted 17 lines
Quoted 5 lines
drivers/thermal/omap-bandgap.c new file +4
-0+ }, + { + .compatible = "ti,omap5430-bandgap", + .data = (void *)&omap5430_data,drivers/thermal/omap-bandgap.c line 1252
Quoted 10 lines
drivers/thermal/omap-bandgap.c new file +10
-0+ }, +/* Sentinel */ + { }, +}; + +static struct omap_bandgap *omap_bandgap_build (struct platform_device *pdev) +{ +struct device_node *node = pdev->dev.of_node; +const struct of_device_id *of_id; +struct omap_bandgap *bg_ptr;
bg_ptris not a super name.
Quoted 1 line
Got a better name? Just don't want a long one to avoid code bending at 80th column...
My concern was mainly with the _ptr, it looks like a Hungarian notation. :-)...
Maybe bg only? Or omap_bg?
Quoted 98 lines
Quoted 11 lines
drivers/thermal/omap-bandgap.c line 1259
Quoted 9 lines
drivers/thermal/omap-bandgap.c new file +7
-0+u32 prop; + +/* just for the sake */ +if (!node) { +dev_err (&pdev->dev,"no platform information available\n" ); +return ERR_PTR (-EINVAL ); + }Not needed, just do the
of_match_devicehere directly.Indeed...
Quoted 15 lines
drivers/thermal/omap-bandgap.c line 1270
Quoted 12 lines
drivers/thermal/omap-bandgap.c new file +11
-0+ + bg_ptr =devm_kzalloc (&pdev->dev,sizeof (struct omap_bandgap ), +GFP_KERNEL ); +if (!bg_ptr) { +dev_err (&pdev->dev,"Unable to allocate mem for driver ref\n" ); +return ERR_PTR (-ENOMEM ); + } + + of_id =of_match_device (of_omap_bandgap_match,&pdev->dev); +if (of_id) + bg_ptr->pdata = of_id->data;Nit: This is not really pdata anymore, so you should maybe remove the "p" to avoid confusion.
OK...
Quoted 32 lines
Quoted 32 lines
drivers/thermal/omap-bandgap.c new file +31
-0+ +if (bg_ptr->pdata->has_tshut) { +if (of_property_read_u32 (node,"ti,tshut-gpio" ,&prop)<0 ) { +dev_err (&pdev->dev,"missing tshut gpio in device tree\n" ); +return ERR_PTR (-EINVAL ); + } + bg_ptr->tshut_gpio = prop; +if (!gpio_is_valid (bg_ptr->tshut_gpio)) { +dev_err (&pdev->dev,"invalid gpio for tshut (%d)\n" , + bg_ptr->tshut_gpio); +return ERR_PTR (-EINVAL ); + } + } + +return bg_ptr; +} + +static +int __devinit omap_bandgap_probe (struct platform_device *pdev) +{ +struct device *cdev = pdev->dev.parent; +struct omap_bandgap *bg_ptr; +int clk_rate, ret =0 , i; + +if (!cdev) { +dev_err (&pdev->dev,"no omap control ref in our parent\n" ); +return -EINVAL ; + } + + bg_ptr =omap_bandgap_build (pdev); +if (IS_ERR_OR_NULL (bg_ptr)) {Quoted 8 lines
drivers/thermal/omap-bandgap.c line 1306
Quoted 5 lines
drivers/thermal/omap-bandgap.c new file +5
-0+dev_err (&pdev->dev,"failed to fetch platform data\n" ); +return PTR_ERR (bg_ptr); + } + +if (bg_ptr->pdata->has_talert) {Nit2: Yeah, in fact instead of pdata, "conf" or "settings" seems to be more representative of what this structure really contain.
conf looks good to me.
Quoted 14 lines
Quoted 14 lines
drivers/thermal/omap-bandgap.c new file +13
-0+ ret =omap_bandgap_talert_init (bg_ptr, pdev); +if (ret) { +dev_err (&pdev->dev,"failed to initialize Talert IRQ\n" ); +return ret; + } + } + +if (bg_ptr->pdata->has_tshut) { + ret =omap_bandgap_tshut_init (bg_ptr, pdev); +if (ret) { +dev_err (&pdev->dev, +"failed to initialize system tshut IRQ\n" ); + goto free_talert;Quoted 8 lines
drivers/thermal/omap-bandgap.c line 1323
Quoted 4 lines
drivers/thermal/omap-bandgap.c new file +4
-0+ } + } + + bg_ptr->fclock =clk_get (NULL , bg_ptr->pdata->fclock_name);That's not good to get a clock without using the local dev alias. But because of lack of clock DT binding yet, I'm not sure we have the choice.
Quoted 5 lines
In fact I didn't touch the clk data on purpose and left the clock handling as is. On my side I didn't know how the clock struct would look like with DT, so, I didn't mess with it.
Do you have a reference to check the work in progress for clock DT ?
Rob sent a pull request, it seems that now it is up to Mike T. :-)
http://lists-archives.com/linux-kernel/27640907-dt-clk-binding-support.html
Quoted 58 lines
Quoted 49 lines
Quoted 49 lines
drivers/thermal/omap-bandgap.c new file +47
-0+ ret =IS_ERR_OR_NULL (bg_ptr->fclock); +if (ret) { +dev_err (&pdev->dev,"failed to request fclock reference\n" ); + goto free_irqs; + } + + bg_ptr->div_clk =clk_get (NULL , bg_ptr->pdata->div_ck_name); + ret =IS_ERR_OR_NULL (bg_ptr->div_clk); +if (ret) { +dev_err (&pdev->dev, +"failed to request div_ts_ck clock ref\n" ); + goto free_irqs; + } + + bg_ptr->conv_table = bg_ptr->pdata->conv_table; +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +u32 val; + + tsr = bg_ptr->pdata->sensors[i].registers; +/* +* check if the efuse has a non-zero value if not +* it is an untrimmed sample and the temperatures +* may not be accurate +*/ + ret =omap_control_readl (cdev, tsr->bgap_efuse,&val); +if (ret || !val) +dev_info (&pdev->dev, +"Non-trimmed BGAP, Temp not accurate\n" ); + } + + clk_rate =clk_round_rate (bg_ptr->div_clk, + bg_ptr->pdata->sensors[0 ].ts_data->max_freq); +if (clk_rate< bg_ptr->pdata->sensors[0 ].ts_data->min_freq || + clk_rate ==0xffffffff ) { + ret = -ENODEV ; + goto put_clks; + } + + ret =clk_set_rate (bg_ptr->div_clk, clk_rate); +if (ret) { +dev_err (&pdev->dev,"Cannot set clock rate\n" ); + goto put_clks; + } + + bg_ptr->clk_rate = clk_rate; +clk_enable (bg_ptr->fclock);Quoted 8 lines
drivers/thermal/omap-bandgap.c line 1376
Quoted 6 lines
drivers/thermal/omap-bandgap.c new file +6
-0+ +mutex_init (&bg_ptr->bg_mutex); + bg_ptr->dev =&pdev->dev; +platform_set_drvdata (pdev, bg_ptr); + +/* 1 clk cycle */ What does that mean exactly?
Quoted 2 lines
That's indeed a good question. I guess by default we configure the bandgap to wait only 1 cycle before it goes to the next read round, if in continuous mode.
OK, so some more explanation in that comment are maybe required.
Thanks,
Benoit
Quoted 309 lines
That should get overwritten when we have, for instance, some policy initialized and changing the update rate based on the temperature level that the sensor is.
These decisions would go under
omapXX-thermal.c, BTW. Check my reply on your suggestion for data structure split.Quoted 290 lines
Regards,
BenoitQuoted 286 lines
drivers/thermal/omap-bandgap.c new file +225
-0+for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) +configure_temp_sensor_counter (bg_ptr, i,1 ); + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_data *ts_data; + + ts_data = bg_ptr->pdata->sensors[i].ts_data; + +temp_sensor_init_talert_thresholds (bg_ptr, i, + ts_data->t_hot, + ts_data->t_cold); +temp_sensor_configure_tshut_hot (bg_ptr, i, + ts_data->tshut_hot); +temp_sensor_configure_tshut_cold (bg_ptr, i, + ts_data->tshut_cold); + } + +enable_continuous_mode (bg_ptr); + +/* Set .250 seconds time as default counter */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) +configure_temp_sensor_counter (bg_ptr, i, + bg_ptr->clk_rate /4 ); + +/* Every thing is good? Then expose the sensors */ +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +char *domain; + + domain = bg_ptr->pdata->sensors[i].domain; +if (bg_ptr->pdata->expose_sensor) + bg_ptr->pdata->expose_sensor (bg_ptr, i, domain); + } + +return 0 ; + +put_clks: +clk_disable (bg_ptr->fclock); +clk_put (bg_ptr->fclock); +clk_put (bg_ptr->div_clk); +free_irqs: +free_irq (gpio_to_irq (bg_ptr->tshut_gpio),NULL ); +gpio_free (bg_ptr->tshut_gpio); +free_talert: +free_irq (bg_ptr->irq, bg_ptr); + +return ret; +} + +static +int __devexit omap_bandgap_remove(struct platform_device *pdev) +{ +struct omap_bandgap *bg_ptr =platform_get_drvdata (pdev); + +clk_disable (bg_ptr->fclock); +clk_put (bg_ptr->fclock); +clk_put (bg_ptr->div_clk); +free_irq (bg_ptr->irq, bg_ptr); +free_irq (gpio_to_irq (bg_ptr->tshut_gpio),NULL ); +gpio_free (bg_ptr->tshut_gpio); + +return 0 ; +} + +#ifdef CONFIG_PM +static int omap_bandgap_save_ctxt (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +int err =0 ; +int i; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +struct temp_sensor_regval *rval; + + rval = bg_ptr->pdata->sensors[i].regval; + tsr = bg_ptr->pdata->sensors[i].registers; + + err =omap_control_readl (cdev, tsr->bgap_mode_ctrl, + &rval->bg_mode_ctrl); + err |=omap_control_readl (cdev, tsr->bgap_mask_ctrl, + &rval->bg_ctrl); + err |=omap_control_readl (cdev, tsr->bgap_counter, + &rval->bg_counter); + err |=omap_control_readl (cdev, tsr->bgap_threshold, + &rval->bg_threshold); + err |=omap_control_readl (cdev, tsr->tshut_threshold, + &rval->tshut_threshold); + +if (err) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return err ? -EIO :0 ; +} + +static int +omap_bandgap_force_single_read (struct omap_bandgap *bg_ptr,int id) +{ +struct device *cdev = bg_ptr->dev->parent; +struct temp_sensor_registers *tsr; +u32 temp =0 , counter =1000 ; +int err; + + tsr = bg_ptr->pdata->sensors[id].registers; +/* Select single conversion mode */ + err =omap_control_readl (cdev, tsr->bgap_mode_ctrl,&temp); + temp&= ~(1 <<__ffs (tsr->mode_ctrl_mask)); +omap_control_writel (cdev, temp, tsr->bgap_mode_ctrl); + +/* Start of Conversion = 1 */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp |=1 <<__ffs (tsr->bgap_soc_mask); +omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); +/* Wait until DTEMP is updated */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= (tsr->bgap_dtemp_mask); +while ((temp ==0 )&& --counter) { + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= (tsr->bgap_dtemp_mask); + } +/* Start of Conversion = 0 */ + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl,&temp); + temp&= ~(1 <<__ffs (tsr->bgap_soc_mask)); + err |=omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); + +return err ? -EIO :0 ; +} + +static int omap_bandgap_restore_ctxt (struct omap_bandgap *bg_ptr) +{ +struct device *cdev = bg_ptr->dev->parent; +int i, err =0 ; +u32 temp =0 ; + +for (i =0 ; i< bg_ptr->pdata->sensor_count; i++) { +struct temp_sensor_registers *tsr; +struct temp_sensor_regval *rval; +u32 val; + + rval = bg_ptr->pdata->sensors[i].regval; + tsr = bg_ptr->pdata->sensors[i].registers; + + err =omap_control_readl (cdev, tsr->bgap_counter,&val); +if (val ==0 ) { + err |=omap_control_writel (cdev, rval->bg_threshold, + tsr->bgap_threshold); + err |=omap_control_writel (cdev, rval->tshut_threshold, + tsr->tshut_threshold); +/* Force immediate temperature measurement and update +* of the DTEMP field +*/ +omap_bandgap_force_single_read (bg_ptr, i); + err |=omap_control_writel (cdev, rval->bg_counter, + tsr->bgap_counter); + err |=omap_control_writel (cdev, rval->bg_mode_ctrl, + tsr->bgap_mode_ctrl); + err |=omap_control_writel (cdev, rval->bg_ctrl, + tsr->bgap_mask_ctrl); + }else { + err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl, + &temp); + temp&= (tsr->bgap_dtemp_mask); +if (temp ==0 ) { +omap_bandgap_force_single_read (bg_ptr, i); + err |=omap_control_readl (cdev, + tsr->bgap_mask_ctrl, + &temp); + temp |=1 <<__ffs (tsr->mode_ctrl_mask); + err |=omap_control_writel (cdev, temp, + tsr->bgap_mask_ctrl); + } + } +if (err) +dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); + } + +return err ? -EIO :0 ; +} + +static int omap_bandgap_suspend (struct device *dev) +{ +struct omap_bandgap *bg_ptr =dev_get_drvdata (dev); +int err; + + err =omap_bandgap_save_ctxt (bg_ptr); +clk_disable (bg_ptr->fclock); + +return err; +} + +static int omap_bandgap_resume (struct device *dev) +{ +struct omap_bandgap *bg_ptr =dev_get_drvdata (dev); + +clk_enable (bg_ptr->fclock); + +return omap_bandgap_restore_ctxt (bg_ptr); +} +static const struct dev_pm_ops omap_bandgap_dev_pm_ops = { +SET_SYSTEM_SLEEP_PM_OPS (omap_bandgap_suspend, + omap_bandgap_resume) +}; + +#define DEV_PM_OPS (&omap_bandgap_dev_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif + +static struct platform_driver omap_bandgap_sensor_driver = { + .probe = omap_bandgap_probe, + .remove = omap_bandgap_remove, + .driver = { + .name ="omap-bandgap" , + .pm =DEV_PM_OPS , + .of_match_table = of_omap_bandgap_match, + }, +}; + +module_platform_driver (omap_bandgap_sensor_driver); +early_platform_init ("early_omap_temperature" ,&omap_bandgap_sensor_driver); + +MODULE_DESCRIPTION ("OMAP4+ bandgap temperature sensor driver" ); +MODULE_LICENSE ("GPL v2" ); +MODULE_ALIAS ("platform:omap-bandgap" ); +MODULE_AUTHOR ("Texas Instrument Inc." );drivers/thermal/omap-bandgap.h new file +55
-0@@ -0,0 +1,63 @@ +/* +* OMAP4 Bandgap temperature sensor driver +* +* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +* Contact: +* Eduardo Valentin<[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ +#ifndef __OMAP_BANDGAP_H +#define __OMAP_BANDGAP_H + +struct omap_bandgap_data ; + +/** +* struct omap_bandgap - bandgap device structure +* @dev: device pointer +* @pdata: platform data with sensor data +* @fclock: pointer to functional clock of temperature sensor +* @div_clk: pointer to parent clock of temperature sensor fclk +* @conv_table: Pointer to adc to temperature conversion table +* @bg_mutex: Mutex for sysfs, irq and PM +* @irq: MPU Irq number for thermal alert +* @tshut_gpio: GPIO where Tshut signal is routed +* @clk_rate: Holds current clock rate +*/ +struct omap_bandgap { +struct device *dev; +const struct omap_bandgap_data *pdata; +struct clk *fclock; +struct clk *div_clk; +const int *conv_table; +struct mutex bg_mutex;/* Mutex for irq and PM */ +int irq; +int tshut_gpio; +u32 clk_rate; +}; + +int omap_bandgap_read_thot (struct omap_bandgap *bg_ptr,int id,int *thot); +int omap_bandgap_write_thot (struct omap_bandgap *bg_ptr,int id,int val); +int omap_bandgap_read_tcold (struct omap_bandgap *bg_ptr,int id,int *tcold); +int omap_bandgap_write_tcold (struct omap_bandgap *bg_ptr,int id,int val);Quoted 9 lines
drivers/thermal/omap-bandgap.h line 63
Quoted 8 lines
drivers/thermal/omap-bandgap.h new file +8
-0+int omap_bandgap_read_update_interval (struct omap_bandgap *bg_ptr,int id, +int *interval); +int omap_bandgap_write_update_interval (struct omap_bandgap *bg_ptr,int id, +u32 interval); +int omap_bandgap_read_temperature (struct omap_bandgap *bg_ptr,int id, +int *temperature); + +#endif ---
Eduardo
RFC PATCH 9/11 ARM: OMAP4+: thermal: introduce bandgap temperature sensor
Quoted 11 lines · Benoit
Quoted 5 lines · Eduardo Valentin
In fact I didn't touch the clk data on purpose and left the clock handling as is. On my side I didn't know how the clock struct would look like with DT, so, I didn't mess with it.
Do you have a reference to check the work in progress for clock DT ?
Rob sent a pull request, it seems that now it is up to Mike T. :-)
http://lists-archives.com/linux-kernel/27640907-dt-clk-binding-support.html
Due to the on-going discussion around those patches I haven't pulled yet. If everyone agrees once the dust settles then I'll take them in.
Regards,
Mike
RFC PATCH 9/11 ARM: OMAP4+: thermal: introduce bandgap temperature sensor
In reply to Eduardo ValentinHi.
Quoted 17 lines · Eduardo Valentin
In the System Control Module, OMAP supplies a voltage reference and a temperature sensor feature that are gathered in the band gap voltage and temperature sensor (VBGAPTS) module. The band gap provides current and voltage reference for its internal circuits and other analog IP blocks. The analog-to-digital converter (ADC) produces an output value that is proportional to the silicon temperature.
This patch provides a platform driver which expose this feature. It is moduled as a MFD child of the System Control Module core MFD driver.
This driver provides only APIs to access the device properties, like temperature, thresholds and update rate.
Signed-off-by Eduardo Valentin <[email protected]>Signed-off-by Keerthy <[email protected]>
Quoted 12 lines
--- .../devicetree/bindings/thermal/omap_bandgap.txt | 27 + drivers/thermal/Kconfig | 13 + drivers/thermal/Makefile | 4 +- drivers/thermal/omap-bandgap.c | 1601 ++++++++++++++++++++ drivers/thermal/omap-bandgap.h | 63 + 5 files changed, 1707 insertions(+), 1 deletions(-) create mode 100644 Documentation/devicetree/bindings/thermal/omap_bandgap.txt create mode 100644 drivers/thermal/omap-bandgap.c create mode 100644 drivers/thermal/omap-bandgap.h
Add private spin lock in omap-bandgap driver to prevent blocking of control module general registers access.
I wasn't able to test - I have panda 4430 board.
TODO:
Prevent over-usage of spin_lock/spin_unlock for sequential calls of bg_writel().
drivers/mfd/omap-control-core.c +17 -1
@@ -67,6 +67,19 @@ EXPORT_SYMBOL_GPL(omap_control_readl);int omap_control_writel (struct device *dev,u32 val,u32 reg) {struct omap_control *omap_control =dev_get_drvdata (dev); + +if (!omap_control) +return -EINVAL ; + +writel (val, omap_control->base + reg); + +return 0 ; +} +EXPORT_SYMBOL_GPL (omap_control_writel); + +int omap_control_lock_writel (struct device *dev,u32 val,u32 reg) +{ +struct omap_control *omap_control =dev_get_drvdata (dev);unsigned long flags;if (!omap_control)
@@ -78,7 +91,7 @@ int omap_control_writel(struct device *dreturn 0 ; } -EXPORT_SYMBOL_GPL (omap_control_writel); +EXPORT_SYMBOL_GPL (omap_control_lock_writel);/** * omap_control_get: returns the control module device pinter
@@ -136,6 +149,9 @@ static int __devinit omap_control_probe(struct device_node *np = dev->of_node;struct omap_control *omap_control; +printk ("\n\t\t **** omap_control_probe(): enter " ); +dump_stack (); + omap_control =devm_kzalloc (dev,sizeof (*omap_control),GFP_KERNEL );if (!omap_control) {dev_err (dev,"not enough memory for omap_control\n" );
drivers/thermal/omap-bandgap.c +43 -28
199 lines not on this page · raw message
drivers/usb/otg/omap4-usb-phy.c +3 -3
@@ -46,13 +46,13 @@ int omap4_usb_phy_power(struct device *dif (on) { ret =omap_control_readl (dev,CONTROL_DEV_CONF , &val);if (!ret && (val &PHY_PD )) { - ret =omap_control_writel (dev, ~PHY_PD , + ret =omap_control_lock_writel (dev, ~PHY_PD ,CONTROL_DEV_CONF );/* XXX: add proper documentation for this delay */ mdelay (200 ); } }else { - ret =omap_control_writel (dev,PHY_PD ,CONTROL_DEV_CONF ); + ret =omap_control_lock_writel (dev,PHY_PD ,CONTROL_DEV_CONF ); }return ret;
@@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(omap4_usb_phy_power);*/ int omap4_usb_phy_mailbox (struct device *dev,u32 val) { -return omap_control_writel (dev, val,CONTROL_USBOTGHS_CONTROL ); +return omap_control_lock_writel (dev, val,CONTROL_USBOTGHS_CONTROL ); }EXPORT_SYMBOL_GPL (omap4_usb_phy_mailbox);
include/linux/mfd/omap_control.h +6 -0
@@ -43,6 +43,7 @@ struct omap_control {#ifdef CONFIG_MFD_OMAP_CONTROL extern int omap_control_readl (struct device *dev,u32 reg,u32 *val);extern int omap_control_writel (struct device *dev,u32 val,u32 reg); +extern int omap_control_lock_writel (struct device *dev,u32 val,u32 reg);extern struct device *omap_control_get (void );extern void omap_control_put (struct device *dev);#else
@@ -55,6 +56,11 @@ static inline int omap_control_writel(st {return 0 ; } + +static inline int omap_control_lock_writel (struct device *dev,u32 val,u32 reg) +{ +return 0 ; +}static inline struct device *omap_control_get (void ) {
RFC PATCH 9/11 ARM: OMAP4+: thermal: introduce bandgap temperature sensor
Hello Konstantin,
Quoted 31 lines · Konstantin Baydarov
Hi.
Quoted 17 lines · Eduardo Valentin
In the System Control Module, OMAP supplies a voltage reference and a temperature sensor feature that are gathered in the band gap voltage and temperature sensor (VBGAPTS) module. The band gap provides current and voltage reference for its internal circuits and other analog IP blocks. The analog-to-digital converter (ADC) produces an output value that is proportional to the silicon temperature.
This patch provides a platform driver which expose this feature. It is moduled as a MFD child of the System Control Module core MFD driver.
This driver provides only APIs to access the device properties, like temperature, thresholds and update rate.
Signed-off-by Eduardo Valentin <[email protected]>Signed-off-by Keerthy <[email protected]>Quoted 12 lines
--- .../devicetree/bindings/thermal/omap_bandgap.txt | 27 + drivers/thermal/Kconfig | 13 + drivers/thermal/Makefile | 4 +- drivers/thermal/omap-bandgap.c | 1601 ++++++++++++++++++++ drivers/thermal/omap-bandgap.h | 63 + 5 files changed, 1707 insertions(+), 1 deletions(-) create mode 100644 Documentation/devicetree/bindings/thermal/omap_bandgap.txt create mode 100644 drivers/thermal/omap-bandgap.c create mode 100644 drivers/thermal/omap-bandgap.h
Quoted 2 lines
Add private spin lock in omap-bandgap driver to prevent blocking of control module general registers access.
Thanks for sending this out. I will rethink these drivers wrt to locking and will your proposal.
Quoted 1 line
I wasn't able to test - I have panda 4430 board.
Right, we definetly need to have it probing on 4430, I will check how we can close on that.
Quoted 4 lines
TODO:
Prevent over-usage of spin_lock/spin_unlock for sequential calls ofbg_writel().
OK...
Quoted 51 lines
Signed-off-by Konstantin Baydarov <[email protected]>Index:
omap-thermal/drivers/mfd/omap-control-core.c
===================================================================drivers/mfd/omap-control-core.c +17
-1@@ -67,6 +67,19 @@ EXPORT_SYMBOL_GPL(omap_control_readl);int omap_control_writel (struct device *dev,u32 val,u32 reg) {struct omap_control *omap_control =dev_get_drvdata (dev); + +if (!omap_control) +return -EINVAL ; + +writel (val, omap_control->base + reg); + +return 0 ; +} +EXPORT_SYMBOL_GPL (omap_control_writel); + +int omap_control_lock_writel (struct device *dev,u32 val,u32 reg) +{ +struct omap_control *omap_control =dev_get_drvdata (dev);unsigned long flags;if (!omap_control)@@ -78,7 +91,7 @@ int omap_control_writel(struct device *dreturn 0 ; } -EXPORT_SYMBOL_GPL (omap_control_writel); +EXPORT_SYMBOL_GPL (omap_control_lock_writel);/** * omap_control_get: returns the control module device pinter @@ -136,6 +149,9 @@ static int __devinit omap_control_probe(struct device_node *np = dev->of_node;struct omap_control *omap_control; +printk ("\n\t\t **** omap_control_probe(): enter " ); +dump_stack (); + omap_control =devm_kzalloc (dev,sizeof (*omap_control),GFP_KERNEL );if (!omap_control) {dev_err (dev,"not enough memory for omap_control\n" );Index:
omap-thermal/drivers/thermal/omap-bandgap.c
===================================================================
drivers/thermal/omap-bandgap.c struct temp_sensor_registers { · line 157
Quoted 4 lines
drivers/thermal/omap-bandgap.c +1
-0@@ -154,6 +154,7 @@ struct temp_sensor_registers {u32 status_cold_mask;u32 bgap_efuse; +spinlock_t bg_reg_lock;
Indeed. I agree we should have this per sensor. Need to revisit the existing mutex as well though.
Quoted 5 lines
drivers/thermal/omap-bandgap.c +0
-0};/** @@ -579,6 +580,17 @@ omap5430_adc_to_temp[OMAP5430_ADC_END_VA 124600, 124900, 125000, 125000, 125000, 125000,
drivers/thermal/omap-bandgap.c omap5430_adc_to_temp[OMAP5430_ADC_END_VA · line 590
Quoted 10 lines
drivers/thermal/omap-bandgap.c +8
-0}; +static int bg_writel (struct device *dev,u32 val,u32 reg,spinlock_t *lock) +{ +unsigned long flags; +int ret; + +spin_lock_irqsave (lock, flags); + ret =omap_control_writel (dev, val, reg); +spin_unlock_irqrestore (lock, flags);
In fact this doesn't help much in the bulk writes case. As you have already mentioned, ideally we should lock, perform the operation, then unlock, instead of several lock/write/unlock sequences.
Quoted 252 lines
drivers/thermal/omap-bandgap.c +34
-28+return ret; +} +static irqreturn_t talert_irq_handler (int irq,void *data) {struct omap_bandgap *bg_ptr = data;@@ -615,7 +627,7 @@ static irqreturn_t talert_irq_handler(in ctrl |= tsr->mask_hot_mask; } - r |=omap_control_writel (cdev, ctrl, tsr->bgap_mask_ctrl); + r |=bg_writel (cdev, ctrl, tsr->bgap_mask_ctrl, &tsr->bg_reg_lock);if (r) {dev_err (bg_ptr->dev,"failed to ack talert interrupt\n" );@@ -705,7 +717,7 @@ static int temp_sensor_unmask_interrupts reg_val |= tsr->mask_cold_mask; else reg_val &= ~tsr->mask_cold_mask; - err |=omap_control_writel (cdev, reg_val, tsr->bgap_mask_ctrl); + err |=bg_writel (cdev, reg_val, tsr->bgap_mask_ctrl, &tsr->bg_reg_lock);if (err) {dev_err (bg_ptr->dev,"failed to unmask interrupts\n" );@@ -751,14 +763,14 @@ int temp_sensor_configure_thot(struct om/* write the new t_cold value */ reg_val = thresh_val & (~tsr->threshold_tcold_mask); reg_val |= cold <<__ffs (tsr->threshold_tcold_mask); - err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + err |=bg_writel (cdev, reg_val, tsr->bgap_threshold, &tsr->bg_reg_lock); thresh_val = reg_val; }/* write the new t_hot value */ reg_val = thresh_val & ~tsr->threshold_thot_mask; reg_val |= (t_hot <<__ffs (tsr->threshold_thot_mask)); - err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + err |=bg_writel (cdev, reg_val, tsr->bgap_threshold, &tsr->bg_reg_lock);if (err) {dev_err (bg_ptr->dev,"failed to reprogram thot threshold\n" );return -EIO ;@@ -782,7 +794,7 @@ int temp_sensor_init_talert_thresholds(s/* write the new t_cold value */ reg_val = thresh_val & ~tsr->threshold_tcold_mask; reg_val |= (t_cold <<__ffs (tsr->threshold_tcold_mask)); - err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + err |=bg_writel (cdev, reg_val, tsr->bgap_threshold, &tsr->bg_reg_lock);if (err) {dev_err (bg_ptr->dev,"failed to reprogram tcold threshold\n" );return -EIO ;@@ -793,7 +805,7 @@ int temp_sensor_init_talert_thresholds(s/* write the new t_hot value */ reg_val = thresh_val & ~tsr->threshold_thot_mask; reg_val |= (t_hot <<__ffs (tsr->threshold_thot_mask)); - err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + err |=bg_writel (cdev, reg_val, tsr->bgap_threshold, &tsr->bg_reg_lock);if (err) {dev_err (bg_ptr->dev,"failed to reprogram thot threshold\n" );return -EIO ;@@ -802,7 +814,7 @@ int temp_sensor_init_talert_thresholds(s err =omap_control_readl (cdev, tsr->bgap_mask_ctrl, ®_val); reg_val |= tsr->mask_hot_mask; reg_val |= tsr->mask_cold_mask; - err |=omap_control_writel (cdev, reg_val, tsr->bgap_mask_ctrl); + err |=bg_writel (cdev, reg_val, tsr->bgap_mask_ctrl, &tsr->bg_reg_lock);if (err) {dev_err (bg_ptr->dev,"failed to reprogram thot threshold\n" );return -EIO ;@@ -833,14 +845,14 @@ int temp_sensor_configure_tcold(struct o/* write the new t_hot value */ reg_val = thresh_val & (~tsr->threshold_thot_mask); reg_val |= hot <<__ffs (tsr->threshold_thot_mask); - err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + err |=bg_writel (cdev, reg_val, tsr->bgap_threshold, &tsr->bg_reg_lock); thresh_val = reg_val; }/* write the new t_cold value */ reg_val = thresh_val & ~tsr->threshold_tcold_mask; reg_val |= (t_cold <<__ffs (tsr->threshold_tcold_mask)); - err |=omap_control_writel (cdev, reg_val, tsr->bgap_threshold); + err |=bg_writel (cdev, reg_val, tsr->bgap_threshold, &tsr->bg_reg_lock);if (err) {dev_err (bg_ptr->dev,"failed to reprogram tcold threshold\n" );return -EIO ;@@ -861,7 +873,7 @@ static int temp_sensor_configure_tshut_h err =omap_control_readl (cdev, tsr->tshut_threshold, ®_val); reg_val &= ~tsr->tshut_hot_mask; reg_val |= tshut_hot <<__ffs (tsr->tshut_hot_mask); - err |=omap_control_writel (cdev, reg_val, tsr->tshut_threshold); + err |=bg_writel (cdev, reg_val, tsr->tshut_threshold, &tsr->bg_reg_lock);if (err) {dev_err (bg_ptr->dev,"failed to reprogram tshut thot\n" );return -EIO ;@@ -882,7 +894,7 @@ static int temp_sensor_configure_tshut_c err =omap_control_readl (cdev, tsr->tshut_threshold, ®_val); reg_val &= ~tsr->tshut_cold_mask; reg_val |= tshut_cold <<__ffs (tsr->tshut_cold_mask); - err |=omap_control_writel (cdev, reg_val, tsr->tshut_threshold); + err |=bg_writel (cdev, reg_val, tsr->tshut_threshold, &tsr->bg_reg_lock);if (err) {dev_err (bg_ptr->dev,"failed to reprogram tshut tcold\n" );return -EIO ;@@ -903,7 +915,7 @@ static int configure_temp_sensor_counter err =omap_control_readl (cdev, tsr->bgap_counter, &val); val &= ~tsr->counter_mask; val |= counter <<__ffs (tsr->counter_mask); - err |=omap_control_writel (cdev, val, tsr->bgap_counter); + err |=bg_writel (cdev, val, tsr->bgap_counter, &tsr->bg_reg_lock);if (err) {dev_err (bg_ptr->dev,"failed to reprogram tshut tcold\n" );return -EIO ;@@ -1124,7 +1136,7 @@ static int enable_continuous_mode(struct tsr = bg_ptr->pdata->sensors[i].registers; r =omap_control_readl (cdev, tsr->bgap_mode_ctrl, &val); val |=1 <<__ffs (tsr->mode_ctrl_mask); - r |=omap_control_writel (cdev, val, tsr->bgap_mode_ctrl); + r |=bg_writel (cdev, val, tsr->bgap_mode_ctrl, &tsr->bg_reg_lock);if (r)dev_err (bg_ptr->dev,"could not save sensor %d\n" , i); }@@ -1342,6 +1354,9 @@ int __devinit omap_bandgap_probe(structu32 val; tsr = bg_ptr->pdata->sensors[i].registers; +/* Initialize register lock */ +spin_lock_init (&tsr->bg_reg_lock); +/* * check if the efuse has a non-zero value if not * it is an untrimmed sample and the temperatures @@ -1482,12 +1497,12 @@ omap_bandgap_force_single_read(struct om/* Select single conversion mode */ err =omap_control_readl (cdev, tsr->bgap_mode_ctrl, &temp); temp &= ~(1 <<__ffs (tsr->mode_ctrl_mask)); -omap_control_writel (cdev, temp, tsr->bgap_mode_ctrl); +bg_writel (cdev, temp, tsr->bgap_mode_ctrl, &tsr->bg_reg_lock);/* Start of Conversion = 1 */ err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl, &temp); temp |=1 <<__ffs (tsr->bgap_soc_mask); -omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); +bg_writel (cdev, temp, tsr->temp_sensor_ctrl, &tsr->bg_reg_lock);/* Wait until DTEMP is updated */ err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl, &temp); temp &= (tsr->bgap_dtemp_mask);@@ -1498,7 +1513,7 @@ omap_bandgap_force_single_read(struct om/* Start of Conversion = 0 */ err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl, &temp); temp &= ~(1 <<__ffs (tsr->bgap_soc_mask)); - err |=omap_control_writel (cdev, temp, tsr->temp_sensor_ctrl); + err |=bg_writel (cdev, temp, tsr->temp_sensor_ctrl, &tsr->bg_reg_lock);return err ? -EIO :0 ; }@@ -1519,20 +1534,20 @@ static int omap_bandgap_restore_ctxt(str err =omap_control_readl (cdev, tsr->bgap_counter, &val);if (val ==0 ) { - err |=omap_control_writel (cdev, rval->bg_threshold, - tsr->bgap_threshold); - err |=omap_control_writel (cdev, rval->tshut_threshold, - tsr->tshut_threshold); + err |=bg_writel (cdev, rval->bg_threshold, + tsr->bgap_threshold, &tsr->bg_reg_lock); + err |=bg_writel (cdev, rval->tshut_threshold, + tsr->tshut_threshold, &tsr->bg_reg_lock);/* Force immediate temperature measurement and update * of the DTEMP field */ omap_bandgap_force_single_read (bg_ptr, i); - err |=omap_control_writel (cdev, rval->bg_counter, - tsr->bgap_counter); - err |=omap_control_writel (cdev, rval->bg_mode_ctrl, - tsr->bgap_mode_ctrl); - err |=omap_control_writel (cdev, rval->bg_ctrl, - tsr->bgap_mask_ctrl); + err |=bg_writel (cdev, rval->bg_counter, + tsr->bgap_counter, &tsr->bg_reg_lock); + err |=bg_writel (cdev, rval->bg_mode_ctrl, + tsr->bgap_mode_ctrl, &tsr->bg_reg_lock); + err |=bg_writel (cdev, rval->bg_ctrl, + tsr->bgap_mask_ctrl, &tsr->bg_reg_lock); }else { err |=omap_control_readl (cdev, tsr->temp_sensor_ctrl, &temp);@@ -1543,8 +1558,8 @@ static int omap_bandgap_restore_ctxt(str tsr->bgap_mask_ctrl, &temp); temp |=1 <<__ffs (tsr->mode_ctrl_mask); - err |=omap_control_writel (cdev, temp, - tsr->bgap_mask_ctrl); + err |=bg_writel (cdev, temp, + tsr->bgap_mask_ctrl, &tsr->bg_reg_lock); } }if (err)Index:
omap-thermal/drivers/usb/otg/omap4-usb-phy.c
===================================================================drivers/usb/otg/omap4-usb-phy.c +3
-3@@ -46,13 +46,13 @@ int omap4_usb_phy_power(struct device *dif (on) { ret =omap_control_readl (dev,CONTROL_DEV_CONF , &val);if (!ret && (val &PHY_PD )) { - ret =omap_control_writel (dev, ~PHY_PD , + ret =omap_control_lock_writel (dev, ~PHY_PD ,CONTROL_DEV_CONF );/* XXX: add proper documentation for this delay */ mdelay (200 ); } }else { - ret =omap_control_writel (dev,PHY_PD ,CONTROL_DEV_CONF ); + ret =omap_control_lock_writel (dev,PHY_PD ,CONTROL_DEV_CONF ); }return ret;@@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(omap4_usb_phy_power);*/ int omap4_usb_phy_mailbox (struct device *dev,u32 val) { -return omap_control_writel (dev, val,CONTROL_USBOTGHS_CONTROL ); +return omap_control_lock_writel (dev, val,CONTROL_USBOTGHS_CONTROL ); }EXPORT_SYMBOL_GPL (omap4_usb_phy_mailbox);Index:
omap-thermal/include/linux/mfd/omap_control.h
===================================================================include/linux/mfd/omap_control.h +6
-0@@ -43,6 +43,7 @@ struct omap_control {#ifdef CONFIG_MFD_OMAP_CONTROL extern int omap_control_readl (struct device *dev,u32 reg,u32 *val);extern int omap_control_writel (struct device *dev,u32 val,u32 reg); +extern int omap_control_lock_writel (struct device *dev,u32 val,u32 reg);extern struct device *omap_control_get (void );extern void omap_control_put (struct device *dev);#else @@ -55,6 +56,11 @@ static inline int omap_control_writel(st {return 0 ; } + +static inline int omap_control_lock_writel (struct device *dev,u32 val,u32 reg) +{ +return 0 ; +}static inline struct device *omap_control_get (void ) {
Tony Lindgren
maintainerRFC PATCH 9/11 ARM: OMAP4+: thermal: introduce bandgap temperature sensor
In reply to Eduardo ValentinQuoted 8 lines · Eduardo Valentin
In the System Control Module, OMAP supplies a voltage reference and a temperature sensor feature that are gathered in the band gap voltage and temperature sensor (VBGAPTS) module. The band gap provides current and voltage reference for its internal circuits and other analog IP blocks. The analog-to-digital converter (ADC) produces an output value that is proportional to the silicon temperature.
Quoted 6 lines
This patch provides a platform driver which expose this feature. It is moduled as a MFD child of the System Control Module core MFD driver.
This driver provides only APIs to access the device properties, like temperature, thresholds and update rate.
Here too you a better long term solution is probably to ioremap the temp sensor registers for the driver. That way alloc_mem_region() provides some checks so the driver won't stomp over other registers.
If you need to use omap_ctrl_read/write here, then we should at least clearly understand and document why it needs to be done that way instead of following standard ioremap + readl/writel.
Regards,
Tony
RFC PATCH 10/11 omap4: thermal: add basic CPU thermal zone
In reply to Eduardo ValentinThis patch exposes OMAP4 thermal sensor as a thermal zone named "cpu". Only thermal creation is done here.
TODO:
- Add cooling bindings
- Add extrapolation rules
--- drivers/thermal/Kconfig | 12 ++++++ drivers/thermal/Makefile | 1 + drivers/thermal/omap-bandgap.c | 1 + drivers/thermal/omap-bandgap.h | 12 ++++++ drivers/thermal/omap4-thermal.c | 72 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 0 deletions(-) create mode 100644 drivers/thermal/omap4-thermal.c
drivers/thermal/Kconfig +12 -0
@@ -39,3 +39,15 @@ config OMAP_BANDGAP This includes alert interrupts generation and also the TSHUT support. +config OMAP4_THERMAL + bool "Texas Instruments OMAP4 thermal support" + depends on OMAP_BANDGAP + depends on ARCH_OMAP4 + help + If you say yes here you get thermal support for the Texas Instruments + OMAP4 SoC family. The current chip supported are: + - OMAP4460 + + This includes alert interrupts generation and also the TSHUT + support. +
drivers/thermal/Makefile +1 -0
@@ -6,3 +6,4 @@ obj-$(CONFIG_THERMAL) += thermal_sys.o obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal.o omap-thermal-y := omap-bandgap.o +omap-thermal-$(CONFIG_OMAP4_THERMAL) += omap4-thermal.o
drivers/thermal/omap-bandgap.c +1 -0
@@ -1192,6 +1192,7 @@ static const struct omap_bandgap_data omap4460_data = { .fclock_name = "bandgap_ts_fclk", .div_ck_name = "div_ts_ck", .conv_table = omap4460_adc_to_temp, + .expose_sensor = omap4_thermal_expose_sensor, .sensors = { { .registers = &omap4460_mpu_temp_sensor_registers,
drivers/thermal/omap-bandgap.h +12 -0
@@ -60,4 +60,16 @@ int omap_bandgap_write_update_interval(struct omap_bandgap *bg_ptr, int id,int omap_bandgap_read_temperature (struct omap_bandgap *bg_ptr,int id,int *temperature); +#ifdef CONFIG_OMAP4_THERMAL +int omap4_thermal_expose_sensor (struct omap_bandgap *bg_ptr,int id, +char *domain); +#else +static inline int omap4_thermal_expose_sensor (struct omap_bandgap *bg_ptr, +int id,char *domain) +{ +return 0 ; +} + +#endif +#endif
drivers/thermal/omap4-thermal.c new file +72 -0
72 lines not on this page · raw message
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 10/11 omap4: thermal: add basic CPU thermal zone
Quoted 26 lines · Eduardo Valentin
This patch exposes OMAP4 thermal sensor as a thermal zone named "cpu". Only thermal creation is done here.
TODO:
?- Add cooling bindings
?- Add extrapolation rulesSigned-off-by Eduardo Valentin <[email protected]>---
?drivers/thermal/Kconfig ? ? ? ? | ? 12 ++++++ ?drivers/thermal/Makefile ? ? ? ?| ? ?1 + ?drivers/thermal/omap-bandgap.c ?| ? ?1 + ?drivers/thermal/omap-bandgap.h ?| ? 12 ++++++ ?drivers/thermal/omap4-thermal.c | ? 72 +++++++++++++++++++++++++++++++++++++++?5 files changed, 98 insertions(+), 0 deletions(-) ?create mode 100644
drivers/thermal/omap4-thermal.cdrivers/thermal/Kconfig +0
-0@@ -39,3 +39,15 @@ config OMAP_BANDGAP? ? ? ? ?This includes alert interrupts generation and also the TSHUT ? ? ? ? ?support.
drivers/thermal/Kconfig
Quoted 9 lines
drivers/thermal/Kconfig +9
-0+config OMAP4_THERMAL + ? ? ? bool "Texas Instruments OMAP4 thermal support" + ? ? ? depends on OMAP_BANDGAP + ? ? ? depends on ARCH_OMAP4 + ? ? ? help + ? ? ? ? If you say yes here you get thermal support for the Texas Instruments + ? ? ? ? OMAP4 SoC family. The current chip supported are: + ? ? ? ? ?- OMAP4460 +
It's more of IP feature than OMAP specific, so something like
config HAVE_BANDGAP_THERMAL_SUPPORT
and then let processor's which support enable it. That OMAP varients in AMXX etc if needed can make use of it.
If you agree, then rest of the driver also can be cleaned to avoid omap_* in file names and variables.
Apart from this minor comment, rest of the patch looks fine to me.
Regards
Santosh
RFC PATCH 10/11 omap4: thermal: add basic CPU thermal zone
Hi,
Quoted 39 lines · Santosh
Quoted 26 lines · Eduardo Valentin
This patch exposes OMAP4 thermal sensor as a thermal zone named "cpu". Only thermal creation is done here.
TODO:
?- Add cooling bindings
?- Add extrapolation rulesSigned-off-by Eduardo Valentin <[email protected]>---
?drivers/thermal/Kconfig ? ? ? ? | ? 12 ++++++ ?drivers/thermal/Makefile ? ? ? ?| ? ?1 + ?drivers/thermal/omap-bandgap.c ?| ? ?1 + ?drivers/thermal/omap-bandgap.h ?| ? 12 ++++++ ?drivers/thermal/omap4-thermal.c | ? 72 +++++++++++++++++++++++++++++++++++++++?5 files changed, 98 insertions(+), 0 deletions(-) ?create mode 100644
drivers/thermal/omap4-thermal.cdrivers/thermal/Kconfig +0
-0@@ -39,3 +39,15 @@ config OMAP_BANDGAP? ? ? ? ?This includes alert interrupts generation and also the TSHUT ? ? ? ? ?support.
drivers/thermal/Kconfig
Quoted 9 lines
drivers/thermal/Kconfig +9
-0+config OMAP4_THERMAL + ? ? ? bool "Texas Instruments OMAP4 thermal support" + ? ? ? depends on OMAP_BANDGAP + ? ? ? depends on ARCH_OMAP4 + ? ? ? help + ? ? ? ? If you say yes here you get thermal support for the Texas Instruments + ? ? ? ? OMAP4 SoC family. The current chip supported are: + ? ? ? ? ?- OMAP4460 +It's more of IP feature than OMAP specific, so something like
Quoted 4 lines
config
HAVE_BANDGAP_THERMAL_SUPPORTand then let processor's which support enable it. That OMAP varients in AMXX etc if needed can make use of it.
Those are just an OMAP in disguise.
Quoted 4 lines
If you agree, then rest of the driver also can be cleaned to avoid omap_* in file names and variables.
Apart from this minor comment, rest of the patch looks fine to me.
Then it will appear as a fully generic bandgap driver, which is not the case. This is really a TI thing, right ?
Signature · 8 lines
balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120528/077cf771/attachment-0001.sig>
RFC PATCH 10/11 omap4: thermal: add basic CPU thermal zone
Hello Santosh,
Quoted 49 lines · Felipe Balbi
Hi,
Quoted 39 lines · Santosh
Quoted 26 lines · Eduardo Valentin
This patch exposes OMAP4 thermal sensor as a thermal zone named "cpu". Only thermal creation is done here.
TODO:
?- Add cooling bindings
?- Add extrapolation rulesSigned-off-by Eduardo Valentin <[email protected]>---
?drivers/thermal/Kconfig ? ? ? ? | ? 12 ++++++ ?drivers/thermal/Makefile ? ? ? ?| ? ?1 + ?drivers/thermal/omap-bandgap.c ?| ? ?1 + ?drivers/thermal/omap-bandgap.h ?| ? 12 ++++++ ?drivers/thermal/omap4-thermal.c | ? 72 +++++++++++++++++++++++++++++++++++++++?5 files changed, 98 insertions(+), 0 deletions(-) ?create mode 100644
drivers/thermal/omap4-thermal.cdrivers/thermal/Kconfig +0
-0@@ -39,3 +39,15 @@ config OMAP_BANDGAP? ? ? ? ?This includes alert interrupts generation and also the TSHUT ? ? ? ? ?support.
drivers/thermal/Kconfig
Quoted 9 lines
drivers/thermal/Kconfig +9
-0+config OMAP4_THERMAL + ? ? ? bool "Texas Instruments OMAP4 thermal support" + ? ? ? depends on OMAP_BANDGAP + ? ? ? depends on ARCH_OMAP4 + ? ? ? help + ? ? ? ? If you say yes here you get thermal support for the Texas Instruments + ? ? ? ? OMAP4 SoC family. The current chip supported are: + ? ? ? ? ?- OMAP4460 +It's more of IP feature than OMAP specific, so something like
Quoted 4 lines
config ?HAVE_BANDGAP_THERMAL_SUPPORT
and then let processor's which support enable it. That OMAP varients in AMXX etc if needed can make use of it.
Those are just an OMAP in disguise.
Quoted 7 lines
Quoted 4 lines
If you agree, then rest of the driver also can be cleaned to avoid omap_* in file names and variables.
Apart from this minor comment, rest of the patch looks fine to me.
Then it will appear as a fully generic bandgap driver, which is not the case. This is really a TI thing, right ?
I have to agree with Felipe here. I do see your point to have a name which is applicable to AMxx, but having such generic naming is not helping either :-( as this bandgap driver is not supposed to be generic.
I though of "ti_bandgap.*", but still seams to be misleading..
I guess same applies to usb_phy and scm.
Again, if you have a name that fits better I won't hesitate to use it :-)
Quoted 3 lines
--
balbi
Signature · 1 line
Eduardo Valentin
RFC PATCH 10/11 omap4: thermal: add basic CPU thermal zone
Quoted 60 lines · Eduardo
Hello Santosh,
Quoted 49 lines · Felipe Balbi
Hi,
Quoted 39 lines · Santosh
Quoted 25 lines · Eduardo Valentin
This patch exposes OMAP4 thermal sensor as a thermal zone named "cpu". Only thermal creation is done here.
TODO:
- Add cooling bindings
- Add extrapolation rulesSigned-off-by Eduardo Valentin<[email protected]>--- drivers/thermal/Kconfig | 12 ++++++ drivers/thermal/Makefile | 1 + drivers/thermal/omap-bandgap.c | 1 + drivers/thermal/omap-bandgap.h | 12 ++++++ drivers/thermal/omap4-thermal.c | 72 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 0 deletions(-)create mode 100644
drivers/thermal/omap4-thermal.cdrivers/thermal/Kconfig +0
-0@@ -39,3 +39,15 @@ config OMAP_BANDGAP This includes alert interrupts generation and also the TSHUT support.drivers/thermal/Kconfig config OMAP_BANDGAP · line 50
Quoted 10 lines
drivers/thermal/Kconfig +9
-0+config OMAP4_THERMAL + bool "Texas Instruments OMAP4 thermal support" + depends on OMAP_BANDGAP + depends on ARCH_OMAP4 + help + If you say yes here you get thermal support for the Texas Instruments + OMAP4 SoC family. The current chip supported are: + - OMAP4460 +It's more of IP feature than OMAP specific, so something like
Quoted 4 lines
config
HAVE_BANDGAP_THERMAL_SUPPORTand then let processor's which support enable it. That OMAP varients in AMXX etc if needed can make use of it.
Those are just an OMAP in disguise.
Quoted 7 lines
Quoted 4 lines
If you agree, then rest of the driver also can be cleaned to avoid omap_* in file names and variables.
Apart from this minor comment, rest of the patch looks fine to me.
Then it will appear as a fully generic bandgap driver, which is not the case. This is really a TI thing, right ?
Quoted 6 lines
I have to agree with Felipe here. I do see your point to have a name which is applicable to AMxx, but having such generic naming is not helping either :-( as this bandgap driver is not supposed to be generic.
I though of "ti_bandgap.*", but still seams to be misleading..
Yeah, I guess omap_bandgap is good enough. This issues is mainly due to the version in OMAP4 for my point of view.
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
In reply to Eduardo ValentinThis patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
--- arch/arm/boot/dts/omap4.dtsi | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
arch/arm/boot/dts/omap4.dtsi +13 -0
@@ -272,5 +272,18 @@ ti,hwmods = "mmc5"; ti,needs-special-reset; }; + + ctrl_module_core: ctrl_module_core at 4a002000 { + compatible = "ti,omap4-control"; + ti,hwmods = "ctrl_module_core"; + bandgap { + compatible = "ti,omap4460-bandgap"; + interrupts = <0 126 4>; /* talert */ + ti,tshut-gpio = <86>; /* tshut */ + }; + usb { + compatible = "ti,omap4-usb-phy"; + }; + }; }; };
Signature · 1 line
1.7.7.1.488.ge8e1c
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Hi, Eduardo.
Quoted 15 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
Signed-off-by Eduardo Valentin <[email protected]>--- arch/arm/boot/dts/omap4.dtsi | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)arch/arm/boot/dts/omap4.dtsi +0
-0@@ -272,5 +272,18 @@ ti,hwmods = "mmc5"; ti,needs-special-reset;
arch/arm/boot/dts/omap4.dtsi line 283
Quoted 10 lines
arch/arm/boot/dts/omap4.dtsi +9
-0}; + + ctrl_module_core: ctrl_module_core at 4a002000 { + compatible = "ti,omap4-control"; + ti,hwmods = "ctrl_module_core"; + bandgap { + compatible = "ti,omap4460-bandgap"; + interrupts = <0 126 4>; /* talert */ + ti,tshut-gpio = <86>; /* tshut */ + };
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
BR,
Konstantin Baydarov.
Quoted 6 lines
arch/arm/boot/dts/omap4.dtsi +4
-0+ usb { + compatible = "ti,omap4-usb-phy"; + }; + }; }; };
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Quoted 21 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 18 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
Signed-off-by Eduardo Valentin<[email protected]>--- arch/arm/boot/dts/omap4.dtsi | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)arch/arm/boot/dts/omap4.dtsi +2
-0@@ -272,5 +272,18 @@ ti,hwmods = "mmc5"; ti,needs-special-reset; }; + + ctrl_module_core: ctrl_module_core at 4a002000 {
Quoted 8 lines
arch/arm/boot/dts/omap4.dtsi line 283
Quoted 7 lines
arch/arm/boot/dts/omap4.dtsi +7
-0+ compatible = "ti,omap4-control"; + ti,hwmods = "ctrl_module_core"; + bandgap { + compatible = "ti,omap4460-bandgap"; + interrupts =<0 126 4>; /* talert */ + ti,tshut-gpio =<86>; /* tshut */ + };I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Regards,
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Quoted 31 lines · Benoit
Quoted 21 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 18 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
Signed-off-by Eduardo Valentin<[email protected]>--- arch/arm/boot/dts/omap4.dtsi | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)arch/arm/boot/dts/omap4.dtsi +2
-0@@ -272,5 +272,18 @@ ti,hwmods = "mmc5"; ti,needs-special-reset; }; + + ctrl_module_core: ctrl_module_core at 4a002000 {Quoted 8 lines
arch/arm/boot/dts/omap4.dtsi line 283
Quoted 7 lines
arch/arm/boot/dts/omap4.dtsi +7
-0+ compatible = "ti,omap4-control"; + ti,hwmods = "ctrl_module_core"; + bandgap { + compatible = "ti,omap4460-bandgap"; + interrupts =<0 126 4>; /* talert */ + ti,tshut-gpio =<86>; /* tshut */ + };I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Quoted 1 line
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file. omap4.dtsi is a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file. Another solution is to determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" in omap4.dtsi should be replaced to "ti,omap4-bandgap".
BR,
Konstantin Baydarov.
Quoted 2 lines
Regards,
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Quoted 7 lines · Konstantin Baydarov
Quoted 6 lines · Benoit
Quoted 5 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 2 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
...
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file.
omap4.dtsiis a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.
OK, I got your point, but in that case we could potentially define a omap4460.dtsi file.
Quoted 4 lines
Another solution is to
determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" inomap4.dtsishould be replaced to "ti,omap4-bandgap".
Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
The IP_REVISION (offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.
The bitfield layout in that register is:
IP_REV_MAJOR: 8..10IP_REV_CUSTOM: 6..7IP_REV_MINOR: 0..5
Regards,
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Hi.
Quoted 31 lines · Benoit
Quoted 7 lines · Konstantin Baydarov
Quoted 6 lines · Benoit
Quoted 5 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 2 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
...
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file.
omap4.dtsiis a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.OK, I got your point, but in that case we could potentially define a
omap4460.dtsifile.Quoted 4 lines
Another solution is to
determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" inomap4.dtsishould be replaced to "ti,omap4-bandgap".Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
Quoted 7 lines
The
IP_REVISION(offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.The bitfield layout in that register is:
IP_REV_MAJOR: 8..10IP_REV_CUSTOM: 6..7IP_REV_MINOR: 0..5
Probably, cpu_is_omap443x() and cpu_is_omap446x() can be used in bandgap driver probe function. Actually many drivers use cpu_is_omap*():drivers/mfd/omap-usb-host.cdrivers/mfd/twl-core.c
BR,
Konstantin Baydarov.
Quoted 3 lines
Regards,
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Quoted 33 lines · Konstantin Baydarov
Hi.Quoted 31 lines · Benoit
Quoted 7 lines · Konstantin Baydarov
Quoted 6 lines · Benoit
Quoted 5 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 2 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
...
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file.
omap4.dtsiis a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.OK, I got your point, but in that case we could potentially define a
omap4460.dtsifile.Quoted 4 lines
Another solution is to
determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" inomap4.dtsishould be replaced to "ti,omap4-bandgap".Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
Quoted 8 lines
Quoted 7 lines
The
IP_REVISION(offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.The bitfield layout in that register is:
IP_REV_MAJOR: 8..10IP_REV_CUSTOM: 6..7IP_REV_MINOR: 0..5Probably,
cpu_is_omap443x()andcpu_is_omap446x()can be used in bandgap driver probe function. Actually many drivers use cpu_is_omap*():
No, we cannot, we are in the process of getting rid of that. A driver should only focus on the IP version in theory. The CPU version is not the proper way of getting that. It will make the driver not scalable at all for future OMAP revision.
Quoted 2 lines
drivers/mfd/omap-usb-host.cdrivers/mfd/twl-core.c
Yeah, these are the ones that still need to be fixed...
Regards,
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Hello,
Quoted 34 lines · Cousson Benoit
Quoted 33 lines · Konstantin Baydarov
Hi.
Quoted 31 lines · Benoit
Quoted 7 lines · Konstantin Baydarov
Quoted 6 lines · Benoit
Quoted 5 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 2 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
...
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file.
omap4.dtsiis a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.OK, I got your point, but in that case we could potentially define a
omap4460.dtsifile.Quoted 4 lines
Another solution is to
determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" inomap4.dtsishould be replaced to "ti,omap4-bandgap".Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
The
IP_REVISION(offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.The bitfield layout in that register is:
IP_REV_MAJOR: 8..10IP_REV_CUSTOM: 6..7IP_REV_MINOR: 0..5
I have the weird deja vu feeling...
The DT entry I sent, I already knew it would cause troubles :-) Having it per board it would be really a PITA. Image that every body doing a 4430 board needs to define a BG entry... That would work, but still do we want this?
Benoit, I guess you should know my option by now.
Ideally we should rely on revision register to decide what to do in the driver. And as we discussed, looks like for BG this is somewhat non-existing.
If we go with the SCM revision register, what do we do if the BG goes away from SCM?
If we go with "ti,omap4-bandgap", we still need a way to say if it is 4430, 4460 or 4470. There are configuration / settings specific for each. Not only on bandgap, but also wrt to sensor location and hotspot extrapolation rules.
Because we lack a revision register for bandgap, one way to go is to have still the revisioning on the same way: "ti,omapXXXX-bandgap", but having a omapXXXX.dtsi per omap revision. But do we want to this only due to bandgap?
BTW, is it only BG which is suffering of this issue?
Quoted 1 line
Quoted 1 line
Probably,
cpu_is_omap443x()andcpu_is_omap446x()can be used in bandgap driver probe function. Actually many drivers use cpu_is_omap*():
No please! Let's not use that stuff...
Quoted 10 lines
No, we cannot, we are in the process of getting rid of that. A driver should only focus on the IP version in theory. The CPU version is not the proper way of getting that. It will make the driver not scalable at all for future OMAP revision.
Quoted 2 lines
drivers/mfd/omap-usb-host.cdrivers/mfd/twl-core.cYeah, these are the ones that still need to be fixed...
agreed with Benoit here.
Quoted 3 lines
Regards,
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Quoted 39 lines · Eduardo Valentin
Hello,
Quoted 36 lines · Cousson Benoit
Quoted 35 lines · Konstantin Baydarov
Hi.Quoted 33 lines · Benoit
Quoted 7 lines · Konstantin Baydarov
Quoted 6 lines · Benoit
Quoted 5 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 2 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
...
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file.
omap4.dtsiis a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.OK, I got your point, but in that case we could potentially define a
omap4460.dtsifile.Quoted 4 lines
Another solution is to
determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" inomap4.dtsishould be replaced to "ti,omap4-bandgap".Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
The
IP_REVISION(offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.
Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
The bitfield layout in that register is:
IP_REV_MAJOR: 8..10IP_REV_CUSTOM: 6..7IP_REV_MINOR: 0..5I have the weird deja vu feeling...
I know :-)
Quoted 4 lines
The DT entry I sent, I already knew it would cause troubles :-) Having it per board it would be really a PITA. Image that every body doing a 4430 board needs to define a BG entry... That would work, but still do we want this?
No, in fact I do not want to do that if we can avoid it.
Quoted 3 lines
Benoit, I guess you should know my option by now.
Ideally we should rely on revision register to decide what to do in the driver. And as we discussed, looks like for BG this is somewhat non-existing.
Oops, sorry I was thinking about the SCM revision :-(
The register seems to be there with the layout detailed before. I just do not have a clue about the value we should expect. That's why we have to read it on both 4430 and 4460 to check if some bits are different.
Quoted 1 line
If we go with the SCM revision register, what do we do if the BG goes away from SCM?
Yeah, good point.
But, if at some point the BG becomes a real IP with an OCP port, then we will have a TI wrapper on top of it with the proper revision register... at least in theory :-)
Quoted 1 line
If we go with "ti,omap4-bandgap", we still need a way to say if it is 4430, 4460 or 4470.
Yeah, so we should check if at least that SCM revision field is meaningful.
Quoted 2 lines
There are configuration / settings specific for each. Not only on bandgap, but also wrt to sensor location and hotspot extrapolation rules.
Assuming the SCM version is usable we can extract from that some SW revision for each sub IP.
But it is still not clear how the children will be aware of the parent revision :-(
Exported a get_scm_revision is doable potentially.
Quoted 4 lines
Because we lack a revision register for bandgap, one way to go is to have still the revisioning on the same way: "ti,omapXXXX-bandgap", but having a
omapXXXX.dtsiper omap revision. But do we want to this only due to bandgap?
BTW, is it only BG which is suffering of this issue?
Mmm, probably not, that being said, SCM is probably the worst IP we have on OMAP :-)
Regards,
Benoit
Quoted 21 lines
Quoted 1 line
Quoted 1 line
Probably,
cpu_is_omap443x()andcpu_is_omap446x()can be used in bandgap driver probe function. Actually many drivers use cpu_is_omap*():No please! Let's not use that stuff...
Quoted 10 lines
No, we cannot, we are in the process of getting rid of that. A driver should only focus on the IP version in theory. The CPU version is not the proper way of getting that. It will make the driver not scalable at all for future OMAP revision.
Quoted 2 lines
drivers/mfd/omap-usb-host.cdrivers/mfd/twl-core.cYeah, these are the ones that still need to be fixed...
agreed with Benoit here.
Quoted 3 lines
Regards,
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
In reply to Cousson, BenoitHi.
Quoted 31 lines · Benoit
Quoted 7 lines · Konstantin Baydarov
Quoted 6 lines · Benoit
Quoted 5 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 2 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
...
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file.
omap4.dtsiis a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.OK, I got your point, but in that case we could potentially define a
omap4460.dtsifile.Quoted 4 lines
Another solution is to
determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" inomap4.dtsishould be replaced to "ti,omap4-bandgap".Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
Quoted 7 lines
The
IP_REVISION(offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.The bitfield layout in that register is:
IP_REV_MAJOR: 8..10IP_REV_CUSTOM: 6..7IP_REV_MINOR: 0..5
The value of CONTROL_GEN_CORE_REVISION register on my panda board(4430) is:CONTROL_GEN_CORE_REVISION: 0x40000900CONTROL_GEN_CORE_HWINFO: 0x0
Eduardo, could you check CONTROL_GEN_CORE_REVISION on your 4460 board.
BR,
Konstantin Baydarov.
Quoted 3 lines
Regards,
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Hello,
Quoted 38 lines · Konstantin Baydarov
Hi.
Quoted 35 lines · Benoit
Quoted 7 lines · Konstantin Baydarov
Quoted 6 lines · Benoit
Quoted 5 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 2 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
...
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file.
omap4.dtsiis a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.OK, I got your point, but in that case we could potentially define a
omap4460.dtsifile.Quoted 4 lines
Another solution is to
determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" inomap4.dtsishould be replaced to "ti,omap4-bandgap".Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
The
IP_REVISION(offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.The bitfield layout in that register is:
Quoted 8 lines
Quoted 3 lines
IP_REV_MAJOR: 8..10IP_REV_CUSTOM: 6..7IP_REV_MINOR: 0..5The value of
CONTROL_GEN_CORE_REVISIONregister on my panda board(4430) is:CONTROL_GEN_CORE_REVISION:0x40000900CONTROL_GEN_CORE_HWINFO:0x0Eduardo, could you check
CONTROL_GEN_CORE_REVISIONon your 4460 board.
4460:
[root@(none) ~]# omapconf read 0x4A002000
40000A00
[root@(none) ~]# omapconf read 0x4A002004
00000000
4470:
[root@(none) ~]# omapconf read 0x4A002000
40000B00
[root@(none) ~]# omapconf read 0x4A002004
00000000
Quoted 8 lines
BR,
Konstantin Baydarov.Quoted 3 lines
Regards,
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Quoted 56 lines · Eduardo Valentin
Hello,
Quoted 38 lines · Konstantin Baydarov
Hi.Quoted 35 lines · Benoit
Quoted 7 lines · Konstantin Baydarov
Quoted 6 lines · Benoit
Quoted 5 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 2 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
...
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file.
omap4.dtsiis a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.OK, I got your point, but in that case we could potentially define a
omap4460.dtsifile.Quoted 4 lines
Another solution is to
determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" inomap4.dtsishould be replaced to "ti,omap4-bandgap".Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
The
IP_REVISION(offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.The bitfield layout in that register is:
Quoted 8 lines
Quoted 3 lines
IP_REV_MAJOR: 8..10IP_REV_CUSTOM: 6..7IP_REV_MINOR: 0..5The value of
CONTROL_GEN_CORE_REVISIONregister on my panda board(4430) is:CONTROL_GEN_CORE_REVISION:0x40000900CONTROL_GEN_CORE_HWINFO:0x0Eduardo, could you check
CONTROL_GEN_CORE_REVISIONon your 4460 board.4460:
[root@(none) ~]# omapconf read0x4A002000
40000A00
[root@(none) ~]# omapconf read0x4A002004
00000000
Quoted 5 lines
4470:
[root@(none) ~]# omapconf read0x4A002000
40000B00
[root@(none) ~]# omapconf read0x4A002004
00000000
Nice! We do have a cool progression 1 -> 2 -> 3 for each revision. Well at least for the SCM.
Benoit
RFC PATCH 11/11 ARM: DT: Add support to system control module for OMAP4
Hi.
Quoted 63 lines · Benoit
Quoted 56 lines · Eduardo Valentin
Hello,
Quoted 38 lines · Konstantin Baydarov
Hi.Quoted 35 lines · Benoit
Quoted 7 lines · Konstantin Baydarov
Quoted 6 lines · Benoit
Quoted 5 lines · Konstantin Baydarov
Hi, Eduardo.
Quoted 2 lines · Eduardo Valentin
This patch add device tree entries on OMAP4 based boards for System Control Module (SCM).
...
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
I believe that CPU-specific bandgap definition should be moved to bard specific dts.
Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file.
omap4.dtsiis a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.OK, I got your point, but in that case we could potentially define a
omap4460.dtsifile.Quoted 4 lines
Another solution is to
determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" inomap4.dtsishould be replaced to "ti,omap4-bandgap".Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
The
IP_REVISION(offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.The bitfield layout in that register is:
Quoted 8 lines
Quoted 3 lines
IP_REV_MAJOR: 8..10IP_REV_CUSTOM: 6..7IP_REV_MINOR: 0..5The value of
CONTROL_GEN_CORE_REVISIONregister on my panda board(4430) is:CONTROL_GEN_CORE_REVISION:0x40000900CONTROL_GEN_CORE_HWINFO:0x0Eduardo, could you check
CONTROL_GEN_CORE_REVISIONon your 4460 board.4460:
[root@(none) ~]# omapconf read0x4A002000
40000A00
[root@(none) ~]# omapconf read0x4A002004
00000000Quoted 5 lines
4470:
[root@(none) ~]# omapconf read0x4A002000
40000B00
[root@(none) ~]# omapconf read0x4A002004
00000000
Quoted 4 lines
Nice! We do have a cool progression 1 -> 2 -> 3 for each revision. Well at least for the SCM.
Benoit
This patch allows checking of bandgap type dynamically in bandgap driver probe function by reading omap core control module revision register CONTROL_GEN_CORE_REVISION. It lets bandgap module to be defined in common omap4.dtsi, because all cpu specific attributes(irq and tshut number) were moved to driver.
Patch wasn't tested because I have panda 4430 board.
arch/arm/boot/dts/omap4.dtsi +1 -3
@@ -277,9 +277,7 @@ compatible = "ti,omap4-control"; ti,hwmods = "ctrl_module_core"; bandgap { - compatible = "ti,omap4460-bandgap"; - interrupts = <0 126 4>; /* talert */ - ti,tshut-gpio = <86>; /* tshut */ + compatible = "ti,omap4-bandgap"; }; usb { compatible = "ti,omap4-usb-phy";
drivers/thermal/omap-bandgap.c +36 -16
104 lines not on this page · raw message
cover OMAP System Control Module
In reply to Eduardo ValentinHello again,
Quoted 1 line · Eduardo Valentin
Hello Paul and Tony,
FYI, Forgot to mention that these patches are available here:git://gitorious.org/omap-thermal/omap-thermal.git omap_scm_dev
Quoted 148 lines
This is a series of patches adding a basic support for system control module, on OMAP4+ context. It is a working in progress, but I wanted to share already to get your feedback.
I've modeled the driver as an MFD. You will see in this series:
. A rework of the system control module header (patch from Santosh, picked from the list) . Device creation for control module core
. Early device creation for control module core
. The MFD core driver for system control module
. The MFD child for usb-phy pin control
. The MFD child for bandgap sensor
. Very early exposure of OMAP4 thermal zone
. All added drivers are only supporting DT probing
. The series is based on linux-omap master, as it has the hwmod entries for SCM.The overall idea of this series is to put in place the infrastructure. It is not touching nor removing the existing APIs under
mach-omap2/control.cfor now. But the target is to have these APIs moved to the MFD core driver.For early access, like ID checking, I have written the platform driver as an early platform driver and you will see also early device addition and probing under
device.cfor this case. This is of course a proposal. I see that there are people that thing this is a bit of an overkill. Konstantin (CCd) was proposing a simpler solution by having APIs with early_* prefixes, and solve the IO address mapping with a DT entry, for instance. But feel free to propose better ways.This code has been ripped off from the Android 3.1 branch. I have rewritten a couple of things, but the major driver functions and API's entries are kept.
So, based on this series, I see as a TODO list, for system control core driver:
- Start to move all the existing APIs undermach-omap2/control.cto the mfd core.
- Rewrite the users of the existing APIs, mentioned on previous item Once we decide the API and agree on how to deal with early calls.
- Add remaining children (from top of my head, the CAM is one of them, but I also think we should prob have one for HWOBS for instance)
- Test on boards that use the existing APIs.TODO list for bandgap driver:
- Improve thermal zone definition for OMAP4
- Introduce the thermal zones for OMAP5Amit, due to hwmod dep, I didn't include any cooling binding in this series, based on the generic CPU cooling device.
Overall series has been tested only with panda board OMAP4460.
Your comments are welcome.
All best,
Eduardo Valentin (9):
ARM: OMAP: exposecontrol.hto mach area
OMAP: Add early device for system control module
mfd: omap: control: core system control driver
OMAP2+: use control module mfd driver inomap_type
mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
ARM: OMAP4+: Adding the temperature sensor register set bit fields
ARM: OMAP4+: thermal: introduce bandgap temperature sensor
omap4: thermal: add basic CPU thermal zone
ARM: DT: Add support to system control module for OMAP4Kishon Vijay Abraham I (1):
arm: omap: device: create a device for system control moduleSantosh Shilimkar (1):
ARM: OMAP4: Remove un-used control module headers and defines..../devicetree/bindings/mfd/omap_control.txt | 44 + .../devicetree/bindings/thermal/omap_bandgap.txt | 27 + arch/arm/boot/dts/omap4.dtsi | 13 + arch/arm/mach-omap2/Kconfig | 1 + arch/arm/mach-omap2/am35xx-emac.c | 2 +- arch/arm/mach-omap2/board-3430sdp.c | 2 +- arch/arm/mach-omap2/board-4430sdp.c | 2 +- arch/arm/mach-omap2/board-am3517crane.c | 2 +- arch/arm/mach-omap2/board-am3517evm.c | 2 +- arch/arm/mach-omap2/board-apollon.c | 2 +- arch/arm/mach-omap2/board-cm-t3517.c | 2 +- arch/arm/mach-omap2/board-h4.c | 2 +- arch/arm/mach-omap2/board-igep0020.c | 2 +- arch/arm/mach-omap2/board-ldp.c | 2 +- arch/arm/mach-omap2/board-omap3logic.c | 2 +- arch/arm/mach-omap2/board-omap4panda.c | 2 +- arch/arm/mach-omap2/board-omap4pcm049.c | 2 +- arch/arm/mach-omap2/clock2420_data.c | 2 +- arch/arm/mach-omap2/clock2430_data.c | 2 +- arch/arm/mach-omap2/clock3xxx_data.c | 2 +- arch/arm/mach-omap2/clock44xx_data.c | 2 +- arch/arm/mach-omap2/common.c | 2 +- arch/arm/mach-omap2/control.c | 2 +- arch/arm/mach-omap2/cpuidle34xx.c | 2 +- arch/arm/mach-omap2/devices.c | 57 +- arch/arm/mach-omap2/display.c | 2 +- arch/arm/mach-omap2/hsmmc.c | 2 +- arch/arm/mach-omap2/id.c | 18 +- arch/arm/mach-omap2/{ => include/mach}/control.h | 163 ++- .../include/mach/ctrl_module_core_44xx.h | 391 ----- .../include/mach/ctrl_module_pad_core_44xx.h | 1409 ----------------- .../include/mach/ctrl_module_pad_wkup_44xx.h | 236 --- .../include/mach/ctrl_module_wkup_44xx.h | 92 -- arch/arm/mach-omap2/mcbsp.c | 2 +- arch/arm/mach-omap2/mux.c | 2 +- arch/arm/mach-omap2/omap_phy_internal.c | 2 +- arch/arm/mach-omap2/opp3xxx_data.c | 2 +- arch/arm/mach-omap2/opp4xxx_data.c | 2 +- arch/arm/mach-omap2/pm24xx.c | 2 +- arch/arm/mach-omap2/pm34xx.c | 2 +- arch/arm/mach-omap2/prcm.c | 2 +- arch/arm/mach-omap2/serial.c | 2 +- arch/arm/mach-omap2/sleep34xx.S | 2 +- arch/arm/mach-omap2/sr_device.c | 2 +- arch/arm/mach-omap2/usb-fs.c | 2 +- arch/arm/mach-omap2/voltage.c | 2 +- arch/arm/plat-omap/Kconfig | 3 + drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 1 + drivers/mfd/omap-control-core.c | 211 +++ drivers/thermal/Kconfig | 25 + drivers/thermal/Makefile | 5 +- drivers/thermal/omap-bandgap.c | 1602 ++++++++++++++++++++ drivers/thermal/omap-bandgap.h | 75 + drivers/thermal/omap4-thermal.c | 72 + drivers/usb/otg/Kconfig | 13 + drivers/usb/otg/Makefile | 1 + drivers/usb/otg/omap4-usb-phy.c | 130 ++ include/linux/mfd/omap_control.h | 69 + include/linux/usb/omap4_usb_phy.h | 53 + 60 files changed, 2617 insertions(+), 2173 deletions(-) create mode 100644 Documentation/devicetree/bindings/mfd/omap_control.txt create mode 100644 Documentation/devicetree/bindings/thermal/omap_bandgap.txt rename arch/arm/mach-omap2/{ => include/mach}/control.h (75%) delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h create mode 100644 drivers/mfd/omap-control-core.c create mode 100644 drivers/thermal/omap-bandgap.c create mode 100644 drivers/thermal/omap-bandgap.h create mode 100644 drivers/thermal/omap4-thermal.c create mode 100644 drivers/usb/otg/omap4-usb-phy.c create mode 100644 include/linux/mfd/omap_control.h create mode 100644 include/linux/usb/omap4_usb_phy.hSignature · 1 line
1.7.7.1.488.ge8e1c
cover OMAP System Control Module
In reply to Eduardo ValentinHi.
Quoted 21 lines · Eduardo Valentin
Hello Paul and Tony,
This is a series of patches adding a basic support for system control module, on OMAP4+ context. It is a working in progress, but I wanted to share already to get your feedback.
I've modeled the driver as an MFD. You will see in this series:
. A rework of the system control module header (patch from Santosh, picked from the list) . Device creation for control module core
. Early device creation for control module core
. The MFD core driver for system control module
. The MFD child for usb-phy pin control
. The MFD child for bandgap sensor
. Very early exposure of OMAP4 thermal zone
. All added drivers are only supporting DT probing
. The series is based on linux-omap master, as it has the hwmod entries for SCM.The overall idea of this series is to put in place the infrastructure. It is not touching nor removing the existing APIs under
mach-omap2/control.cfor now. But the target is to have these APIs moved to the MFD core driver.
Quoted 7 lines
For early access, like ID checking, I have written the platform driver as an early platform driver and you will see also early device addition and probing under
device.cfor this case. This is of course a proposal. I see that there are people that thing this is a bit of an overkill. Konstantin (CCd) was proposing a simpler solution by having APIs with early_* prefixes, and solve the IO address mapping with a DT entry, for instance. But feel free to propose better ways.
In my latest version I got rid from early API set, check out patch for V3 patch set. I'll attach patch for current version later.
BR,
Konstantin Baydarov.
Quoted 118 lines
This code has been ripped off from the Android 3.1 branch. I have rewritten a couple of things, but the major driver functions and API's entries are kept.
So, based on this series, I see as a TODO list, for system control core driver:
- Start to move all the existing APIs undermach-omap2/control.cto the mfd core.
- Rewrite the users of the existing APIs, mentioned on previous item Once we decide the API and agree on how to deal with early calls.
- Add remaining children (from top of my head, the CAM is one of them, but I also think we should prob have one for HWOBS for instance)
- Test on boards that use the existing APIs.TODO list for bandgap driver:
- Improve thermal zone definition for OMAP4
- Introduce the thermal zones for OMAP5Amit, due to hwmod dep, I didn't include any cooling binding in this series, based on the generic CPU cooling device.
Overall series has been tested only with panda board OMAP4460.
Your comments are welcome.
All best,
Eduardo Valentin (9):
ARM: OMAP: exposecontrol.hto mach area
OMAP: Add early device for system control module
mfd: omap: control: core system control driver
OMAP2+: use control module mfd driver inomap_type
mfd: omap: control: usb-phy: introduce the ctrl-module usb driver
ARM: OMAP4+: Adding the temperature sensor register set bit fields
ARM: OMAP4+: thermal: introduce bandgap temperature sensor
omap4: thermal: add basic CPU thermal zone
ARM: DT: Add support to system control module for OMAP4Kishon Vijay Abraham I (1):
arm: omap: device: create a device for system control moduleSantosh Shilimkar (1):
ARM: OMAP4: Remove un-used control module headers and defines..../devicetree/bindings/mfd/omap_control.txt | 44 + .../devicetree/bindings/thermal/omap_bandgap.txt | 27 + arch/arm/boot/dts/omap4.dtsi | 13 + arch/arm/mach-omap2/Kconfig | 1 + arch/arm/mach-omap2/am35xx-emac.c | 2 +- arch/arm/mach-omap2/board-3430sdp.c | 2 +- arch/arm/mach-omap2/board-4430sdp.c | 2 +- arch/arm/mach-omap2/board-am3517crane.c | 2 +- arch/arm/mach-omap2/board-am3517evm.c | 2 +- arch/arm/mach-omap2/board-apollon.c | 2 +- arch/arm/mach-omap2/board-cm-t3517.c | 2 +- arch/arm/mach-omap2/board-h4.c | 2 +- arch/arm/mach-omap2/board-igep0020.c | 2 +- arch/arm/mach-omap2/board-ldp.c | 2 +- arch/arm/mach-omap2/board-omap3logic.c | 2 +- arch/arm/mach-omap2/board-omap4panda.c | 2 +- arch/arm/mach-omap2/board-omap4pcm049.c | 2 +- arch/arm/mach-omap2/clock2420_data.c | 2 +- arch/arm/mach-omap2/clock2430_data.c | 2 +- arch/arm/mach-omap2/clock3xxx_data.c | 2 +- arch/arm/mach-omap2/clock44xx_data.c | 2 +- arch/arm/mach-omap2/common.c | 2 +- arch/arm/mach-omap2/control.c | 2 +- arch/arm/mach-omap2/cpuidle34xx.c | 2 +- arch/arm/mach-omap2/devices.c | 57 +- arch/arm/mach-omap2/display.c | 2 +- arch/arm/mach-omap2/hsmmc.c | 2 +- arch/arm/mach-omap2/id.c | 18 +- arch/arm/mach-omap2/{ => include/mach}/control.h | 163 ++- .../include/mach/ctrl_module_core_44xx.h | 391 ----- .../include/mach/ctrl_module_pad_core_44xx.h | 1409 ----------------- .../include/mach/ctrl_module_pad_wkup_44xx.h | 236 --- .../include/mach/ctrl_module_wkup_44xx.h | 92 -- arch/arm/mach-omap2/mcbsp.c | 2 +- arch/arm/mach-omap2/mux.c | 2 +- arch/arm/mach-omap2/omap_phy_internal.c | 2 +- arch/arm/mach-omap2/opp3xxx_data.c | 2 +- arch/arm/mach-omap2/opp4xxx_data.c | 2 +- arch/arm/mach-omap2/pm24xx.c | 2 +- arch/arm/mach-omap2/pm34xx.c | 2 +- arch/arm/mach-omap2/prcm.c | 2 +- arch/arm/mach-omap2/serial.c | 2 +- arch/arm/mach-omap2/sleep34xx.S | 2 +- arch/arm/mach-omap2/sr_device.c | 2 +- arch/arm/mach-omap2/usb-fs.c | 2 +- arch/arm/mach-omap2/voltage.c | 2 +- arch/arm/plat-omap/Kconfig | 3 + drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 1 + drivers/mfd/omap-control-core.c | 211 +++ drivers/thermal/Kconfig | 25 + drivers/thermal/Makefile | 5 +- drivers/thermal/omap-bandgap.c | 1602 ++++++++++++++++++++ drivers/thermal/omap-bandgap.h | 75 + drivers/thermal/omap4-thermal.c | 72 + drivers/usb/otg/Kconfig | 13 + drivers/usb/otg/Makefile | 1 + drivers/usb/otg/omap4-usb-phy.c | 130 ++ include/linux/mfd/omap_control.h | 69 + include/linux/usb/omap4_usb_phy.h | 53 + 60 files changed, 2617 insertions(+), 2173 deletions(-) create mode 100644 Documentation/devicetree/bindings/mfd/omap_control.txt create mode 100644 Documentation/devicetree/bindings/thermal/omap_bandgap.txt rename arch/arm/mach-omap2/{ => include/mach}/control.h (75%) delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h create mode 100644 drivers/mfd/omap-control-core.c create mode 100644 drivers/thermal/omap-bandgap.c create mode 100644 drivers/thermal/omap-bandgap.h create mode 100644 drivers/thermal/omap4-thermal.c create mode 100644 drivers/usb/otg/omap4-usb-phy.c create mode 100644 include/linux/mfd/omap_control.h create mode 100644 include/linux/usb/omap4_usb_phy.h
cover OMAP System Control Module
Konstantin,
Quoted 31 lines · Konstantin Baydarov
?Hi.
Quoted 21 lines · Eduardo Valentin
Hello Paul and Tony,
This is a series of patches adding a basic support for system control module, on OMAP4+ context. It is a working in progress, but I wanted to share already to get your feedback.
I've modeled the driver as an MFD. You will see in this series:
. A rework of the system control module header (patch from Santosh, picked from the list) . Device creation for control module core
. Early device creation for control module core
. The MFD core driver for system control module
. The MFD child for usb-phy pin control
. The MFD child for bandgap sensor
. Very early exposure of OMAP4 thermal zone
. All added drivers are only supporting DT probing
. The series is based on linux-omap master, as it has the hwmod entries for SCM.The overall idea of this series is to put in place the infrastructure. It is not touching nor removing the existing APIs under
mach-omap2/control.cfor now. But the target is to have these APIs moved to the MFD core driver.Quoted 7 lines
For early access, like ID checking, I have written the platform driver as an early platform driver and you will see also early device addition and probing under
device.cfor this case. This is of course a proposal. I see that there are people that thing this is a bit of an overkill. Konstantin (CCd) was proposing a simpler solution by having APIs with early_* prefixes, and solve the IO address mapping with a DT entry, for instance. But feel free to propose better ways.
Quoted 2 lines
In my latest version I got rid from early API set, check out patch for V3 patch set. I'll attach patch for current version later.
Please send it across so we can compare your approach with the one present in this series.
Quoted 123 lines
BR,
? ?Konstantin Baydarov.Quoted 118 lines
This code has been ripped off from the Android 3.1 branch. I have rewritten a couple of things, but the major driver functions and API's entries are kept.
So, based on this series, I see as a TODO list, for system control core driver:
- Start to move all the existing APIs undermach-omap2/control.cto the mfd core.
- Rewrite the users of the existing APIs, mentioned on previous item Once we decide the API and agree on how to deal with early calls.
- Add remaining children (from top of my head, the CAM is one of them, but I also think we should prob have one for HWOBS for instance)
- Test on boards that use the existing APIs.TODO list for bandgap driver:
- Improve thermal zone definition for OMAP4
- Introduce the thermal zones for OMAP5Amit, due to hwmod dep, I didn't include any cooling binding in this series, based on the generic CPU cooling device.
Overall series has been tested only with panda board OMAP4460.
Your comments are welcome.
All best,
Eduardo Valentin (9):
? ARM: OMAP: exposecontrol.hto mach area
? OMAP: Add early device for system control module
? mfd: omap: control: core system control driver
? OMAP2+: use control module mfd driver inomap_type
? mfd: omap: control: usb-phy: introduce the ctrl-module usb driver ? ARM: OMAP4+: Adding the temperature sensor register set bit fields ? ARM: OMAP4+: thermal: introduce bandgap temperature sensor ? omap4: thermal: add basic CPU thermal zone
? ARM: DT: Add support to system control module for OMAP4Kishon Vijay Abraham I (1):
? arm: omap: device: create a device for system control moduleSantosh Shilimkar (1):
? ARM: OMAP4: Remove un-used control module headers and defines.?.../devicetree/bindings/mfd/omap_control.txt ? ? ? | ? 44 + ?.../devicetree/bindings/thermal/omap_bandgap.txt ? | ? 27 + ?arch/arm/boot/dts/omap4.dtsi ? ? ? ? ? ? ? ? ? ? ? | ? 13 + ?arch/arm/mach-omap2/Kconfig ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 + ?arch/arm/mach-omap2/am35xx-emac.c ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/board-3430sdp.c ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/board-4430sdp.c ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/board-am3517crane.c ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/board-am3517evm.c ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/board-apollon.c ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/board-cm-t3517.c ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/board-h4.c ? ? ? ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/board-igep0020.c ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/board-ldp.c ? ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/board-omap3logic.c ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/board-omap4panda.c ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/board-omap4pcm049.c ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/clock2420_data.c ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/clock2430_data.c ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/clock3xxx_data.c ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/clock44xx_data.c ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/common.c ? ? ? ? ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/control.c ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/cpuidle34xx.c ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/devices.c ? ? ? ? ? ? ? ? ? ? ?| ? 57 +- ?arch/arm/mach-omap2/display.c ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/hsmmc.c ? ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/id.c ? ? ? ? ? ? ? ? ? ? ? ? ? | ? 18 +- ?arch/arm/mach-omap2/{ => include/mach}/control.h ? | ?163 ++- ?.../include/mach/ctrl_module_core_44xx.h ? ? ? ? ? | ?391 ----- ?.../include/mach/ctrl_module_pad_core_44xx.h ? ? ? | 1409 ----------------- ?.../include/mach/ctrl_module_pad_wkup_44xx.h ? ? ? | ?236 --- ?.../include/mach/ctrl_module_wkup_44xx.h ? ? ? ? ? | ? 92 -- ?arch/arm/mach-omap2/mcbsp.c ? ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/mux.c ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/omap_phy_internal.c ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/opp3xxx_data.c ? ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/opp4xxx_data.c ? ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/pm24xx.c ? ? ? ? ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/pm34xx.c ? ? ? ? ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/prcm.c ? ? ? ? ? ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/serial.c ? ? ? ? ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/sleep34xx.S ? ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/sr_device.c ? ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/mach-omap2/usb-fs.c ? ? ? ? ? ? ? ? ? ? ? | ? ?2 +- ?arch/arm/mach-omap2/voltage.c ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +- ?arch/arm/plat-omap/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? | ? ?3 + ?drivers/mfd/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?9 + ?drivers/mfd/Makefile ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 + ?drivers/mfd/omap-control-core.c ? ? ? ? ? ? ? ? ? ?| ?211 +++ ?drivers/thermal/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 25 + ?drivers/thermal/Makefile ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?5 +- ?drivers/thermal/omap-bandgap.c ? ? ? ? ? ? ? ? ? ? | 1602 ++++++++++++++++++++ ?drivers/thermal/omap-bandgap.h ? ? ? ? ? ? ? ? ? ? | ? 75 + ?drivers/thermal/omap4-thermal.c ? ? ? ? ? ? ? ? ? ?| ? 72 + ?drivers/usb/otg/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 13 + ?drivers/usb/otg/Makefile ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 + ?drivers/usb/otg/omap4-usb-phy.c ? ? ? ? ? ? ? ? ? ?| ?130 ++ ?include/linux/mfd/omap_control.h ? ? ? ? ? ? ? ? ? | ? 69 + ?include/linux/usb/omap4_usb_phy.h ? ? ? ? ? ? ? ? ?| ? 53 +?60 files changed, 2617 insertions(+), 2173 deletions(-)
?create mode 100644Documentation/devicetree/bindings/mfd/omap_control.txt?create mode 100644Documentation/devicetree/bindings/thermal/omap_bandgap.txt?renamearch/arm/mach-omap2/{=>include/mach}/control.h(75%) ?delete mode 100644arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h?delete mode 100644arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h?delete mode 100644arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h?delete mode 100644arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h?create mode 100644drivers/mfd/omap-control-core.c
?create mode 100644drivers/thermal/omap-bandgap.c
?create mode 100644drivers/thermal/omap-bandgap.h
?create mode 100644drivers/thermal/omap4-thermal.c
?create mode 100644drivers/usb/otg/omap4-usb-phy.c
?create mode 100644include/linux/mfd/omap_control.h
?create mode 100644include/linux/usb/omap4_usb_phy.h
Signature · 1 line
Eduardo Valentin
cover OMAP System Control Module
Hi.
Quoted 35 lines · Eduardo
Konstantin,
Quoted 31 lines · Konstantin Baydarov
Hi.
Quoted 28 lines · Eduardo Valentin
Hello Paul and Tony,
This is a series of patches adding a basic support for system control module, on OMAP4+ context. It is a working in progress, but I wanted to share already to get your feedback.
I've modeled the driver as an MFD. You will see in this series:
. A rework of the system control module header (patch from Santosh, picked from the list) . Device creation for control module core
. Early device creation for control module core
. The MFD core driver for system control module
. The MFD child for usb-phy pin control
. The MFD child for bandgap sensor
. Very early exposure of OMAP4 thermal zone
. All added drivers are only supporting DT probing
. The series is based on linux-omap master, as it has the hwmod entries for SCM.The overall idea of this series is to put in place the infrastructure. It is not touching nor removing the existing APIs under
mach-omap2/control.cfor now. But the target is to have these APIs moved to the MFD core driver.For early access, like ID checking, I have written the platform driver as an early platform driver and you will see also early device addition and probing under
device.cfor this case. This is of course a proposal. I see that there are people that thing this is a bit of an overkill. Konstantin (CCd) was proposing a simpler solution by having APIs with early_* prefixes, and solve the IO address mapping with a DT entry, for instance. But feel free to propose better ways.
Quoted 5 lines
Quoted 2 lines
In my latest version I got rid from early API set, check out patch for V3 patch set. I'll attach patch for current version later.
Please send it across so we can compare your approach with the one present in this series.
Moved control module window remap to early_initcall to allow usage of control module API very early during kernel initialization. Switched omap_type() to omap-control-core.c API.
drivers/mfd/omap-control-core.c +61 -23
@@ -31,12 +31,16 @@#include <linux/mfd/core.h> #include <linux/mfd/omap_control.h> +#include <linux/of.h> +#include <linux/of_address.h> +static struct omap_control *omap_control_module; +struct omap_control omap_control_data;/** * omap_control_readl: Read a single omap control module register. * -* @dev: device to read from. +* @dev: unused - there is only one controle module * @reg: register to read. * @val: output with register value. *
@@ -44,7 +48,7 @@ static struct omap_control *omap_control*/ int omap_control_readl (struct device *dev,u32 reg,u32 *val) { -struct omap_control *omap_control =dev_get_drvdata (dev); +struct omap_control *omap_control = omap_control_module;if (!omap_control)return -EINVAL ;
@@ -58,7 +62,7 @@ EXPORT_SYMBOL_GPL(omap_control_readl);/** * omap_control_writel: Write a single omap control module register. * -* @dev: device to read from. +* @dev: unused - there is only one controle module * @val: value to write. * @reg: register to write to. *
@@ -66,7 +70,7 @@ EXPORT_SYMBOL_GPL(omap_control_readl);*/ int omap_control_writel (struct device *dev,u32 val,u32 reg) { -struct omap_control *omap_control =dev_get_drvdata (dev); +struct omap_control *omap_control = omap_control_module;unsigned long flags;if (!omap_control)
@@ -130,40 +134,26 @@ static const struct of_device_id of_omapstatic int __devinit omap_control_probe (struct platform_device *pdev) { -struct resource *res; -void __iomem *base;struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;struct omap_control *omap_control; - omap_control =devm_kzalloc (dev,sizeof (*omap_control),GFP_KERNEL ); -if (!omap_control) { -dev_err (dev,"not enough memory for omap_control\n" ); -return -ENOMEM ; - } - - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); -if (!res) { -dev_err (dev,"missing memory base resource\n" ); -return -EINVAL ; - } - - base =devm_request_and_ioremap (dev, res); -if (!base) { +if (!omap_control_module) {dev_err (dev,"ioremap failed\n" );return -EADDRNOTAVAIL ; } + omap_control = omap_control_module; - omap_control->base = base; omap_control->dev = dev;spin_lock_init (&omap_control->reg_lock);platform_set_drvdata (pdev, omap_control); - omap_control_module = omap_control;return of_platform_populate (np, of_omap_control_match,NULL , dev); } +/* Looks like that there is no need to remove control module */ +#if 0 static int __devexit omap_control_remove(struct platform_device *pdev) {struct omap_control *omap_control =platform_get_drvdata (pdev);
@@ -181,10 +171,11 @@ static int __devexit omap_control_removereturn 0 ; } +#endif static struct platform_driver omap_control_driver = { .probe = omap_control_probe, - .remove =__devexit_p (omap_control_remove), +// .remove = __devexit_p(omap_control_remove), .driver = { .name ="omap-control-core" , .owner =THIS_MODULE ,
@@ -192,6 +183,53 @@ static struct platform_driver omap_contr }, }; +int __init omap_control_of_init (struct device_node *node, +struct device_node *parent) +{ +struct resource res; + +if (WARN_ON (!node)) +return -ENODEV ; + +if (of_address_to_resource (node,0 , &res)) { +WARN (1 ,"unable to get intc registers\n" ); +return -EINVAL ; + } + +return 0 ; +} + +void __init of_omap_control_init (const struct of_device_id *matches) +{ +struct device_node *np; +struct property *pp =0 ; +unsigned long phys_base =0 ; +size_t mapsize =0 ; + +for_each_matching_node (np, matches) { + + pp =of_find_property (np,"reg" ,NULL ); +if (pp) { + phys_base = (unsigned long )be32_to_cpup (pp->value); + mapsize = (size_t )be32_to_cpup ( (void *)((char *)pp->value +4 ) ); + omap_control_data.base =ioremap (phys_base, mapsize); +if (omap_control_data.base) + omap_control_module = &omap_control_data; + +// printk("\t\t **** of_omap_control_init(): ioremap addr %x \n", omap_control_data.base); + } + } +} + +static int __init +omap_control_early_initcall (void ) +{ +of_omap_control_init (of_omap_control_match); + +return 0 ; +} +early_initcall (omap_control_early_initcall); +static int __init omap_control_init (void ) {return platform_driver_register (&omap_control_driver);
arch/arm/boot/dts/omap4.dtsi +3 -0
@@ -275,7 +275,10 @@ ctrl_module_core: ctrl_module_core at 4a002000 { compatible = "ti,omap4-control"; + #address-cells = <1>; + #size-cells = <1>; ti,hwmods = "ctrl_module_core"; + reg = <0x4a002000 0x1000>; bandgap { compatible = "ti,omap4460-bandgap"; interrupts = <0 126 4>; /* talert */
arch/arm/mach-omap2/id.c +3 -13
@@ -39,16 +39,12 @@ unsigned int omap_rev(void) }EXPORT_SYMBOL (omap_rev); +int omap_control_readl (struct device *dev,u32 reg,u32 *val); +int omap_type (void ) { -struct device *scm; -int ret =0 ;u32 val =0 ; - scm =omap_control_get (); -if (IS_ERR_OR_NULL (scm)) -return 0 ; -if (cpu_is_omap24xx ()) { val =omap_ctrl_readl (OMAP24XX_CONTROL_STATUS ); }else if (cpu_is_am33xx ()) {
@@ -56,23 +52,17 @@ int omap_type(void) }else if (cpu_is_omap34xx ()) { val =omap_ctrl_readl (OMAP343X_CONTROL_STATUS ); }else if (cpu_is_omap44xx ()) { - ret =omap_control_readl (scm,OMAP4_CTRL_MODULE_CORE_STATUS , +omap_control_readl (0x0 ,OMAP4_CTRL_MODULE_CORE_STATUS , &val); }else {pr_err ("Cannot detect omap type!\n" ); goto out; } -if (ret) { -pr_err ("problem while fetching omap type\n" ); - goto out; - } - val &=OMAP2_DEVICETYPE_MASK ; val >>=8 ; out: -omap_control_put (scm);return val; }EXPORT_SYMBOL (omap_type);
arch/arm/mach-omap2/devices.c +2 -0
@@ -40,6 +40,7 @@#define L3_MODULES_MAX_LEN 12#define L3_MODULES 3 +#if 0 static struct resource control_resources[] = { [0] = { .start = 0x4a002000,
@@ -68,6 +69,7 @@ static int __init plat_early_device_setu return 0; }early_initcall (plat_early_device_setup); +#endif static int omap_init_control (void ) {
cover OMAP System Control Module
In reply to Eduardo ValentinHi Eduardo,
Quoted 5 lines · Eduardo Valentin
Hello Paul and Tony,
This is a series of patches adding a basic support for system control module, on OMAP4+ context. It is a working in progress, but I wanted to share already to get your feedback.
This is a great start, thanks for working on this. We have been needing to do this for awhile now so I'm glad to see you working on it.
Quoted 11 lines
I've modeled the driver as an MFD. You will see in this series:
. A rework of the system control module header (patch from Santosh, picked from the list) . Device creation for control module core
. Early device creation for control module core
. The MFD core driver for system control module
. The MFD child for usb-phy pin control
. The MFD child for bandgap sensor
. Very early exposure of OMAP4 thermal zone
. All added drivers are only supporting DT probing
. The series is based on linux-omap master, as it has the hwmod entries for SCM.
Quoted 3 lines
The overall idea of this series is to put in place the infrastructure. It is not touching nor removing the existing APIs under
mach-omap2/control.cfor now. But the target is to have these APIs moved to the MFD core driver.
IMO, the best time to create the APIs is when the new MFD children are created.
The goal should be that none of these drivers should be doing direct read/writes to the control module.
Kevin
RFC PATCH v2 1/11 ARM: OMAP4: Remove un-used control module headers and defines.
In reply to Eduardo ValentinFrom: Santosh Shilimkar <[email protected]>
Most of the OMAP4 control module register defines are not used and can be removed. Keep only needed defines and move them to common control module header just like other OMAP versions.
--- arch/arm/mach-omap2/control.h | 45 +- .../include/mach/ctrl_module_core_44xx.h | 391 ------ .../include/mach/ctrl_module_pad_core_44xx.h | 1409 -------------------- .../include/mach/ctrl_module_pad_wkup_44xx.h | 236 ---- .../include/mach/ctrl_module_wkup_44xx.h | 92 -- 5 files changed, 40 insertions(+), 2133 deletions(-) delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h delete mode 100644 arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
arch/arm/mach-omap2/control.h +40 -5
@@ -16,11 +16,6 @@#ifndef __ARCH_ARM_MACH_OMAP2_CONTROL_H#define __ARCH_ARM_MACH_OMAP2_CONTROL_H -#include <mach/ctrl_module_core_44xx.h> -#include <mach/ctrl_module_wkup_44xx.h> -#include <mach/ctrl_module_pad_core_44xx.h> -#include <mach/ctrl_module_pad_wkup_44xx.h> -#ifndef __ASSEMBLY__#define OMAP242X_CTRL_REGADDR (reg) \ OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
@@ -183,6 +178,43 @@#define OMAP3630_CONTROL_FUSE_OPP50_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)#define OMAP3630_CONTROL_FUSE_OPP100_VDD2 (OMAP2_CONTROL_GENERAL + 0x012C) +/* OMAP4 IDCODE CONTROL */ +#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1 0x0218 +#define OMAP4_CTRL_MODULE_CORE_STATUS 0x02c4 + +/* CONTROL_I2C_1 */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1 0x0624 +#define OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK (1 << 28) +#define OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK (1 << 24) + +/* DSI CONTROL_DSIPHY */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY 0x0618 +#define OMAP4_DSI2_LANEENABLE_SHIFT 29 +#define OMAP4_DSI2_LANEENABLE_MASK (0x7 << 29) +#define OMAP4_DSI1_LANEENABLE_SHIFT 24 +#define OMAP4_DSI1_LANEENABLE_MASK (0x1f << 24) +#define OMAP4_DSI1_PIPD_SHIFT 19 +#define OMAP4_DSI1_PIPD_MASK (0x1f << 19) +#define OMAP4_DSI2_PIPD_SHIFT 14 +#define OMAP4_DSI2_PIPD_MASK (0x1f << 14) + +/* CONTROL_PBIASLITE */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE 0x0600 +#define OMAP4_MMC1_PWRDNZ_MASK (1 << 26) +#define OMAP4_MMC1_PBIASLITE_VMODE_MASK (1 << 21) +#define OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK (1 << 22) +#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK (1 << 23) + +/* CONTROL_MMC1 */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1 0x0628 +#define OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK (1 << 31) +#define OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK (1 << 30) +#define OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK (1 << 29) +#define OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK (1 << 28) +#define OMAP4_SDMMC1_DR0_SPEEDCTRL_MASK (1 << 27) +#define OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK (1 << 26) +#define OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK (1 << 25) +/* OMAP44xx control efuse offsets */ #define OMAP44XX_CONTROL_FUSE_IVA_OPP50 0x22C#define OMAP44XX_CONTROL_FUSE_IVA_OPP100 0x22F
@@ -195,6 +227,9 @@#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257 +/* OMAP44xx control McBSP padconf */ +#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP 0x061c +/* AM35XX only CONTROL_GENERAL register offsets */ #define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h deleted +0 -391
391 lines not on this page · raw message
arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h deleted +0 -1409
1,409 lines not on this page · raw message
arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h deleted +0 -236
236 lines not on this page · raw message
arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h deleted +0 -92
92 lines not on this page · raw message
-- 1.7.7.1.488.ge8e1c
RFC PATCH v2 2/11 ARM: OMAP: expose control.h to mach area
In reply to Eduardo ValentinThis patch exposes the definitions under control.h to drivers outside the machine code.
---
arch/arm/mach-omap2/am35xx-emac.c | 2 +-
arch/arm/mach-omap2/board-3430sdp.c | 2 +-
arch/arm/mach-omap2/board-4430sdp.c | 2 +-
arch/arm/mach-omap2/board-am3517crane.c | 2 +-
arch/arm/mach-omap2/board-am3517evm.c | 2 +-
arch/arm/mach-omap2/board-apollon.c | 2 +-
arch/arm/mach-omap2/board-cm-t3517.c | 2 +-
arch/arm/mach-omap2/board-h4.c | 2 +-
arch/arm/mach-omap2/board-igep0020.c | 2 +-
arch/arm/mach-omap2/board-ldp.c | 2 +-
arch/arm/mach-omap2/board-omap3logic.c | 2 +-
arch/arm/mach-omap2/board-omap4panda.c | 2 +-
arch/arm/mach-omap2/board-omap4pcm049.c | 2 +-
arch/arm/mach-omap2/clock2420_data.c | 2 +-
arch/arm/mach-omap2/clock2430_data.c | 2 +-
arch/arm/mach-omap2/clock3xxx_data.c | 2 +-
arch/arm/mach-omap2/clock44xx_data.c | 2 +-
arch/arm/mach-omap2/common.c | 2 +-
arch/arm/mach-omap2/control.c | 2 +-
arch/arm/mach-omap2/cpuidle34xx.c | 2 +-
arch/arm/mach-omap2/devices.c | 2 +-
arch/arm/mach-omap2/display.c | 2 +-
arch/arm/mach-omap2/hsmmc.c | 2 +-
arch/arm/mach-omap2/id.c | 2 +-
arch/arm/mach-omap2/{ => include/mach}/control.h | 2 +-
arch/arm/mach-omap2/mcbsp.c | 2 +-
arch/arm/mach-omap2/mux.c | 2 +-
arch/arm/mach-omap2/omap_phy_internal.c | 2 +-
arch/arm/mach-omap2/opp3xxx_data.c | 2 +-
arch/arm/mach-omap2/opp4xxx_data.c | 2 +-
arch/arm/mach-omap2/pm24xx.c | 2 +-
arch/arm/mach-omap2/pm34xx.c | 2 +-
arch/arm/mach-omap2/prcm.c | 2 +-
arch/arm/mach-omap2/serial.c | 2 +-
arch/arm/mach-omap2/sleep34xx.S | 2 +-
arch/arm/mach-omap2/sr_device.c | 2 +-
arch/arm/mach-omap2/usb-fs.c | 2 +-
arch/arm/mach-omap2/voltage.c | 2 +-
38 files changed, 38 insertions(+), 38 deletions(-)
rename arch/arm/mach-omap2/{ => include/mach}/control.h (99%)arch/arm/mach-omap2/am35xx-emac.c +1 -1
@@ -21,7 +21,7 @@#include <plat/irqs.h> #include <mach/am35xx.h> -#include "control.h" +#include <mach/control.h> static struct mdio_platform_data am35xx_emac_mdio_pdata;
arch/arm/mach-omap2/board-3430sdp.c +1 -1
@@ -46,7 +46,7 @@#include "sdram-qimonda-hyb18m512160af-6.h" #include "hsmmc.h" #include "pm.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #define CONFIG_DISABLE_HFCLK 1
arch/arm/mach-omap2/board-4430sdp.c +1 -1
@@ -47,7 +47,7 @@#include "mux.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #define ETH_KS8851_IRQ 34
arch/arm/mach-omap2/board-am3517crane.c +1 -1
@@ -32,7 +32,7 @@#include "am35xx-emac.h" #include "mux.h" -#include "control.h" +#include <mach/control.h> #define GPIO_USB_POWER 35#define GPIO_USB_NRESET 38
arch/arm/mach-omap2/board-am3517evm.c +1 -1
@@ -41,7 +41,7 @@#include "am35xx-emac.h" #include "mux.h" -#include "control.h" +#include <mach/control.h> #include "hsmmc.h" #define LCD_PANEL_PWR 176
arch/arm/mach-omap2/board-apollon.c +1 -1
@@ -44,7 +44,7 @@#include <video/omap-panel-generic-dpi.h> #include "mux.h" -#include "control.h" +#include <mach/control.h> /* LED & Switch macros */ #define LED0_GPIO13 13
arch/arm/mach-omap2/board-cm-t3517.c +1 -1
@@ -47,7 +47,7 @@#include <mach/am35xx.h> #include "mux.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #include "am35xx-emac.h"
arch/arm/mach-omap2/board-h4.c +1 -1
@@ -43,7 +43,7 @@#include <video/omap-panel-generic-dpi.h> #include "mux.h" -#include "control.h" +#include <mach/control.h> #define H4_FLASH_CS 0#define H4_SMC91X_CS 1
arch/arm/mach-omap2/board-igep0020.c +1 -1
@@ -42,7 +42,7 @@#include "sdram-numonyx-m65kxxxxam.h" #include "common-board-devices.h" #include "board-flash.h" -#include "control.h" +#include <mach/control.h> #define IGEP2_SMSC911X_CS 5#define IGEP2_SMSC911X_GPIO 176
arch/arm/mach-omap2/board-ldp.c +1 -1
@@ -50,7 +50,7 @@#include "board-flash.h" #include "mux.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #define LDP_SMSC911X_CS 1
arch/arm/mach-omap2/board-omap3logic.c +1 -1
@@ -37,7 +37,7 @@#include "mux.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "common-board-devices.h" #include <plat/mux.h>
arch/arm/mach-omap2/board-omap4panda.c +1 -1
@@ -45,7 +45,7 @@#include <video/omap-panel-tfp410.h> #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "mux.h" #include "common-board-devices.h"
arch/arm/mach-omap2/board-omap4pcm049.c +1 -1
@@ -48,7 +48,7 @@#include "common.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #include "mux.h" #include "common-board-devices.h"
arch/arm/mach-omap2/clock2420_data.c +1 -1
@@ -30,7 +30,7 @@#include "prm-regbits-24xx.h" #include "cm-regbits-24xx.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> #define OMAP_CM_REGADDR OMAP2420_CM_REGADDR
arch/arm/mach-omap2/clock2430_data.c +1 -1
@@ -29,7 +29,7 @@#include "prm-regbits-24xx.h" #include "cm-regbits-24xx.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> #define OMAP_CM_REGADDR OMAP2430_CM_REGADDR
arch/arm/mach-omap2/clock3xxx_data.c +1 -1
@@ -34,7 +34,7 @@#include "cm-regbits-34xx.h" #include "prm2xxx_3xxx.h" #include "prm-regbits-34xx.h" -#include "control.h" +#include <mach/control.h> /* * clocks
arch/arm/mach-omap2/clock44xx_data.c +1 -1
@@ -39,7 +39,7 @@#include "cm-regbits-44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" -#include "control.h" +#include <mach/control.h> #include "scrm44xx.h" /* OMAP4 modulemode control */
arch/arm/mach-omap2/common.c +1 -1
@@ -25,7 +25,7 @@#include "iomap.h" #include "common.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> /* Global address base setup code */
arch/arm/mach-omap2/control.c +1 -1
@@ -26,7 +26,7 @@#include "cm2xxx_3xxx.h" #include "sdrc.h" #include "pm.h" -#include "control.h" +#include <mach/control.h> /* Used by omap3_ctrl_save_padconf() */ #define START_PADCONF_SAVE 0x2
arch/arm/mach-omap2/cpuidle34xx.c +1 -1
@@ -33,7 +33,7 @@#include "clockdomain.h" #include "pm.h" -#include "control.h" +#include <mach/control.h> #include "common.h" #ifdef CONFIG_CPU_IDLE
arch/arm/mach-omap2/devices.c +1 -1
@@ -34,7 +34,7 @@#include <plat/omap4-keypad.h> #include "mux.h" -#include "control.h" +#include <mach/control.h> #include "devices.h" #define L3_MODULES_MAX_LEN 12
arch/arm/mach-omap2/display.c +1 -1
@@ -32,7 +32,7 @@#include "iomap.h" #include "mux.h" -#include "control.h" +#include <mach/control.h> #include "display.h" #define DISPC_CONTROL 0x0040
arch/arm/mach-omap2/hsmmc.c +1 -1
@@ -22,7 +22,7 @@#include "mux.h" #include "hsmmc.h" -#include "control.h" +#include <mach/control.h> #if defined(CONFIG_MMC_OMAP_HS ) || defined(CONFIG_MMC_OMAP_HS_MODULE )
arch/arm/mach-omap2/id.c +1 -1
@@ -26,7 +26,7 @@#include <mach/id.h> -#include "control.h" +#include <mach/control.h> static unsigned int omap_revision;static const char *cpu_rev;
arch/arm/mach-omap2/include/mach/control.h renamed from arch/arm/mach-omap2/control.h +1 -1
@@ -1,5 +1,5 @@/* -* arch/arm/mach-omap2/control.h +* arch/arm/mach-omap2/include/mach/control.h * * OMAP2/3/4 System Control Module definitions *
arch/arm/mach-omap2/mcbsp.c +1 -1
@@ -25,7 +25,7 @@#include <plat/omap_device.h> #include <linux/pm_runtime.h> -#include "control.h" +#include <mach/control.h> /* * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
arch/arm/mach-omap2/mux.c +1 -1
@@ -38,7 +38,7 @@#include <plat/omap_hwmod.h> -#include "control.h" +#include <mach/control.h> #include "mux.h" #include "prm.h"
arch/arm/mach-omap2/omap_phy_internal.c +1 -1
@@ -29,7 +29,7 @@#include <linux/usb.h> #include <plat/usb.h> -#include "control.h" +#include <mach/control.h> /* OMAP control module register for UTMI PHY */ #define CONTROL_DEV_CONF 0x300
arch/arm/mach-omap2/opp3xxx_data.c +1 -1
@@ -21,7 +21,7 @@#include <plat/cpu.h> -#include "control.h" +#include <mach/control.h> #include "omap_opp_data.h" #include "pm.h"
arch/arm/mach-omap2/opp4xxx_data.c +1 -1
@@ -22,7 +22,7 @@#include <plat/cpu.h> -#include "control.h" +#include <mach/control.h> #include "omap_opp_data.h" #include "pm.h"
arch/arm/mach-omap2/pm24xx.c +1 -1
@@ -49,7 +49,7 @@#include "cm-regbits-24xx.h" #include "sdrc.h" #include "pm.h" -#include "control.h" +#include <mach/control.h> #include "powerdomain.h" #include "clockdomain.h"
arch/arm/mach-omap2/pm34xx.c +1 -1
@@ -49,7 +49,7 @@#include "prm2xxx_3xxx.h" #include "pm.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> /* pm34xx errata defined in pm.h */ u16 pm34xx_errata;
arch/arm/mach-omap2/prcm.c +1 -1
@@ -37,7 +37,7 @@#include "prminst44xx.h" #include "prm-regbits-24xx.h" #include "prm-regbits-44xx.h" -#include "control.h" +#include <mach/control.h> void __iomem *prm_base;void __iomem *cm_base;
arch/arm/mach-omap2/serial.c +1 -1
@@ -39,7 +39,7 @@#include "pm.h" #include "cm2xxx_3xxx.h" #include "prm-regbits-34xx.h" -#include "control.h" +#include <mach/control.h> #include "mux.h" /*
arch/arm/mach-omap2/sleep34xx.S +1 -1
@@ -33,7 +33,7 @@ #include "cm2xxx_3xxx.h" #include "prm2xxx_3xxx.h" #include "sdrc.h" -#include "control.h" +#include <mach/control.h> /* * Registers access definitions
arch/arm/mach-omap2/sr_device.c +1 -1
@@ -26,7 +26,7 @@#include "smartreflex.h" #include "voltage.h" -#include "control.h" +#include <mach/control.h> #include "pm.h" static bool sr_enable_on_init;
arch/arm/mach-omap2/usb-fs.c +1 -1
@@ -32,7 +32,7 @@#include <plat/usb.h> #include <plat/board.h> -#include "control.h" +#include <mach/control.h> #include "mux.h" #define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN
arch/arm/mach-omap2/voltage.c +1 -1
@@ -34,7 +34,7 @@#include "prm44xx.h" #include "prcm44xx.h" #include "prminst44xx.h" -#include "control.h" +#include <mach/control.h> #include "voltage.h" #include "powerdomain.h"
-- 1.7.7.1.488.ge8e1c
Tony Lindgren
maintainerRFC PATCH v2 2/11 ARM: OMAP: expose control.h to mach area
Quoted 2 lines · Konstantin Baydarov
This patch exposes the definitions under
control.hto drivers outside the machine code.
As discussed earlier, this will likely lead into misuse of these registers that will be a big mess to clean up.
Can't you make these private to the driver(s)?
Tony
RFC PATCH v2 3/11 mfd: omap: control: core system control driver
In reply to Eduardo ValentinThis patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
Changes since previous version:
- omap-control-core: driver is basically the same as arch/arm/mach-omap2/control.c, but resources aren't hardcoded, they are specified in dts file.
- omap-control-core: Control module is a built-in driver - added control module select to ARCH_HAS_CONTROL_MODULE and ARCH_OMAP4. Probably, no configuration option is required!
- omap-control-core: Added early init call that ioremaps control module IOMEM window, this allowsomap-control-core.c API to be called very early, for example from omap_type()
- omap-control-core: Removed device pointer from omap-control-core API arguments, becuase there can be only one instance control module device.
--- Documentation/devicetree/bindings/mfd/omap_control.txt | 44 +++++ arch/arm/mach-omap2/Kconfig | 1 arch/arm/plat-omap/Kconfig | 4 drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 1 drivers/mfd/omap-control-core.c | 141 +++++++++++++++++ include/linux/mfd/omap_control.h | 70 ++++++++ 7 files changed, 270 insertions(+)
Documentation/devicetree/bindings/mfd/omap_control.txt new file +44 -0
@@ -0,0 +1,44 @@ +* Texas Instrument OMAP System Control Module (SCM) bindings + +The control module allows software control of various static modes supported by +the device. The control module controls the settings of various device modules +through register configuration and internal signals. It also controls the pad +configuration, pin functional multiplexing, and the routing of internal signals +(such as PRCM signals or DMA requests) to output pins configured for hardware +observability. + +Required properties: +- compatible : Should be: + - "ti,omap3-control" for OMAP3 support + - "ti,omap4-control" for OMAP4 support + - "ti,omap5-control" for OMAP5 support + +OMAP specific properties: +- ti,hwmods: Name of the hwmod associated to the control module: + Should be "ctrl_module_core"; + +Sub-nodes: +- bandgap : contains the bandgap node + + The bindings details of individual bandgap device can be found in: + Documentation/devicetree/bindings/thermal/omap_bandgap.txt + +- usb : contains the usb phy pin control node + + The only required property for this child is: + - compatible = "ti,omap4-control-usb"; + +Examples: + +ctrl_module_core: ctrl_module_core at 4a002000 { + compatible = "ti,omap4-control"; + ti,hwmods = "ctrl_module_core"; + bandgap { + compatible = "ti,omap4460-bandgap"; + interrupts = <0 126 4>; /* talert */ + ti,tshut-gpio = <86>; /* tshut */ + }; + usb { + compatible = "ti,omap4-usb-phy"; + }; +};
arch/arm/mach-omap2/Kconfig +1 -0
@@ -52,6 +52,7 @@ config ARCH_OMAP4 select PL310_ERRATA_727915 select ARM_ERRATA_720789 select ARCH_HAS_OPP + select ARCH_HAS_CONTROL_MODULE select PM_OPP if PM select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PM
arch/arm/plat-omap/Kconfig +4 -0
@@ -5,6 +5,10 @@ menu "TI OMAP Common Features" config ARCH_OMAP_OTG bool +config ARCH_HAS_CONTROL_MODULE + bool + select MFD_OMAP_CONTROL + choice prompt "OMAP System Type" default ARCH_OMAP2PLUS
drivers/mfd/Kconfig +9 -0
@@ -822,6 +822,15 @@ config MFD_WL1273_CORE driver connects the radio-wl1273 V4L2 module and the wl1273 audio codec. +config MFD_OMAP_CONTROL + bool "Texas Instruments OMAP System control module" + depends on ARCH_HAS_CONTROL_MODULE + help + This is the core driver for system control module. This driver + is responsible for creating the control module mfd child, + like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic + change for off mode. + config MFD_OMAP_USB_HOST bool "Support OMAP USBHS core driver" depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
drivers/mfd/Makefile +1 -0
@@ -107,6 +107,7 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
drivers/mfd/omap-control-core.c new file +141 -0
141 lines not on this page · raw message
include/linux/mfd/omap_control.h new file +70 -0
70 lines not on this page · raw message
Tony Lindgren
maintainerRFC PATCH v2 3/11 mfd: omap: control: core system control driver
Quoted 10 lines · Konstantin Baydarov
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
+++
linux-2.6/drivers/mfd/omap-control-core.c
...
drivers/mfd/omap-control-core.c line 52
Quoted 9 lines
drivers/mfd/omap-control-core.c new file +9
-0+u32 omap_control_readl (u16 offset) +{ +return __raw_readl (omap_control_base + (offset)); +} + +void omap_control_writel (u32 val,u16 offset) +{ +__raw_writel (val, omap_control_base + (offset)); +}
There should not be any need to have the individual drivers use these. Please instead just set up something where individual drivers register with the control module core, and get their own iobase returned so they can use readl/writel and behave like normal device drivers.
Regards,
Tony
RFC PATCH v2 3/11 mfd: omap: control: core system control driver
Hi, Tony.
Quoted 13 lines · Tony Lindgren
Quoted 9 lines · Konstantin Baydarov
This patch introduces a MFD core device driver for OMAP system control module.
The control module allows software control of various static modes supported by the device. It is composed of two control submodules: general control module and device (padconfiguration) control module.
+++linux-2.6/drivers/mfd/omap-control-core.c...
Quoted 14 lines
drivers/mfd/omap-control-core.c line 52
Quoted 9 lines
drivers/mfd/omap-control-core.c new file +9
-0+u32 omap_control_readl (u16 offset) +{ +return __raw_readl (omap_control_base + (offset)); +} + +void omap_control_writel (u32 val,u16 offset) +{ +__raw_writel (val, omap_control_base + (offset)); +}There should not be any need to have the individual drivers use these. Please instead just set up something where individual drivers register with the control module core, and get their own iobase returned so they can use readl/writel and behave like normal device drivers.
IIUC one of the reasons drivers/mfd/omap-control-core.c introduction is replacement of arch/arm/mach-omap2/control.c. control.c provides omap_ctrl_readl/omap_ctrl_writel API which are heavily used in arch/arm/mach-omap2/:arch/arm/mach-omap2/hsmmc.carch/arm/mach-omap2/usb-fs.carch/arm/mach-omap2/sr_device.carch/arm/mach-omap2/id.c
...
So,the same API set (omap_control_readl/omap_control_writel) was added to omap-control-core.c.
If omap-control-core.c should only service users from driver/ directory, than I agree - we can remove
omap_control_readl/omap_control_writel from omap-control-core.c.
But IIUC you are agree to "switch" arch/arm/mach-omap2/id.c from control.c to omap-control-core.c. If arch/arm/mach-omap2/id.c is switched to control.c, then I guess all arch/arm/mach-omap2/*.c should be "switched" to omap-control-core.c as well. But this means that omap-control-core.c should provide omap_control_readl/omap_control_writel API.
BR,
Konstantin Baydarov.
Quoted 8 lines
Regards,
Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html