diff options
author | Chris Dearman <chris.dearman@imgtec.com> | 2016-02-16 10:45:45 -0800 |
---|---|---|
committer | Chris Dearman <chris.dearman@imgtec.com> | 2016-02-16 13:06:37 -0800 |
commit | 217d0c79fea0526b2400301eaf20147d21dfde9c (patch) | |
tree | e397323a4644cbb7d03349fdb7c3bd6da57d9e9a | |
parent | 70c68b8d90c19f04ff2ecc751428426e87f25bc8 (diff) | |
download | v4.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/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/boot/dts/pistachio/pistachio.dtsi | 2 | ||||
-rw-r--r-- | arch/mips/boot/dts/pistachio/pistachio_marduk.dts | 2 | ||||
-rw-r--r-- | arch/mips/configs/pistachio_defconfig | 3 | ||||
-rw-r--r-- | drivers/clk/pistachio/clk-pistachio.c | 8 | ||||
-rw-r--r-- | drivers/clocksource/time-pistachio.c | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-img-scb.c | 185 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-img-spfi.c | 10 |
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) << |