Commit 0e4b0743 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC fixes from Olof Johansson:
 "Mostly bugfixes and a few small code removals.  Worth pointing out is:

   - A handful of more fixes to get DT enablement working properly on
     OMAP, finding new breakage of things that don't work quite right
     yet without the traditional board files.  I expect a bit more of
     this to come in this release as people test on their hardware.
   - Implementation of power_down_finish() on vexpress, to make kexec
     work and to stop the MCPM core to produce a warning (the warning
     was new to 3.13-rc1).
   - A handful of minor fixes for various platforms"

* tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc:
  ARM: bcm2835: add missing #xxx-cells to I2C nodes
  ARM: dts: Add max77686 RTC interrupt to cros5250-common
  ARM: vexpress/TC2: Implement MCPM power_down_finish()
  ARM: tegra: Provide dummy powergate implementation
  ARM: omap: fix warning with LPAE build
  ARM: OMAP2+: Remove legacy omap4_twl6030_hsmmc_init
  ARM: OMAP2+: Remove legacy mux code for display.c
  ARM: OMAP2+: Fix undefined reference to set_cntfreq
  gpio: twl4030: Fix passing of pdata in the device tree case
  gpio: twl4030: Fix regression for twl gpio output
  ARM: OMAP2+: More randconfig fixes for reconfigure_io_chain
  ARM: dts: imx6qdl: disable spdif "rxtx5" clock option
  ARM: dts: Fix omap2 specific dtsi files by adding the missing entries
  ARM: OMAP2+: Fix GPMC and simplify bootloader timings for 8250 and smc91x
  i2c: omap: Fix missing device tree flags for omap2
