* [Patch v3 2/2] dmaengine: qcom_bam_dma: Add device tree binding
From: Andy Gross @ 2014-01-30 6:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4697306.PPWWh8UGTE@wuerfel>
On Tue, Jan 28, 2014 at 10:16:53AM +0100, Arnd Bergmann wrote:
> On Tuesday 28 January 2014 10:05:35 Lars-Peter Clausen wrote:
> > > +
> > > +Clients must use the format described in the dma.txt file, using a three cell
> > > +specifier for each channel.
> > > +
> > > +The three cells in order are:
> > > + 1. A phandle pointing to the DMA controller
> > > + 2. The channel number
> > > + 3. Direction of the fixed unidirectional channel
> > > + 0 - Memory to Device
> > > + 1 - Device to Memory
> > > + 2 - Device to Device
> > > +
> >
> > Why does the direction needs to be specified in specifier? I see two
> > options, either the direction per is fixed in hardware. In that case the DMA
> > controller node should describe which channel is which direction. Or the
> > direction is not fixed in hardware and can be changed at runtime in which
> > case it should be set on a per descriptor basis.
>
> Normally the direction is implied by dmaengine_slave_config().
> Note that neither the dma slave API nor the generic DT binding
> can actually support device-to-device transfers, since this
> normally implies using two dma-request lines rather than one.
>
> There might be a case where the direction is required in order
> to allocate a channel, because the engine has specialized channels
> per direction, and might connect any of them to any dma request
> line. This does not seem to be the case for "bam", because
> the DMA specifier already contains a specific channel number, not
> a request line or slave ID number.
After some deliberation, I think the best solution is removing the direction
from the DT for now. It doesn't add anything except some verification
of direction.
As for the device to device:
As I mentioned before, each bam dma node is attached to a specific peripheral
(with one exception, but lets skip over that). The peripherals allow for more
than one execution environment to access the peripheral and attached bam. 2 bam
channels can be connected to form a unidirectional pipe from one execution
environment to another. Once the pipe is configured, the actually transfer
resembles a cyclical dma transfer and continues until you explicitly stop it.
That functionality will come later.
--
sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* [PATCH V2] arm64: add DSB after icache flush in __flush_icache_all()
From: Vinayak Kale @ 2014-01-30 6:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128161402.GI2885@mudshark.cambridge.arm.com>
Hi Will,
On Tue, Jan 28, 2014 at 9:44 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jan 28, 2014 at 07:06:53AM +0000, Vinayak Kale wrote:
>> Add DSB after icache flush. It's needed to complete the cache maintenance
>> operation. The function __flush_icache_all() is used only for user space
>> mappings and an ISB is not required because of an exception return before
>> executing user instructions. An exception return would behave like an ISB.
>>
>> This patch also uses 'memory' clobber for flush operation instruction to
>> prevent instruction re-ordering by compiler.
>>
>> Signed-off-by: Vinayak Kale <vkale@apm.com>
>> ---
>>
>> V2: - Add more desciption in the commit message as suggested by Catalin & Will
>> - Use 'memory' clobber for flush instruction as suggested by Will
>
> Please can you check and fix other occurrences of this bug too, as I asked
> in v1? For example, a 2 second grep shows problems with data-cache
> maintenance in kvm. I can also see the same problem for system register
> writes followed up with isb.
Can you please elaborate whether you are referring to lack of memory
clobber or missing barriers?
>
> I also don't buy you not being able to test AArch32 kernels. Does KVM not
> work for you?
Let me see what I can do to address this.
>
> Will
>
>>
>> arch/arm64/include/asm/cacheflush.h | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
>> index fea9ee3..bd30f42 100644
>> --- a/arch/arm64/include/asm/cacheflush.h
>> +++ b/arch/arm64/include/asm/cacheflush.h
>> @@ -115,7 +115,8 @@ extern void flush_dcache_page(struct page *);
>>
>> static inline void __flush_icache_all(void)
>> {
>> - asm("ic ialluis");
>> + asm volatile("ic ialluis" : : : "memory");
>> + dsb();
>> }
>>
>> #define flush_dcache_mmap_lock(mapping) \
>> --
>> 1.8.2.1
>>
>>
^ permalink raw reply
* [PATCH v2 0/2] drivers/media: Add controls for Horizontal and Vertical MV Search Range
From: Sachin Kamat @ 2014-01-30 6:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391060563-27015-1-git-send-email-amit.grover@samsung.com>
Hi Amit,
On 30 January 2014 11:12, Amit Grover <amit.grover@samsung.com> wrote:
> Based on 'master' branch of Linux-next.
Kamil's tree [1] would be more current most of the times for this driver.
[1] git://linuxtv.org/kdebski/media.git
> This is v2 version for the patch:
> s5p-mfc: Add Horizontal and Vertical search range for Video Macro Blocks
> (https://lkml.org/lkml/2013/12/30/83)
>
> Changes from v1:
> 1) Splitted the patch into v4l2 and mfc driver patches.
> 2) Incorporated review comments of v1
>
> Amit Grover (2):
> drivers/media: v4l2: Add settings for Horizontal and Vertical MV
> Search Range
> drivers/media: s5p-mfc: Add Horizontal and Vertical MV Search Range
nit: media changes use the following title format:
[media] v4l2: Add settings for Horizontal and Vertical MV Search Range
[media] s5p-mfc: Add Horizontal and Vertical MV Search Range
--
With warm regards,
Sachin
^ permalink raw reply
* [PATCH] serial: sirf: move to use generic dma dt-binding to get dma channels
From: Barry Song @ 2014-01-30 5:57 UTC (permalink / raw)
To: linux-arm-kernel
From: Qipan Li <Qipan.Li@csr.com>
instead of using sirf specific dma channel property like "sirf,uart-dma-rx-channel"
and "sirf,uart-dma-tx-channel", here we move to use generic dma dt-binding to get
the channel like:
- sirf,uart-dma-rx-channel = <21>;
- sirf,uart-dma-tx-channel = <2>;
+ dmas = <&dmac1 5>, <&dmac0 2>;
+ dma-names = "rx", "tx";
and we move dma_request_channel() to dma_request_slave_channel(), we don't need to
call sirfsoc dma filter function sirfsoc_dma_filter_id() again.
Signed-off-by: Qipan Li <Qipan.Li@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
arch/arm/boot/dts/atlas6.dtsi | 17 ++--
arch/arm/boot/dts/prima2.dtsi | 20 ++--
drivers/tty/serial/sirfsoc_uart.c | 195 ++++++++++++-------------------------
drivers/tty/serial/sirfsoc_uart.h | 5 -
4 files changed, 81 insertions(+), 156 deletions(-)
diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi
index f8674bc..0c81dc9 100644
--- a/arch/arm/boot/dts/atlas6.dtsi
+++ b/arch/arm/boot/dts/atlas6.dtsi
@@ -217,8 +217,8 @@
interrupts = <17>;
fifosize = <128>;
clocks = <&clks 13>;
- sirf,uart-dma-rx-channel = <21>;
- sirf,uart-dma-tx-channel = <2>;
+ dmas = <&dmac1 5>, <&dmac0 2>;
+ dma-names = "rx", "tx";
};
uart1: uart at b0060000 {
@@ -228,6 +228,7 @@
interrupts = <18>;
fifosize = <32>;
clocks = <&clks 14>;
+ dma-names = "no-rx", "no-tx";
};
uart2: uart at b0070000 {
@@ -237,8 +238,8 @@
interrupts = <19>;
fifosize = <128>;
clocks = <&clks 15>;
- sirf,uart-dma-rx-channel = <6>;
- sirf,uart-dma-tx-channel = <7>;
+ dmas = <&dmac0 6>, <&dmac0 7>;
+ dma-names = "rx", "tx";
};
usp0: usp at b0080000 {
@@ -248,8 +249,8 @@
interrupts = <20>;
fifosize = <128>;
clocks = <&clks 28>;
- sirf,usp-dma-rx-channel = <17>;
- sirf,usp-dma-tx-channel = <18>;
+ dmas = <&dmac1 1>, <&dmac1 2>;
+ dma-names = "rx", "tx";
};
usp1: usp at b0090000 {
@@ -259,8 +260,8 @@
interrupts = <21>;
fifosize = <128>;
clocks = <&clks 29>;
- sirf,usp-dma-rx-channel = <14>;
- sirf,usp-dma-tx-channel = <15>;
+ dmas = <&dmac0 14>, <&dmac0 15>;
+ dma-names = "rx", "tx";
};
dmac0: dma-controller at b00b0000 {
diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi
index 0e21993..8582ae4 100644
--- a/arch/arm/boot/dts/prima2.dtsi
+++ b/arch/arm/boot/dts/prima2.dtsi
@@ -223,8 +223,8 @@
interrupts = <17>;
fifosize = <128>;
clocks = <&clks 13>;
- sirf,uart-dma-rx-channel = <21>;
- sirf,uart-dma-tx-channel = <2>;
+ dmas = <&dmac1 5>, <&dmac0 2>;
+ dma-names = "rx", "tx";
};
uart1: uart at b0060000 {
@@ -243,8 +243,8 @@
interrupts = <19>;
fifosize = <128>;
clocks = <&clks 15>;
- sirf,uart-dma-rx-channel = <6>;
- sirf,uart-dma-tx-channel = <7>;
+ dmas = <&dmac0 6>, <&dmac0 7>;
+ dma-names = "rx", "tx";
};
usp0: usp at b0080000 {
@@ -254,8 +254,8 @@
interrupts = <20>;
fifosize = <128>;
clocks = <&clks 28>;
- sirf,usp-dma-rx-channel = <17>;
- sirf,usp-dma-tx-channel = <18>;
+ dmas = <&dmac1 1>, <&dmac1 2>;
+ dma-names = "rx", "tx";
};
usp1: usp at b0090000 {
@@ -265,8 +265,8 @@
interrupts = <21>;
fifosize = <128>;
clocks = <&clks 29>;
- sirf,usp-dma-rx-channel = <14>;
- sirf,usp-dma-tx-channel = <15>;
+ dmas = <&dmac0 14>, <&dmac0 15>;
+ dma-names = "rx", "tx";
};
usp2: usp at b00a0000 {
@@ -276,8 +276,8 @@
interrupts = <22>;
fifosize = <128>;
clocks = <&clks 30>;
- sirf,usp-dma-rx-channel = <10>;
- sirf,usp-dma-tx-channel = <11>;
+ dmas = <&dmac0 10>, <&dmac0 11>;
+ dma-names = "rx", "tx";
};
dmac0: dma-controller at b00b0000 {
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c
index b7bfe24..68b0fd4 100644
--- a/drivers/tty/serial/sirfsoc_uart.c
+++ b/drivers/tty/serial/sirfsoc_uart.c
@@ -24,7 +24,6 @@
#include <linux/dmaengine.h>
#include <linux/dma-direction.h>
#include <linux/dma-mapping.h>
-#include <linux/sirfsoc_dma.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
@@ -173,7 +172,7 @@ static void sirfsoc_uart_stop_tx(struct uart_port *port)
struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
- if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) {
+ if (sirfport->tx_dma_chan) {
if (sirfport->tx_dma_state == TX_DMA_RUNNING) {
dmaengine_pause(sirfport->tx_dma_chan);
sirfport->tx_dma_state = TX_DMA_PAUSE;
@@ -288,7 +287,7 @@ static void sirfsoc_uart_start_tx(struct uart_port *port)
struct sirfsoc_uart_port *sirfport = to_sirfport(port);
struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
- if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no))
+ if (sirfport->tx_dma_chan)
sirfsoc_uart_tx_with_dma(sirfport);
else {
sirfsoc_uart_pio_tx_chars(sirfport, 1);
@@ -310,7 +309,7 @@ static void sirfsoc_uart_stop_rx(struct uart_port *port)
struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0);
- if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) {
+ if (sirfport->rx_dma_chan) {
if (!sirfport->is_marco)
wr_regl(port, ureg->sirfsoc_int_en_reg,
rd_regl(port, ureg->sirfsoc_int_en_reg) &
@@ -675,7 +674,7 @@ recv_char:
uart_handle_cts_change(port, cts_status);
wake_up_interruptible(&state->port.delta_msr_wait);
}
- if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) {
+ if (sirfport->rx_dma_chan) {
if (intr_status & uint_st->sirfsoc_rx_timeout)
sirfsoc_uart_handle_rx_tmo(sirfport);
if (intr_status & uint_st->sirfsoc_rx_done)
@@ -686,7 +685,7 @@ recv_char:
SIRFSOC_UART_IO_RX_MAX_CNT);
}
if (intr_status & uint_st->sirfsoc_txfifo_empty) {
- if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no))
+ if (sirfport->tx_dma_chan)
sirfsoc_uart_tx_with_dma(sirfport);
else {
if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
@@ -778,7 +777,7 @@ static void sirfsoc_uart_start_rx(struct uart_port *port)
wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET);
wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0);
wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START);
- if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no))
+ if (sirfport->rx_dma_chan)
sirfsoc_uart_start_next_rx_dma(port);
else {
if (!sirfport->is_marco)
@@ -1014,11 +1013,11 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
(sample_div_reg & SIRFSOC_USP_ASYNC_DIV2_MASK) <<
SIRFSOC_USP_ASYNC_DIV2_OFFSET);
}
- if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no))
+ if (sirfport->tx_dma_chan)
wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_DMA_MODE);
else
wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_IO_MODE);
- if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no))
+ if (sirfport->rx_dma_chan)
wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_DMA_MODE);
else
wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_IO_MODE);
@@ -1049,93 +1048,6 @@ static void sirfsoc_uart_pm(struct uart_port *port, unsigned int state,
clk_disable_unprepare(sirfport->clk);
}
-static unsigned int sirfsoc_uart_init_tx_dma(struct uart_port *port)
-{
- struct sirfsoc_uart_port *sirfport = to_sirfport(port);
- dma_cap_mask_t dma_mask;
- struct dma_slave_config tx_slv_cfg = {
- .dst_maxburst = 2,
- };
-
- dma_cap_zero(dma_mask);
- dma_cap_set(DMA_SLAVE, dma_mask);
- sirfport->tx_dma_chan = dma_request_channel(dma_mask,
- (dma_filter_fn)sirfsoc_dma_filter_id,
- (void *)sirfport->tx_dma_no);
- if (!sirfport->tx_dma_chan) {
- dev_err(port->dev, "Uart Request Dma Channel Fail %d\n",
- sirfport->tx_dma_no);
- return -EPROBE_DEFER;
- }
- dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg);
-
- return 0;
-}
-
-static unsigned int sirfsoc_uart_init_rx_dma(struct uart_port *port)
-{
- struct sirfsoc_uart_port *sirfport = to_sirfport(port);
- dma_cap_mask_t dma_mask;
- int ret;
- int i, j;
- struct dma_slave_config slv_cfg = {
- .src_maxburst = 2,
- };
-
- dma_cap_zero(dma_mask);
- dma_cap_set(DMA_SLAVE, dma_mask);
- sirfport->rx_dma_chan = dma_request_channel(dma_mask,
- (dma_filter_fn)sirfsoc_dma_filter_id,
- (void *)sirfport->rx_dma_no);
- if (!sirfport->rx_dma_chan) {
- dev_err(port->dev, "Uart Request Dma Channel Fail %d\n",
- sirfport->rx_dma_no);
- ret = -EPROBE_DEFER;
- goto request_err;
- }
- for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) {
- sirfport->rx_dma_items[i].xmit.buf =
- dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
- &sirfport->rx_dma_items[i].dma_addr, GFP_KERNEL);
- if (!sirfport->rx_dma_items[i].xmit.buf) {
- dev_err(port->dev, "Uart alloc bufa failed\n");
- ret = -ENOMEM;
- goto alloc_coherent_err;
- }
- sirfport->rx_dma_items[i].xmit.head =
- sirfport->rx_dma_items[i].xmit.tail = 0;
- }
- dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg);
-
- return 0;
-alloc_coherent_err:
- for (j = 0; j < i; j++)
- dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
- sirfport->rx_dma_items[j].xmit.buf,
- sirfport->rx_dma_items[j].dma_addr);
- dma_release_channel(sirfport->rx_dma_chan);
-request_err:
- return ret;
-}
-
-static void sirfsoc_uart_uninit_tx_dma(struct sirfsoc_uart_port *sirfport)
-{
- dmaengine_terminate_all(sirfport->tx_dma_chan);
- dma_release_channel(sirfport->tx_dma_chan);
-}
-
-static void sirfsoc_uart_uninit_rx_dma(struct sirfsoc_uart_port *sirfport)
-{
- int i;
- struct uart_port *port = &sirfport->port;
- dmaengine_terminate_all(sirfport->rx_dma_chan);
- dma_release_channel(sirfport->rx_dma_chan);
- for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++)
- dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
- sirfport->rx_dma_items[i].xmit.buf,
- sirfport->rx_dma_items[i].dma_addr);
-}
-
static int sirfsoc_uart_startup(struct uart_port *port)
{
struct sirfsoc_uart_port *sirfport = to_sirfport(port);
@@ -1174,18 +1086,12 @@ static int sirfsoc_uart_startup(struct uart_port *port)
wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0);
wr_regl(port, ureg->sirfsoc_tx_fifo_ctrl, SIRFUART_FIFO_THD(port));
wr_regl(port, ureg->sirfsoc_rx_fifo_ctrl, SIRFUART_FIFO_THD(port));
-
- if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) {
- ret = sirfsoc_uart_init_rx_dma(port);
- if (ret)
- goto init_rx_err;
+ if (sirfport->rx_dma_chan)
wr_regl(port, ureg->sirfsoc_rx_fifo_level_chk,
- SIRFUART_RX_FIFO_CHK_SC(port->line, 0x4) |
- SIRFUART_RX_FIFO_CHK_LC(port->line, 0xe) |
- SIRFUART_RX_FIFO_CHK_HC(port->line, 0x1b));
- }
- if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) {
- sirfsoc_uart_init_tx_dma(port);
+ SIRFUART_RX_FIFO_CHK_SC(port->line, 0x4) |
+ SIRFUART_RX_FIFO_CHK_LC(port->line, 0xe) |
+ SIRFUART_RX_FIFO_CHK_HC(port->line, 0x1b));
+ if (sirfport->tx_dma_chan) {
sirfport->tx_dma_state = TX_DMA_IDLE;
wr_regl(port, ureg->sirfsoc_tx_fifo_level_chk,
SIRFUART_TX_FIFO_CHK_SC(port->line, 0x1b) |
@@ -1232,12 +1138,8 @@ static void sirfsoc_uart_shutdown(struct uart_port *port)
gpio_set_value(sirfport->rts_gpio, 1);
free_irq(gpio_to_irq(sirfport->cts_gpio), sirfport);
}
- if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no))
- sirfsoc_uart_uninit_rx_dma(sirfport);
- if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) {
- sirfsoc_uart_uninit_tx_dma(sirfport);
+ if (sirfport->tx_dma_chan)
sirfport->tx_dma_state = TX_DMA_IDLE;
- }
}
static const char *sirfsoc_uart_type(struct uart_port *port)
@@ -1313,8 +1215,8 @@ sirfsoc_uart_console_setup(struct console *co, char *options)
port->cons = co;
/* default console tx/rx transfer using io mode */
- sirfport->rx_dma_no = UNVALID_DMA_CHAN;
- sirfport->tx_dma_no = UNVALID_DMA_CHAN;
+ sirfport->rx_dma_chan = NULL;
+ sirfport->tx_dma_chan = NULL;
return uart_set_options(port, co, baud, parity, bits, flow);
}
@@ -1382,6 +1284,13 @@ static int sirfsoc_uart_probe(struct platform_device *pdev)
struct uart_port *port;
struct resource *res;
int ret;
+ int i, j;
+ struct dma_slave_config slv_cfg = {
+ .src_maxburst = 2,
+ };
+ struct dma_slave_config tx_slv_cfg = {
+ .dst_maxburst = 2,
+ };
const struct of_device_id *match;
match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node);
@@ -1402,27 +1311,10 @@ static int sirfsoc_uart_probe(struct platform_device *pdev)
sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node,
"sirf,uart-has-rtscts");
- if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart")) {
+ if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart"))
sirfport->uart_reg->uart_type = SIRF_REAL_UART;
- if (of_property_read_u32(pdev->dev.of_node,
- "sirf,uart-dma-rx-channel",
- &sirfport->rx_dma_no))
- sirfport->rx_dma_no = UNVALID_DMA_CHAN;
- if (of_property_read_u32(pdev->dev.of_node,
- "sirf,uart-dma-tx-channel",
- &sirfport->tx_dma_no))
- sirfport->tx_dma_no = UNVALID_DMA_CHAN;
- }
if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) {
sirfport->uart_reg->uart_type = SIRF_USP_UART;
- if (of_property_read_u32(pdev->dev.of_node,
- "sirf,usp-dma-rx-channel",
- &sirfport->rx_dma_no))
- sirfport->rx_dma_no = UNVALID_DMA_CHAN;
- if (of_property_read_u32(pdev->dev.of_node,
- "sirf,usp-dma-tx-channel",
- &sirfport->tx_dma_no))
- sirfport->tx_dma_no = UNVALID_DMA_CHAN;
if (!sirfport->hw_flow_ctrl)
goto usp_no_flow_control;
if (of_find_property(pdev->dev.of_node, "cts-gpios", NULL))
@@ -1515,8 +1407,32 @@ usp_no_flow_control:
goto port_err;
}
- return 0;
+ sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx");
+ for (i = 0; sirfport->rx_dma_chan && i < SIRFSOC_RX_LOOP_BUF_CNT; i++) {
+ sirfport->rx_dma_items[i].xmit.buf =
+ dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
+ &sirfport->rx_dma_items[i].dma_addr, GFP_KERNEL);
+ if (!sirfport->rx_dma_items[i].xmit.buf) {
+ dev_err(port->dev, "Uart alloc bufa failed\n");
+ ret = -ENOMEM;
+ goto alloc_coherent_err;
+ }
+ sirfport->rx_dma_items[i].xmit.head =
+ sirfport->rx_dma_items[i].xmit.tail = 0;
+ }
+ if (sirfport->rx_dma_chan)
+ dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg);
+ sirfport->tx_dma_chan = dma_request_slave_channel(port->dev, "tx");
+ if (sirfport->tx_dma_chan)
+ dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg);
+ return 0;
+alloc_coherent_err:
+ for (j = 0; j < i; j++)
+ dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
+ sirfport->rx_dma_items[j].xmit.buf,
+ sirfport->rx_dma_items[j].dma_addr);
+ dma_release_channel(sirfport->rx_dma_chan);
port_err:
clk_put(sirfport->clk);
err:
@@ -1529,6 +1445,19 @@ static int sirfsoc_uart_remove(struct platform_device *pdev)
struct uart_port *port = &sirfport->port;
clk_put(sirfport->clk);
uart_remove_one_port(&sirfsoc_uart_drv, port);
+ if (sirfport->rx_dma_chan) {
+ int i;
+ dmaengine_terminate_all(sirfport->rx_dma_chan);
+ dma_release_channel(sirfport->rx_dma_chan);
+ for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++)
+ dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
+ sirfport->rx_dma_items[i].xmit.buf,
+ sirfport->rx_dma_items[i].dma_addr);
+ }
+ if (sirfport->tx_dma_chan) {
+ dmaengine_terminate_all(sirfport->tx_dma_chan);
+ dma_release_channel(sirfport->tx_dma_chan);
+ }
return 0;
}
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h
index b7d679c..8a6edda 100644
--- a/drivers/tty/serial/sirfsoc_uart.h
+++ b/drivers/tty/serial/sirfsoc_uart.h
@@ -392,9 +392,6 @@ struct sirfsoc_uart_register sirfsoc_uart = {
/* Indicate how many buffers used */
#define SIRFSOC_RX_LOOP_BUF_CNT 2
-/* Indicate if DMA channel valid */
-#define IS_DMA_CHAN_VALID(x) ((x) != -1)
-#define UNVALID_DMA_CHAN -1
/* For Fast Baud Rate Calculation */
struct sirfsoc_baudrate_to_regv {
unsigned int baud_rate;
@@ -423,8 +420,6 @@ struct sirfsoc_uart_port {
/* for SiRFmarco, there are SET/CLR for UART_INT_EN */
bool is_marco;
struct sirfsoc_uart_register *uart_reg;
- int rx_dma_no;
- int tx_dma_no;
struct dma_chan *rx_dma_chan;
struct dma_chan *tx_dma_chan;
dma_addr_t tx_dma_addr;
--
1.7.5.4
^ permalink raw reply related
* [PATCH 2/2] ARM: dts: sirf: add pin group for USP0 with only RX or TX frame sync for atlas6
From: Barry Song @ 2014-01-30 5:54 UTC (permalink / raw)
To: linux-arm-kernel
From: Rongjun Ying <rongjun.ying@csr.com>
add pin groups for USP0 only holding one of TX and RX frame sync. this patch
matches with the change in drivers/pinctrl/sirf.
commit 73f68c01f46 did this for prima2, but missed prima2. this patch fixes
the problem.
Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
arch/arm/boot/dts/atlas6.dtsi | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi
index 0c81dc9..8e60ae1 100644
--- a/arch/arm/boot/dts/atlas6.dtsi
+++ b/arch/arm/boot/dts/atlas6.dtsi
@@ -551,6 +551,18 @@
sirf,function = "usp0_uart_nostreamctrl";
};
};
+ usp0_only_utfs_pins_a: usp0 at 2 {
+ usp0 {
+ sirf,pins = "usp0_only_utfs_grp";
+ sirf,function = "usp0_only_utfs";
+ };
+ };
+ usp0_only_urfs_pins_a: usp0 at 3 {
+ usp0 {
+ sirf,pins = "usp0_only_urfs_grp";
+ sirf,function = "usp0_only_urfs";
+ };
+ };
usp1_pins_a: usp1 at 0 {
usp1 {
sirf,pins = "usp1grp";
--
1.7.5.4
^ permalink raw reply related
* [PATCH 1/2] pinctrl: sirf: add pin group for USP0 with only RX or TX frame sync for atlas6
From: Barry Song @ 2014-01-30 5:54 UTC (permalink / raw)
To: linux-arm-kernel
From: Rongjun Ying <rongjun.ying@csr.com>
USP0 has multiple functions, and has RX and TX frame sync signals, for some scenarios
like audio PCM, we don't need both of them. so here we add two possibilities for USP0
only holding one of TX and RX frame sync.
commit 8385af02bad only added this group for prima2, and missed atlas6. her this patch
fixes it.
Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
drivers/pinctrl/sirf/pinctrl-atlas6.c | 43 +++++++++++++++++++++++++++++++++
1 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/drivers/pinctrl/sirf/pinctrl-atlas6.c b/drivers/pinctrl/sirf/pinctrl-atlas6.c
index 2b9f320..09211fb 100644
--- a/drivers/pinctrl/sirf/pinctrl-atlas6.c
+++ b/drivers/pinctrl/sirf/pinctrl-atlas6.c
@@ -529,6 +529,40 @@ static const struct sirfsoc_padmux usp0_padmux = {
static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 };
+static const struct sirfsoc_muxmask usp0_only_utfs_muxmask[] = {
+ {
+ .group = 1,
+ .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22),
+ },
+};
+
+static const struct sirfsoc_padmux usp0_only_utfs_padmux = {
+ .muxmask_counts = ARRAY_SIZE(usp0_only_utfs_muxmask),
+ .muxmask = usp0_only_utfs_muxmask,
+ .ctrlreg = SIRFSOC_RSC_PIN_MUX,
+ .funcmask = BIT(1) | BIT(2) | BIT(6),
+ .funcval = 0,
+};
+
+static const unsigned usp0_only_utfs_pins[] = { 51, 52, 53, 54 };
+
+static const struct sirfsoc_muxmask usp0_only_urfs_muxmask[] = {
+ {
+ .group = 1,
+ .mask = BIT(19) | BIT(20) | BIT(21) | BIT(23),
+ },
+};
+
+static const struct sirfsoc_padmux usp0_only_urfs_padmux = {
+ .muxmask_counts = ARRAY_SIZE(usp0_only_urfs_muxmask),
+ .muxmask = usp0_only_urfs_muxmask,
+ .ctrlreg = SIRFSOC_RSC_PIN_MUX,
+ .funcmask = BIT(1) | BIT(2) | BIT(9),
+ .funcval = 0,
+};
+
+static const unsigned usp0_only_urfs_pins[] = { 51, 52, 53, 55 };
+
static const struct sirfsoc_muxmask usp0_uart_nostreamctrl_muxmask[] = {
{
.group = 1,
@@ -905,6 +939,8 @@ static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = {
SIRFSOC_PIN_GROUP("usp0grp", usp0_pins),
SIRFSOC_PIN_GROUP("usp0_uart_nostreamctrl_grp",
usp0_uart_nostreamctrl_pins),
+ SIRFSOC_PIN_GROUP("usp0_only_utfs_grp", usp0_only_utfs_pins),
+ SIRFSOC_PIN_GROUP("usp0_only_urfs_grp", usp0_only_urfs_pins),
SIRFSOC_PIN_GROUP("usp1grp", usp1_pins),
SIRFSOC_PIN_GROUP("usp1_uart_nostreamctrl_grp",
usp1_uart_nostreamctrl_pins),
@@ -953,6 +989,9 @@ static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" };
static const char * const usp0_uart_nostreamctrl_grp[] = {
"usp0_uart_nostreamctrl_grp" };
static const char * const usp0grp[] = { "usp0grp" };
+static const char * const usp0_only_utfs_grp[] = { "usp0_only_utfs_grp" };
+static const char * const usp0_only_urfs_grp[] = { "usp0_only_urfs_grp" };
+
static const char * const usp1grp[] = { "usp1grp" };
static const char * const usp1_uart_nostreamctrl_grp[] = {
"usp1_uart_nostreamctrl_grp" };
@@ -1003,6 +1042,10 @@ static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = {
SIRFSOC_PMX_FUNCTION("usp0_uart_nostreamctrl",
usp0_uart_nostreamctrl_grp,
usp0_uart_nostreamctrl_padmux),
+ SIRFSOC_PMX_FUNCTION("usp0_only_utfs", usp0_only_utfs_grp,
+ usp0_only_utfs_padmux),
+ SIRFSOC_PMX_FUNCTION("usp0_only_urfs", usp0_only_urfs_grp,
+ usp0_only_urfs_padmux),
SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux),
SIRFSOC_PMX_FUNCTION("usp1_uart_nostreamctrl",
usp1_uart_nostreamctrl_grp,
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 0/5] Smart Card(SC) interface, TI USIM & NxP SC phy driver
From: Satish Patel @ 2014-01-30 5:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390192434-19386-1-git-send-email-satish.patel@ti.com>
On 1/20/2014 10:03 AM, Satish Patel wrote:
> Changes from v1:
> * RFC(v1) comments are fixed
>
> ** removed "gpio_to_irq" as GPIO controller process cell from DT and
> give it to DT node
> ** comments on documentation
> ** few other comments on null checks are resolved
>
> * BWT timing configuration is added to ti-usim driver
>
> v1 cover letter link#
> https://lkml.org/lkml/2014/1/6/250
>
> Satish Patel (5):
> sc_phy:SmartCard(SC) PHY interface to SC controller
> misc: tda8026: Add NXP TDA8026 PHY driver
> char: ti-usim: Add driver for USIM module on AM43xx
> ARM: dts: AM43xx: DT entries added for ti-usim
> ARM: dts: AM43xx-epos-evm: DT entries for ti-usim and phy
>
> Documentation/devicetree/bindings/misc/tda8026.txt | 19 +
> .../devicetree/bindings/ti-usim/ti-usim.txt | 31 +
> Documentation/sc_phy.txt | 171 ++
> arch/arm/boot/dts/am4372.dtsi | 10 +
> arch/arm/boot/dts/am43x-epos-evm.dts | 43 +
> drivers/char/Kconfig | 7 +
> drivers/char/Makefile | 1 +
> drivers/char/ti-usim-hw.h | 863 +++++++++
> drivers/char/ti-usim.c | 1859 ++++++++++++++++++++
> drivers/misc/Kconfig | 7 +
> drivers/misc/Makefile | 1 +
> drivers/misc/tda8026.c | 1255 +++++++++++++
> include/linux/sc_phy.h | 132 ++
> include/linux/ti-usim.h | 98 +
> 14 files changed, 4497 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/misc/tda8026.txt
> create mode 100644 Documentation/devicetree/bindings/ti-usim/ti-usim.txt
> create mode 100644 Documentation/sc_phy.txt
> create mode 100644 drivers/char/ti-usim-hw.h
> create mode 100644 drivers/char/ti-usim.c
> create mode 100644 drivers/misc/tda8026.c
> create mode 100644 include/linux/sc_phy.h
> create mode 100644 include/linux/ti-usim.h
Any comments on this patch series ?
If not,
Can you accept these patches for next merge window
Thanks
Satish
>
>
^ permalink raw reply
* [PATCH v2] pwm: add CSR SiRFSoC PWM driver
From: Barry Song @ 2014-01-30 5:52 UTC (permalink / raw)
To: linux-arm-kernel
From: Rongjun Ying <Rongjun.ying@csr.com>
PWM controller of CSR SiRFSoC can generate 7 independent outputs. Each output
duty cycle can be adjusted by setting the corresponding wait & hold registers.
Supports 7 independent channel output: 6 for external(channel0-5) and 1 for
internal(channel6).
Supports wide frequency range: divide by 2 to 65536*2 of source clock.
Signed-off-by: Rongjun Ying <Rongjun.ying@csr.com>
Signed-off-by: Huayi Li <Huayi.Li@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
-v2: clean the source clock of PWM wave, use OSC(26MHz)
drivers/pwm/Kconfig | 9 ++
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-sirf.c | 294 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 304 insertions(+), 0 deletions(-)
create mode 100644 drivers/pwm/pwm-sirf.c
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 7acab93..0a252f8 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -166,6 +166,15 @@ config PWM_SAMSUNG
To compile this driver as a module, choose M here: the module
will be called pwm-samsung.
+config PWM_SIRF
+ tristate "SiRF PWM support"
+ depends on ARCH_SIRF
+ help
+ Generic PWM framework driver for SiRF SoC.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-sirf.
+
config PWM_SPEAR
tristate "STMicroelectronics SPEAr PWM support"
depends on PLAT_SPEAR
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 4abf337..49ab0d7 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_PWM_PUV3) += pwm-puv3.o
obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o
obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
+obj-$(CONFIG_PWM_SIRF) += pwm-sirf.o
obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
diff --git a/drivers/pwm/pwm-sirf.c b/drivers/pwm/pwm-sirf.c
new file mode 100644
index 0000000..1a5c5b7
--- /dev/null
+++ b/drivers/pwm/pwm-sirf.c
@@ -0,0 +1,294 @@
+/*
+ * SIRF serial SoC PWM device core driver
+ *
+ * Copyright (c) 2014 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/pwm.h>
+#include <linux/of.h>
+#include <linux/io.h>
+
+#define SIRF_PWM_SELECT_PRECLK 0x0
+#define SIRF_PWM_OE 0x4
+#define SIRF_PWM_ENABLE_PRECLOCK 0x8
+#define SIRF_PWM_ENABLE_POSTCLOCK 0xC
+#define SIRF_PWM_GET_WAIT_OFFSET(n) (0x10 + 0x8*n)
+#define SIRF_PWM_GET_HOLD_OFFSET(n) (0x14 + 0x8*n)
+
+#define SIRF_PWM_TR_STEP(n) (0x48 + 0x8*n)
+#define SIRF_PWM_STEP_HOLD(n) (0x4c + 0x8*n)
+
+#define SRC_FIELD_SIZE 3
+#define BYPASS_MODE_BIT 21
+#define TRANS_MODE_SELECT_BIT 7
+
+#define SIRF_PWM_CHL_NUM 7
+#define SIRF_PWM_BLS_GRP_NUM 16
+
+struct sirf_pwm {
+ void __iomem *base;
+ struct clk *clk;
+ struct pwm_chip chip;
+};
+
+#define to_sirf_chip(chip) container_of(chip, struct sirf_pwm, chip)
+
+static unsigned int sirf_pwm_ns_to_cycles(struct pwm_chip *chip, unsigned int time_ns)
+{
+ u64 dividend;
+ unsigned int cycle;
+ /*
+ * on SiRFSoC, OSC input is const, we use it as the source to generate
+ * PWM wave
+ */
+#define SRC_OSC_RATE 26000000ULL
+ dividend = SRC_OSC_RATE * time_ns + NSEC_PER_SEC / 2;
+ do_div(dividend, NSEC_PER_SEC);
+
+ cycle = dividend & 0xFFFFFFFFUL;
+
+ return cycle > 1 ? cycle : 1;
+}
+
+static int sirf_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ unsigned int period_cycles, high_cycles, low_cycles;
+ unsigned int val;
+ struct sirf_pwm *spwm = to_sirf_chip(chip);
+
+ period_cycles = sirf_pwm_ns_to_cycles(chip, period_ns);
+
+ high_cycles = sirf_pwm_ns_to_cycles(chip, duty_ns);
+ low_cycles = period_cycles - high_cycles;
+
+ if (period_cycles == 1) {
+ /* bypass mode */
+ val = readl(spwm->base + SIRF_PWM_SELECT_PRECLK);
+ val |= 0x1 << (BYPASS_MODE_BIT + pwm->hwpwm);
+ writel(val, spwm->base + SIRF_PWM_SELECT_PRECLK);
+ dev_warn(chip->dev, "period is too short!\n");
+ } else {
+ /* divider mode */
+ val = readl(spwm->base + SIRF_PWM_SELECT_PRECLK);
+ val &= ~(0x1 << (BYPASS_MODE_BIT + pwm->hwpwm));
+ writel(val, spwm->base + SIRF_PWM_SELECT_PRECLK);
+
+ if (high_cycles == period_cycles) {
+ high_cycles--;
+ low_cycles = 1;
+ }
+
+ writel(high_cycles, spwm->base + SIRF_PWM_GET_WAIT_OFFSET(pwm->hwpwm));
+ writel(low_cycles, spwm->base + SIRF_PWM_GET_HOLD_OFFSET(pwm->hwpwm));
+ }
+
+ return 0;
+}
+
+static int sirf_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct sirf_pwm *spwm = to_sirf_chip(chip);
+ unsigned int val;
+
+ /* disable preclock */
+ val = readl(spwm->base + SIRF_PWM_ENABLE_PRECLOCK);
+ val &= ~(1 << pwm->hwpwm);
+ writel(val, spwm->base + SIRF_PWM_ENABLE_PRECLOCK);
+
+ /* select preclock source must after disable preclk*/
+ val = readl(spwm->base + SIRF_PWM_SELECT_PRECLK);
+ val &= ~(0x7 << (SRC_FIELD_SIZE * pwm->hwpwm));
+ writel(val, spwm->base + SIRF_PWM_SELECT_PRECLK);
+ /* wait for some time */
+ udelay(100);
+
+ /* enable preclock */
+ val = readl(spwm->base + SIRF_PWM_ENABLE_PRECLOCK);
+ val |= (1 << pwm->hwpwm);
+ writel(val, spwm->base + SIRF_PWM_ENABLE_PRECLOCK);
+
+ /* enable post clock*/
+ val = readl(spwm->base + SIRF_PWM_ENABLE_POSTCLOCK);
+ val |= (1 << pwm->hwpwm);
+ writel(val, spwm->base + SIRF_PWM_ENABLE_POSTCLOCK);
+
+ /* enable output */
+ val = readl(spwm->base + SIRF_PWM_OE);
+ val |= 1 << pwm->hwpwm;
+ val &= ~(1 << (pwm->hwpwm + TRANS_MODE_SELECT_BIT));
+
+ writel(val, spwm->base + SIRF_PWM_OE);
+
+ return 0;
+}
+
+static void sirf_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ unsigned int val;
+ struct sirf_pwm *spwm = to_sirf_chip(chip);
+ /* disable output */
+ val = readl(spwm->base + SIRF_PWM_OE);
+ val &= ~(1 << pwm->hwpwm);
+ writel(val, spwm->base + SIRF_PWM_OE);
+
+ /* disable postclock */
+ val = readl(spwm->base + SIRF_PWM_ENABLE_POSTCLOCK);
+ val &= ~(1 << pwm->hwpwm);
+ writel(val, spwm->base + SIRF_PWM_ENABLE_POSTCLOCK);
+
+ /* disable preclock */
+ val = readl(spwm->base + SIRF_PWM_ENABLE_PRECLOCK);
+ val &= ~(1 << pwm->hwpwm);
+ writel(val, spwm->base + SIRF_PWM_ENABLE_PRECLOCK);
+}
+
+static struct pwm_ops sirf_pwm_ops = {
+ .enable = sirf_pwm_enable,
+ .disable = sirf_pwm_disable,
+ .config = sirf_pwm_config,
+ .owner = THIS_MODULE,
+};
+
+static int sirf_pwm_probe(struct platform_device *pdev)
+{
+ struct sirf_pwm *spwm;
+ struct resource *mem_res;
+ int ret;
+
+ spwm = devm_kzalloc(&pdev->dev, sizeof(struct sirf_pwm),
+ GFP_KERNEL);
+ if (!spwm)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, spwm);
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ spwm->base = devm_ioremap_resource(&pdev->dev, mem_res);
+ if (!spwm->base)
+ return -ENOMEM;
+
+ spwm->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(spwm->clk)) {
+ dev_err(&pdev->dev, "Get clock failed.\n");
+ return PTR_ERR(spwm->clk);
+ }
+
+ clk_prepare_enable(spwm->clk);
+
+ spwm->chip.dev = &pdev->dev;
+ spwm->chip.ops = &sirf_pwm_ops;
+ spwm->chip.base = 0;
+ spwm->chip.npwm = SIRF_PWM_CHL_NUM;
+
+ ret = pwmchip_add(&spwm->chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to register pwm\n");
+ clk_disable_unprepare(spwm->clk);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int sirf_pwm_remove(struct platform_device *pdev)
+{
+ struct sirf_pwm *spwm = platform_get_drvdata(pdev);
+ clk_disable_unprepare(spwm->clk);
+
+ pwmchip_remove(&spwm->chip);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sirf_pwm_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sirf_pwm *spwm = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(spwm->clk);
+
+ return 0;
+}
+
+static void sirf_pwm_config_restore(struct sirf_pwm *spwm)
+{
+ struct pwm_device *pwm;
+ int i;
+
+ for (i = 0; i < spwm->chip.npwm; i++) {
+ pwm = &spwm->chip.pwms[i];
+ /*
+ * while restoring from hibernation, state of pwm is enabled,
+ * but PWM hardware is not re-enabled
+ */
+ if (test_bit(PWMF_REQUESTED, &pwm->flags) &&
+ test_bit(PWMF_ENABLED, &pwm->flags))
+ sirf_pwm_enable(&spwm->chip, pwm);
+ }
+}
+
+static int sirf_pwm_resume(struct device *dev)
+{
+ struct sirf_pwm *spwm = dev_get_drvdata(dev);
+
+ clk_prepare_enable(spwm->clk);
+
+ sirf_pwm_config_restore(spwm);
+
+ return 0;
+}
+
+static int sirf_pwm_restore(struct device *dev)
+{
+ struct sirf_pwm *spwm = dev_get_drvdata(dev);
+
+ /* back from hibernation, clock is already enabled */
+ sirf_pwm_config_restore(spwm);
+
+ return 0;
+}
+
+#else
+#define sirf_pwm_resume NULL
+#define sirf_pwm_suspend NULL
+#define sirf_pwm_restore NULL
+#endif
+
+static const struct dev_pm_ops sirf_pwm_pm_ops = {
+ .suspend = sirf_pwm_suspend,
+ .resume = sirf_pwm_resume,
+ .restore = sirf_pwm_restore,
+};
+
+static const struct of_device_id sirf_pwm_of_match[] = {
+ { .compatible = "sirf,prima2-pwm", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sirf_pwm_of_match);
+
+static struct platform_driver sirf_pwm_driver = {
+ .driver = {
+ .name = "prima2-pwm",
+ .owner = THIS_MODULE,
+ .pm = &sirf_pwm_pm_ops,
+ .of_match_table = sirf_pwm_of_match,
+ },
+ .probe = sirf_pwm_probe,
+ .remove = sirf_pwm_remove,
+};
+
+module_platform_driver(sirf_pwm_driver);
+
+MODULE_DESCRIPTION("SIRF serial SoC PWM device core driver");
+MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>, "
+ "Huayi Li <huayi.li@csr.com>");
+MODULE_LICENSE("GPL v2");
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2 1/6] idle: move the cpuidle entry point to the generic idle loop
From: Preeti U Murthy @ 2014-01-30 5:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.11.1401300021530.1652@knanqh.ubzr>
Hi Nicolas,
On 01/30/2014 10:58 AM, Nicolas Pitre wrote:
> On Thu, 30 Jan 2014, Preeti U Murthy wrote:
>
>> Hi Nicolas,
>>
>> On 01/30/2014 02:01 AM, Nicolas Pitre wrote:
>>> On Wed, 29 Jan 2014, Nicolas Pitre wrote:
>>>
>>>> In order to integrate cpuidle with the scheduler, we must have a better
>>>> proximity in the core code with what cpuidle is doing and not delegate
>>>> such interaction to arch code.
>>>>
>>>> Architectures implementing arch_cpu_idle() should simply enter
>>>> a cheap idle mode in the absence of a proper cpuidle driver.
>>>>
>>>> Signed-off-by: Nicolas Pitre <nico@linaro.org>
>>>> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>>>
>>> As mentioned in my reply to Olof's comment on patch #5/6, here's a new
>>> version of this patch adding the safety local_irq_enable() to the core
>>> code.
>>>
>>> ----- >8
>>>
>>> From: Nicolas Pitre <nicolas.pitre@linaro.org>
>>> Subject: idle: move the cpuidle entry point to the generic idle loop
>>>
>>> In order to integrate cpuidle with the scheduler, we must have a better
>>> proximity in the core code with what cpuidle is doing and not delegate
>>> such interaction to arch code.
>>>
>>> Architectures implementing arch_cpu_idle() should simply enter
>>> a cheap idle mode in the absence of a proper cpuidle driver.
>>>
>>> In both cases i.e. whether it is a cpuidle driver or the default
>>> arch_cpu_idle(), the calling convention expects IRQs to be disabled
>>> on entry and enabled on exit. There is a warning in place already but
>>> let's add a forced IRQ enable here as well. This will allow for
>>> removing the forced IRQ enable some implementations do locally and
>>
>> Why would this patch allow for removing the forced IRQ enable that are
>> being done on some archs in arch_cpu_idle()? Isn't this patch expecting
>> the default arch_cpu_idle() to have re-enabled the interrupts after
>> exiting from the default idle state? Its supposed to only catch faulty
>> cpuidle drivers that haven't enabled IRQs on exit from idle state but
>> are expected to have done so, isn't it?
>
> Exact. However x86 currently does this:
>
> if (cpuidle_idle_call())
> x86_idle();
> else
> local_irq_enable();
>
> So whenever cpuidle_idle_call() is successful then IRQs are
> unconditionally enabled whether or not the underlying cpuidle driver has
> properly done it or not. And the reason is that some of the x86 cpuidle
> do fail to enable IRQs before returning.
>
> So the idea is to get rid of this unconditional IRQ enabling and let the
> core issue a warning instead (as well as enabling IRQs to allow the
> system to run).
Oh ok, thank you for clarifying this:)
Regards
Preeti U Murthy
>
>
> Nicolas
>
^ permalink raw reply
* [PATCH v2 2/2] drivers/media: s5p-mfc: Add Horizontal and Vertical MV Search Range
From: Amit Grover @ 2014-01-30 5:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391060563-27015-1-git-send-email-amit.grover@samsung.com>
This patch adds Controls to set Horizontal and Vertical search range
for Motion Estimation block for Samsung MFC video Encoders.
Signed-off-by: Swami Nathan <swaminath.p@samsung.com>
Signed-off-by: Amit Grover <amit.grover@samsung.com>
---
drivers/media/platform/s5p-mfc/regs-mfc-v6.h | 1 +
drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 2 ++
drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 24 +++++++++++++++++++++++
drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 8 ++------
4 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
index 2398cdf..8d0b686 100644
--- a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
+++ b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
@@ -229,6 +229,7 @@
#define S5P_FIMV_E_PADDING_CTRL_V6 0xf7a4
#define S5P_FIMV_E_MV_HOR_RANGE_V6 0xf7ac
#define S5P_FIMV_E_MV_VER_RANGE_V6 0xf7b0
+#define S5P_FIMV_E_MV_RANGE_V6_MASK 0x3fff
#define S5P_FIMV_E_VBV_BUFFER_SIZE_V6 0xf84c
#define S5P_FIMV_E_VBV_INIT_DELAY_V6 0xf850
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index 6920b54..b90ee34 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -430,6 +430,8 @@ struct s5p_mfc_vp8_enc_params {
struct s5p_mfc_enc_params {
u16 width;
u16 height;
+ u32 mv_h_range;
+ u32 mv_v_range;
u16 gop_size;
enum v4l2_mpeg_video_multi_slice_mode slice_mode;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index 4ff3b6c..704f30c1 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -208,6 +208,24 @@ static struct mfc_control controls[] = {
.default_value = 0,
},
{
+ .id = V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Horizontal MV Search Range",
+ .minimum = 16,
+ .maximum = 128,
+ .step = 16,
+ .default_value = 32,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Vertical MV Search Range",
+ .minimum = 16,
+ .maximum = 128,
+ .step = 16,
+ .default_value = 32,
+ },
+ {
.id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE,
.type = V4L2_CTRL_TYPE_INTEGER,
.minimum = 0,
@@ -1377,6 +1395,12 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
p->vbv_size = ctrl->val;
break;
+ case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
+ p->mv_h_range = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
+ p->mv_v_range = ctrl->val;
+ break;
case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
p->codec.h264.cpb_size = ctrl->val;
break;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
index 461358c..3c10188 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -727,14 +727,10 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6);
/* setting for MV range [16, 256] */
- reg = 0;
- reg &= ~(0x3FFF);
- reg = 256;
+ reg = (p->mv_h_range & S5P_FIMV_E_MV_RANGE_V6_MASK);
WRITEL(reg, S5P_FIMV_E_MV_HOR_RANGE_V6);
- reg = 0;
- reg &= ~(0x3FFF);
- reg = 256;
+ reg = (p->mv_v_range & S5P_FIMV_E_MV_RANGE_V6_MASK);
WRITEL(reg, S5P_FIMV_E_MV_VER_RANGE_V6);
WRITEL(0x0, S5P_FIMV_E_FRAME_INSERTION_V6);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 1/2] drivers/media: v4l2: Add settings for Horizontal and Vertical MV Search Range
From: Amit Grover @ 2014-01-30 5:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391060563-27015-1-git-send-email-amit.grover@samsung.com>
Adding V4L2 controls for horizontal and vertical search range in pixels
for motion estimation module in video encoder.
Signed-off-by: Swami Nathan <swaminath.p@samsung.com>
Signed-off-by: Amit Grover <amit.grover@samsung.com>
---
Documentation/DocBook/media/v4l/controls.xml | 20 ++++++++++++++++++++
drivers/media/v4l2-core/v4l2-ctrls.c | 14 ++++++++++++++
include/uapi/linux/v4l2-controls.h | 2 ++
3 files changed, 36 insertions(+)
diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 7a3b49b..be04d18 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -2258,6 +2258,26 @@ Applicable to the MPEG1, MPEG2, MPEG4 encoders.</entry>
VBV buffer control.</entry>
</row>
+ <row><entry></entry></row>
+ <row id=""v4l2-mpeg-video-hor-search-range">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE</constant> </entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Horizontal search range defines maximum horizontal search area in pixels
+to search and match for the present Macroblock (MB) in the reference picture. This V4L2 control macro is used to set
+horizontal search range for motion estimation module in video encoder.</entry>
+ </row>
+
+ <row><entry></entry></row>
+ <row id="v4l2-mpeg-video-vert-search-range">
+ <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE</constant> </entry>
+ <entry>integer</entry>
+ </row>
+ <row><entry spanname="descr">Vertical search range defines maximum vertical search area in pixels
+to search and match for the present Macroblock (MB) in the reference picture. This V4L2 control macro is used to set
+vertical search range for motion estimation module in video encoder.</entry>
+ </row>
+
<row><entry></entry></row>
<row>
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE</constant> </entry>
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index fb46790..e775388 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -735,6 +735,8 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS";
case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count";
case V4L2_CID_MPEG_VIDEO_VBV_DELAY: return "Initial Delay for VBV Control";
+ case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: return "Horizontal MV Search Range";
+ case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: return "Vertical MV Search Range";
case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: return "Repeat Sequence Header";
/* VPX controls */
@@ -905,6 +907,18 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
*min = 0;
*max = *step = 1;
break;
+ case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
+ *type = V4L2_CTRL_TYPE_INTEGER;
+ *min = 16;
+ *max = 128;
+ *step = 16;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
+ *type = V4L2_CTRL_TYPE_INTEGER;
+ *min = 16;
+ *max = 128;
+ *step = 16;
+ break;
case V4L2_CID_PAN_RESET:
case V4L2_CID_TILT_RESET:
case V4L2_CID_FLASH_STROBE:
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 1666aab..80e1def 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -372,6 +372,8 @@ enum v4l2_mpeg_video_multi_slice_mode {
#define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224)
#define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_BASE+225)
#define V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER (V4L2_CID_MPEG_BASE+226)
+#define V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE (V4L2_CID_MPEG_BASE+227)
+#define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_MPEG_BASE+228)
#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300)
#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 0/2] drivers/media: Add controls for Horizontal and Vertical MV Search Range
From: Amit Grover @ 2014-01-30 5:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52E0ED10.2020901@samsung.com>
Based on 'master' branch of Linux-next.
This is v2 version for the patch:
s5p-mfc: Add Horizontal and Vertical search range for Video Macro Blocks
(https://lkml.org/lkml/2013/12/30/83)
Changes from v1:
1) Splitted the patch into v4l2 and mfc driver patches.
2) Incorporated review comments of v1
Amit Grover (2):
drivers/media: v4l2: Add settings for Horizontal and Vertical MV
Search Range
drivers/media: s5p-mfc: Add Horizontal and Vertical MV Search Range
Documentation/DocBook/media/v4l/controls.xml | 20 +++++++++++++++++++
drivers/media/platform/s5p-mfc/regs-mfc-v6.h | 1 +
drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 2 ++
drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 24 +++++++++++++++++++++++
drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 8 ++------
drivers/media/v4l2-core/v4l2-ctrls.c | 14 +++++++++++++
include/uapi/linux/v4l2-controls.h | 2 ++
7 files changed, 65 insertions(+), 6 deletions(-)
--
1.7.9.5
^ permalink raw reply
* linux-next: manual merge of the arm-soc tree with Linus' tree
From: Kevin Hilman @ 2014-01-30 5:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140130111919.afc7f4e5b58e409aaabf7550@canb.auug.org.au>
On Wed, Jan 29, 2014 at 4:19 PM, Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> Hi all,
>
> Today's linux-next merge of the arm-soc tree got a conflict in
> drivers/clk/Makefile between commit fd3fdaf09f26 ("clk: sort Makefile")
> from Linus' tree and commit 7ee2c5117483 ("clk: bcm281xx: add initial
> clock framework support") from the arm-soc tree.
Ugh. Looks like some last minute cleanup stuff went into clk-next
that didn't spend time in linux-next, and now causes conflicts with
some clk stuff we still have queued in arm-soc (ack'd by Mike.)
Now, based on the Hulk's response to Mike's pull request, if we submit
this, introducing yet more conflicts in the Makefile, it will surely
be Hulk angry, Hulk smash.
Kevin
^ permalink raw reply
* [RFC PATCH 2/3] ARM/ARM64: KVM: Add support for PSCI v0.2 emulation
From: Anup Patel @ 2014-01-30 5:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128210410.GA26671@cbox>
Hi Christoffer,
On Wed, Jan 29, 2014 at 2:34 AM, Christoffer Dall
<christoffer.dall@linaro.org> wrote:
> On Tue, Jan 21, 2014 at 06:31:40PM +0530, Anup Patel wrote:
>> Currently, the in-kernel PSCI emulation provides PSCI v0.1 interface to
>> VCPUs. This patch extends current in-kernel PSCI emulation to provide
>> PSCI v0.2 interface to VCPUs.
>>
>> By default, ARM/ARM64 KVM will always provide PSCI v0.1 interface for
>> keeping the ABI backward-compatible.
>>
>> To select PSCI v0.2 interface for VCPUs, the user space (i.e. QEMU or
>> KVMTOOL) will have to set KVM_ARM_VCPU_PSCI_0_2 feature when doing VCPU
>> init using KVM_ARM_VCPU_INIT ioctl.
>>
>> Signed-off-by: Anup Patel <anup.patel@linaro.org>
>> Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
>> ---
>> arch/arm/include/asm/kvm_host.h | 2 +-
>> arch/arm/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
>> arch/arm/kvm/arm.c | 6 ++-
>> arch/arm/kvm/psci.c | 79 ++++++++++++++++++++++++++++++-------
>> arch/arm64/include/asm/kvm_host.h | 2 +-
>> arch/arm64/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
>> 6 files changed, 143 insertions(+), 24 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
>> index 8a6f6db..0239ac5 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -36,7 +36,7 @@
>> #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
>> #define KVM_HAVE_ONE_REG
>>
>> -#define KVM_VCPU_MAX_FEATURES 1
>> +#define KVM_VCPU_MAX_FEATURES 2
>>
>> #include <kvm/arm_vgic.h>
>>
>> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
>> index c498b60..d9eb74c 100644
>> --- a/arch/arm/include/uapi/asm/kvm.h
>> +++ b/arch/arm/include/uapi/asm/kvm.h
>> @@ -83,6 +83,7 @@ struct kvm_regs {
>> #define KVM_VGIC_V2_CPU_SIZE 0x2000
>>
>> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
>> +#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
>>
>> struct kvm_vcpu_init {
>> __u32 target;
>> @@ -164,7 +165,7 @@ struct kvm_arch_memory_slot {
>> /* Highest supported SPI, from VGIC_NR_IRQS */
>> #define KVM_ARM_IRQ_GIC_MAX 127
>>
>> -/* PSCI interface */
>> +/* PSCI v0.1 interface */
>> #define KVM_PSCI_FN_BASE 0x95c1ba5e
>> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>>
>> @@ -173,9 +174,41 @@ struct kvm_arch_memory_slot {
>> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
>> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>>
>> +/* PSCI v0.2 interface */
>> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
>> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
>> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
>> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
>> +
>> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
>> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
>> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
>> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
>> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
>> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
>> + KVM_PSCI_0_2_FN(6)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN(7)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
>> +
>> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
>> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
>> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN64(7)
>> +
>> +/* PSCI return values */
>> #define KVM_PSCI_RET_SUCCESS 0
>> -#define KVM_PSCI_RET_NI ((unsigned long)-1)
>> -#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
>> +#define KVM_PSCI_RET_NOT_SUPPORTED ((unsigned long)-1)
>> +#define KVM_PSCI_RET_INVALID_PARAMS ((unsigned long)-2)
>> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
>> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
>> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
>> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
>> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
>> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>>
>> #endif /* __ARM_KVM_H__ */
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 2a700e0..0b7817a 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -193,6 +193,7 @@ int kvm_dev_ioctl_check_extension(long ext)
>> case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
>> case KVM_CAP_ONE_REG:
>> case KVM_CAP_ARM_PSCI:
>> + case KVM_CAP_ARM_PSCI_0_2:
>> r = 1;
>> break;
>> case KVM_CAP_COALESCED_MMIO:
>> @@ -483,7 +484,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
>> * PSCI code.
>> */
>> if (test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) {
>> - *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
>> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
>> + *vcpu_reg(vcpu, 0) = KVM_PSCI_0_2_FN_CPU_OFF;
>> + else
>> + *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
>> kvm_psci_call(vcpu);
>
> Which tree does this patch apply to? It looks like you'll get a
> conflict with:
> 478a823 arm: KVM: Don't return PSCI_INVAL if waitqueue is inactive
>
>> }
>>
>> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
>> index 0881bf1..ee044a3 100644
>> --- a/arch/arm/kvm/psci.c
>> +++ b/arch/arm/kvm/psci.c
>> @@ -55,13 +55,13 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>> }
>>
>> if (!vcpu)
>> - return KVM_PSCI_RET_INVAL;
>> + return KVM_PSCI_RET_INVALID_PARAMS;
>>
>> target_pc = *vcpu_reg(source_vcpu, 2);
>>
>> wq = kvm_arch_vcpu_wq(vcpu);
>> if (!waitqueue_active(wq))
>> - return KVM_PSCI_RET_INVAL;
>> + return KVM_PSCI_RET_INVALID_PARAMS;
>>
>> kvm_reset_vcpu(vcpu);
>>
>> @@ -84,17 +84,49 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>> return KVM_PSCI_RET_SUCCESS;
>> }
>>
>> -/**
>> - * kvm_psci_call - handle PSCI call if r0 value is in range
>> - * @vcpu: Pointer to the VCPU struct
>> - *
>> - * Handle PSCI calls from guests through traps from HVC instructions.
>> - * The calling convention is similar to SMC calls to the secure world where
>> - * the function number is placed in r0 and this function returns true if the
>> - * function number specified in r0 is withing the PSCI range, and false
>> - * otherwise.
>> - */
>> -bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> +static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
>> +{
>> + unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
>> + unsigned long val;
>> +
>> + switch (psci_fn) {
>> + case KVM_PSCI_0_2_FN_PSCI_VERSION:
>> + /*
>> + * Bits[31:16] = Major Version = 0
>> + * Bits[15:0] = Minor Version = 2
>> + */
>> + val = 2;
>> + break;
>> + case KVM_PSCI_0_2_FN_CPU_OFF:
>> + kvm_psci_vcpu_off(vcpu);
>> + val = KVM_PSCI_RET_SUCCESS;
>> + break;
>> + case KVM_PSCI_0_2_FN_CPU_ON:
>> + case KVM_PSCI_0_2_FN64_CPU_ON:
>> + val = kvm_psci_vcpu_on(vcpu);
>> + break;
>> + case KVM_PSCI_0_2_FN_CPU_SUSPEND:
>> + case KVM_PSCI_0_2_FN_AFFINITY_INFO:
>> + case KVM_PSCI_0_2_FN_MIGRATE:
>> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
>> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
>> + case KVM_PSCI_0_2_FN_SYSTEM_OFF:
>> + case KVM_PSCI_0_2_FN_SYSTEM_RESET:
>> + case KVM_PSCI_0_2_FN64_CPU_SUSPEND:
>> + case KVM_PSCI_0_2_FN64_AFFINITY_INFO:
>> + case KVM_PSCI_0_2_FN64_MIGRATE:
>> + case KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
>> + val = KVM_PSCI_RET_NOT_SUPPORTED;
>> + break;
>> + default:
>> + return false;
>> + }
>> +
>> + *vcpu_reg(vcpu, 0) = val;
>> + return true;
>> +}
>> +
>> +static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
>> {
>> unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
>> unsigned long val;
>> @@ -109,9 +141,8 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> break;
>> case KVM_PSCI_FN_CPU_SUSPEND:
>> case KVM_PSCI_FN_MIGRATE:
>> - val = KVM_PSCI_RET_NI;
>> + val = KVM_PSCI_RET_NOT_SUPPORTED;
>> break;
>> -
>> default:
>> return false;
>> }
>> @@ -119,3 +150,21 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> *vcpu_reg(vcpu, 0) = val;
>> return true;
>> }
>> +
>> +/**
>> + * kvm_psci_call - handle PSCI call if r0 value is in range
>> + * @vcpu: Pointer to the VCPU struct
>> + *
>> + * Handle PSCI calls from guests through traps from HVC instructions.
>> + * The calling convention is similar to SMC calls to the secure world where
>> + * the function number is placed in r0 and this function returns true if the
>> + * function number specified in r0 is withing the PSCI range, and false
>> + * otherwise.
>> + */
>> +bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> +{
>> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
>> + return kvm_psci_0_2_call(vcpu);
>> +
>> + return kvm_psci_0_1_call(vcpu);
>> +}
>
> Why don't we just try one after the other? Do they conflict in some
> way?
>
> I assume PSCI calls are never going to be in the critical path and calls
> into PSCI are pretty much expected to be slow as a dog anyhow, so if we
> could avoid the extra churn in user space code and potential user
> confusion (providing PSCI 0.2 kernel but too old user space tool for
> example), I think that would be preferred.
I gave more thought to this.
Currently, there is no conflict of function IDs between PSCI v0.1 and v0.2
but what if in future some new PSCI vX.Y comes-up with function IDs which
conflict with existing PSCI vA.B.
I think it is very likely that we will have more versions of PSCI and each
subsequent of version of PSCI will generally extend functions IDs defined
by PSCI v0.2
I will keep the KVM_ARM_VCPU_PSCI_0_2 feature for v2 patchset and
wait for more comments on this.
Regards,
Anup
>
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index 0a1d697..92242ce 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -39,7 +39,7 @@
>> #include <kvm/arm_vgic.h>
>> #include <kvm/arm_arch_timer.h>
>>
>> -#define KVM_VCPU_MAX_FEATURES 2
>> +#define KVM_VCPU_MAX_FEATURES 3
>>
>> struct kvm_vcpu;
>> int kvm_target_cpu(void);
>> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
>> index d9f026b..0eb254d 100644
>> --- a/arch/arm64/include/uapi/asm/kvm.h
>> +++ b/arch/arm64/include/uapi/asm/kvm.h
>> @@ -77,6 +77,7 @@ struct kvm_regs {
>>
>> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
>> #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
>> +#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
>>
>> struct kvm_vcpu_init {
>> __u32 target;
>> @@ -150,7 +151,7 @@ struct kvm_arch_memory_slot {
>> /* Highest supported SPI, from VGIC_NR_IRQS */
>> #define KVM_ARM_IRQ_GIC_MAX 127
>>
>> -/* PSCI interface */
>> +/* PSCI v0.1 interface */
>> #define KVM_PSCI_FN_BASE 0x95c1ba5e
>> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>>
>> @@ -159,10 +160,42 @@ struct kvm_arch_memory_slot {
>> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
>> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>>
>> +/* PSCI v0.2 interface */
>> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
>> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
>> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
>> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
>> +
>> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
>> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
>> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
>> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
>> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
>> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
>> + KVM_PSCI_0_2_FN(6)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN(7)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
>> +
>> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
>> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
>> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN64(7)
>> +
>> +/* PSCI return values */
>> #define KVM_PSCI_RET_SUCCESS 0
>> -#define KVM_PSCI_RET_NI ((unsigned long)-1)
>> -#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
>> +#define KVM_PSCI_RET_NOT_SUPPORTED ((unsigned long)-1)
>> +#define KVM_PSCI_RET_INVALID_PARAMS ((unsigned long)-2)
>> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
>> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
>> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
>> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
>> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
>> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>>
>> #endif
>>
>> --
>> 1.7.9.5
>>
>
> Thanks,
> --
> Christoffer
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
^ permalink raw reply
* [PATCH v2 1/6] idle: move the cpuidle entry point to the generic idle loop
From: Nicolas Pitre @ 2014-01-30 5:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52E9C946.50704@linux.vnet.ibm.com>
On Thu, 30 Jan 2014, Preeti U Murthy wrote:
> Hi Nicolas,
>
> On 01/30/2014 02:01 AM, Nicolas Pitre wrote:
> > On Wed, 29 Jan 2014, Nicolas Pitre wrote:
> >
> >> In order to integrate cpuidle with the scheduler, we must have a better
> >> proximity in the core code with what cpuidle is doing and not delegate
> >> such interaction to arch code.
> >>
> >> Architectures implementing arch_cpu_idle() should simply enter
> >> a cheap idle mode in the absence of a proper cpuidle driver.
> >>
> >> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> >> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> >
> > As mentioned in my reply to Olof's comment on patch #5/6, here's a new
> > version of this patch adding the safety local_irq_enable() to the core
> > code.
> >
> > ----- >8
> >
> > From: Nicolas Pitre <nicolas.pitre@linaro.org>
> > Subject: idle: move the cpuidle entry point to the generic idle loop
> >
> > In order to integrate cpuidle with the scheduler, we must have a better
> > proximity in the core code with what cpuidle is doing and not delegate
> > such interaction to arch code.
> >
> > Architectures implementing arch_cpu_idle() should simply enter
> > a cheap idle mode in the absence of a proper cpuidle driver.
> >
> > In both cases i.e. whether it is a cpuidle driver or the default
> > arch_cpu_idle(), the calling convention expects IRQs to be disabled
> > on entry and enabled on exit. There is a warning in place already but
> > let's add a forced IRQ enable here as well. This will allow for
> > removing the forced IRQ enable some implementations do locally and
>
> Why would this patch allow for removing the forced IRQ enable that are
> being done on some archs in arch_cpu_idle()? Isn't this patch expecting
> the default arch_cpu_idle() to have re-enabled the interrupts after
> exiting from the default idle state? Its supposed to only catch faulty
> cpuidle drivers that haven't enabled IRQs on exit from idle state but
> are expected to have done so, isn't it?
Exact. However x86 currently does this:
if (cpuidle_idle_call())
x86_idle();
else
local_irq_enable();
So whenever cpuidle_idle_call() is successful then IRQs are
unconditionally enabled whether or not the underlying cpuidle driver has
properly done it or not. And the reason is that some of the x86 cpuidle
do fail to enable IRQs before returning.
So the idea is to get rid of this unconditional IRQ enabling and let the
core issue a warning instead (as well as enabling IRQs to allow the
system to run).
Nicolas
^ permalink raw reply
* [PATCH] clk: Correct handling of NULL clk in __clk_{get, put}
From: Sachin Kamat @ 2014-01-30 4:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52CFC5C9.4000006@samsung.com>
On 10 January 2014 15:34, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
> On 08/01/14 05:44, Sachin Kamat wrote:
>> Hi Sylwester,
>>
>> On 7 January 2014 17:33, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>>> Ensure clk->kref is dereferenced only when clk is not NULL.
>>>
>>> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
>>> ---
>>> Hi Sachin,
>>>
>>> please try if this patch fixes the exyno5420 boot crash.
>>
>> Confirmed that this patch works fine on 5420 as well as already
>> working 4210 and 5250 boards.
>> Thanks for the quick fix.
>>
>> Tested-by: Sachin Kamat <sachin.kamat@linaro.org>
>
> Thanks Sachin. Mike, it seems we need this patch on top of
> my clk-unregister branch. Sorry for overlooking this issue.
> Could you add the $subject patch to your clk-next tree ?
Gentle ping Mike. Hope we can have this patch in rc-2.
--
With warm regards,
Sachin
^ permalink raw reply
* [PATCH v4 1/1] ARM: davinci: aemif: get rid of davinci-nand driver dependency on aemif
From: Sekhar Nori @ 2014-01-30 4:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52E91C54.9090302@ti.com>
On Wednesday 29 January 2014 08:50 PM, Ivan Khoronzhuk wrote:
> Hi Sekhar,
>
> Do you want me to correct it?
Yes, please!
Thanks,
Sekhar
^ permalink raw reply
* [RFC PATCH 2/3] ARM/ARM64: KVM: Add support for PSCI v0.2 emulation
From: Anup Patel @ 2014-01-30 4:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140129155005.GC3570@cbox>
On Wed, Jan 29, 2014 at 9:20 PM, Christoffer Dall
<christoffer.dall@linaro.org> wrote:
> On Wed, Jan 29, 2014 at 10:22:47AM +0530, Anup Patel wrote:
>> On Wed, Jan 29, 2014 at 2:34 AM, Christoffer Dall
>> <christoffer.dall@linaro.org> wrote:
>> > On Tue, Jan 21, 2014 at 06:31:40PM +0530, Anup Patel wrote:
>
> [...]
>
>> >
>> > Which tree does this patch apply to? It looks like you'll get a
>> > conflict with:
>> > 478a823 arm: KVM: Don't return PSCI_INVAL if waitqueue is inactive
>>
>> This patchset applies on v3.13 tag of Torvalds tree.
>
> That would not contain anything in kvm/next or kvm-arm-next.
>
>>
>> I generally base my patches on latest stable/rc tag of Torvalds tree
>> so that I can provide KVM patches to folks interested in trying KVM
>> on X-Gene with latest Linux stable/rc.
>
> If you want to make it slightly easier for me or Marc to apply your
> patches in general I would recommend basing them off kvm/next or
> kvm-arm-next, but it's no big deal.
>
> In this case all you need to consider is already in linus/master.
>
>>
>> I will make sure that revised patchset applies on top of
>> 478a823 arm: KVM: Don't return PSCI_INVAL if waitqueue is inactive
>>
>> >
>> >> }
>> >>
>> >> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
>> >> index 0881bf1..ee044a3 100644
>> >> --- a/arch/arm/kvm/psci.c
>> >> +++ b/arch/arm/kvm/psci.c
>> >> @@ -55,13 +55,13 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>> >> }
>> >>
>> >> if (!vcpu)
>> >> - return KVM_PSCI_RET_INVAL;
>> >> + return KVM_PSCI_RET_INVALID_PARAMS;
>> >>
>> >> target_pc = *vcpu_reg(source_vcpu, 2);
>> >>
>> >> wq = kvm_arch_vcpu_wq(vcpu);
>> >> if (!waitqueue_active(wq))
>> >> - return KVM_PSCI_RET_INVAL;
>> >> + return KVM_PSCI_RET_INVALID_PARAMS;
>> >>
>> >> kvm_reset_vcpu(vcpu);
>> >>
>> >> @@ -84,17 +84,49 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>> >> return KVM_PSCI_RET_SUCCESS;
>> >> }
>> >>
>> >> -/**
>> >> - * kvm_psci_call - handle PSCI call if r0 value is in range
>> >> - * @vcpu: Pointer to the VCPU struct
>> >> - *
>> >> - * Handle PSCI calls from guests through traps from HVC instructions.
>> >> - * The calling convention is similar to SMC calls to the secure world where
>> >> - * the function number is placed in r0 and this function returns true if the
>> >> - * function number specified in r0 is withing the PSCI range, and false
>> >> - * otherwise.
>> >> - */
>> >> -bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> >> +static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
>> >> +{
>> >> + unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
>> >> + unsigned long val;
>> >> +
>> >> + switch (psci_fn) {
>> >> + case KVM_PSCI_0_2_FN_PSCI_VERSION:
>> >> + /*
>> >> + * Bits[31:16] = Major Version = 0
>> >> + * Bits[15:0] = Minor Version = 2
>> >> + */
>> >> + val = 2;
>> >> + break;
>> >> + case KVM_PSCI_0_2_FN_CPU_OFF:
>> >> + kvm_psci_vcpu_off(vcpu);
>> >> + val = KVM_PSCI_RET_SUCCESS;
>> >> + break;
>> >> + case KVM_PSCI_0_2_FN_CPU_ON:
>> >> + case KVM_PSCI_0_2_FN64_CPU_ON:
>> >> + val = kvm_psci_vcpu_on(vcpu);
>> >> + break;
>> >> + case KVM_PSCI_0_2_FN_CPU_SUSPEND:
>> >> + case KVM_PSCI_0_2_FN_AFFINITY_INFO:
>> >> + case KVM_PSCI_0_2_FN_MIGRATE:
>> >> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
>> >> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
>> >> + case KVM_PSCI_0_2_FN_SYSTEM_OFF:
>> >> + case KVM_PSCI_0_2_FN_SYSTEM_RESET:
>> >> + case KVM_PSCI_0_2_FN64_CPU_SUSPEND:
>> >> + case KVM_PSCI_0_2_FN64_AFFINITY_INFO:
>> >> + case KVM_PSCI_0_2_FN64_MIGRATE:
>> >> + case KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
>> >> + val = KVM_PSCI_RET_NOT_SUPPORTED;
>> >> + break;
>> >> + default:
>> >> + return false;
>> >> + }
>> >> +
>> >> + *vcpu_reg(vcpu, 0) = val;
>> >> + return true;
>> >> +}
>> >> +
>> >> +static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
>> >> {
>> >> unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
>> >> unsigned long val;
>> >> @@ -109,9 +141,8 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> >> break;
>> >> case KVM_PSCI_FN_CPU_SUSPEND:
>> >> case KVM_PSCI_FN_MIGRATE:
>> >> - val = KVM_PSCI_RET_NI;
>> >> + val = KVM_PSCI_RET_NOT_SUPPORTED;
>> >> break;
>> >> -
>> >> default:
>> >> return false;
>> >> }
>> >> @@ -119,3 +150,21 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> >> *vcpu_reg(vcpu, 0) = val;
>> >> return true;
>> >> }
>> >> +
>> >> +/**
>> >> + * kvm_psci_call - handle PSCI call if r0 value is in range
>> >> + * @vcpu: Pointer to the VCPU struct
>> >> + *
>> >> + * Handle PSCI calls from guests through traps from HVC instructions.
>> >> + * The calling convention is similar to SMC calls to the secure world where
>> >> + * the function number is placed in r0 and this function returns true if the
>> >> + * function number specified in r0 is withing the PSCI range, and false
>> >> + * otherwise.
>> >> + */
>> >> +bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> >> +{
>> >> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
>> >> + return kvm_psci_0_2_call(vcpu);
>> >> +
>> >> + return kvm_psci_0_1_call(vcpu);
>> >> +}
>> >
>> > Why don't we just try one after the other? Do they conflict in some
>> > way?
>>
>> Atleast the functions IDs are totally different in v0.2 and v0.1
>>
>> Also, in v0.2 we have separate function IDs for 32bit and 64bit
>> VCPU calling same PSCI function.
>>
>
> So we could just do:
>
> {
> ret = kvm_psci_0_2_call(vcpu);
> if (ret)
> return ret;
>
> ret = kvm_psci_0_1_call(vcpu);
> if (ret)
> return ret;
>
> return false;
> }
>
> and be rid of the vcpu feature, or? I thought this was Marc's point in
> the last KVM/ARM call?
OK, I will update kvm_psci_call() as per this.
>
>> >
>> > I assume PSCI calls are never going to be in the critical path and calls
>> > into PSCI are pretty much expected to be slow as a dog anyhow, so if we
>> > could avoid the extra churn in user space code and potential user
>> > confusion (providing PSCI 0.2 kernel but too old user space tool for
>> > example), I think that would be preferred.
>>
>> Yes, PSCI calls will not be in critical path except few functions such as
>> PSCI CPU_SUSPEND and CPU_ON.
>>
>> For example,
>> On real HW, people are very much interested in time taken to resume a
>> HW CPU from suspended state because this affects responsiveness of
>> a system.
>>
>
> In which case time taken to wake up from suspended state in a VM will
> for sure not be dominated by an extra call to a psci function id
> checking function.
>
> Thanks,
> -Christoffer
--
Anup
^ permalink raw reply
* [PATCH v2 1/6] idle: move the cpuidle entry point to the generic idle loop
From: Preeti U Murthy @ 2014-01-30 3:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.11.1401291526320.1652@knanqh.ubzr>
Hi Nicolas,
On 01/30/2014 02:01 AM, Nicolas Pitre wrote:
> On Wed, 29 Jan 2014, Nicolas Pitre wrote:
>
>> In order to integrate cpuidle with the scheduler, we must have a better
>> proximity in the core code with what cpuidle is doing and not delegate
>> such interaction to arch code.
>>
>> Architectures implementing arch_cpu_idle() should simply enter
>> a cheap idle mode in the absence of a proper cpuidle driver.
>>
>> Signed-off-by: Nicolas Pitre <nico@linaro.org>
>> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
>
> As mentioned in my reply to Olof's comment on patch #5/6, here's a new
> version of this patch adding the safety local_irq_enable() to the core
> code.
>
> ----- >8
>
> From: Nicolas Pitre <nicolas.pitre@linaro.org>
> Subject: idle: move the cpuidle entry point to the generic idle loop
>
> In order to integrate cpuidle with the scheduler, we must have a better
> proximity in the core code with what cpuidle is doing and not delegate
> such interaction to arch code.
>
> Architectures implementing arch_cpu_idle() should simply enter
> a cheap idle mode in the absence of a proper cpuidle driver.
>
> In both cases i.e. whether it is a cpuidle driver or the default
> arch_cpu_idle(), the calling convention expects IRQs to be disabled
> on entry and enabled on exit. There is a warning in place already but
> let's add a forced IRQ enable here as well. This will allow for
> removing the forced IRQ enable some implementations do locally and
Why would this patch allow for removing the forced IRQ enable that are
being done on some archs in arch_cpu_idle()? Isn't this patch expecting
the default arch_cpu_idle() to have re-enabled the interrupts after
exiting from the default idle state? Its supposed to only catch faulty
cpuidle drivers that haven't enabled IRQs on exit from idle state but
are expected to have done so, isn't it?
Thanks
Regards
Preeti U Murthy
> allowing for the warning to trig.
>
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
>
> diff --git a/kernel/cpu/idle.c b/kernel/cpu/idle.c
> index 988573a9a3..14ca43430a 100644
> --- a/kernel/cpu/idle.c
> +++ b/kernel/cpu/idle.c
> @@ -3,6 +3,7 @@
> */
> #include <linux/sched.h>
> #include <linux/cpu.h>
> +#include <linux/cpuidle.h>
> #include <linux/tick.h>
> #include <linux/mm.h>
> #include <linux/stackprotector.h>
> @@ -95,8 +96,10 @@ static void cpu_idle_loop(void)
> if (!current_clr_polling_and_test()) {
> stop_critical_timings();
> rcu_idle_enter();
> - arch_cpu_idle();
> - WARN_ON_ONCE(irqs_disabled());
> + if (cpuidle_idle_call())
> + arch_cpu_idle();
> + if (WARN_ON_ONCE(irqs_disabled()))
> + local_irq_enable();
> rcu_idle_exit();
> start_critical_timings();
> } else {
>
^ permalink raw reply
* [PATCH] of: add vendor prefix for Allwinner Technology
From: Emilio López @ 2014-01-30 1:36 UTC (permalink / raw)
To: linux-arm-kernel
We have been using the "allwinner" prefix for everything so far; let's
document it here.
Signed-off-by: Emilio L?pez <emilio@elopez.com.ar>
---
Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index edbb8d8..5a2904b 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -7,6 +7,7 @@ ad Avionic Design GmbH
adi Analog Devices, Inc.
aeroflexgaisler Aeroflex Gaisler AB
ak Asahi Kasei Corp.
+allwinner Allwinner Technology Co., Ltd.
altr Altera Corp.
amcc Applied Micro Circuits Corporation (APM, formally AMCC)
apm Applied Micro Circuits Corporation (APM)
--
1.8.5.3
^ permalink raw reply related
* [linux-sunxi] [PATCH v2 3/5] spi: sunxi: Add Allwinner A31 SPI controller driver
From: Emilio López @ 2014-01-30 1:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390993850-9054-4-git-send-email-maxime.ripard@free-electrons.com>
Hi Maxime,
El 29/01/14 08:10, Maxime Ripard escribi?:
> The Allwinner A31 has a new SPI controller IP compared to the older Allwinner
> SoCs.
>
> It supports DMA, but the driver only does PIO for now, and DMA will be
> supported eventually.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
(snip)
> + struct sun6i_spi *sspi = spi_master_get_devdata(master);
> + int ret;
> +
> + ret = clk_prepare_enable(sspi->hclk);
> + if (ret) {
> + dev_err(dev, "Couldn't enable clock 'ahb spi'\n");
> + goto out;
> + }
> +
> + ret = clk_prepare_enable(sspi->mclk);
> + if (ret) {
> + dev_err(dev, "Couldn't enable clock 'ahb spi'\n");
A different message would be nice :)
Cheers,
Emilio
^ permalink raw reply
* [RFC PATCH V3 0/4] APM X-Gene PCIe controller
From: Tanmay Inamdar @ 2014-01-30 0:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAErSpo7Dfd4NJBEDuVe1VCvZObFq1YvV2x77S60Z4-CZq89QJw@mail.gmail.com>
On Wed, Jan 29, 2014 at 4:18 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Sat, Jan 25, 2014 at 9:09 AM, Dann Frazier
> <dann.frazier@canonical.com> wrote:
>> On Fri, Jan 24, 2014 at 2:32 PM, Tanmay Inamdar <tinamdar@apm.com> wrote:
>>> This patch adds support for AppliedMicro X-Gene PCIe host controller. The
>>> driver is tested on X-Gene platform with different gen1/2/3 PCIe endpoint
>>> cards.
>>>
>>> X-Gene PCIe controller driver has depedency on the pcie arch support for
>>> arm64. The arm64 pcie arch support is not yet part of mainline Linux kernel
>>> and approach for arch support is under discussion with arm64 maintainers.
>>> The reference patch can be found here --> https://lkml.org/lkml/2013/10/23/244
>>
>> The reference patch looks corrupted (pcibios.c has no includes, etc),
>> would you mind reposting?
>
> When you repost, please make sure you fix whatever problem is
> preventing your email from appearing on the vger mailing lists. I
> won't apply things that haven't appeared on the linux-pci list,
> because that list is the opportunity for other people to review them.
>
You are absolutely right. If the patches are not reaching mailing
list, they should not appear on archive list as well. However I am
seeing my patches recorded on archives. So I am not sure if they are
actually getting dropped on linux-pci or any other mailing list.
http://www.spinics.net/lists/linux-pci/msg28198.html
http://article.gmane.org/gmane.linux.kernel.pci/28442/match=tanmay+inamdar
> Bjorn
^ permalink raw reply
* linux-next: manual merge of the arm-soc tree with Linus' tree
From: Stephen Rothwell @ 2014-01-30 0:19 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
Today's linux-next merge of the arm-soc tree got a conflict in
drivers/clk/Makefile between commit fd3fdaf09f26 ("clk: sort Makefile")
from Linus' tree and commit 7ee2c5117483 ("clk: bcm281xx: add initial
clock framework support") from the arm-soc tree.
I fixed it up (see below) and can carry the fix as necessary (no action
is required).
--
Cheers,
Stephen Rothwell sfr at canb.auug.org.au
diff --cc drivers/clk/Makefile
index a367a9831717,7c7f40e9ba05..000000000000
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@@ -9,44 -9,44 +9,45 @@@ obj-$(CONFIG_COMMON_CLK) += clk-gate.
obj-$(CONFIG_COMMON_CLK) += clk-mux.o
obj-$(CONFIG_COMMON_CLK) += clk-composite.o
-# SoCs specific
-obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
-obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
-obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
-obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
-obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/
-obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
-obj-$(CONFIG_ARCH_MXS) += mxs/
-obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
-obj-$(CONFIG_PLAT_SPEAR) += spear/
-obj-$(CONFIG_ARCH_U300) += clk-u300.o
-obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
-obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o
-obj-$(CONFIG_PLAT_ORION) += mvebu/
+# hardware specific clock types
+# please keep this section sorted lexicographically by file/directory path name
++obj-$(CONFIG_ARCH_BCM) += bcm/
+obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
+obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
+obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
+obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
+obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
+obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
+obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
+obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
+obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
+obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
+obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
+obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
+obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
+obj-$(CONFIG_ARCH_U300) += clk-u300.o
+obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
+obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
+obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
+obj-$(CONFIG_COMMON_CLK_AT91) += at91/
+obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/
+obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
ifeq ($(CONFIG_COMMON_CLK), y)
-obj-$(CONFIG_ARCH_MMP) += mmp/
+obj-$(CONFIG_ARCH_MMP) += mmp/
endif
-obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
-obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
-obj-$(CONFIG_ARCH_SUNXI) += sunxi/
-obj-$(CONFIG_ARCH_U8500) += ux500/
-obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
-obj-$(CONFIG_ARCH_ZYNQ) += zynq/
-obj-$(CONFIG_ARCH_TEGRA) += tegra/
-obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
-obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
-obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
-obj-$(CONFIG_COMMON_CLK_AT91) += at91/
+obj-$(CONFIG_PLAT_ORION) += mvebu/
+obj-$(CONFIG_ARCH_MXS) += mxs/
+obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
+obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
+obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile/
-
-obj-$(CONFIG_X86) += x86/
-obj-$(CONFIG_ARCH_BCM) += bcm/
-
-# Chip specific
-obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
-obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
-obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
-obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
-obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
-obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
-obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
+obj-$(CONFIG_ARCH_SIRF) += sirf/
+obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
+obj-$(CONFIG_PLAT_SPEAR) += spear/
+obj-$(CONFIG_ARCH_SUNXI) += sunxi/
+obj-$(CONFIG_ARCH_TEGRA) += tegra/
+obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/
+obj-$(CONFIG_ARCH_U8500) += ux500/
+obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
+obj-$(CONFIG_X86) += x86/
+obj-$(CONFIG_ARCH_ZYNQ) += zynq/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140130/7fbd45c9/attachment.sig>
^ permalink raw reply
* [RFC PATCH V3 0/4] APM X-Gene PCIe controller
From: Bjorn Helgaas @ 2014-01-30 0:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CALdTtnsEo74UeYgoQ0DF7=LN074b_0bL0vg6Bxs02B9nDkRTNA@mail.gmail.com>
On Sat, Jan 25, 2014 at 9:09 AM, Dann Frazier
<dann.frazier@canonical.com> wrote:
> On Fri, Jan 24, 2014 at 2:32 PM, Tanmay Inamdar <tinamdar@apm.com> wrote:
>> This patch adds support for AppliedMicro X-Gene PCIe host controller. The
>> driver is tested on X-Gene platform with different gen1/2/3 PCIe endpoint
>> cards.
>>
>> X-Gene PCIe controller driver has depedency on the pcie arch support for
>> arm64. The arm64 pcie arch support is not yet part of mainline Linux kernel
>> and approach for arch support is under discussion with arm64 maintainers.
>> The reference patch can be found here --> https://lkml.org/lkml/2013/10/23/244
>
> The reference patch looks corrupted (pcibios.c has no includes, etc),
> would you mind reposting?
When you repost, please make sure you fix whatever problem is
preventing your email from appearing on the vger mailing lists. I
won't apply things that haven't appeared on the linux-pci list,
because that list is the opportunity for other people to review them.
Bjorn
^ permalink raw reply
* [PATCH V5 5/5] Documentation: power: reset: Add documentation for generic SYSCON reboot driver
From: Feng Kan @ 2014-01-30 0:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391040198-14185-1-git-send-email-fkan@apm.com>
Add documentation for generic SYSCON reboot driver.
Signed-off-by: Feng Kan <fkan@apm.com>
---
.../bindings/power/reset/syscon-reboot.txt | 23 ++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power/reset/syscon-reboot.txt
diff --git a/Documentation/devicetree/bindings/power/reset/syscon-reboot.txt b/Documentation/devicetree/bindings/power/reset/syscon-reboot.txt
new file mode 100644
index 0000000..963f3c3
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/syscon-reboot.txt
@@ -0,0 +1,23 @@
+Generic SYSCON mapped register reset driver
+
+This is a generic reset driver using syscon to map the reset register.
+The reset is generally performed with a write to the reset register
+defined by the register map pointed by syscon reference plus the offset
+with the mask defined in the reboot node.
+
+Required properties:
+- compatible: should contain "syscon-reboot"
+- regmap: this is phandle to the register map node
+- offset: offset in the register map for the reboot register (in bytes)
+- mask: the reset value written to the reboot register (32 bit access)
+
+Default will be little endian mode, 32 bit access only.
+
+Examples:
+
+ reboot {
+ compatible = "syscon-reboot";
+ regmap = <®mapnode>;
+ offset = <0x0>;
+ mask = <0x1>;
+ };
--
1.7.6.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox