aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dearman <chris.dearman@imgtec.com>2016-02-16 10:45:45 -0800
committerChris Dearman <chris.dearman@imgtec.com>2016-02-16 13:06:37 -0800
commit217d0c79fea0526b2400301eaf20147d21dfde9c (patch)
treee397323a4644cbb7d03349fdb7c3bd6da57d9e9a
parent70c68b8d90c19f04ff2ecc751428426e87f25bc8 (diff)
downloadv4.1-217d0c79fea0526b2400301eaf20147d21dfde9c.tar.gz
Merge commit imgsystems/4.1-imgsystems into aosp/master
This is a partial merge of the imgsystems/4.1-imgsystems branch before the 4.2 USB updates are imported; the 4.2 USB changes will cause some additional conflicts with the Android USB changes. Conflicts: arch/mips/boot/dts/pistachio/Makefile arch/mips/boot/dts/pistachio/pistachio_marduk.dts Change-Id: I560904bc1cbbc28cf33337ebd21555138d42a557
-rw-r--r--arch/mips/boot/dts/pistachio/Makefile2
-rw-r--r--arch/mips/boot/dts/pistachio/pistachio.dtsi2
-rw-r--r--arch/mips/boot/dts/pistachio/pistachio_marduk.dts2
-rw-r--r--arch/mips/configs/pistachio_defconfig3
-rw-r--r--drivers/clk/pistachio/clk-pistachio.c8
-rw-r--r--drivers/clocksource/time-pistachio.c2
-rw-r--r--drivers/i2c/busses/i2c-img-scb.c185
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c4
-rw-r--r--drivers/spi/spi-img-spfi.c10
9 files changed, 90 insertions, 128 deletions
diff --git a/arch/mips/boot/dts/pistachio/Makefile b/arch/mips/boot/dts/pistachio/Makefile
index c3f4b766351..3a18b2cde42 100644
--- a/arch/mips/boot/dts/pistachio/Makefile
+++ b/arch/mips/boot/dts/pistachio/Makefile
@@ -1,4 +1,4 @@
-dtb-$(CONFIG_MACH_PISTACHIO) += pistachio_bub.dtb pistachio_fpga.dtb pistachio_marduk.dtb pistachio_concerto_mbub.dtb pistachio_beetle_mbub.dtb
+dtb-$(CONFIG_MACH_PISTACHIO) += pistachio_bub.dtb pistachio_fpga.dtb pistachio_marduk.dtb
obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
diff --git a/arch/mips/boot/dts/pistachio/pistachio.dtsi b/arch/mips/boot/dts/pistachio/pistachio.dtsi
index ffaddc3ad92..05222e88250 100644
--- a/arch/mips/boot/dts/pistachio/pistachio.dtsi
+++ b/arch/mips/boot/dts/pistachio/pistachio.dtsi
@@ -938,7 +938,7 @@
pinctrl-names = "default";
fifo-depth = <0x20>;
num-slots = <1>;
- clock-frequency = <200000000>;
+ clock-frequency = <50000000>;
bus-width = <8>;
cap-mmc-highspeed;
cap-sd-highspeed;
diff --git a/arch/mips/boot/dts/pistachio/pistachio_marduk.dts b/arch/mips/boot/dts/pistachio/pistachio_marduk.dts
index 511386e4cac..d6268371351 100644
--- a/arch/mips/boot/dts/pistachio/pistachio_marduk.dts
+++ b/arch/mips/boot/dts/pistachio/pistachio_marduk.dts
@@ -246,7 +246,7 @@
&sdhost {
status = "okay";
- bus-width = <4>;
+ bus-width = <4>;
disable-wp;
};
diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig
index 8e83ce1e9e3..2c602dec58d 100644
--- a/arch/mips/configs/pistachio_defconfig
+++ b/arch/mips/configs/pistachio_defconfig
@@ -37,6 +37,8 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_CPU_FREQ=y
@@ -168,7 +170,6 @@ CONFIG_ZRAM=m
CONFIG_BLK_DEV_LOOP=y
CONFIG_SRAM=y
CONFIG_ATU=y
-CONFIG_SND_SOC_IMG_PISTACHIO_EVENT_TIMER_ATU=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=m
diff --git a/drivers/clk/pistachio/clk-pistachio.c b/drivers/clk/pistachio/clk-pistachio.c
index 87e5b6ef551..fd64bd93625 100644
--- a/drivers/clk/pistachio/clk-pistachio.c
+++ b/drivers/clk/pistachio/clk-pistachio.c
@@ -286,10 +286,10 @@ static struct pistachio_div pistachio_periph_divs[] __initdata = {
DIV(PERIPH_CLK_ROM_DIV, "rom_div", "periph_sys", 0x10c, 7),
DIV(PERIPH_CLK_COUNTER_FAST_DIV, "counter_fast_div", "periph_sys",
0x110, 7),
- DIV(PERIPH_CLK_COUNTER_SLOW_PRE_DIV, "counter_slow_pre_div",
- "periph_sys", 0x114, 7),
- DIV(PERIPH_CLK_COUNTER_SLOW_DIV, "counter_slow_div",
- "counter_slow_pre_div", 0x118, 7),
+ DIV_F(PERIPH_CLK_COUNTER_SLOW_PRE_DIV, "counter_slow_pre_div",
+ "periph_sys", 0x114, 7, 0, CLK_DIVIDER_ROUND_CLOSEST),
+ DIV_F(PERIPH_CLK_COUNTER_SLOW_DIV, "counter_slow_div",
+ "counter_slow_pre_div", 0x118, 7, 0, CLK_DIVIDER_ROUND_CLOSEST),
DIV_F(PERIPH_CLK_IR_PRE_DIV, "ir_pre_div", "periph_sys", 0x11c, 7,
0, CLK_DIVIDER_ROUND_CLOSEST),
DIV_F(PERIPH_CLK_IR_DIV, "ir_div", "ir_pre_div", 0x120, 7,
diff --git a/drivers/clocksource/time-pistachio.c b/drivers/clocksource/time-pistachio.c
index 4540d2b2c02..a29a0934ff8 100644
--- a/drivers/clocksource/time-pistachio.c
+++ b/drivers/clocksource/time-pistachio.c
@@ -146,7 +146,7 @@ static void __init pistachio_clksrc_of_init(struct device_node *node)
/* Switch to using the fast counter clock */
ret = regmap_update_bits(periph_regs, PERIP_TIMER_CONTROL,
- 0xf, 0x0);
+ 0x1, 0x0);
if (ret)
return;
diff --git a/drivers/i2c/busses/i2c-img-scb.c b/drivers/i2c/busses/i2c-img-scb.c
index bb98088402e..379ef9c3166 100644
--- a/drivers/i2c/busses/i2c-img-scb.c
+++ b/drivers/i2c/busses/i2c-img-scb.c
@@ -280,8 +280,6 @@
#define ISR_COMPLETE(err) (ISR_COMPLETE_M | (ISR_STATUS_M & (err)))
#define ISR_FATAL(err) (ISR_COMPLETE(err) | ISR_FATAL_M)
-#define REL_SOC_IP_SCB_2_2_1 0x00020201
-
enum img_i2c_mode {
MODE_INACTIVE,
MODE_RAW,
@@ -511,22 +509,8 @@ static void img_i2c_soft_reset(struct img_i2c *i2c)
{
i2c->t_halt = false;
img_i2c_writel(i2c, SCB_CONTROL_REG, 0);
-
- /* Disable all interrupts */
- img_i2c_writel(i2c, SCB_INT_MASK_REG, 0);
-
- /* Clear all interrupts */
- img_i2c_writel(i2c, SCB_INT_CLEAR_REG, ~0);
-
- /* Clear the scb_line_status events */
- img_i2c_writel(i2c, SCB_CLEAR_REG, ~0);
-
img_i2c_writel(i2c, SCB_CONTROL_REG,
SCB_CONTROL_CLK_ENABLE | SCB_CONTROL_SOFT_RESET);
-
- /* Enable interrupts */
- img_i2c_switch_mode(i2c, MODE_INACTIVE);
- img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable);
}
/*
@@ -638,10 +622,7 @@ static void img_i2c_complete_transaction(struct img_i2c *i2c, int status)
img_i2c_switch_mode(i2c, MODE_INACTIVE);
if (status) {
i2c->msg_status = status;
- img_i2c_soft_reset(i2c);
- } else {
- img_i2c_writel(i2c, SCB_INT_CLEAR_REG, ~0);
- img_i2c_writel(i2c, SCB_CLEAR_REG, ~0);
+ img_i2c_transaction_halt(i2c, false);
}
complete(&i2c->msg_complete);
}
@@ -780,8 +761,8 @@ static unsigned int img_i2c_atomic(struct img_i2c *i2c,
break;
case CMD_RET_ACK:
if (i2c->line_status & LINESTAT_ACK_DET ||
- (i2c->line_status & LINESTAT_NACK_DET
- && i2c->msg.flags & I2C_M_IGNORE_NAK)) {
+ (i2c->line_status & LINESTAT_NACK_DET &&
+ i2c->msg.flags & I2C_M_IGNORE_NAK)) {
if (i2c->msg.len == 0) {
next_cmd = CMD_GEN_STOP;
} else if (i2c->msg.flags & I2C_M_RD) {
@@ -888,87 +869,42 @@ static unsigned int img_i2c_auto(struct img_i2c *i2c,
}
/* Enable transaction halt on start bit */
- if (i2c->line_status & LINESTAT_START_BIT_DET) {
- if (!i2c->last_msg) {
- img_i2c_transaction_halt(i2c, true);
- /* we're no longer interested in the slave event */
- i2c->int_enable &= ~INT_SLAVE_EVENT;
- }
- /*
- * Remove start bit detected status after it is handled,
- * doing so will prevent this condition being hit for
- * every interrupt on a particular transfer.
- */
- i2c->line_status &= ~LINESTAT_START_BIT_DET;
+ if (!i2c->last_msg && line_status & LINESTAT_START_BIT_DET) {
+ img_i2c_transaction_halt(i2c, !i2c->last_msg);
+ /* we're no longer interested in the slave event */
+ i2c->int_enable &= ~INT_SLAVE_EVENT;
}
mod_timer(&i2c->check_timer, jiffies + msecs_to_jiffies(1));
+ if (int_status & INT_STOP_DETECTED) {
+ /* Drain remaining data in FIFO and complete transaction */
+ if (i2c->msg.flags & I2C_M_RD)
+ img_i2c_read_fifo(i2c);
+ return ISR_COMPLETE(0);
+ }
+
if (i2c->msg.flags & I2C_M_RD) {
- if (int_status & INT_MASTER_HALTED) {
+ if (int_status & (INT_FIFO_FULL_FILLING | INT_MASTER_HALTED)) {
img_i2c_read_fifo(i2c);
if (i2c->msg.len == 0)
- return ISR_COMPLETE(0);
- /*
- * By releasing and then enabling transaction halt,
- * trying to allow only a single byte to proceed.
- */
- img_i2c_transaction_halt(i2c, false);
- img_i2c_transaction_halt(i2c, !i2c->last_msg);
- }
- if (int_status & INT_FIFO_FULL_FILLING) {
- img_i2c_read_fifo(i2c);
- if (i2c->msg.len == 0) {
- if (i2c->last_msg)
- return ISR_WAITSTOP;
- return ISR_COMPLETE(0);
- }
- }
- if (int_status & INT_STOP_DETECTED) {
- int ret;
- /*
- * Stop bit indicates the end of the transfer, it means
- * we should read all the data (or drain the FIFO). We
- * must signal completion for this transaction.
- */
- img_i2c_transaction_halt(i2c, false);
- img_i2c_read_fifo(i2c);
- ret = (i2c->msg.len == 0) ? 0 : EIO;
- return ISR_COMPLETE(ret);
+ return ISR_WAITSTOP;
}
} else {
- if (int_status & INT_MASTER_HALTED) {
+ if (int_status & (INT_FIFO_EMPTY | INT_MASTER_HALTED)) {
if ((int_status & INT_FIFO_EMPTY) &&
- i2c->msg.len == 0)
- return ISR_COMPLETE(0);
- img_i2c_write_fifo(i2c);
- /*
- * By releasing and then enabling transaction halt,
- * trying to allow only a single byte to proceed.
- */
- img_i2c_transaction_halt(i2c, false);
- img_i2c_transaction_halt(i2c, !i2c->last_msg);
- }
- if (int_status & INT_FIFO_EMPTY) {
- if (i2c->msg.len == 0) {
- if (i2c->last_msg)
- return ISR_WAITSTOP;
- return ISR_COMPLETE(0);
- }
+ i2c->msg.len == 0)
+ return ISR_WAITSTOP;
img_i2c_write_fifo(i2c);
}
- if (int_status & INT_STOP_DETECTED) {
- int ret;
-
- img_i2c_transaction_halt(i2c, false);
- /*
- * Stop bit indicates the end of a transfer and if the
- * transfer has finished before all data is written to
- * the fifo return error with transfer complete signal.
- */
- ret = (i2c->msg.len == 0) ? 0 : EIO;
- return ISR_COMPLETE(ret);
- }
+ }
+ if (int_status & INT_MASTER_HALTED) {
+ /*
+ * Release and then enable transaction halt, to
+ * allow only a single byte to proceed.
+ */
+ img_i2c_transaction_halt(i2c, false);
+ img_i2c_transaction_halt(i2c, !i2c->last_msg);
}
return 0;
@@ -1147,6 +1083,15 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
i2c->last_msg = (i == num - 1);
reinit_completion(&i2c->msg_complete);
+ /*
+ * Clear line status and all interrupts before starting a
+ * transfer, as we may have unserviced interrupts from
+ * previous transfers that might be handled in the context
+ * of the new transfer.
+ */
+ img_i2c_writel(i2c, SCB_INT_CLEAR_REG, ~0);
+ img_i2c_writel(i2c, SCB_CLEAR_REG, ~0);
+
if (atomic) {
img_i2c_atomic_start(i2c);
} else {
@@ -1162,8 +1107,8 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
img_i2c_write(i2c);
/*
- * By releasing and then enabling transaction halt,
- * trying to allow only a single byte to proceed.
+ * Release and then enable transaction halt, to
+ * allow only a single byte to proceed.
* This doesn't have an effect on the initial transfer
* but will allow the following transfers to start
* processing if the previous transfer was marked as
@@ -1181,7 +1126,6 @@ static int img_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
if (time_left == 0) {
dev_err(adap->dev.parent, "i2c transfer timed out\n");
i2c->msg_status = -ETIMEDOUT;
- img_i2c_soft_reset(i2c);
break;
}
@@ -1225,13 +1169,8 @@ static int img_i2c_init(struct img_i2c *i2c)
return -EINVAL;
}
- if (rev >= REL_SOC_IP_SCB_2_2_1) {
- i2c->need_wr_rd_fence = true;
- dev_info(i2c->adap.dev.parent, "fence quirk enabled");
- }
-
- bitrate_khz = i2c->bitrate / 1000;
- clk_khz = clk_get_rate(i2c->scb_clk) / 1000;
+ /* Fencing enabled by default. */
+ i2c->need_wr_rd_fence = true;
/* Determine what mode we're in from the bitrate */
timing = timings[0];
@@ -1241,13 +1180,18 @@ static int img_i2c_init(struct img_i2c *i2c)
break;
}
}
- if (i2c->bitrate > timing.max_bitrate) {
- dev_err(i2c->adap.dev.parent,
- "requested bitrate (%d) not supported\n",
- i2c->bitrate);
- return -EINVAL;
+ if (i2c->bitrate > timings[ARRAY_SIZE(timings) - 1].max_bitrate) {
+ dev_warn(i2c->adap.dev.parent,
+ "requested bitrate (%u) is higher than the max bitrate supported (%u)\n",
+ i2c->bitrate,
+ timings[ARRAY_SIZE(timings) - 1].max_bitrate);
+ timing = timings[ARRAY_SIZE(timings) - 1];
+ i2c->bitrate = timing.max_bitrate;
}
+ bitrate_khz = i2c->bitrate / 1000;
+ clk_khz = clk_get_rate(i2c->scb_clk) / 1000;
+
/* Find the prescale that would give us that inc (approx delay = 0) */
prescale = SCB_OPT_INC * clk_khz / (256 * 16 * bitrate_khz);
prescale = clamp_t(unsigned int, prescale, 1, 8);
@@ -1297,14 +1241,11 @@ static int img_i2c_init(struct img_i2c *i2c)
* Setup clock duty cycle, start with 50% and adjust TCKH and TCKL
* values from there if they don't meet minimum timing requirements
*/
- tckh = tckl = int_bitrate / 2;
- if (int_bitrate % 2)
- tckl++;
+ tckh = int_bitrate / 2;
+ tckl = int_bitrate - tckh;
/* Adjust TCKH and TCKL values */
- data = timing.tckl / clk_period;
- if (timing.tckl % clk_period)
- data++;
+ data = DIV_ROUND_UP(timing.tckl, clk_period);
if (tckl < data) {
tckl = data;
@@ -1312,18 +1253,16 @@ static int img_i2c_init(struct img_i2c *i2c)
}
if (tckh > 0)
- tckh -= 1;
+ --tckh;
if (tckl > 0)
- tckl -= 1;
+ --tckl;
img_i2c_writel(i2c, SCB_TIME_TCKH_REG, tckh);
img_i2c_writel(i2c, SCB_TIME_TCKL_REG, tckl);
/* Setup TSDH value */
- tsdh = timing.tsdh / clk_period;
- if (timing.tsdh % clk_period)
- tsdh++;
+ tsdh = DIV_ROUND_UP(timing.tsdh, clk_period);
if (tsdh > 1)
data = tsdh - 1;
@@ -1362,6 +1301,18 @@ static int img_i2c_init(struct img_i2c *i2c)
/* Take module out of soft reset and enable clocks */
img_i2c_soft_reset(i2c);
+ /* Disable all interrupts */
+ img_i2c_writel(i2c, SCB_INT_MASK_REG, 0);
+
+ /* Clear all interrupts */
+ img_i2c_writel(i2c, SCB_INT_CLEAR_REG, ~0);
+
+ /* Clear the scb_line_status events */
+ img_i2c_writel(i2c, SCB_CLEAR_REG, ~0);
+
+ /* Enable interrupts */
+ img_i2c_writel(i2c, SCB_INT_MASK_REG, i2c->int_enable);
+
/* Perform a synchronous sequence to reset the bus */
ret = img_i2c_reset_bus(i2c);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7a084a2efd1..483112dedb2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3029,6 +3029,10 @@ int stmmac_suspend(struct net_device *ndev)
stmmac_clear_descriptors(priv);
+ /* Release the DMA TX/RX socket buffers */
+ dma_free_rx_skbufs(priv);
+ dma_free_tx_skbufs(priv);
+
/* Enable Power down mode by programming the PMT regs */
if (device_may_wakeup(priv->device)) {
priv->hw->mac->pmt(priv->hw, priv->wolopts);
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c
index 5dba219db4b..c31195892ed 100644
--- a/drivers/spi/spi-img-spfi.c
+++ b/drivers/spi/spi-img-spfi.c
@@ -551,8 +551,14 @@ static void img_spfi_config(struct spi_master *master, struct spi_device *spi,
spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select));
if (!list_is_last(&xfer->transfer_list, &master->cur_msg->transfers) &&
- (xfer->tx_buf) && (xfer->len <= SPFI_DATA_REQUEST_MAX_SIZE)
- && !is_pending) {
+ /*
+ * For duplex mode (both the tx and rx buffers are !NULL) the
+ * CMD, ADDR, and DUMMY byte parts of the transaction register
+ * should always be 0 and therefore the pending transfer
+ * technique cannot be used.
+ */
+ (xfer->tx_buf) && (!xfer->rx_buf) &&
+ (xfer->len <= SPFI_DATA_REQUEST_MAX_SIZE) && !is_pending) {
transact = (1 & SPFI_TRANSACTION_CMD_MASK) <<
SPFI_TRANSACTION_CMD_SHIFT;
transact |= ((xfer->len - 1) & SPFI_TRANSACTION_ADDR_MASK) <<