parents 3af4977e a31ab44e
I2C for OMAP platforms
Required properties :
- compatible : Must be "ti,omap3-i2c" or "ti,omap4-i2c"
- compatible : Must be "ti,omap2420-i2c", "ti,omap2430-i2c", "ti,omap3-i2c"
or "ti,omap4-i2c"
- ti,hwmods : Must be "i2c<n>", n being the instance number (1-based)
- #address-cells = <1>;
- #size-cells = <0>;
......
......@@ -85,6 +85,8 @@ i2c0: i2c@20205000 {
reg = <0x7e205000 0x1000>;
interrupts = <2 21>;
clocks = <&clk_i2c>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
......@@ -93,6 +95,8 @@ i2c1: i2c@20804000 {
reg = <0x7e804000 0x1000>;
interrupts = <2 21>;
clocks = <&clk_i2c>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
......
......@@ -27,6 +27,13 @@ pinctrl@11400000 {
i2c2_bus: i2c2-bus {
samsung,pin-pud = <0>;
};
max77686_irq: max77686-irq {
samsung,pins = "gpx3-2";
samsung,pin-function = <0>;
samsung,pin-pud = <0>;
samsung,pin-drv = <0>;
};
};
i2c@12C60000 {
......@@ -35,6 +42,11 @@ i2c@12C60000 {
max77686@09 {
compatible = "maxim,max77686";
interrupt-parent = <&gpx3>;
interrupts = <2 0>;
pinctrl-names = "default";
pinctrl-0 = <&max77686_irq>;
wakeup-source;
reg = <0x09>;
voltage-regulators {
......
......@@ -161,7 +161,7 @@ spdif: spdif@02004000 {
clocks = <&clks 197>, <&clks 3>,
<&clks 197>, <&clks 107>,
<&clks 0>, <&clks 118>,
<&clks 62>, <&clks 139>,
<&clks 0>, <&clks 139>,
<&clks 0>;
clock-names = "core", "rxtx0",
"rxtx1", "rxtx2",
......
......@@ -13,7 +13,7 @@ &gpmc {
* they probably share the same GPIO IRQ
* REVISIT: Add timing support from slls644g.pdf
*/
8250@3,0 {
uart@3,0 {
compatible = "ns16550a";
reg = <3 0 0x100>;
bank-width = <2>;
......
......@@ -9,6 +9,7 @@
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pinctrl/omap.h>
#include "skeleton.dtsi"
......@@ -21,6 +22,8 @@ aliases {
serial0 = &uart1;
serial1 = &uart2;
serial2 = &uart3;
i2c0 = &i2c1;
i2c1 = &i2c2;
};
cpus {
......@@ -53,6 +56,28 @@ ocp {
ranges;
ti,hwmods = "l3_main";
aes: aes@480a6000 {
compatible = "ti,omap2-aes";
ti,hwmods = "aes";
reg = <0x480a6000 0x50>;
dmas = <&sdma 9 &sdma 10>;
dma-names = "tx", "rx";
};
hdq1w: 1w@480b2000 {
compatible = "ti,omap2420-1w";
ti,hwmods = "hdq1w";
reg = <0x480b2000 0x1000>;
interrupts = <58>;
};
mailbox: mailbox@48094000 {
compatible = "ti,omap2-mailbox";
ti,hwmods = "mailbox";
reg = <0x48094000 0x200>;
interrupts = <26>;
};
intc: interrupt-controller@1 {
compatible = "ti,omap2-intc";
interrupt-controller;
......@@ -63,6 +88,7 @@ intc: interrupt-controller@1 {
sdma: dma-controller@48056000 {
compatible = "ti,omap2430-sdma", "ti,omap2420-sdma";
ti,hwmods = "dma";
reg = <0x48056000 0x1000>;
interrupts = <12>,
<13>,
......@@ -73,21 +99,91 @@ sdma: dma-controller@48056000 {
#dma-requests = <64>;
};
i2c1: i2c@48070000 {
compatible = "ti,omap2-i2c";
ti,hwmods = "i2c1";
reg = <0x48070000 0x80>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <56>;
dmas = <&sdma 27 &sdma 28>;
dma-names = "tx", "rx";
};
i2c2: i2c@48072000 {
compatible = "ti,omap2-i2c";
ti,hwmods = "i2c2";
reg = <0x48072000 0x80>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <57>;
dmas = <&sdma 29 &sdma 30>;
dma-names = "tx", "rx";
};
mcspi1: mcspi@48098000 {
compatible = "ti,omap2-mcspi";
ti,hwmods = "mcspi1";
reg = <0x48098000 0x100>;
interrupts = <65>;
dmas = <&sdma 35 &sdma 36 &sdma 37 &sdma 38
&sdma 39 &sdma 40 &sdma 41 &sdma 42>;
dma-names = "tx0", "rx0", "tx1", "rx1",
"tx2", "rx2", "tx3", "rx3";
};
mcspi2: mcspi@4809a000 {
compatible = "ti,omap2-mcspi";
ti,hwmods = "mcspi2";
reg = <0x4809a000 0x100>;
interrupts = <66>;
dmas = <&sdma 43 &sdma 44 &sdma 45 &sdma 46>;
dma-names = "tx0", "rx0", "tx1", "rx1";
};
rng: rng@480a0000 {
compatible = "ti,omap2-rng";
ti,hwmods = "rng";
reg = <0x480a0000 0x50>;
interrupts = <36>;
};
sham: sham@480a4000 {
compatible = "ti,omap2-sham";
ti,hwmods = "sham";
reg = <0x480a4000 0x64>;
interrupts = <51>;
dmas = <&sdma 13>;
dma-names = "rx";
};
uart1: serial@4806a000 {
compatible = "ti,omap2-uart";
ti,hwmods = "uart1";
reg = <0x4806a000 0x2000>;
interrupts = <72>;
dmas = <&sdma 49 &sdma 50>;
dma-names = "tx", "rx";
clock-frequency = <48000000>;
};
uart2: serial@4806c000 {
compatible = "ti,omap2-uart";
ti,hwmods = "uart2";
reg = <0x4806c000 0x400>;
interrupts = <73>;
dmas = <&sdma 51 &sdma 52>;
dma-names = "tx", "rx";
clock-frequency = <48000000>;
};
uart3: serial@4806e000 {
compatible = "ti,omap2-uart";
ti,hwmods = "uart3";
reg = <0x4806e000 0x400>;
interrupts = <74>;
dmas = <&sdma 53 &sdma 54>;
dma-names = "tx", "rx";
clock-frequency = <48000000>;
};
......
......@@ -114,6 +114,15 @@ mcbsp2: mcbsp@48076000 {
dma-names = "tx", "rx";
};
msdi1: mmc@4809c000 {
compatible = "ti,omap2420-mmc";
ti,hwmods = "msdi1";
reg = <0x4809c000 0x80>;
interrupts = <83>;
dmas = <&sdma 61 &sdma 62>;
dma-names = "tx", "rx";
};
timer1: timer@48028000 {
compatible = "ti,omap2420-timer";
reg = <0x48028000 0x400>;
......@@ -121,5 +130,19 @@ timer1: timer@48028000 {
ti,hwmods = "timer1";
ti,timer-alwon;
};
wd_timer2: wdt@48022000 {
compatible = "ti,omap2-wdt";
ti,hwmods = "wd_timer2";
reg = <0x48022000 0x80>;
};
};
};
&i2c1 {
compatible = "ti,omap2420-i2c";
};
&i2c2 {
compatible = "ti,omap2420-i2c";
};
......@@ -175,6 +175,25 @@ mcbsp5: mcbsp@48096000 {
dma-names = "tx", "rx";
};
mmc1: mmc@4809c000 {
compatible = "ti,omap2-hsmmc";
reg = <0x4809c000 0x200>;
interrupts = <83>;
ti,hwmods = "mmc1";
ti,dual-volt;
dmas = <&sdma 61>, <&sdma 62>;
dma-names = "tx", "rx";
};
mmc2: mmc@480b4000 {
compatible = "ti,omap2-hsmmc";
reg = <0x480b4000 0x200>;
interrupts = <86>;
ti,hwmods = "mmc2";
dmas = <&sdma 47>, <&sdma 48>;
dma-names = "tx", "rx";
};
timer1: timer@49018000 {
compatible = "ti,omap2420-timer";
reg = <0x49018000 0x400>;
......@@ -182,5 +201,35 @@ timer1: timer@49018000 {
ti,hwmods = "timer1";
ti,timer-alwon;
};
mcspi3: mcspi@480b8000 {
compatible = "ti,omap2-mcspi";
ti,hwmods = "mcspi3";
reg = <0x480b8000 0x100>;
interrupts = <91>;
dmas = <&sdma 15 &sdma 16 &sdma 23 &sdma 24>;
dma-names = "tx0", "rx0", "tx1", "rx1";
};
usb_otg_hs: usb_otg_hs@480ac000 {
compatible = "ti,omap2-musb";
ti,hwmods = "usb_otg_hs";
reg = <0x480ac000 0x1000>;
interrupts = <93>;
};
wd_timer2: wdt@49016000 {
compatible = "ti,omap2-wdt";
ti,hwmods = "wd_timer2";
reg = <0x49016000 0x80>;
};
};
};
&i2c1 {
compatible = "ti,omap2430-i2c";
};
&i2c2 {
compatible = "ti,omap2430-i2c";
};
......@@ -19,11 +19,11 @@ secure-common = omap-smc.o omap-secure.o
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common)
obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common)
obj-$(CONFIG_SOC_OMAP5) += prm44xx.o $(hwmod-common) $(secure-common)
obj-$(CONFIG_SOC_OMAP5) += $(hwmod-common) $(secure-common)
obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common)
obj-$(CONFIG_SOC_DRA7XX) += prm44xx.o $(hwmod-common) $(secure-common)
obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common)
ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
obj-y += mcbsp.o
......
......@@ -299,7 +299,6 @@ struct omap_sdrc_params;
extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1);
struct omap2_hsmmc_info;
extern int omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers);
extern void omap_reserve(void);
struct omap_hwmod;
......
......@@ -32,7 +32,6 @@
#include "soc.h"
#include "iomap.h"
#include "mux.h"
#include "control.h"
#include "display.h"
#include "prm.h"
......@@ -102,90 +101,13 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = {
{ "dss_hdmi", "omapdss_hdmi", -1 },
};
static void __init omap4_tpd12s015_mux_pads(void)
{
omap_mux_init_signal("hdmi_cec",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("hdmi_ddc_scl",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("hdmi_ddc_sda",
OMAP_PIN_INPUT_PULLUP);
}
static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
{
u32 reg;
u16 control_i2c_1;
/*
* CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and
* HDMI_DDC_SCL_PULLUPRESX (bit 24) are set to disable
* internal pull up resistor.
*/
if (flags & OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP) {
control_i2c_1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1;
reg = omap4_ctrl_pad_readl(control_i2c_1);
reg |= (OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK |
OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK);
omap4_ctrl_pad_writel(reg, control_i2c_1);
}
}
static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
{
u32 enable_mask, enable_shift;
u32 pipd_mask, pipd_shift;
u32 reg;
if (dsi_id == 0) {
enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
pipd_mask = OMAP4_DSI1_PIPD_MASK;
pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
} else if (dsi_id == 1) {
enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
pipd_mask = OMAP4_DSI2_PIPD_MASK;
pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
} else {
return -ENODEV;
}
reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
reg &= ~enable_mask;
reg &= ~pipd_mask;
reg |= (lanes << enable_shift) & enable_mask;
reg |= (lanes << pipd_shift) & pipd_mask;
omap4_ctrl_pad_writel(reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
return 0;
}
int __init omap_hdmi_init(enum omap_hdmi_flags flags)
{
if (cpu_is_omap44xx()) {
omap4_hdmi_mux_pads(flags);
omap4_tpd12s015_mux_pads();
}
return 0;
}
static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
{
if (cpu_is_omap44xx())
return omap4_dsi_mux_pads(dsi_id, lane_mask);
return 0;
}
static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
{
if (cpu_is_omap44xx())
omap4_dsi_mux_pads(dsi_id, 0);
}
static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput)
......
......@@ -1501,6 +1501,22 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
return ret;
}
/*
* For some GPMC devices we still need to rely on the bootloader
* timings because the devices can be connected via FPGA. So far
* the list is smc91x on the omap2 SDP boards, and 8250 on zooms.
* REVISIT: Add timing support from slls644g.pdf and from the
* lan91c96 manual.
*/
if (of_device_is_compatible(child, "ns16550a") ||
of_device_is_compatible(child, "smsc,lan91c94") ||
of_device_is_compatible(child, "smsc,lan91c111")) {
dev_warn(&pdev->dev,
"%s using bootloader timings on CS%d\n",
child->name, cs);
goto no_timings;
}
/*
* FIXME: gpmc_cs_request() will map the CS to an arbitary
* location in the gpmc address space. When booting with
......@@ -1529,6 +1545,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
gpmc_read_timings_dt(child, &gpmc_t);
gpmc_cs_set_timings(cs, &gpmc_t);
no_timings:
if (of_platform_device_create(child, NULL, &pdev->dev))
return 0;
......@@ -1541,42 +1558,6 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
return ret;
}
/*
* REVISIT: Add timing support from slls644g.pdf
*/
static int gpmc_probe_8250(struct platform_device *pdev,
struct device_node *child)
{
struct resource res;
unsigned long base;
int ret, cs;
if (of_property_read_u32(child, "reg", &cs) < 0) {
dev_err(&pdev->dev, "%s has no 'reg' property\n",
child->full_name);
return -ENODEV;
}
if (of_address_to_resource(child, 0, &res) < 0) {
dev_err(&pdev->dev, "%s has malformed 'reg' property\n",
child->full_name);
return -ENODEV;
}
ret = gpmc_cs_request(cs, resource_size(&res), &base);
if (ret < 0) {
dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
return ret;
}
if (of_platform_device_create(child, NULL, &pdev->dev))
return 0;
dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
return -ENODEV;
}
static int gpmc_probe_dt(struct platform_device *pdev)
{
int ret;
......@@ -1618,10 +1599,9 @@ static int gpmc_probe_dt(struct platform_device *pdev)
else if (of_node_cmp(child->name, "onenand") == 0)
ret = gpmc_probe_onenand_child(pdev, child);
else if (of_node_cmp(child->name, "ethernet") == 0 ||
of_node_cmp(child->name, "nor") == 0)
of_node_cmp(child->name, "nor") == 0 ||
of_node_cmp(child->name, "uart") == 0)
ret = gpmc_probe_generic_child(pdev, child);
else if (of_node_cmp(child->name, "8250") == 0)
ret = gpmc_probe_8250(pdev, child);
if (WARN(ret < 0, "%s: probing gpmc child %s failed\n",
__func__, child->full_name))
......
......@@ -76,6 +76,13 @@ static inline void omap_barrier_reserve_memblock(void)
{ }
#endif
#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
void set_cntfreq(void);
#else
static inline void set_cntfreq(void)
{
}
#endif
#endif /* __ASSEMBLER__ */
#endif /* OMAP_ARCH_OMAP_SECURE_H */
......@@ -35,7 +35,6 @@
#include "iomap.h"
#include "common.h"
#include "mmc.h"
#include "hsmmc.h"
#include "prminst44xx.h"
#include "prcm_mpu44xx.h"
#include "omap4-sar-layout.h"
......@@ -284,59 +283,3 @@ void __init omap_gic_of_init(void)
omap_wakeupgen_init();
irqchip_init();
}
#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
static int omap4_twl6030_hsmmc_late_init(struct device *dev)
{
int irq = 0;
struct platform_device *pdev = container_of(dev,
struct platform_device, dev);
struct omap_mmc_platform_data *pdata = dev->platform_data;
/* Setting MMC1 Card detect Irq */
if (pdev->id == 0) {
irq = twl6030_mmc_card_detect_config();
if (irq < 0) {
dev_err(dev, "%s: Error card detect config(%d)\n",
__func__, irq);
return irq;
}
pdata->slots[0].card_detect_irq = irq;
pdata->slots[0].card_detect = twl6030_mmc_card_detect;
}
return 0;
}
static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
{
struct omap_mmc_platform_data *pdata;
/* dev can be null if CONFIG_MMC_OMAP_HS is not set */
if (!dev) {
pr_err("Failed %s\n", __func__);
return;
}
pdata = dev->platform_data;
pdata->init = omap4_twl6030_hsmmc_late_init;
}
int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
{
struct omap2_hsmmc_info *c;
omap_hsmmc_init(controllers);
for (c = controllers; c->mmc; c++) {
/* pdev can be null if CONFIG_MMC_OMAP_HS is not set */
if (!c->pdev)
continue;
omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
}
return 0;
}
#else
int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
{
return 0;
}
#endif
......@@ -120,7 +120,7 @@ static void omap3_save_secure_ram_context(void)
* will hang the system.
*/
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
ret = _omap_save_secure_sram((u32 *)
ret = _omap_save_secure_sram((u32 *)(unsigned long)
__pa(omap3_secure_ram_storage));
pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state);
/* Following is for error tracking, it should not happen */
......
......@@ -43,7 +43,7 @@ extern void omap4_prm_vcvp_write(u32 val, u8 offset);
extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
defined(CONFIG_SOC_DRA7XX)
defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
void omap44xx_prm_reconfigure_io_chain(void);
#else
static inline void omap44xx_prm_reconfigure_io_chain(void)
......
......@@ -53,6 +53,11 @@
#define A15_BX_ADDR0 0x68
#define A7_BX_ADDR0 0x78
/* SPC CPU/cluster reset statue */
#define STANDBYWFI_STAT 0x3c
#define STANDBYWFI_STAT_A15_CPU_MASK(cpu) (1 << (cpu))
#define STANDBYWFI_STAT_A7_CPU_MASK(cpu) (1 << (3 + (cpu)))
/* SPC system config interface registers */
#define SYSCFG_WDATA 0x70
#define SYSCFG_RDATA 0x74
......@@ -213,6 +218,41 @@ void ve_spc_powerdown(u32 cluster, bool enable)
writel_relaxed(enable, info->baseaddr + pwdrn_reg);
}
static u32 standbywfi_cpu_mask(u32 cpu, u32 cluster)
{
return cluster_is_a15(cluster) ?
STANDBYWFI_STAT_A15_CPU_MASK(cpu)
: STANDBYWFI_STAT_A7_CPU_MASK(cpu);
}
/**
* ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
*
* @cpu: mpidr[7:0] bitfield describing CPU affinity level within cluster
* @cluster: mpidr[15:8] bitfield describing cluster affinity level
*
* @return: non-zero if and only if the specified CPU is in WFI
*
* Take care when interpreting the result of this function: a CPU might
* be in WFI temporarily due to idle, and is not necessarily safely
* parked.
*/
int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
{
int ret;
u32 mask = standbywfi_cpu_mask(cpu, cluster);
if (cluster >= MAX_CLUSTERS)
return 1;
ret = readl_relaxed(info->baseaddr + STANDBYWFI_STAT);
pr_debug("%s: PCFGREG[0x%X] = 0x%08X, mask = 0x%X\n",
__func__, STANDBYWFI_STAT, ret, mask);
return ret & mask;
}
static int ve_spc_get_performance(int cluster, u32 *freq)
{
struct ve_spc_opp *opps = info->opps[cluster];
......
......@@ -20,5 +20,6 @@ void ve_spc_global_wakeup_irq(bool set);
void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set);
void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr);
void ve_spc_powerdown(u32 cluster, bool enable);
int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster);
#endif
......@@ -12,6 +12,7 @@
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
......@@ -32,11 +33,17 @@
#include "spc.h"
/* SCC conf registers */
#define RESET_CTRL 0x018
#define RESET_A15_NCORERESET(cpu) (1 << (2 + (cpu)))
#define RESET_A7_NCORERESET(cpu) (1 << (16 + (cpu)))
#define A15_CONF 0x400
#define A7_CONF 0x500
#define SYS_INFO 0x700
#define SPC_BASE 0xb00
static void __iomem *scc;
/*
* We can't use regular spinlocks. In the switcher case, it is possible
* for an outbound CPU to call power_down() after its inbound counterpart
......@@ -190,6 +197,55 @@ static void tc2_pm_power_down(void)
tc2_pm_down(0);
}
static int tc2_core_in_reset(unsigned int cpu, unsigned int cluster)
{
u32 mask = cluster ?
RESET_A7_NCORERESET(cpu)
: RESET_A15_NCORERESET(cpu);
return !(readl_relaxed(scc + RESET_CTRL) & mask);
}
#define POLL_MSEC 10
#define TIMEOUT_MSEC 1000
static int tc2_pm_power_down_finish(unsigned int cpu, unsigned int cluster)
{
unsigned tries;
pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; ++tries) {
/*
* Only examine the hardware state if the target CPU has
* caught up at least as far as tc2_pm_down():
*/
if (ACCESS_ONCE(tc2_pm_use_count[cpu][cluster]) == 0) {
pr_debug("%s(cpu=%u, cluster=%u): RESET_CTRL = 0x%08X\n",
__func__, cpu, cluster,
readl_relaxed(scc + RESET_CTRL));
/*
* We need the CPU to reach WFI, but the power
* controller may put the cluster in reset and
* power it off as soon as that happens, before
* we have a chance to see STANDBYWFI.
*
* So we need to check for both conditions:
*/
if (tc2_core_in_reset(cpu, cluster) ||
ve_spc_cpu_in_wfi(cpu, cluster))
return 0; /* success: the CPU is halted */
}
/* Otherwise, wait and retry: */
msleep(POLL_MSEC);
}
return -ETIMEDOUT; /* timeout */
}
static void tc2_pm_suspend(u64 residency)
{
unsigned int mpidr, cpu, cluster;
......@@ -234,6 +290,7 @@ static void tc2_pm_powered_up(void)
static const struct mcpm_platform_ops tc2_pm_power_ops = {
.power_up = tc2_pm_power_up,
.power_down = tc2_pm_power_down,
.power_down_finish = tc2_pm_power_down_finish,
.suspend = tc2_pm_suspend,
.powered_up = tc2_pm_powered_up,
};
......@@ -269,7 +326,6 @@ static void __naked tc2_pm_power_up_setup(unsigned int affinity_level)
static int __init tc2_pm_init(void)
{
int ret, irq;
void __iomem *scc;
u32 a15_cluster_id, a7_cluster_id, sys_info;
struct device_node *np;
......
......@@ -354,17 +354,18 @@ static void twl_set(struct gpio_chip *chip, unsigned offset, int value)
static int twl_direction_out(struct gpio_chip *chip, unsigned offset, int value)
{
struct gpio_twl4030_priv *priv = to_gpio_twl4030(chip);
int ret = -EINVAL;
mutex_lock(&priv->mutex);
if (offset < TWL4030_GPIO_MAX)
twl4030_set_gpio_dataout(offset, value);
ret = twl4030_set_gpio_direction(offset, 0);
priv->direction |= BIT(offset);
mutex_unlock(&priv->mutex);
twl_set(chip, offset, value);
return 0;
return ret;
}
static int twl_to_irq(struct gpio_chip *chip, unsigned offset)
......@@ -435,7 +436,8 @@ static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
static int gpio_twl4030_remove(struct platform_device *pdev);
static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev,
struct twl4030_gpio_platform_data *pdata)
{
struct twl4030_gpio_platform_data *omap_twl_info;
......@@ -443,6 +445,9 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
if (!omap_twl_info)
return NULL;
if (pdata)
*omap_twl_info = *pdata;
omap_twl_info->use_leds = of_property_read_bool(dev->of_node,
"ti,use-leds");
......@@ -500,7 +505,7 @@ static int gpio_twl4030_probe(struct platform_device *pdev)
mutex_init(&priv->mutex);
if (node)
pdata = of_gpio_twl4030(&pdev->dev);
pdata = of_gpio_twl4030(&pdev->dev, pdata);
if (pdata == NULL) {
dev_err(&pdev->dev, "Platform data is missing\n");
......
......@@ -1037,6 +1037,20 @@ static const struct i2c_algorithm omap_i2c_algo = {
};
#ifdef CONFIG_OF
static struct omap_i2c_bus_platform_data omap2420_pdata = {
.rev = OMAP_I2C_IP_VERSION_1,
.flags = OMAP_I2C_FLAG_NO_FIFO |
OMAP_I2C_FLAG_SIMPLE_CLOCK |
OMAP_I2C_FLAG_16BIT_DATA_REG |
OMAP_I2C_FLAG_BUS_SHIFT_2,
};
static struct omap_i2c_bus_platform_data omap2430_pdata = {
.rev = OMAP_I2C_IP_VERSION_1,
.flags = OMAP_I2C_FLAG_BUS_SHIFT_2 |
OMAP_I2C_FLAG_FORCE_19200_INT_CLK,
};
static struct omap_i2c_bus_platform_data omap3_pdata = {
.rev = OMAP_I2C_IP_VERSION_1,
.flags = OMAP_I2C_FLAG_BUS_SHIFT_2,
......@@ -1055,6 +1069,14 @@ static const struct of_device_id omap_i2c_of_match[] = {
.compatible = "ti,omap3-i2c",
.data = &omap3_pdata,
},
{
.compatible = "ti,omap2430-i2c",
.data = &omap2430_pdata,
},
{
.compatible = "ti,omap2420-i2c",
.data = &omap2420_pdata,
},
{ },
};
MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
......
......@@ -45,6 +45,7 @@ struct clk;
#define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D
#ifdef CONFIG_ARCH_TEGRA
int tegra_powergate_is_powered(int id);
int tegra_powergate_power_on(int id);
int tegra_powergate_power_off(int id);
......@@ -52,5 +53,31 @@ int tegra_powergate_remove_clamping(int id);
/* Must be called with clk disabled, and returns with clk enabled */
int tegra_powergate_sequence_power_up(int id, struct clk *clk);
#else
static inline int tegra_powergate_is_powered(int id)
{
return -ENOSYS;
}
static inline int tegra_powergate_power_on(int id)
{
return -ENOSYS;
}
static inline int tegra_powergate_power_off(int id)
{
return -ENOSYS;
}
static inline int tegra_powergate_remove_clamping(int id)
{
return -ENOSYS;
}
static inline int tegra_powergate_sequence_power_up(int id, struct clk *clk)
{
return -ENOSYS;
}
#endif
#endif /* _MACH_TEGRA_POWERGATE_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment